Create a gist now

Instantly share code, notes, and snippets.

@lisovy /MTRR.c
Last active Aug 29, 2015

What would you like to do?
/*
* Inpired by https://www.opensource.apple.com/source/xnu/xnu-1456.1.26/osfmk/i386/mtrr.c
*/
#define MTRR_TYPE_UC 0x0
#define MTRR_TYPE_WC 0x1
#define MTRR_TYPE_WT 0x4
#define MTRR_TYPE_WP 0x5
#define MTRR_TYPE_WB 0x6
#define MSR_MTRRCAP 0xfe
#define MSR_MTRR_PHYSBASE(n) (0x200 + n*2)
#define MSR_MTRR_PHYSMASK(n) (0x201 + n*2)
#define MTRR_PHYSBASE_TYPE_mask 0xff
#define MTRR_PHYSBASE_BASE_mask 0xffffff000ULL /* Assume MAXPHYADDR is 36-bit phys addr */
#define MTRR_PHYSBASE_BASE_shft 12
#define MTRR_PHYSMASK_VALID_mask (1ULL << 11)
#define MTRR_PHYSMASK_MASK_mask 0xffffff000ULL /* Assume MAXPHYADDR is 36-bit phys addr */
static inline uint64_t read_msr(int msr)
{
uint32_t hi, lo;
uint64_t val;
asm volatile("rdmsr":"=a"(lo),"=d"(hi):"c"(msr));
val = (uint64_t)lo | (((uint64_t)hi) << 32);
return val;
}
int main(int argc, char* argv[])
{
uint64_t msr1;
uint64_t msr2;
int type;
const char mtrr_type[7][3] = {
[0] = "UC",
[1] = "WC",
[2] = " ",
[3] = " ",
[4] = "WT",
[5] = "WP",
[6] = "WB"};
msr1 = read_msr(MSR_MTRRCAP);
printf("MSR: 0x%016llx\n", msr1);
for (int mtrr = 0; mtrr < 9; mtrr++) {
msr1 = read_msr(MSR_MTRR_PHYSMASK(mtrr));
if (msr1 & MTRR_PHYSMASK_VALID_mask) {
msr2 = read_msr(MSR_MTRR_PHYSBASE(mtrr));
type = msr2 & MTRR_PHYSBASE_TYPE_mask;
printf("MTRR[%u] base: 0x%016llx (%06u MB) type: %s",
mtrr,
/* ... is extended by 12 bits at the low
end to form the base address ... */
((msr2 & MTRR_PHYSBASE_BASE_mask)
/*>> MTRR_PHYSBASE_BASE_shft*/),
(uint32_t)(((~(msr1 & MTRR_PHYSMASK_MASK_mask)
& 0xffffffff)+ 1) / (1024*1024)),
mtrr_type[(type <= 6) ? type : 2]);
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment