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>
This commit is contained in:
Arthur Heymans 2021-10-28 16:48:36 +02:00 committed by Felix Held
parent 6179f7b618
commit b4ba289fa5
3 changed files with 109 additions and 3 deletions

View File

@ -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

View File

@ -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

View File

@ -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);
}