cpu/x86/mtrr: Simplify MTRR solution calculation on AMD systems
AMD systems have a TOM2WB bit in SYS_CFG MSR to forcefully cover the address space between 4GB-TOM2 as WB. Any WB MTRR that falls into that range may be skipped from programming. It can save a lot of MTRRs when calculating the MTRR solution. It is especially needed when using a temporary MTRR to cover the flash as WP, as the MTRR space gets more fragmented. Add checks for SYS_CFG TOM2WB in the MTRR driver and skip the WB MTRR ranges when possible. TEST=Successfully enable temporary MTRR range for flash on Gigabyte MZ33-AR1. Change-Id: Ie9af9b54a1037c843d8f019506af761a8d8769d0 Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/89199 Reviewed-by: Patrick Rudolph <patrick.rudolph@9elements.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
6957f84aa7
commit
04f83ff7dc
2 changed files with 39 additions and 5 deletions
|
|
@ -598,6 +598,25 @@ static void calc_var_mtrrs_with_hole(struct var_mtrr_state *var_state,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_tom2_wb_active(void)
|
||||||
|
{
|
||||||
|
msr_t syscfg = rdmsr(SYSCFG_MSR);
|
||||||
|
syscfg.lo &= (SYSCFG_MSR_TOM2WB | SYSCFG_MSR_TOM2En);
|
||||||
|
return (syscfg.lo == (SYSCFG_MSR_TOM2WB | SYSCFG_MSR_TOM2En));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_range_in_tom2_wb(struct range_entry *r)
|
||||||
|
{
|
||||||
|
const msr_t tom2_msr = rdmsr(TOP_MEM2_MSR);
|
||||||
|
const uint64_t tom2 = tom2_msr.lo | ((uint64_t)tom2_msr.hi << 32);
|
||||||
|
const int mtrr_type = range_entry_mtrr_type(r);
|
||||||
|
|
||||||
|
if ((r->begin >= (4ULL * GiB)) && (r->end < tom2))
|
||||||
|
return (mtrr_type == MTRR_TYPE_WRBACK);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void __calc_var_mtrrs(struct memranges *addr_space,
|
static void __calc_var_mtrrs(struct memranges *addr_space,
|
||||||
bool above4gb, int address_bits,
|
bool above4gb, int address_bits,
|
||||||
int *num_def_wb_mtrrs, int *num_def_uc_mtrrs)
|
int *num_def_wb_mtrrs, int *num_def_uc_mtrrs)
|
||||||
|
|
@ -633,6 +652,15 @@ static void __calc_var_mtrrs(struct memranges *addr_space,
|
||||||
|
|
||||||
mtrr_type = range_entry_mtrr_type(r);
|
mtrr_type = range_entry_mtrr_type(r);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WB MTRRs inside [4G - TOM2] range can be skipped on AMD, if
|
||||||
|
* TOM2 WB is active.
|
||||||
|
*/
|
||||||
|
if (CONFIG(X86_AMD_FIXED_MTRRS) && above4gb) {
|
||||||
|
if (is_tom2_wb_active() && is_range_in_tom2_wb(r))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (mtrr_type != MTRR_TYPE_UNCACHEABLE) {
|
if (mtrr_type != MTRR_TYPE_UNCACHEABLE) {
|
||||||
var_state.mtrr_index = 0;
|
var_state.mtrr_index = 0;
|
||||||
var_state.def_mtrr_type = MTRR_TYPE_UNCACHEABLE;
|
var_state.def_mtrr_type = MTRR_TYPE_UNCACHEABLE;
|
||||||
|
|
@ -704,6 +732,16 @@ static void prepare_var_mtrrs(struct memranges *addr_space, int def_type,
|
||||||
memranges_each_entry(r, var_state.addr_space) {
|
memranges_each_entry(r, var_state.addr_space) {
|
||||||
if (range_entry_mtrr_type(r) == def_type)
|
if (range_entry_mtrr_type(r) == def_type)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WB MTRRs inside [4G - TOM2] range can be skipped on AMD, if
|
||||||
|
* TOM2 WB is active.
|
||||||
|
*/
|
||||||
|
if (CONFIG(X86_AMD_FIXED_MTRRS) && above4gb) {
|
||||||
|
if (is_tom2_wb_active() && is_range_in_tom2_wb(r))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
calc_var_mtrrs_with_hole(&var_state, r);
|
calc_var_mtrrs_with_hole(&var_state, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,7 @@
|
||||||
/* AP MTRRs will be synced to the BSP in the SIPI vector so set them up before MP init. */
|
/* AP MTRRs will be synced to the BSP in the SIPI vector so set them up before MP init. */
|
||||||
static void pre_mp_init(void)
|
static void pre_mp_init(void)
|
||||||
{
|
{
|
||||||
const msr_t syscfg = rdmsr(SYSCFG_MSR);
|
x86_setup_mtrrs_with_detect();
|
||||||
if (syscfg.lo & SYSCFG_MSR_TOM2WB)
|
|
||||||
x86_setup_mtrrs_with_detect_no_above_4gb();
|
|
||||||
else
|
|
||||||
x86_setup_mtrrs_with_detect();
|
|
||||||
x86_mtrr_check();
|
x86_mtrr_check();
|
||||||
if (CONFIG(SOC_AMD_COMMON_BLOCK_UCODE))
|
if (CONFIG(SOC_AMD_COMMON_BLOCK_UCODE))
|
||||||
amd_load_microcode_from_cbfs();
|
amd_load_microcode_from_cbfs();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue