X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fmtrr.c;h=0548043376986bf861b4158ca8808b8e1a0a251f;hb=b93739776593eb470bd18ce8f8b028054cee0e3d;hp=6bd0dba46bbbfce4562423e1cf988e0ed972f3bd;hpb=e622ff635f8b1b53cbb433764f6f42e21350df6a;p=seabios.git diff --git a/src/mtrr.c b/src/mtrr.c index 6bd0dba..0548043 100644 --- a/src/mtrr.c +++ b/src/mtrr.c @@ -6,6 +6,7 @@ #include "util.h" // dprintf #include "biosvar.h" // GET_EBDA +#include "xen.h" // usingXen #define MSR_MTRRcap 0x000000fe #define MSR_MTRRfix64K_00000 0x00000250 @@ -24,9 +25,15 @@ #define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg)) #define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1) +#define MTRR_MEMTYPE_UC 0 +#define MTRR_MEMTYPE_WC 1 +#define MTRR_MEMTYPE_WT 4 +#define MTRR_MEMTYPE_WP 5 +#define MTRR_MEMTYPE_WB 6 + void mtrr_setup(void) { - if (CONFIG_COREBOOT) + if (!CONFIG_MTRR_INIT || CONFIG_COREBOOT || usingXen()) return; u32 eax, ebx, ecx, edx, cpuid_features; @@ -38,42 +45,42 @@ void mtrr_setup(void) dprintf(3, "init mtrr\n"); - int i, vcnt, fix, wc; - u32 ram_size = GET_GLOBAL(RamSize); - u32 mtrr_cap; - union { + u32 mtrr_cap = rdmsr(MSR_MTRRcap); + int vcnt = mtrr_cap & 0xff; + int fix = mtrr_cap & 0x100; + if (!vcnt || !fix) + return; + + // Disable MTRRs + wrmsr_smp(MSR_MTRRdefType, 0); + + // Set fixed MTRRs + union u64b { u8 valb[8]; u64 val; } u; - - mtrr_cap = rdmsr(MSR_MTRRcap); - vcnt = mtrr_cap & 0xff; - fix = mtrr_cap & 0x100; - wc = mtrr_cap & 0x400; - if (!vcnt || !fix) - return; u.val = 0; - for (i = 0; i < 8; ++i) - if (ram_size >= 65536 * (i + 1)) - u.valb[i] = 6; + int i; + for (i = 0; i < 8; i++) + if (RamSize >= 65536 * (i + 1)) + u.valb[i] = MTRR_MEMTYPE_WB; wrmsr_smp(MSR_MTRRfix64K_00000, u.val); u.val = 0; - for (i = 0; i < 8; ++i) - if (ram_size >= 65536 * 8 + 16384 * (i + 1)) - u.valb[i] = 6; + for (i = 0; i < 8; i++) + if (RamSize >= 0x80000 + 16384 * (i + 1)) + u.valb[i] = MTRR_MEMTYPE_WB; wrmsr_smp(MSR_MTRRfix16K_80000, u.val); - wrmsr_smp(MSR_MTRRfix16K_A0000, 0); - wrmsr_smp(MSR_MTRRfix4K_C0000, 0); - wrmsr_smp(MSR_MTRRfix4K_C8000, 0); - wrmsr_smp(MSR_MTRRfix4K_D0000, 0); - wrmsr_smp(MSR_MTRRfix4K_D8000, 0); - wrmsr_smp(MSR_MTRRfix4K_E0000, 0); - wrmsr_smp(MSR_MTRRfix4K_E8000, 0); - wrmsr_smp(MSR_MTRRfix4K_F0000, 0); - 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(MSR_MTRRfix16K_A0000, 0); // 0xA0000-0xC0000 is uncached + int j; + for (j = 0; j < 8; j++) { + u.val = 0; + for (i = 0; i < 8; i++) + if (RamSize >= 0xC0000 + j * 0x8000 + 4096 * (i + 1)) + u.valb[i] = MTRR_MEMTYPE_WP; + wrmsr_smp(MSR_MTRRfix4K_C0000 + j, u.val); + } + // Set variable MTRRs int phys_bits = 36; cpuid(0x80000000u, &eax, &ebx, &ecx, &edx); if (eax >= 0x80000008) { @@ -82,7 +89,15 @@ void mtrr_setup(void) phys_bits = eax & 0xff; } u64 phys_mask = ((1ull << phys_bits) - 1); - wrmsr_smp(MTRRphysMask_MSR(0), (~(0x20000000ull - 1) & phys_mask) | 0x800); + for (i=0; i