cpu/x86/: Centralize MSEG location calculation
This patch centralizes the MSEG location calculation. In the current implementation, the calculation happens in smm_module_loader and mp_init. When smm_module_loaderv2 was added, this calculation became broken as the original calculation made assumptions based on perm_smbase. The calculation is now located in smm_subregion (tseg_region.c), as the MSEG is located within the TSEG (or SMM); These patches have been tested on a Purism librem-l1um server. Change-Id: Ic17e1a505401c3b2a218826dffae6fe12a5c15c6 Signed-off-by: Eugene Myers <edmyers@tycho.nsa.gov> Reviewed-on: https://review.coreboot.org/c/coreboot/+/55628 Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
0f93a91548
commit
e7e2bd2a59
|
@ -756,9 +756,9 @@ static void asmlinkage smm_do_relocation(void *arg)
|
||||||
if (CONFIG(STM)) {
|
if (CONFIG(STM)) {
|
||||||
if (is_smm_enabled()) {
|
if (is_smm_enabled()) {
|
||||||
uintptr_t mseg;
|
uintptr_t mseg;
|
||||||
|
size_t mseg_size;
|
||||||
|
|
||||||
mseg = mp_state.perm_smbase +
|
smm_subregion(SMM_SUBREGION_MSEG, &mseg, &mseg_size);
|
||||||
(mp_state.perm_smsize - CONFIG_MSEG_SIZE);
|
|
||||||
|
|
||||||
stm_setup(mseg, p->cpu, runtime->num_cpus,
|
stm_setup(mseg, p->cpu, runtime->num_cpus,
|
||||||
perm_smbase,
|
perm_smbase,
|
||||||
|
|
|
@ -368,7 +368,7 @@ int smm_load_module(void *smram, size_t size, struct smm_loader_params *params)
|
||||||
base += size;
|
base += size;
|
||||||
|
|
||||||
if (CONFIG(STM))
|
if (CONFIG(STM))
|
||||||
base -= CONFIG_MSEG_SIZE + CONFIG_BIOS_RESOURCE_LIST_SIZE;
|
base -= CONFIG_BIOS_RESOURCE_LIST_SIZE;
|
||||||
|
|
||||||
params->stack_top = base;
|
params->stack_top = base;
|
||||||
|
|
||||||
|
|
|
@ -586,8 +586,8 @@ int smm_load_module(void *smram, size_t size, struct smm_loader_params *params)
|
||||||
|
|
||||||
/* MSEG starts at the top of SMRAM and works down */
|
/* MSEG starts at the top of SMRAM and works down */
|
||||||
if (CONFIG(STM)) {
|
if (CONFIG(STM)) {
|
||||||
base -= CONFIG_MSEG_SIZE + CONFIG_BIOS_RESOURCE_LIST_SIZE;
|
base -= CONFIG_BIOS_RESOURCE_LIST_SIZE;
|
||||||
total_size += CONFIG_MSEG_SIZE + CONFIG_BIOS_RESOURCE_LIST_SIZE;
|
total_size += CONFIG_BIOS_RESOURCE_LIST_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FXSAVE goes below MSEG */
|
/* FXSAVE goes below MSEG */
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <cpu/x86/smm.h>
|
#include <cpu/x86/smm.h>
|
||||||
#include <stage_cache.h>
|
#include <stage_cache.h>
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Subregions within SMM
|
* Subregions within SMM
|
||||||
|
@ -25,6 +26,8 @@
|
||||||
* +-------------------------+
|
* +-------------------------+
|
||||||
* | External Stage Cache | SMM_RESERVED_SIZE
|
* | External Stage Cache | SMM_RESERVED_SIZE
|
||||||
* +-------------------------+
|
* +-------------------------+
|
||||||
|
* | STM | MSEG_SIZE
|
||||||
|
* +-------------------------+
|
||||||
* | code and data |
|
* | code and data |
|
||||||
* | (TSEG) |
|
* | (TSEG) |
|
||||||
* +-------------------------+ TSEG
|
* +-------------------------+ TSEG
|
||||||
|
@ -35,17 +38,24 @@ int smm_subregion(int sub, uintptr_t *start, size_t *size)
|
||||||
size_t sub_size;
|
size_t sub_size;
|
||||||
const size_t ied_size = CONFIG_IED_REGION_SIZE;
|
const size_t ied_size = CONFIG_IED_REGION_SIZE;
|
||||||
const size_t cache_size = CONFIG_SMM_RESERVED_SIZE;
|
const size_t cache_size = CONFIG_SMM_RESERVED_SIZE;
|
||||||
|
const size_t mseg_size = CONFIG_MSEG_SIZE;
|
||||||
|
|
||||||
smm_region(&sub_base, &sub_size);
|
smm_region(&sub_base, &sub_size);
|
||||||
|
|
||||||
ASSERT(IS_ALIGNED(sub_base, sub_size));
|
ASSERT(IS_ALIGNED(sub_base, sub_size));
|
||||||
ASSERT(sub_size > (cache_size + ied_size));
|
ASSERT(sub_size > (cache_size + ied_size + mseg_size));
|
||||||
|
|
||||||
switch (sub) {
|
switch (sub) {
|
||||||
case SMM_SUBREGION_HANDLER:
|
case SMM_SUBREGION_HANDLER:
|
||||||
/* Handler starts at the base of TSEG. */
|
/* Handler starts at the base of TSEG. */
|
||||||
sub_size -= ied_size;
|
sub_size -= ied_size;
|
||||||
sub_size -= cache_size;
|
sub_size -= cache_size;
|
||||||
|
sub_size -= mseg_size;
|
||||||
|
break;
|
||||||
|
case SMM_SUBREGION_MSEG:
|
||||||
|
/* MSEG follows the SMM HANDLER subregion */
|
||||||
|
sub_base += sub_size - (ied_size + cache_size + mseg_size);
|
||||||
|
sub_size = mseg_size;
|
||||||
break;
|
break;
|
||||||
case SMM_SUBREGION_CACHE:
|
case SMM_SUBREGION_CACHE:
|
||||||
/* External cache is in the middle of TSEG. */
|
/* External cache is in the middle of TSEG. */
|
||||||
|
@ -88,11 +98,11 @@ void smm_list_regions(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
printk(BIOS_DEBUG, "SMM Memory Map\n");
|
printk(BIOS_DEBUG, "SMM Memory Map\n");
|
||||||
printk(BIOS_DEBUG, "SMRAM : 0x%zx 0x%zx\n", base, size);
|
printk(BIOS_DEBUG, "SMRAM : 0x%" PRIxPTR " 0x%zx\n", base, size);
|
||||||
|
|
||||||
for (i = 0; i < SMM_SUBREGION_NUM; i++) {
|
for (i = 0; i < SMM_SUBREGION_NUM; i++) {
|
||||||
if (smm_subregion(i, &base, &size))
|
if (smm_subregion(i, &base, &size))
|
||||||
continue;
|
continue;
|
||||||
printk(BIOS_DEBUG, " Subregion %d: 0x%zx 0x%zx\n", i, base, size);
|
printk(BIOS_DEBUG, " Subregion %d: 0x%" PRIxPTR " 0x%zx\n", i, base, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,6 +168,8 @@ void smm_region(uintptr_t *start, size_t *size);
|
||||||
enum {
|
enum {
|
||||||
/* SMM handler area. */
|
/* SMM handler area. */
|
||||||
SMM_SUBREGION_HANDLER,
|
SMM_SUBREGION_HANDLER,
|
||||||
|
/* MSEG (STM). */
|
||||||
|
SMM_SUBREGION_MSEG,
|
||||||
/* SMM cache region. */
|
/* SMM cache region. */
|
||||||
SMM_SUBREGION_CACHE,
|
SMM_SUBREGION_CACHE,
|
||||||
/* Chipset specific area. */
|
/* Chipset specific area. */
|
||||||
|
|
Loading…
Reference in New Issue