Use MSR to map framebuffer as WC (write-combining) = huge speed diff on real HW
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* @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;
|
||||
}
|
||||
Reference in New Issue
Block a user