summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur Heymans <arthur@aheymans.xyz>2021-10-28 16:48:36 +0200
committerFelix Held <felix-coreboot@felixheld.de>2022-02-28 13:33:59 +0000
commitb4ba289fa5be16f3d94a0da30fc9b07a99a61a91 (patch)
tree4f3856c1097657a8935ea0ee1407377f1d99656f
parent6179f7b6182755a74ca7e92e54b4f8e1f0462d96 (diff)
cpu/x86/smm: Support PARALLEL_MP with SMM_ASEG
This will allow to migrate all platform to the parallel_mp init code and drop the old lapic_init code. Change-Id: If499e21a8dc7fca18bd5990f833170d0fc21e10c Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/58700 Reviewed-by: Angel Pons <th3fanbus@gmail.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
-rw-r--r--src/cpu/x86/Kconfig2
-rw-r--r--src/cpu/x86/smm/Makefile.inc10
-rw-r--r--src/cpu/x86/smm/smm_module_loader.c100
3 files changed, 109 insertions, 3 deletions
diff --git a/src/cpu/x86/Kconfig b/src/cpu/x86/Kconfig
index 86f31e05c7..d5c688d40f 100644
--- a/src/cpu/x86/Kconfig
+++ b/src/cpu/x86/Kconfig
@@ -120,7 +120,7 @@ config SMM_LEGACY_ASEG
help
SMM support without PARALLEL_MP, to be deprecated.
-if SMM_TSEG
+if HAVE_SMI_HANDLER && !SMM_LEGACY_ASEG
config SMM_MODULE_HEAP_SIZE
hex
diff --git a/src/cpu/x86/smm/Makefile.inc b/src/cpu/x86/smm/Makefile.inc
index 36aa113443..cd920daf1a 100644
--- a/src/cpu/x86/smm/Makefile.inc
+++ b/src/cpu/x86/smm/Makefile.inc
@@ -35,6 +35,10 @@ ramstage-y += tseg_region.c
romstage-y += tseg_region.c
postcar-y += tseg_region.c
+endif
+
+ifeq ($(CONFIG_PARALLEL_MP),y)
+
smmstub-y += smm_stub.S
smm-y += smm_module_handler.c
@@ -71,7 +75,9 @@ endif
$(obj)/smm/smm: $(obj)/smm/smm.elf.rmod
$(OBJCOPY_smm) -O binary $< $@
-else # CONFIG_SMM_TSEG
+endif
+
+ifeq ($(CONFIG_SMM_LEGACY_ASEG),y)
smm-y += smm.ld
@@ -83,4 +89,4 @@ $(obj)/smm/smm: $(obj)/smm/smm.o $(call src-to-obj,smm,$(src)/cpu/x86/smm/smm.ld
smm-y += smmhandler.S
smm-y += smihandler.c
-endif # CONFIG_SMM_TSEG
+endif # CONFIG_SMM_LEGACY_ASEG
diff --git a/src/cpu/x86/smm/smm_module_loader.c b/src/cpu/x86/smm/smm_module_loader.c
index beddb3cd81..14e2aa3b74 100644
--- a/src/cpu/x86/smm/smm_module_loader.c
+++ b/src/cpu/x86/smm/smm_module_loader.c
@@ -437,6 +437,9 @@ int smm_setup_relocation_handler(struct smm_loader_params *params)
params, fxsave_area_relocation);
}
+static int smm_load_module_aseg(const uintptr_t smram_base, const size_t smram_size,
+ struct smm_loader_params *params);
+
/*
*The SMM module is placed within the provided region in the following
* manner:
@@ -477,6 +480,9 @@ int smm_load_module(const uintptr_t smram_base, const size_t smram_size,
size_t total_size = 0;
uintptr_t base; /* The base for the permanent handler */
+ if (CONFIG(SMM_ASEG))
+ return smm_load_module_aseg(smram_base, smram_size, params);
+
if (smram_size <= SMM_DEFAULT_SIZE)
return -1;
@@ -592,3 +598,97 @@ int smm_load_module(const uintptr_t smram_base, const size_t smram_size,
return smm_module_setup_stub(base, smram_size, params, fxsave_area);
}
+
+/*
+ *The SMM module is placed within the provided region in the following
+ * manner:
+ * +-----------------+ <- smram + size == 0x10000
+ * | save states |
+ * +-----------------+
+ * | fxsave area |
+ * +-----------------+
+ * | smi handler |
+ * | ... |
+ * +-----------------+ <- cpu0
+ * | stub code | <- cpu1
+ * | stub code | <- cpu2
+ * | stub code | <- cpu3, etc
+ * | |
+ * | |
+ * | |
+ * | stacks |
+ * +-----------------+ <- smram start = 0xA0000
+ */
+static int smm_load_module_aseg(const uintptr_t smram_base, const size_t smram_size,
+ struct smm_loader_params *params)
+{
+ struct rmodule smm_mod;
+ struct smm_runtime *handler_mod_params;
+
+ if (smram_size != SMM_DEFAULT_SIZE)
+ return -1;
+
+ if (smram_base != SMM_BASE)
+ return -1;
+
+ /* Fail if can't parse the smm rmodule. */
+ if (rmodule_parse(&_binary_smm_start, &smm_mod))
+ return -1;
+
+ if (!smm_create_map(smram_base, params->num_concurrent_save_states, params)) {
+ printk(BIOS_ERR, "%s: Error creating CPU map\n", __func__);
+ return -1;
+ }
+
+ const uintptr_t entry0_end = cpus[0].code_end;
+ const uintptr_t save_state_base = cpus[params->num_cpus - 1].ss_start;
+ const size_t fxsave_size = FXSAVE_SIZE * params->num_cpus;
+ const uintptr_t fxsave_base = ALIGN_DOWN(save_state_base - fxsave_size, 16);
+
+ if (fxsave_base <= entry0_end) {
+ printk(BIOS_ERR, "%s, fxsave %lx won't fit smram\n", __func__, fxsave_base);
+ return -1;
+ }
+
+ const size_t handler_size = rmodule_memory_size(&smm_mod);
+ const size_t module_alignment = rmodule_load_alignment(&smm_mod);
+ const uintptr_t module_base = ALIGN_DOWN(fxsave_base - handler_size, module_alignment);
+
+ if (module_base <= entry0_end) {
+ printk(BIOS_ERR, "%s, module won't fit smram\n", __func__);
+ return -1;
+ }
+
+ if (rmodule_load((void *)module_base, &smm_mod))
+ return -1;
+
+ params->handler = rmodule_entry(&smm_mod);
+ handler_mod_params = rmodule_parameters(&smm_mod);
+ handler_mod_params->smbase = smram_base;
+ handler_mod_params->smm_size = smram_size;
+ handler_mod_params->save_state_size = params->real_cpu_save_state_size;
+ handler_mod_params->num_cpus = params->num_cpus;
+ handler_mod_params->gnvs_ptr = (uintptr_t)acpi_get_gnvs();
+
+ for (int i = 0; i < params->num_cpus; i++) {
+ handler_mod_params->save_state_top[i] =
+ cpus[i].ss_start + params->per_cpu_save_state_size;
+ }
+
+ printk(BIOS_DEBUG, "%s: smram_start: 0x%lx\n", __func__, smram_base);
+ printk(BIOS_DEBUG, "%s: smram_end: %lx\n", __func__, smram_base + smram_size);
+ printk(BIOS_DEBUG, "%s: handler start %p\n", __func__, params->handler);
+ printk(BIOS_DEBUG, "%s: handler_size %zx\n", __func__, handler_size);
+ printk(BIOS_DEBUG, "%s: fxsave_area %lx\n", __func__, fxsave_base);
+ printk(BIOS_DEBUG, "%s: fxsave_size %zx\n", __func__, fxsave_size);
+
+ printk(BIOS_DEBUG, "%s: handler_mod_params.smbase = 0x%x\n", __func__,
+ handler_mod_params->smbase);
+ printk(BIOS_DEBUG, "%s: per_cpu_save_state_size = 0x%x\n", __func__,
+ handler_mod_params->save_state_size);
+ printk(BIOS_DEBUG, "%s: num_cpus = 0x%x\n", __func__, handler_mod_params->num_cpus);
+ printk(BIOS_DEBUG, "%s: total_save_state_size = 0x%x\n", __func__,
+ (handler_mod_params->save_state_size * handler_mod_params->num_cpus));
+
+ return smm_module_setup_stub(smram_base, smram_size, params, (void *)fxsave_base);
+}