Name of user not set #1002358 has uploaded this change for review.

View Change

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

To view, visit change 33235. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I935cd5a8bc0bf293240324c2e3a04a655d44c69f
Gerrit-Change-Number: 33235
Gerrit-PatchSet: 1
Gerrit-Owner: Name of user not set #1002358
Gerrit-MessageType: newchange