Attention is currently required from: Jason Glenesk, Raul Rangel, Marshall Dawson, Fred Reitberger, Felix Held. Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/63728 )
Change subject: [NOTFORMERGE/WIP]cpu/x86: Prepare for the page table to be linked in stage ......................................................................
[NOTFORMERGE/WIP]cpu/x86: Prepare for the page table to be linked in stage
Change-Id: Ifafad97a5216616a5c7cf01684484cd23ae137b8 Signed-off-by: Arthur Heymans arthur@aheymans.xyz --- M src/arch/x86/Kconfig M src/arch/x86/bootblock.ld M src/cpu/x86/64bit/Makefile.inc M src/cpu/x86/64bit/entry64.inc M src/cpu/x86/mp_init.c M src/cpu/x86/sipi_vector.S M src/cpu/x86/smm/smm_module_handler.c M src/cpu/x86/smm/smm_module_loader.c M src/cpu/x86/smm/smm_stub.S M src/include/cpu/x86/smm.h M src/soc/amd/common/block/cpu/Kconfig 11 files changed, 53 insertions(+), 7 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/28/63728/1
diff --git a/src/arch/x86/Kconfig b/src/arch/x86/Kconfig index e9fce50..7285575 100644 --- a/src/arch/x86/Kconfig +++ b/src/arch/x86/Kconfig @@ -81,9 +81,16 @@ is an experimental option: do not enable unless one wants to test it and has the means to recover a system when coreboot fails to boot.
+config ARCH_X86_64_PGTBL_CBFS + bool + depends on ARCH_BOOTBLOCK_X86_64 + default y + help + Select this if you want to include RO page tables as a cbfs file. + config ARCH_X86_64_PGTBL_LOC hex "x86_64 page table location in CBFS" - depends on ARCH_BOOTBLOCK_X86_64 + depends on ARCH_X86_64_PGTBL_CBFS default 0xfffe9000 help The position where to place pagetables. Needs to be known at diff --git a/src/arch/x86/bootblock.ld b/src/arch/x86/bootblock.ld index 0b908bb..a99e8c0 100644 --- a/src/arch/x86/bootblock.ld +++ b/src/arch/x86/bootblock.ld @@ -29,7 +29,7 @@ * may cause the total size of a section to change when the start * address gets applied. */ - PROGRAM_SZ = SIZEOF(.text) + 512; + PROGRAM_SZ = SIZEOF(.text) + 10000;
. = MIN(_ECFW_PTR, MIN(_ID_SECTION, _FIT_POINTER)) - EARLYASM_SZ; . = CONFIG(SIPI_VECTOR_IN_ROM) ? ALIGN(4096) : ALIGN(16); diff --git a/src/cpu/x86/64bit/Makefile.inc b/src/cpu/x86/64bit/Makefile.inc index 47fd006..ea319bb 100644 --- a/src/cpu/x86/64bit/Makefile.inc +++ b/src/cpu/x86/64bit/Makefile.inc @@ -5,8 +5,13 @@ $(OBJCOPY_ramstage) -Obinary -j .rodata $@.tmp $@ rm $@.tmp
-cbfs-files-y += pagetables +cbfs-files-$(CONFIG_ARCH_X86_64_PGTBL_CBFS) += pagetables pagetables-file := $(objcbfs)/pt pagetables-type := raw pagetables-compression := none pagetables-COREBOOT-position := $(CONFIG_ARCH_X86_64_PGTBL_LOC) + +smm-y += pt.S +ifneq ($(CONFIGARCH_X86_64_PGTBL_CBFS),y) +all-y += pt.S +endif diff --git a/src/cpu/x86/64bit/entry64.inc b/src/cpu/x86/64bit/entry64.inc index 7da68b4..51e5585 100644 --- a/src/cpu/x86/64bit/entry64.inc +++ b/src/cpu/x86/64bit/entry64.inc @@ -22,10 +22,15 @@ #include <arch/rom_segs.h> #endif
+#if CONFIG(ARCH_X86_64_PGTBL_CBFS) && ENV_BOOTBLOCK +#define PGTBL_LOC $(CONFIG_ARCH_X86_64_PGTBL_LOC) +#else +#define PGTBL_LOC PM4LE +#endif
setup_longmode: /* Get page table address */ - movl $(CONFIG_ARCH_X86_64_PGTBL_LOC), %eax + movl PGTBL_LOC, %eax
/* load identity mapped page tables */ movl %eax, %cr3 diff --git a/src/cpu/x86/mp_init.c b/src/cpu/x86/mp_init.c index 81c987b..b035b89 100644 --- a/src/cpu/x86/mp_init.c +++ b/src/cpu/x86/mp_init.c @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-only */
+#include "rules.h" #include <console/console.h> +#include <stdint.h> #include <string.h> #include <rmodule.h> #include <arch/cpu.h> @@ -98,6 +100,7 @@ uint32_t msr_count; uint32_t c_handler; atomic_t ap_count; + uint32_t cr3; } __packed;
/* This also needs to match the assembly code for saved MSR encoding. */ @@ -348,6 +351,8 @@ else sp->microcode_lock = 0; sp->c_handler = (uintptr_t)&ap_init; + if (ENV_X86_64) + sp->cr3 = read_cr3(); ap_count = &sp->ap_count; atomic_set(ap_count, 0);
diff --git a/src/cpu/x86/sipi_vector.S b/src/cpu/x86/sipi_vector.S index b8cac96..80ee79d 100644 --- a/src/cpu/x86/sipi_vector.S +++ b/src/cpu/x86/sipi_vector.S @@ -40,12 +40,19 @@ .long 0 ap_count: .long 0 +cr3: +.long 0
#define CR0_CLEAR_FLAGS_CACHE_ENABLE (CR0_CD | CR0_NW) #define CR0_SET_FLAGS (CR0_CLEAR_FLAGS_CACHE_ENABLE | CR0_PE) #define CR0_CLEAR_FLAGS \ (CR0_PG | CR0_AM | CR0_WP | CR0_NE | CR0_TS | CR0_EM | CR0_MP)
+.data +.align 32 +PM4LE: +.quad 0 + .text .code16 .global _start @@ -233,6 +240,8 @@ andl $0xfffffff0, %esp /* ensure stack alignment */
#if ENV_X86_64 + movl cr3, %eax + movl %eax, PM4LE /* entry64.inc preserves ebx. */ #include <cpu/x86/64bit/entry64.inc>
diff --git a/src/cpu/x86/smm/smm_module_handler.c b/src/cpu/x86/smm/smm_module_handler.c index e18a26a..00a0090 100644 --- a/src/cpu/x86/smm/smm_module_handler.c +++ b/src/cpu/x86/smm/smm_module_handler.c @@ -20,7 +20,7 @@ __attribute__((aligned(4))) smi_semaphore smi_handler_status = SMI_UNLOCKED;
static const volatile -__attribute((aligned(4), __section__(".module_parameters"))) struct smm_runtime smm_runtime; +__attribute((aligned(4), __section__(".module_parameters"))) struct smm_runtime smm_runtime = {};
static int smi_obtain_lock(void) { diff --git a/src/cpu/x86/smm/smm_module_loader.c b/src/cpu/x86/smm/smm_module_loader.c index 9068435..3a80a37 100644 --- a/src/cpu/x86/smm/smm_module_loader.c +++ b/src/cpu/x86/smm/smm_module_loader.c @@ -6,6 +6,7 @@ #include <string.h> #include <rmodule.h> #include <cbmem.h> +#include <cpu/x86/cr.h> #include <cpu/x86/smm.h> #include <commonlib/helpers.h> #include <console/console.h> @@ -375,9 +376,9 @@ stub_params->c_handler = (uintptr_t)params->handler; stub_params->fxsave_area = (uintptr_t)fxsave_area; stub_params->fxsave_area_size = FXSAVE_SIZE; + stub_params->cr3 = read_cr3();
- printk(BIOS_DEBUG, - "%s: stack_top = 0x%x\n", __func__, stub_params->stack_top); + printk(BIOS_DEBUG, "%s: stack_top = 0x%x\n", __func__, stub_params->stack_top); printk(BIOS_DEBUG, "%s: per cpu stack_size = 0x%x\n", __func__, stub_params->stack_size); printk(BIOS_DEBUG, "%s: runtime.start32_offset = 0x%x\n", __func__, diff --git a/src/cpu/x86/smm/smm_stub.S b/src/cpu/x86/smm/smm_stub.S index 02532a4..ccfd686 100644 --- a/src/cpu/x86/smm/smm_stub.S +++ b/src/cpu/x86/smm/smm_stub.S @@ -26,6 +26,8 @@ .long 0 fxsave_area_size: .long 0 +cr3: +.long 0 /* apic_to_cpu_num is a table mapping the default APIC id to CPU num. If the * APIC id is found at the given index, the contiguous CPU number is index * into the table. */ @@ -36,6 +38,10 @@ .long smm_trampoline32 - _start
.data +.global PM4LE +.align 32 +PM4LE: +.quad /* Provide fallback stack to use when a valid CPU number cannot be found. */ fallback_stack_bottom: .skip 128 @@ -233,6 +239,9 @@ movl %eax, -0x8(%ebp) movl %edx, -0xc(%ebp)
+ movl cr3, %eax + movl %eax, PM4LE + /* entry64.inc preserves ebx, esi, edi */ #include <cpu/x86/64bit/entry64.inc> mov %edi, %ecx diff --git a/src/include/cpu/x86/smm.h b/src/include/cpu/x86/smm.h index 03b9c39..a0074e6 100644 --- a/src/include/cpu/x86/smm.h +++ b/src/include/cpu/x86/smm.h @@ -67,6 +67,7 @@ u32 cbmemc_size; void *cbmemc; uintptr_t save_state_top[CONFIG_MAX_CPUS]; + u32 cr3; } __packed;
struct smm_module_params { @@ -85,6 +86,7 @@ u32 c_handler; u32 fxsave_area; u32 fxsave_area_size; + u32 cr3; /* The apic_id_to_cpu provides a mapping from APIC id to CPU number. * The CPU number is indicated by the index into the array by matching * the default APIC id and value at the index. The stub loader diff --git a/src/soc/amd/common/block/cpu/Kconfig b/src/soc/amd/common/block/cpu/Kconfig index fef12f4..db15bf8 100644 --- a/src/soc/amd/common/block/cpu/Kconfig +++ b/src/soc/amd/common/block/cpu/Kconfig @@ -30,6 +30,9 @@ help The size of the cbfs_cache region.
+config ARCH_X86_64_PGTBL_CBFS + default y + endif # SOC_AMD_COMMON_BLOCK_NONCAR
config SOC_AMD_COMMON_BLOCK_MCA_COMMON