Oskar Enoksson (enok@lysator.liu.se) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/238
-gerrit
commit feb5cbb72fc0424f9aecf0db122d2344b4fb9512 Author: Oskar Enoksson enok@lysator.liu.se Date: Thu Oct 6 18:21:19 2011 +0200
Fixed broken MTRR for >4GB memory on AMD K8 fam 0fh rev <=E
AMD K8 rev F and later implements a bit SYSCFG_MSR_TOM2WB to mark dram memory above 4GB as WB. However, AMD K8 rev E and earlier don't implement this bit and therefore need MTRR spanning dram memory above 4GB. The current implementation of amd_setup_mtrrs never generate MTRR above 4GB. This caused memory > 4GB not to be recognized in e.g. Linux on those rev E or older platforms. This commit should fix that bug.
Signed-off-by: Oskar Enoksson enok@lysator.liu.se Change-Id: Ie568a52a8eb355969c86964d5afc4692e60f69c1 --- src/cpu/amd/mtrr/amd_mtrr.c | 19 ++++++++++++++++--- 1 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/src/cpu/amd/mtrr/amd_mtrr.c b/src/cpu/amd/mtrr/amd_mtrr.c index 623a344..c5e01b1 100644 --- a/src/cpu/amd/mtrr/amd_mtrr.c +++ b/src/cpu/amd/mtrr/amd_mtrr.c @@ -112,7 +112,14 @@ void amd_setup_mtrrs(void) struct mem_state state; unsigned long i; msr_t msr, sys_cfg; - + // Test if this CPU is a Fam 0Fh rev. F or later + const int cpu_id = cpuid_eax(0x80000001); + const int has_tom2wb = + (((cpu_id>>8 )&0xf) > 0xf) || // Family > 0F + ((((cpu_id>>8 )&0xf) == 0xf) && // Family == 0F + (((cpu_id>>16)&0xf) >= 0x4)); // Rev>=F deduced from rev tables + if(has_tom2wb) + printk(BIOS_DEBUG, "CPU is Fam 0Fh rev.F or later, using TOM2WB instead of MTRR above 4GB\n");
/* Enable the access to AMD RdDram and WrDram extension bits */ disable_cache(); @@ -168,7 +175,9 @@ void amd_setup_mtrrs(void) msr.hi = state.tomk >> 22; msr.lo = state.tomk << 10; wrmsr(TOP_MEM2, msr); - sys_cfg.lo |= SYSCFG_MSR_TOM2En | SYSCFG_MSR_TOM2WB; + sys_cfg.lo |= SYSCFG_MSR_TOM2En; + if(has_tom2wb) + sys_cfg.lo |= SYSCFG_MSR_TOM2WB; }
/* zero the IORR's before we enable to prevent @@ -201,5 +210,9 @@ void amd_setup_mtrrs(void) /* Now that I have mapped what is memory and what is not * Setup the mtrrs so we can cache the memory. */ - x86_setup_var_mtrrs(address_bits, 0); + + // Rev. F K8 supports has SYSCFG_MSR_TOM2WB and dont need + // variable MTRR to span memory above 4GB + // Lower revisions K8 need variable MTRR over 4GB + x86_setup_var_mtrrs(address_bits, has_tom2wb ? 0 : 1); }