skylake: use smm_subregion() during SMM relocation

The smm_subregion() support allows the SMM relocation
to not use duplicated math by calling out the specific
regions it wants.  IED base is now correct and not
pointing outside from SMRAM.

BUG=chrome-os-partner:43636
BRANCH=None
TEST=Built, booted, suspended, resumed on glados.

Original-Change-Id: Ief8940c2ab6320449500ced2121d0cd7ed73af4b
Original-Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/290930
Original-Reviewed-by: Leroy P Leahy <leroy.p.leahy@intel.com>
Original-Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Original-Trybot-Ready: David James <davidjames@chromium.org>

Change-Id: I00c3284cfacb2a73942640ccfa7912b7d65efb9d
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/11198
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
Aaron Durbin 2015-08-05 17:28:50 -05:00
parent abf87a25f2
commit d452b6edd6
1 changed files with 13 additions and 27 deletions

View File

@ -196,28 +196,20 @@ static void asmlinkage cpu_smm_do_relocation(void *arg)
write_smrr(relo_params); write_smrr(relo_params);
} }
static u32 northbridge_get_base_reg(device_t dev, int reg)
{
u32 value;
value = pci_read_config32(dev, reg);
/* Base registers are at 1MiB granularity. */
value &= ~((1 << 20) - 1);
return value;
}
static void fill_in_relocation_params(device_t dev, static void fill_in_relocation_params(device_t dev,
struct smm_relocation_params *params) struct smm_relocation_params *params)
{ {
u32 tseg_size; void *handler_base;
u32 tsegmb; size_t handler_size;
u32 bgsm; void *ied_base;
size_t ied_size;
void *tseg_base;
size_t tseg_size;
u32 emrr_base; u32 emrr_base;
u32 emrr_size; u32 emrr_size;
int phys_bits; int phys_bits;
/* All range registers are aligned to 4KiB */ /* All range registers are aligned to 4KiB */
const u32 rmask = ~((1 << 12) - 1); const u32 rmask = ~((1 << 12) - 1);
config_t *conf = dev->chip_info;
/* /*
* Some of the range registers are dependent on the number of physical * Some of the range registers are dependent on the number of physical
@ -225,21 +217,15 @@ static void fill_in_relocation_params(device_t dev,
*/ */
phys_bits = cpuid_eax(0x80000008) & 0xff; phys_bits = cpuid_eax(0x80000008) & 0xff;
/* smm_region(&tseg_base, &tseg_size);
* The range bounded by the TSEGMB and BGSM registers encompasses the smm_subregion(SMM_SUBREGION_HANDLER, &handler_base, &handler_size);
* SMRAM range as well as the IED range. smm_subregion(SMM_SUBREGION_CHIPSET, &ied_base, &ied_size);
*/
tsegmb = northbridge_get_base_reg(dev, TSEG);
bgsm = northbridge_get_base_reg(dev, BGSM);
tseg_size = bgsm - tsegmb;
params->ied_size = conf->IedSize; params->smram_size = handler_size;
params->smram_size = tseg_size - params->ied_size; params->smram_base = (uintptr_t)handler_base;
params->smram_base = tsegmb;
params->ied_base = tsegmb + params->smram_size;
/* Adjust available SMM handler memory size. */ params->ied_base = (uintptr_t)ied_base;
params->smram_size -= CONFIG_SMM_RESERVED_SIZE; params->ied_size = ied_size;
/* SMRR has 32-bits of valid address aligned to 4KiB. */ /* SMRR has 32-bits of valid address aligned to 4KiB. */
params->smrr_base.lo = (params->smram_base & rmask) | MTRR_TYPE_WRBACK; params->smrr_base.lo = (params->smram_base & rmask) | MTRR_TYPE_WRBACK;