Files
pepperOS/src/arch/x86/msr.c
T

66 lines
1.4 KiB
C

/*
* @author xamidev <xamidev@riseup.net>
* @brief x86 MSR C wrappers
* @description
* Wrapper functions to access Model Specific Registers
*
* @license GPL-3.0-only
*/
#include <stdint.h>
#include <stdbool.h>
#include <arch/x86.h>
/*
* 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> - 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;
}