From 2bba0dfca48be619e7a00312036b5c936acf903b Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 8 Nov 2022 21:49:41 -0500 Subject: [PATCH] Add hulk.mtrr module --- src/hulk/mtrr.d | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/hulk/mtrr.d diff --git a/src/hulk/mtrr.d b/src/hulk/mtrr.d new file mode 100644 index 0000000..6370d09 --- /dev/null +++ b/src/hulk/mtrr.d @@ -0,0 +1,70 @@ +/** + * 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); + } +}