Name of user not set #1002358 has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/33235
Change subject: cpu/x86/smm/ STM Support ......................................................................
cpu/x86/smm/ STM Support
SMI Handler modifications needed to setup the STM data structures
Change-Id: I935cd5a8bc0bf293240324c2e3a04a655d44c69f --- 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 4 files changed, 92 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/35/33235/1
diff --git a/src/cpu/x86/smm/smm_module_handler.c b/src/cpu/x86/smm/smm_module_handler.c index f9af965..26ddd66 100644 --- a/src/cpu/x86/smm/smm_module_handler.c +++ b/src/cpu/x86/smm/smm_module_handler.c @@ -18,6 +18,15 @@ #include <cpu/x86/smm.h> #include <rmodule.h>
+#include <cpu/x86/msr.h> +#include <cpu/x86/cache.h> + +#include <security/intel/stm/StmApi.h> +#include <security/intel/stm/StmPlatformResource.h> +#include <arch/acpi.h> +#include <lib.h> +#include <security/intel/stm/SmmStm.h> + #if IS_ENABLED(CONFIG_SPI_FLASH_SMM) #include <spi-generic.h> #endif @@ -116,6 +125,10 @@ return base; }
+#ifdef CONFIG_STM + static uint32_t MsegInit = 0; // used for STM/mseg initialization +#endif + asmlinkage void smm_handler_start(void *arg) { const struct smm_module_params *p; @@ -123,7 +136,16 @@ int cpu; uintptr_t actual_canary; uintptr_t expected_canary; +#ifdef CONFIG_STM + int MsegInit2 = 1; // assume that the STM has been set
+ /* this initialzation strategy works on the assumption that all + * processors will enter SMM at generally the same time. + * If a single processor lags then a locking/counting scheme will + * need to be implemented. */ + if (MsegInit == 0) + MsegInit2 = 0; +#endif p = arg; runtime = p->runtime; cpu = p->cpu; @@ -140,9 +162,33 @@ "Invalid CPU number assigned in SMM stub: %d\n", cpu); return; } +#ifdef CONFIG_STM + if (MsegInit == 0) { + + /* Initialize the MSEG base address for each logical processor + * and indicate that there is an STM present */ + msr_t InitMseg; + msr_t MsegChk; + + InitMseg.lo = smm_runtime->mseg | IA32_SMM_MONITOR_VALID; + InitMseg.hi = 0; + + wrmsr(IA32_SMM_MONITOR_CTL_MSR_INDEX, InitMseg); + + MsegChk = rdmsr(IA32_SMM_MONITOR_CTL_MSR_INDEX); + console_init(); + + printk(BIOS_DEBUG, "MSEG Initialized (%d) 0x%08x 0x%08x\n", + cpu, MsegChk.hi, MsegChk.lo); + } + +#endif
/* Are we ok to execute the handler? */ if (!smi_obtain_lock()) { +#ifdef CONFIG_STM + void *smbase = (void *) smm_runtime->smbase; +#endif /* For security reasons we don't release the other CPUs * until the CPU with the lock is actually done */ while (smi_handler_status == SMI_LOCKED) { @@ -150,13 +196,35 @@ ".byte 0xf3, 0x90\n" /* PAUSE */ ); } +#ifdef CONFIG_STM + if (MsegInit2 == 0) { + + /* Setup an SMM Descriptor for this logical processor */ + SetupSmmDescriptor(smbase, smm_runtime->save_state_size, cpu, smm_runtime->start32_offset); + MsegInit2 = 1; + } +#endif + wbinvd(); return; }
+#ifdef CONFIG_STM + + if (MsegInit == 0) { + void *smbase = (void *) smm_runtime->smbase; + + AddResourcesCmd(); + + /* Setup an SMM Descriptor for this logical processor */ + + SetupSmmDescriptor(smbase, smm_runtime->save_state_size, cpu, + smm_runtime->start32_offset); + MsegInit = 1; // flag that we are done + wbinvd(); // force the tables to memory + } +#endif smi_backup_pci_address(); - console_init(); - printk(BIOS_SPEW, "\nSMI# #%d\n", cpu);
/* Allow drivers to initialize variables in SMM context. */ diff --git a/src/cpu/x86/smm/smm_module_loader.c b/src/cpu/x86/smm/smm_module_loader.c index 6c16645..4f15fdd 100644 --- a/src/cpu/x86/smm/smm_module_loader.c +++ b/src/cpu/x86/smm/smm_module_loader.c @@ -18,6 +18,7 @@ #include <cpu/x86/smm.h> #include <cpu/x86/cache.h> #include <console/console.h> +#include <security/intel/stm/SmmStm.h>
#define FXSAVE_SIZE 512
@@ -268,6 +269,9 @@ stub_params->fxsave_area_size = FXSAVE_SIZE; stub_params->runtime.smbase = (uintptr_t)smbase; stub_params->runtime.save_state_size = params->per_cpu_save_state_size; + + /* mseg is after the smi handler */ + stub_params->runtime.mseg = (uint32_t) params->stack_top;
/* Initialize the APIC id to CPU number table to be 1:1 */ for (i = 0; i < params->num_concurrent_stacks; i++) @@ -354,7 +358,13 @@
/* Stacks start at the top of the region. */ base = smram; + +#ifdef CONFIG_STM + base += size - CONFIG_MSEG_SIZE; // take out the mseg +#else base += size; +#endif + params->stack_top = base;
/* SMM module starts at offset SMM_DEFAULT_SIZE with the load alignment diff --git a/src/cpu/x86/smm/smm_stub.S b/src/cpu/x86/smm/smm_stub.S index 59eb27c..3817424 100644 --- a/src/cpu/x86/smm/smm_stub.S +++ b/src/cpu/x86/smm/smm_stub.S @@ -46,6 +46,11 @@ .long 0 save_state_size: .long 0 +mseg: +.long 0 +/* allows the STM to bring up SMM in 32-bit mode*/ +start32_offset: +.long smm_trampoline32 - _start /* 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. */ @@ -92,6 +97,10 @@ /* gdt selector 0x10, flat data segment */ .word 0xffff, 0x0000 .byte 0x00, 0x93, 0xcf, 0x00 + + /* gdt selector 0x18 tr segment */ + .word 0xffff, 0x0000 + .byte 0x00, 0x8b, 0x80, 0x00 smm_relocate_gdt_end:
.align 4 diff --git a/src/include/cpu/x86/smm.h b/src/include/cpu/x86/smm.h index 576449d..b2d7445 100644 --- a/src/include/cpu/x86/smm.h +++ b/src/include/cpu/x86/smm.h @@ -512,6 +512,9 @@ struct smm_runtime { u32 smbase; u32 save_state_size; + u32 mseg; + /* used so that the STM can start the SMI handler in 32bit mode */ + u32 start32_offset; /* 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