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:
parent
6179f7b618
commit
b4ba289fa5
|
@ -120,7 +120,7 @@ config SMM_LEGACY_ASEG
|
||||||
help
|
help
|
||||||
SMM support without PARALLEL_MP, to be deprecated.
|
SMM support without PARALLEL_MP, to be deprecated.
|
||||||
|
|
||||||
if SMM_TSEG
|
if HAVE_SMI_HANDLER && !SMM_LEGACY_ASEG
|
||||||
|
|
||||||
config SMM_MODULE_HEAP_SIZE
|
config SMM_MODULE_HEAP_SIZE
|
||||||
hex
|
hex
|
||||||
|
|
|
@ -35,6 +35,10 @@ ramstage-y += tseg_region.c
|
||||||
romstage-y += tseg_region.c
|
romstage-y += tseg_region.c
|
||||||
postcar-y += tseg_region.c
|
postcar-y += tseg_region.c
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_PARALLEL_MP),y)
|
||||||
|
|
||||||
smmstub-y += smm_stub.S
|
smmstub-y += smm_stub.S
|
||||||
|
|
||||||
smm-y += smm_module_handler.c
|
smm-y += smm_module_handler.c
|
||||||
|
@ -71,7 +75,9 @@ endif
|
||||||
$(obj)/smm/smm: $(obj)/smm/smm.elf.rmod
|
$(obj)/smm/smm: $(obj)/smm/smm.elf.rmod
|
||||||
$(OBJCOPY_smm) -O binary $< $@
|
$(OBJCOPY_smm) -O binary $< $@
|
||||||
|
|
||||||
else # CONFIG_SMM_TSEG
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_SMM_LEGACY_ASEG),y)
|
||||||
|
|
||||||
smm-y += smm.ld
|
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 += smmhandler.S
|
||||||
smm-y += smihandler.c
|
smm-y += smihandler.c
|
||||||
|
|
||||||
endif # CONFIG_SMM_TSEG
|
endif # CONFIG_SMM_LEGACY_ASEG
|
||||||
|
|
|
@ -437,6 +437,9 @@ int smm_setup_relocation_handler(struct smm_loader_params *params)
|
||||||
params, fxsave_area_relocation);
|
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
|
*The SMM module is placed within the provided region in the following
|
||||||
* manner:
|
* manner:
|
||||||
|
@ -477,6 +480,9 @@ int smm_load_module(const uintptr_t smram_base, const size_t smram_size,
|
||||||
size_t total_size = 0;
|
size_t total_size = 0;
|
||||||
uintptr_t base; /* The base for the permanent handler */
|
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)
|
if (smram_size <= SMM_DEFAULT_SIZE)
|
||||||
return -1;
|
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);
|
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);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue