/** * MTRR (Memory Type Range Register) support for HULK. */ module hulk.mtrr; import hulk.cpu; import hulk.klog; enum ulong MTRR_TYPE_UC = 0u; /* Uncacheable */ enum ulong MTRR_TYPE_WC = 1u; /* Write-Combining */ enum ulong MTRR_TYPE_WT = 4u; /* Writethrough */ enum ulong MTRR_TYPE_WP = 5u; /* Write-Protect */ enum ulong MTRR_TYPE_WB = 6u; /* Writeback */ enum uint MSR_MTRRCAP = 0xFEu; enum uint MSR_MTRRDEFTYPE = 0x2FFu; enum uint MSR_MTRRPHYSBASE0 = 0x200u; enum uint MSR_MTRRPHYSMASK0 = 0x201u; enum ulong MTRRCAP_WC = 0x400u; enum ulong MTRRCAP_FIX = 0x100u; enum ulong MTRRCAP_VCNT_MASK = 0xFFu; enum ulong MTRRDEFTYPE_E = 0x800u; enum ulong MTRRDEFTYPE_FE = 0x400u; enum ulong MTRRDEFTYPE_TYPE_MASK = 0xFFu; enum ulong MTRRPHYSBASE_PHYSBASE_MASK = 0x000F_FFFF_FFFF_F000u; enum ulong MTRRPHYSBASE_TYPE_MASK = 0xFFu; enum ulong MTRRPHYSMASK_PHYSMASK_MASK = 0x000F_FFFF_FFFF_F000u; enum ulong MTRRPHYSMASK_VALID = 0x800u; struct Mtrr { public static void initialize() { uint ebx; uint ecx; uint edx; cpuid1(&ebx, &ecx, &edx); if ((edx & CPUID_1_EDX_MTRR) == 0u) { Klog.writefln("CPU does not support MTRR"); return; } const(ulong) mtrrcap = rdmsr(MSR_MTRRCAP); const(ulong) mtrrdeftype = rdmsr(MSR_MTRRDEFTYPE); } private static ulong get_phys_base(uint n) { return rdmsr(MSR_MTRRPHYSBASE0 + 2u * n); } private static void set_phys_base(uint n, ulong physbase) { wrmsr(MSR_MTRRPHYSBASE0 + 2u * n, physbase); } private static ulong get_phys_mask(uint n) { return rdmsr(MSR_MTRRPHYSMASK0 + 2u * n); } private static void set_phys_mask(uint n, ulong physmask) { wrmsr(MSR_MTRRPHYSMASK0 + 2u * n, physmask); } }