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:
parent
edf5761c83
commit
f9eaee35b8
5 changed files with 46 additions and 10 deletions
|
@ -10,7 +10,7 @@ set_property(SOURCE intel64/locore.S PROPERTY LANGUAGE ASM)
|
||||||
|
|
||||||
zephyr_library_sources(
|
zephyr_library_sources(
|
||||||
intel64/locore.S
|
intel64/locore.S
|
||||||
intel64/tss.c
|
intel64/cpu.c
|
||||||
intel64/irq.c
|
intel64/irq.c
|
||||||
intel64/thread.c
|
intel64/thread.c
|
||||||
intel64/fatal.c
|
intel64/fatal.c
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
#include <kernel_arch_data.h>
|
#include <kernel_arch_data.h>
|
||||||
#include <kernel_arch_func.h>
|
#include <kernel_arch_func.h>
|
||||||
#include <kernel_structs.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[];
|
extern u8_t _exception_stack[];
|
||||||
|
|
||||||
|
@ -15,6 +18,14 @@ struct x86_tss64 tss0 = {
|
||||||
.ist1 = (u64_t) _interrupt_stack + CONFIG_ISR_STACK_SIZE,
|
.ist1 = (u64_t) _interrupt_stack + CONFIG_ISR_STACK_SIZE,
|
||||||
.ist7 = (u64_t) _exception_stack + CONFIG_EXCEPTION_STACK_SIZE,
|
.ist7 = (u64_t) _exception_stack + CONFIG_EXCEPTION_STACK_SIZE,
|
||||||
.iomapb = 0xFFFF, /* no I/O access bitmap */
|
.iomapb = 0xFFFF, /* no I/O access bitmap */
|
||||||
|
|
||||||
.cpu = &(_kernel.cpus[0])
|
.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
|
||||||
|
}
|
||||||
|
};
|
|
@ -39,6 +39,9 @@ __start:
|
||||||
movl $__bss_num_dwords, %ecx
|
movl $__bss_num_dwords, %ecx
|
||||||
rep stosl
|
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,
|
* transition to long mode, reload the segment registers,
|
||||||
* and configure per-CPU stuff: GS, task register, stack.
|
* and configure per-CPU stuff: GS, task register, stack.
|
||||||
|
@ -71,12 +74,12 @@ __start:
|
||||||
movw %ax, %ss
|
movw %ax, %ss
|
||||||
movw %ax, %fs
|
movw %ax, %fs
|
||||||
|
|
||||||
movl $X86_KERNEL_CPU0_TR, %eax
|
movw __x86_cpuboot_t_tr_OFFSET(%rbp), %ax
|
||||||
ltr %ax
|
ltr %ax
|
||||||
movl $X86_KERNEL_CPU0_GS, %eax
|
movw __x86_cpuboot_t_gs_OFFSET(%rbp), %ax
|
||||||
movw %ax, %gs
|
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.
|
* finally, complete environment for the C runtime and go.
|
||||||
|
@ -86,7 +89,8 @@ __start:
|
||||||
|
|
||||||
#ifdef CONFIG_INIT_STACKS
|
#ifdef CONFIG_INIT_STACKS
|
||||||
movq $0xAAAAAAAAAAAAAAAA, %rax
|
movq $0xAAAAAAAAAAAAAAAA, %rax
|
||||||
movq $_interrupt_stack, %rdi
|
movq %rsp, %rdi
|
||||||
|
subq $CONFIG_ISR_STACK_SIZE, %rdi
|
||||||
movq $(CONFIG_ISR_STACK_SIZE >> 3), %rcx
|
movq $(CONFIG_ISR_STACK_SIZE >> 3), %rcx
|
||||||
rep stosq
|
rep stosq
|
||||||
#endif
|
#endif
|
||||||
|
@ -100,8 +104,8 @@ __start:
|
||||||
|
|
||||||
/* don't replace CALL with JMP; honor the ABI stack alignment! */
|
/* don't replace CALL with JMP; honor the ABI stack alignment! */
|
||||||
|
|
||||||
movl %ebx, %edi /* multiboot pointer (or NULL) */
|
movq __x86_cpuboot_t_arg_OFFSET(%rbp), %rdi
|
||||||
call z_x86_prep_c /* enter kernel; never returns */
|
call *__x86_cpuboot_t_fn_OFFSET(%rbp) /* enter kernel; never return */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void x86_sse_init(struct k_thread *thread);
|
* void x86_sse_init(struct k_thread *thread);
|
||||||
|
@ -147,13 +151,13 @@ z_arch_switch:
|
||||||
movq %r14, _thread_offset_to_r14(%rsi)
|
movq %r14, _thread_offset_to_r14(%rsi)
|
||||||
movq %r15, _thread_offset_to_r15(%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 */
|
/* fall through to __resume */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Entry:
|
* Entry:
|
||||||
* RSP = top of _interrupt_stack
|
* RSP = top of CPU interrupt stack
|
||||||
* RDI = (struct k_thread *) thread to resume
|
* RDI = (struct k_thread *) thread to resume
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -31,3 +31,10 @@ GEN_OFFSET_SYM(_thread_arch_t, sse);
|
||||||
GEN_OFFSET_SYM(x86_tss64_t, ist1);
|
GEN_OFFSET_SYM(x86_tss64_t, ist1);
|
||||||
GEN_OFFSET_SYM(x86_tss64_t, cpu);
|
GEN_OFFSET_SYM(x86_tss64_t, cpu);
|
||||||
GEN_ABSOLUTE_SYM(__X86_TSS64_SIZEOF, sizeof(x86_tss64_t));
|
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));
|
||||||
|
|
|
@ -72,6 +72,20 @@ struct x86_tss64 {
|
||||||
|
|
||||||
typedef struct x86_tss64 x86_tss64_t;
|
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 /* _ASMLANGUAGE */
|
||||||
|
|
||||||
#endif /* ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_DATA_H_ */
|
#endif /* ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_DATA_H_ */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue