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,
|
||||
bool above4gb, int address_bits,
|
||||
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);
|
||||
|
||||
/*
|
||||
* 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) {
|
||||
var_state.mtrr_index = 0;
|
||||
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) {
|
||||
if (range_entry_mtrr_type(r) == def_type)
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,11 +17,7 @@
|
|||
/* 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)
|
||||
{
|
||||
const msr_t syscfg = rdmsr(SYSCFG_MSR);
|
||||
if (syscfg.lo & SYSCFG_MSR_TOM2WB)
|
||||
x86_setup_mtrrs_with_detect_no_above_4gb();
|
||||
else
|
||||
x86_setup_mtrrs_with_detect();
|
||||
x86_setup_mtrrs_with_detect();
|
||||
x86_mtrr_check();
|
||||
if (CONFIG(SOC_AMD_COMMON_BLOCK_UCODE))
|
||||
amd_load_microcode_from_cbfs();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue