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:
Eugene Myers 2021-05-12 07:55:28 -04:00 committed by Stefan Reinauer
parent 0f93a91548
commit e7e2bd2a59
5 changed files with 20 additions and 8 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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. */