diff --git a/arch/x86/core/intel64.cmake b/arch/x86/core/intel64.cmake index db83ed7c69b..b6227d2ecde 100644 --- a/arch/x86/core/intel64.cmake +++ b/arch/x86/core/intel64.cmake @@ -10,7 +10,7 @@ set_property(SOURCE intel64/locore.S PROPERTY LANGUAGE ASM) zephyr_library_sources( intel64/locore.S - intel64/tss.c + intel64/cpu.c intel64/irq.c intel64/thread.c intel64/fatal.c diff --git a/arch/x86/core/intel64/tss.c b/arch/x86/core/intel64/cpu.c similarity index 63% rename from arch/x86/core/intel64/tss.c rename to arch/x86/core/intel64/cpu.c index 3e2d6cddd3d..15cd04e6463 100644 --- a/arch/x86/core/intel64/tss.c +++ b/arch/x86/core/intel64/cpu.c @@ -7,6 +7,9 @@ #include #include #include +#include + +extern FUNC_NORETURN void z_x86_prep_c(struct multiboot_info *); extern u8_t _exception_stack[]; @@ -15,6 +18,14 @@ struct x86_tss64 tss0 = { .ist1 = (u64_t) _interrupt_stack + CONFIG_ISR_STACK_SIZE, .ist7 = (u64_t) _exception_stack + CONFIG_EXCEPTION_STACK_SIZE, .iomapb = 0xFFFF, /* no I/O access bitmap */ - .cpu = &(_kernel.cpus[0]) }; + +struct x86_cpuboot x86_cpuboot[] = { + { + .tr = X86_KERNEL_CPU0_TR, + .gs = X86_KERNEL_CPU0_GS, + .sp = (u64_t) _interrupt_stack + CONFIG_ISR_STACK_SIZE, + .fn = z_x86_prep_c + } +}; diff --git a/arch/x86/core/intel64/locore.S b/arch/x86/core/intel64/locore.S index 160f68bd666..2a065239e91 100644 --- a/arch/x86/core/intel64/locore.S +++ b/arch/x86/core/intel64/locore.S @@ -39,6 +39,9 @@ __start: movl $__bss_num_dwords, %ecx rep stosl + movl $x86_cpuboot, %ebp /* BSP is always logical CPU id 0 */ + movl %ebx, __x86_cpuboot_t_arg_OFFSET(%ebp) /* multiboot info */ + /* * transition to long mode, reload the segment registers, * and configure per-CPU stuff: GS, task register, stack. @@ -71,12 +74,12 @@ __start: movw %ax, %ss movw %ax, %fs - movl $X86_KERNEL_CPU0_TR, %eax + movw __x86_cpuboot_t_tr_OFFSET(%rbp), %ax ltr %ax - movl $X86_KERNEL_CPU0_GS, %eax + movw __x86_cpuboot_t_gs_OFFSET(%rbp), %ax movw %ax, %gs - movl $(_interrupt_stack + CONFIG_ISR_STACK_SIZE), %esp + movq __x86_cpuboot_t_sp_OFFSET(%rbp), %rsp /* * finally, complete environment for the C runtime and go. @@ -86,7 +89,8 @@ __start: #ifdef CONFIG_INIT_STACKS movq $0xAAAAAAAAAAAAAAAA, %rax - movq $_interrupt_stack, %rdi + movq %rsp, %rdi + subq $CONFIG_ISR_STACK_SIZE, %rdi movq $(CONFIG_ISR_STACK_SIZE >> 3), %rcx rep stosq #endif @@ -100,8 +104,8 @@ __start: /* don't replace CALL with JMP; honor the ABI stack alignment! */ - movl %ebx, %edi /* multiboot pointer (or NULL) */ - call z_x86_prep_c /* enter kernel; never returns */ + movq __x86_cpuboot_t_arg_OFFSET(%rbp), %rdi + call *__x86_cpuboot_t_fn_OFFSET(%rbp) /* enter kernel; never return */ /* * void x86_sse_init(struct k_thread *thread); @@ -147,13 +151,13 @@ z_arch_switch: movq %r14, _thread_offset_to_r14(%rsi) movq %r15, _thread_offset_to_r15(%rsi) - movq $(_interrupt_stack + CONFIG_ISR_STACK_SIZE), %rsp + movq %gs:__x86_tss64_t_ist1_OFFSET, %rsp /* fall through to __resume */ /* * Entry: - * RSP = top of _interrupt_stack + * RSP = top of CPU interrupt stack * RDI = (struct k_thread *) thread to resume */ diff --git a/arch/x86/core/offsets/intel64_offsets.c b/arch/x86/core/offsets/intel64_offsets.c index c721a2b3fb2..34e2e4d0e05 100644 --- a/arch/x86/core/offsets/intel64_offsets.c +++ b/arch/x86/core/offsets/intel64_offsets.c @@ -31,3 +31,10 @@ GEN_OFFSET_SYM(_thread_arch_t, sse); GEN_OFFSET_SYM(x86_tss64_t, ist1); GEN_OFFSET_SYM(x86_tss64_t, cpu); GEN_ABSOLUTE_SYM(__X86_TSS64_SIZEOF, sizeof(x86_tss64_t)); + +GEN_OFFSET_SYM(x86_cpuboot_t, tr); +GEN_OFFSET_SYM(x86_cpuboot_t, gs); +GEN_OFFSET_SYM(x86_cpuboot_t, sp); +GEN_OFFSET_SYM(x86_cpuboot_t, fn); +GEN_OFFSET_SYM(x86_cpuboot_t, arg); +GEN_ABSOLUTE_SYM(__X86_CPUBOOT_SIZEOF, sizeof(x86_cpuboot_t)); diff --git a/arch/x86/include/intel64/kernel_arch_data.h b/arch/x86/include/intel64/kernel_arch_data.h index 794b28aba73..858672e3bfd 100644 --- a/arch/x86/include/intel64/kernel_arch_data.h +++ b/arch/x86/include/intel64/kernel_arch_data.h @@ -72,6 +72,20 @@ struct x86_tss64 { typedef struct x86_tss64 x86_tss64_t; +/* + * Per-CPU bootstrapping parameters. See locore.S and cpu.c. + */ + +struct x86_cpuboot { + u16_t tr; /* selector for task register */ + u16_t gs; /* selector for GS */ + u64_t sp; /* initial stack pointer */ + void *fn; /* kernel entry function */ + void *arg; /* argument for above function */ +}; + +typedef struct x86_cpuboot x86_cpuboot_t; + #endif /* _ASMLANGUAGE */ #endif /* ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_DATA_H_ */