arch/x86: (Intel64) use per-CPU parameter struct for CPU startup

A new 'struct x86_cpuboot' is created as well as an instance called
'x86_cpuboot[]' which contains per-CPU boot data (initial stack,
entry function/arg, selectors, etc.). The locore now consults this
table to set up per-CPU registers, etc. during early boot.

Also, rename tss.c to cpu.c as its scope is growing.

Signed-off-by: Charles E. Youse <charles.youse@intel.com>
This commit is contained in:
Charles E. Youse 2019-09-28 20:52:07 -04:00 committed by Anas Nashif
commit f9eaee35b8
5 changed files with 46 additions and 10 deletions

View file

@ -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

View file

@ -7,6 +7,9 @@
#include <kernel_arch_data.h>
#include <kernel_arch_func.h>
#include <kernel_structs.h>
#include <arch/x86/multiboot.h>
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
}
};

View file

@ -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
*/

View file

@ -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));

View file

@ -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_ */