From e1f2292895495d99091c0fe34336d312a036c3fb Mon Sep 17 00:00:00 2001 From: Andrew Boie Date: Fri, 18 Oct 2019 12:08:10 -0700 Subject: [PATCH] x86: intel64: set page tables for every CPU The page tables to use are now stored in the cpuboot struct. For the first CPU, we set to the flat page tables, and then update later in z_x86_prep_c() once the runtime tables have been generated. For other CPUs, by the time we get to z_arch_start_cpu() the runtime tables are ready do go, and so we just install them directly. Signed-off-by: Andrew Boie --- arch/x86/core/intel64/cpu.c | 11 ++++++++++- arch/x86/core/intel64/locore.S | 9 +++++++-- arch/x86/core/offsets/intel64_offsets.c | 3 +++ arch/x86/include/intel64/kernel_arch_data.h | 5 +++++ 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/arch/x86/core/intel64/cpu.c b/arch/x86/core/intel64/cpu.c index 4bb2e65e784..60291c57a39 100644 --- a/arch/x86/core/intel64/cpu.c +++ b/arch/x86/core/intel64/cpu.c @@ -8,6 +8,7 @@ #include #include #include +#include #include /* @@ -59,12 +60,17 @@ struct x86_tss64 tss3 = { }; #endif +extern struct x86_page_tables z_x86_flat_ptables; + 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 + .fn = z_x86_prep_c, +#ifdef CONFIG_X86_MMU + .ptables = &z_x86_flat_ptables, +#endif }, #if CONFIG_MP_NUM_CPUS > 1 { @@ -100,6 +106,9 @@ void z_arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz, x86_cpuboot[cpu_num].sp = (u64_t) Z_THREAD_STACK_BUFFER(stack) + sz; x86_cpuboot[cpu_num].fn = fn; x86_cpuboot[cpu_num].arg = arg; +#ifdef CONFIG_X86_MMU + x86_cpuboot[cpu_num].ptables = &z_x86_kernel_ptables; +#endif /* CONFIG_X86_MMU */ z_loapic_ipi(apic_id, LOAPIC_ICR_IPI_INIT, 0); k_busy_wait(10000); diff --git a/arch/x86/core/intel64/locore.S b/arch/x86/core/intel64/locore.S index 92e09c1dc3e..632872d51b6 100644 --- a/arch/x86/core/intel64/locore.S +++ b/arch/x86/core/intel64/locore.S @@ -109,7 +109,11 @@ go64: movl %cr4, %eax /* enable PAE and SSE */ movl %eax, %cr4 clts - movl $pml4, %eax /* load page base */ +#ifdef CONFIG_X86_MMU + movl __x86_cpuboot_t_ptables_OFFSET(%ebp), %eax +#else + movl $z_x86_flat_ptables, %eax +#endif movl %eax, %cr3 movl $X86_EFER_MSR, %ecx /* enable long mode and no-execute */ @@ -548,7 +552,8 @@ idt48: .align 4096 -pml4: +.globl z_x86_flat_ptables +z_x86_flat_ptables: .long pdp + 0x03 /* 0x03 = R/W, P */ .long 0 .fill 4088, 1, 0 diff --git a/arch/x86/core/offsets/intel64_offsets.c b/arch/x86/core/offsets/intel64_offsets.c index 0d2ca10380e..7f60630257c 100644 --- a/arch/x86/core/offsets/intel64_offsets.c +++ b/arch/x86/core/offsets/intel64_offsets.c @@ -38,4 +38,7 @@ 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); +#ifdef CONFIG_X86_MMU +GEN_OFFSET_SYM(x86_cpuboot_t, ptables); +#endif /* CONFIG_X86_MMU */ 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 6885e956f95..02621446127 100644 --- a/arch/x86/include/intel64/kernel_arch_data.h +++ b/arch/x86/include/intel64/kernel_arch_data.h @@ -6,6 +6,8 @@ #ifndef ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_DATA_H_ #define ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_DATA_H_ +#include + /* * Some SSE definitions. Ideally these will ultimately be shared with 32-bit. */ @@ -89,6 +91,9 @@ struct x86_cpuboot { u64_t sp; /* initial stack pointer */ void *fn; /* kernel entry function */ void *arg; /* argument for above function */ +#ifdef CONFIG_X86_MMU + struct x86_page_tables *ptables; /* Runtime page tables to install */ +#endif /* CONFIG_X86_MMU */ }; typedef struct x86_cpuboot x86_cpuboot_t;