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>
This commit is contained in:
parent
e8d0c0092a
commit
06f818c932
|
@ -37,6 +37,10 @@
|
||||||
#define G_SMRAME (1 << 3)
|
#define G_SMRAME (1 << 3)
|
||||||
#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))
|
#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 {
|
struct ied_header {
|
||||||
char signature[10];
|
char signature[10];
|
||||||
u32 size;
|
u32 size;
|
||||||
|
@ -57,13 +61,33 @@ struct smm_relocation_params {
|
||||||
static struct smm_relocation_params smm_reloc_params;
|
static struct smm_relocation_params smm_reloc_params;
|
||||||
static void *default_smm_area = NULL;
|
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",
|
printk(BIOS_DEBUG, "Writing SMRR. base = 0x%08x, mask=0x%08x\n",
|
||||||
relo_params->smrr_base.lo, relo_params->smrr_mask.lo);
|
relo_params->smrr_base.lo, relo_params->smrr_mask.lo);
|
||||||
|
/* 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_BASE, relo_params->smrr_base);
|
||||||
wrmsr(IA32_SMRR_PHYS_MASK, relo_params->smrr_mask);
|
wrmsr(IA32_SMRR_PHYS_MASK, relo_params->smrr_mask);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* The relocation work is actually performed in SMM context, but the code
|
/* The relocation work is actually performed in SMM context, but the code
|
||||||
* resides in the ramstage module. This occurs by trampolining from the default
|
* resides in the ramstage module. This occurs by trampolining from the default
|
||||||
|
@ -137,7 +161,15 @@ static void fill_in_relocation_params(struct smm_relocation_params *params)
|
||||||
params->smram_size -= CONFIG_SMM_RESERVED_SIZE;
|
params->smram_size -= CONFIG_SMM_RESERVED_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;
|
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_base.hi = 0;
|
||||||
params->smrr_mask.lo = (~(tseg_size - 1) & rmask)
|
params->smrr_mask.lo = (~(tseg_size - 1) & rmask)
|
||||||
| MTRR_PHYS_MASK_VALID;
|
| MTRR_PHYS_MASK_VALID;
|
||||||
|
|
|
@ -31,6 +31,10 @@
|
||||||
#define IA32_SMRR_PHYS_BASE 0x1f2
|
#define IA32_SMRR_PHYS_BASE 0x1f2
|
||||||
#define IA32_SMRR_PHYS_MASK 0x1f3
|
#define IA32_SMRR_PHYS_MASK 0x1f3
|
||||||
|
|
||||||
|
/* Specific to model_6fx and model_1067x */
|
||||||
|
#define MSR_SMRR_PHYS_BASE 0xa0
|
||||||
|
#define MSR_SMRR_PHYS_MASK 0xa1
|
||||||
|
|
||||||
#define MTRR_PHYS_BASE(reg) (0x200 + 2 * (reg))
|
#define MTRR_PHYS_BASE(reg) (0x200 + 2 * (reg))
|
||||||
#define MTRR_PHYS_MASK(reg) (MTRR_PHYS_BASE(reg) + 1)
|
#define MTRR_PHYS_MASK(reg) (MTRR_PHYS_BASE(reg) + 1)
|
||||||
#define MTRR_PHYS_MASK_VALID (1 << 11)
|
#define MTRR_PHYS_MASK_VALID (1 << 11)
|
||||||
|
|
Loading…
Reference in New Issue