Properly mask value for MTRR mask.
authorKevin O'Connor <kevin@koconnor.net>
Tue, 10 Nov 2009 00:30:17 +0000 (19:30 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Tue, 10 Nov 2009 00:30:17 +0000 (19:30 -0500)
Signed-off-by: Magnus Christensson <mch@virtutech.com>
src/mtrr.c

index a9cd5f781cb7b16a1137b260d4dd702dcdbe6198..6bd0dba46bbbfce4562423e1cf988e0ed972f3bd 100644 (file)
@@ -29,7 +29,7 @@ void mtrr_setup(void)
     if (CONFIG_COREBOOT)
         return;
 
-    u32 eax, ebx, ecx, cpuid_features;
+    u32 eax, ebx, ecx, edx, cpuid_features;
     cpuid(1, &eax, &ebx, &ecx, &cpuid_features);
     if (!(cpuid_features & CPUID_MTRR))
         return;
@@ -73,6 +73,16 @@ void mtrr_setup(void)
     wrmsr_smp(MSR_MTRRfix4K_F8000, 0);
     /* Mark 3.5-4GB as UC, anything not specified defaults to WB */
     wrmsr_smp(MTRRphysBase_MSR(0), 0xe0000000ull | 0);
-    wrmsr_smp(MTRRphysMask_MSR(0), ~(0x20000000ull - 1) | 0x800);
+
+    int phys_bits = 36;
+    cpuid(0x80000000u, &eax, &ebx, &ecx, &edx);
+    if (eax >= 0x80000008) {
+            /* Get physical bits from leaf 0x80000008 (if available) */
+            cpuid(0x80000008u, &eax, &ebx, &ecx, &edx);
+            phys_bits = eax & 0xff;
+    }
+    u64 phys_mask = ((1ull << phys_bits) - 1);
+    wrmsr_smp(MTRRphysMask_MSR(0), (~(0x20000000ull - 1) & phys_mask) | 0x800);
+
     wrmsr_smp(MSR_MTRRdefType, 0xc06);
 }