# HG changeset patch # User Wei Huang # Date 1302023015 18000 # Node ID 4a9430efe643d18c8b69d377a6e70325ac7a9483 # Parent 8957b6b3f43932b4e50f489bc50ed87ab1a286cd MTRR: correct DramModEn bit of SYS_CFG MSR Some buggy BIOS might set SYS_CFG DramModEn bit to 1, which can cause unexpected behavior on AMD platforms. This patch clears DramModEn bit if it is 1. Signed-off-by: Wei Huang diff -r 8957b6b3f439 -r 4a9430efe643 xen/arch/x86/cpu/amd.c --- a/xen/arch/x86/cpu/amd.c Tue Apr 05 11:13:02 2011 -0500 +++ b/xen/arch/x86/cpu/amd.c Tue Apr 05 12:03:35 2011 -0500 @@ -300,6 +300,32 @@ on_each_cpu(disable_c1e, NULL, 1); } +/* + * BIOS is expected to clear MtrrFixDramModEn bit. According to AMD BKDG : + * "The MtrrFixDramModEn bit should be set to 1 during BIOS initalization of + * the fixed MTRRs, then cleared to 0 for operation." + */ +static void check_syscfg_dram_mod_en(void) +{ + uint64_t syscfg; + static int printed = 0; + + if (!((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && + (boot_cpu_data.x86 >= 0x0f))) + return; + + rdmsrl(MSR_K8_SYSCFG, syscfg); + if (syscfg & K8_MTRRFIXRANGE_DRAM_MODIFY) { + if (!printed) { + printed++; + printk(KERN_ERR "MTRR: SYSCFG[MtrrFixDramModEn] not " + "cleared by BIOS, clearing this bit\n"); + } + syscfg &= ~K8_MTRRFIXRANGE_DRAM_MODIFY; + wrmsrl(MSR_K8_SYSCFG, syscfg); + } +} + static void __devinit init_amd(struct cpuinfo_x86 *c) { u32 l, h; @@ -453,6 +479,8 @@ disable_c1_ramping(); set_cpuidmask(c); + + check_syscfg_dram_mod_en(); } static struct cpu_dev amd_cpu_dev __cpuinitdata = {