summaryrefslogtreecommitdiff
path: root/src/cpu/x86
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/x86')
-rw-r--r--src/cpu/x86/mp_init.c34
-rw-r--r--src/cpu/x86/smm/smm_module_loader.c19
-rw-r--r--src/cpu/x86/smm/smm_stub.S13
3 files changed, 65 insertions, 1 deletions
diff --git a/src/cpu/x86/mp_init.c b/src/cpu/x86/mp_init.c
index b093be7003..331f3b552a 100644
--- a/src/cpu/x86/mp_init.c
+++ b/src/cpu/x86/mp_init.c
@@ -38,6 +38,8 @@
#include <timer.h>
#include <thread.h>
+#include <security/intel/stm/SmmStm.h>
+
#define MAX_APIC_IDS 256
struct mp_callback {
@@ -743,6 +745,23 @@ static void asmlinkage smm_do_relocation(void *arg)
/* Setup code checks this callback for validity. */
mp_state.ops.relocation_handler(cpu, curr_smbase, perm_smbase);
+
+ if (CONFIG(STM)) {
+ if (is_smm_enabled()) {
+ uintptr_t mseg;
+
+ mseg = mp_state.perm_smbase +
+ (mp_state.perm_smsize - CONFIG_MSEG_SIZE);
+
+ stm_setup(mseg, p->cpu, runtime->num_cpus,
+ perm_smbase,
+ mp_state.perm_smbase,
+ runtime->start32_offset);
+ } else {
+ printk(BIOS_DEBUG,
+ "STM not loaded because SMM is not enabled!\n");
+ }
+ }
}
static void adjust_smm_apic_id_map(struct smm_loader_params *smm_params)
@@ -1023,6 +1042,21 @@ static void fill_mp_state(struct mp_state *state, const struct mp_ops *ops)
&state->smm_save_state_size);
/*
+ * Make sure there is enough room for the SMM descriptor
+ */
+ if (CONFIG(STM))
+ state->smm_save_state_size +=
+ sizeof(TXT_PROCESSOR_SMM_DESCRIPTOR);
+
+ /* Currently, the CPU SMM save state size is based on a simplistic
+ * algorithm. (align on 4K)
+ * note: In the future, this will need to handle newer x86 processors
+ * that require alignment of the save state on 32K boundaries.
+ */
+ state->smm_save_state_size =
+ ALIGN_UP(state->smm_save_state_size, 0x1000);
+
+ /*
* Default to smm_initiate_relocation() if trigger callback isn't
* provided.
*/
diff --git a/src/cpu/x86/smm/smm_module_loader.c b/src/cpu/x86/smm/smm_module_loader.c
index c6c6b38737..a421436893 100644
--- a/src/cpu/x86/smm/smm_module_loader.c
+++ b/src/cpu/x86/smm/smm_module_loader.c
@@ -17,6 +17,7 @@
#include <cpu/x86/cache.h>
#include <commonlib/helpers.h>
#include <console/console.h>
+#include <security/intel/stm/SmmStm.h>
#define FXSAVE_SIZE 512
@@ -267,6 +268,7 @@ static int smm_module_setup_stub(void *smbase, struct smm_loader_params *params,
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;
+ stub_params->runtime.num_cpus = params->num_concurrent_stacks;
/* Initialize the APIC id to CPU number table to be 1:1 */
for (i = 0; i < params->num_concurrent_stacks; i++)
@@ -313,6 +315,11 @@ int smm_setup_relocation_handler(struct smm_loader_params *params)
* +-----------------+ <- smram + size
* | stacks |
* +-----------------+ <- smram + size - total_stack_size
+ * | fxsave area |
+ * +-----------------+ <- smram + size - total_stack_size - fxsave_size
+ * | BIOS resource |
+ * | list (STM) |
+ * +-----------------+ <- .. - CONFIG_BIOS_RESOURCE_LIST_SIZE
* | ... |
* +-----------------+ <- smram + handler_size + SMM_DEFAULT_SIZE
* | handler |
@@ -353,7 +360,12 @@ int smm_load_module(void *smram, size_t size, struct smm_loader_params *params)
/* Stacks start at the top of the region. */
base = smram;
- base += size;
+
+ if (CONFIG(STM))
+ base += size - CONFIG_MSEG_SIZE; // take out the mseg
+ else
+ base += size;
+
params->stack_top = base;
/* SMM module starts at offset SMM_DEFAULT_SIZE with the load alignment
@@ -382,6 +394,11 @@ int smm_load_module(void *smram, size_t size, struct smm_loader_params *params)
/* Does the required amount of memory exceed the SMRAM region size? */
total_size = total_stack_size + handler_size;
total_size += fxsave_size + SMM_DEFAULT_SIZE;
+
+ // account for the bios resource list
+ if (CONFIG(STM))
+ total_size += CONFIG_BIOS_RESOURCE_LIST_SIZE;
+
if (total_size > size)
return -1;
diff --git a/src/cpu/x86/smm/smm_stub.S b/src/cpu/x86/smm/smm_stub.S
index f0e55f9a18..8207d233a0 100644
--- a/src/cpu/x86/smm/smm_stub.S
+++ b/src/cpu/x86/smm/smm_stub.S
@@ -44,6 +44,11 @@ smbase:
.long 0
save_state_size:
.long 0
+num_cpus:
+.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. */
@@ -90,6 +95,14 @@ smm_relocate_gdt:
/* gdt selector 0x10, flat data segment */
.word 0xffff, 0x0000
.byte 0x00, 0x93, 0xcf, 0x00
+
+ /* gdt selector 0x18, flat code segment (64-bit) */
+ .word 0xffff, 0x0000
+ .byte 0x00, 0x9b, 0xcf, 0x00
+
+ /* gdt selector 0x20 tss segment */
+ .word 0xffff, 0x0000
+ .byte 0x00, 0x8b, 0x80, 0x00
smm_relocate_gdt_end:
.align 4