/* * @author xamidev * @brief x86 MSR C wrappers * @description * Wrapper functions to access Model Specific Registers * * @license GPL-3.0-only */ #include #include #include /* * rdmsr - Read from MSR * @msr: model specific register number * * Read a 64-bit word from a Model Specific Register. * Wrapper for the "rdmsr" instruction. It originally * outputs to two 32-bit registers (EDX:EAX), so the * function does the job of uniting them as a 64-bit * value for us. * * Return: * - value read from MSR */ uint64_t rdmsr(uint32_t msr) { uint32_t low; uint32_t high; __asm__ volatile("rdmsr" : "=a"(low), "=d"(high) : "c"(msr)); return ((uint64_t)high << 32) | low; } /* * wrmsr - Write to MSR * @msr: model specific register number * * Write a 64-bit value to a Model Specific Register. */ void wrmsr(uint32_t msr, uint64_t value) { uint32_t low = (uint32_t)(value & 0xFFFFFFFF); uint32_t high = (uint32_t)(value >> 32); __asm__ volatile("wrmsr" : : "c"(msr), "a"(low), "d"(high) : "memory"); } /* * x86_has_msr - Test for MSR support * * Checks if CPU supports Model Specific Registers * using CPUID.01h:EDX[bit 5]. * * Return: * true - MSR are supported * false - MSR are not supported */ bool x86_has_msr() { uint32_t eax, ebx, ecx, edx; cpuid(1, &eax, &ebx, &ecx, &edx); return (edx & (1 << 5)) != 0; }