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

View Change

cpu/x86/smm: Add STM Support

SMI Handler modifications needed to setup the SMM descriptors
used by the STM during its initialization

Change-Id: I935cd5a8bc0bf293240324c2e3a04a655d44c69f

Signed-off-by: Eugene D Myers <cedarhouse1@comcast.net>
Change-Id: I5a89fefb4fbd3672f33b718f54b359d816f34939
---
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, 91 insertions(+), 0 deletions(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/72/33272/1
diff --git a/src/cpu/x86/smm/smm_module_handler.c b/src/cpu/x86/smm/smm_module_handler.c
index f9af965..a01bbec 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,8 @@
return base;
}

+ static uint32_t MsegInit = 0; // used for STM/mseg initialization
+
asmlinkage void smm_handler_start(void *arg)
{
const struct smm_module_params *p;
@@ -124,6 +135,16 @@
uintptr_t actual_canary;
uintptr_t expected_canary;

+ msr_t InitMseg;
+ msr_t MsegChk;
+ 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;
p = arg;
runtime = p->runtime;
cpu = p->cpu;
@@ -140,9 +161,27 @@
"Invalid CPU number assigned in SMM stub: %d\n", cpu);
return;
}
+ if (MsegInit == 0) {
+
+ /* Initialize the MSEG base address for each logical processor
+ * and indicate that there is an STM present */
+ if(smm_runtime->mseg != 0) { // has the STM been loaded
+
+ 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);
+ }
+
+ printk(BIOS_DEBUG, "MSEG Initialized (%d) 0x%08x 0x%08x\n",
+ cpu, MsegChk.hi, MsegChk.lo);
+ }

/* Are we ok to execute the handler? */
if (!smi_obtain_lock()) {
+ void *smbase = (void *) smm_runtime->smbase;
/* 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,9 +189,35 @@
".byte 0xf3, 0x90\n" /* PAUSE */
);
}
+ if ((MsegInit2 == 0) && (smm_runtime->mseg != 0)) {
+
+ /* Setup an SMM Descriptor for this logical processor */
+ SetupSmmDescriptor(smbase, smm_runtime->save_state_size,
+ cpu, smm_runtime->start32_offset);
+ printk(BIOS_DEBUG, "MSEG Initialized (%d) 0x%08x 0x%08x\n",
+ cpu, MsegChk.hi, MsegChk.lo);
+ }
+ MsegInit2 = 1;
+ wbinvd();
return;
}

+ if ((MsegInit == 0) && (smm_runtime->mseg != 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
+
+ printk(BIOS_DEBUG, "MSEG Initialized (%d) 0x%08x 0x%08x\n",
+ cpu, MsegChk.hi, MsegChk.lo);
+ }
+
smi_backup_pci_address();

console_init();
diff --git a/src/cpu/x86/smm/smm_module_loader.c b/src/cpu/x86/smm/smm_module_loader.c
index 6c16645..d1f1044 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

@@ -269,6 +270,13 @@
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 */
+#ifdef CONFIG_STM
+ stub_params->runtime.mseg = (uint32_t) params->stack_top;
+#else
+ stub_params->runtime.mseg = 0; //STM not configured - no mseg
+#endif
+
/* Initialize the APIC id to CPU number table to be 1:1 */
for (i = 0; i < params->num_concurrent_stacks; i++)
stub_params->runtime.apic_id_to_cpu[i] = i;
@@ -354,7 +362,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 33272. To unsubscribe, or for help writing mail filters, visit settings.

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