summaryrefslogtreecommitdiffstats
path: root/arch/x86_64/msr.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/msr.c')
-rw-r--r--arch/x86_64/msr.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/arch/x86_64/msr.c b/arch/x86_64/msr.c
new file mode 100644
index 0000000..1891126
--- /dev/null
+++ b/arch/x86_64/msr.c
@@ -0,0 +1,67 @@
+#include "arch/x86_64/msr.h"
+
+void
+msr_write(uint32_t msr, uint64_t v)
+{
+ __asm__ volatile("wrmsr":: "a"(v), "d"(v >> 32), "c"(msr));
+}
+
+uint64_t
+msr_read(uint32_t msr)
+{
+ uint32_t lo, hi;
+ __asm__ volatile("rdmsr": "=a"(lo), "=d"(hi): "c"(msr));
+ uint64_t v = hi;
+ v = (v << 32) | lo;
+ return v;
+}
+
+void
+msr_efer_write(msr_efer_t v)
+{
+ msr_write(MSR_EFER, *((uintptr_t*)&v));
+}
+
+msr_efer_t
+msr_efer_read(void)
+{
+ uint64_t rawv = msr_read(MSR_EFER);
+ return *((msr_efer_t*)&rawv);
+}
+
+void
+msr_star_write(msr_star_t v)
+{
+ msr_write(MSR_STAR, *((uintptr_t*)&v));
+}
+
+msr_star_t
+msr_star_read(void)
+{
+ uint64_t rawv = msr_read(MSR_STAR);
+ return *((msr_star_t*)&rawv);
+}
+
+void
+msr_lstar_write(msr_lstar_t v)
+{
+ msr_write(MSR_LSTAR, v);
+}
+
+msr_lstar_t
+msr_lstar_read(void)
+{
+ return msr_read(MSR_LSTAR);
+}
+
+void
+msr_gsbase_write(uintptr_t gsbase)
+{
+ msr_write(MSR_GSBASE, gsbase);
+}
+
+uintptr_t
+msr_gsbase_read(void)
+{
+ return msr_read(MSR_GSBASE);
+}