diff options
author | Arthur Heymans <arthur@aheymans.xyz> | 2018-07-20 23:41:54 +0200 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2018-07-30 19:03:27 +0000 |
commit | 06f818c932be5e19176db0d50939ee89da3267ad (patch) | |
tree | 9865fb6b53caeb4535b36c0a9375144797c4edc0 /src/cpu | |
parent | e8d0c0092a71c5890a1dfbdc7b941dc5e05b0501 (diff) |
cpu/intel/smm/gen1: Use correct MSR for model_6fx and model_1067x
According to the "Intel® 64 and IA-32 Architectures Software Developer’s Manual"
the SMRR MSR are at a different offset for model_6fx and model_1067x.
This still need SMRR enabled and lock bit set in MSR_FEATURE_CONTROL.
Change-Id: I8ee8292ab038e58deb8c24745ec1a9b5da8c31a9
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/27585
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/intel/smm/gen1/smmrelocate.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/src/cpu/intel/smm/gen1/smmrelocate.c b/src/cpu/intel/smm/gen1/smmrelocate.c index 9806882376..c50d8a4743 100644 --- a/src/cpu/intel/smm/gen1/smmrelocate.c +++ b/src/cpu/intel/smm/gen1/smmrelocate.c @@ -37,6 +37,10 @@ #define G_SMRAME (1 << 3) #define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0)) +#define IA32_FEATURE_CONTROL 0x3a +#define FEATURE_CONTROL_LOCK_BIT (1 << 0) +#define SMRR_ENABLE (1 << 3) + struct ied_header { char signature[10]; u32 size; @@ -57,12 +61,32 @@ struct smm_relocation_params { static struct smm_relocation_params smm_reloc_params; static void *default_smm_area = NULL; -static inline void write_smrr(struct smm_relocation_params *relo_params) +static void write_smrr(struct smm_relocation_params *relo_params) { + struct cpuinfo_x86 c; + printk(BIOS_DEBUG, "Writing SMRR. base = 0x%08x, mask=0x%08x\n", relo_params->smrr_base.lo, relo_params->smrr_mask.lo); - wrmsr(IA32_SMRR_PHYS_BASE, relo_params->smrr_base); - wrmsr(IA32_SMRR_PHYS_MASK, relo_params->smrr_mask); + /* Both model_6fx and model_1067x SMRR function slightly differently + from the rest. The MSR are at different location from the rest + and need to be explicitly enabled. */ + get_fms(&c, cpuid_eax(1)); + if (c.x86 == 6 && (c.x86_model == 0xf || c.x86_model == 0x17)) { + msr_t msr; + msr = rdmsr(IA32_FEATURE_CONTROL); + /* SMRR enabled and feature locked */ + if (!((msr.lo & SMRR_ENABLE) + && (msr.lo & FEATURE_CONTROL_LOCK_BIT))) { + printk(BIOS_WARNING, + "SMRR not enabled, skip writing SMRR...\n"); + return; + } + wrmsr(MSR_SMRR_PHYS_BASE, relo_params->smrr_base); + wrmsr(MSR_SMRR_PHYS_MASK, relo_params->smrr_mask); + } else { + wrmsr(IA32_SMRR_PHYS_BASE, relo_params->smrr_base); + wrmsr(IA32_SMRR_PHYS_MASK, relo_params->smrr_mask); + } } /* The relocation work is actually performed in SMM context, but the code @@ -137,7 +161,15 @@ static void fill_in_relocation_params(struct smm_relocation_params *params) params->smram_size -= CONFIG_SMM_RESERVED_SIZE; /* SMRR has 32-bits of valid address aligned to 4KiB. */ - params->smrr_base.lo = (params->smram_base & rmask) | MTRR_TYPE_WRBACK; + struct cpuinfo_x86 c; + + /* On model_6fx and model_1067x bits [0:11] on smrr_base are reserved */ + get_fms(&c, cpuid_eax(1)); + if (c.x86 == 6 && (c.x86_model == 0xf || c.x86_model == 0x17)) + params->smrr_base.lo = (params->smram_base & rmask); + else + params->smrr_base.lo = (params->smram_base & rmask) + | MTRR_TYPE_WRBACK; params->smrr_base.hi = 0; params->smrr_mask.lo = (~(tseg_size - 1) & rmask) | MTRR_PHYS_MASK_VALID; |