Browse Source

Kernel: Hide the implementation detail that MSRs use two registers

When retrieving and setting x86 MSRs two registers are required. The
existing setter and getter for the MSR class made this implementation
detail visible to the caller. This changes the setter and getter to
use u64 instead.
Gunnar Beutner 4 years ago
parent
commit
04a912f68f
3 changed files with 10 additions and 9 deletions
  1. 6 2
      Kernel/Arch/x86/MSR.h
  2. 1 1
      Kernel/Arch/x86/common/Processor.cpp
  3. 3 6
      Kernel/Interrupts/APIC.cpp

+ 6 - 2
Kernel/Arch/x86/MSR.h

@@ -30,15 +30,19 @@ public:
     {
     {
     }
     }
 
 
-    void get(u32& low, u32& high)
+    [[nodiscard]] u64 get()
     {
     {
+        u32 low, high;
         asm volatile("rdmsr"
         asm volatile("rdmsr"
                      : "=a"(low), "=d"(high)
                      : "=a"(low), "=d"(high)
                      : "c"(m_msr));
                      : "c"(m_msr));
+        return ((u64)high << 32) | low;
     }
     }
 
 
-    void set(u32 low, u32 high)
+    void set(u64 value)
     {
     {
+        u32 low = value & 0xffffffff;
+        u32 high = value >> 32;
         asm volatile("wrmsr" ::"a"(low), "d"(high), "c"(m_msr));
         asm volatile("wrmsr" ::"a"(low), "d"(high), "c"(m_msr));
     }
     }
 };
 };

+ 1 - 1
Kernel/Arch/x86/common/Processor.cpp

@@ -1128,7 +1128,7 @@ UNMAP_AFTER_INIT void Processor::gdt_init()
 
 
 #if ARCH(X86_64)
 #if ARCH(X86_64)
     MSR gs_base(MSR_GS_BASE);
     MSR gs_base(MSR_GS_BASE);
-    gs_base.set((size_t)this & 0xffffffff, (size_t)this >> 32);
+    gs_base.set((u64)this);
 #else
 #else
     asm volatile(
     asm volatile(
         "mov %%ax, %%ds\n"
         "mov %%ax, %%ds\n"

+ 3 - 6
Kernel/Interrupts/APIC.cpp

@@ -136,18 +136,15 @@ UNMAP_AFTER_INIT void APIC::initialize()
 
 
 PhysicalAddress APIC::get_base()
 PhysicalAddress APIC::get_base()
 {
 {
-    u32 lo, hi;
     MSR msr(APIC_BASE_MSR);
     MSR msr(APIC_BASE_MSR);
-    msr.get(lo, hi);
-    return PhysicalAddress(lo & 0xfffff000);
+    auto base = msr.get();
+    return PhysicalAddress(base & 0xfffff000);
 }
 }
 
 
 void APIC::set_base(const PhysicalAddress& base)
 void APIC::set_base(const PhysicalAddress& base)
 {
 {
-    u32 hi = 0;
-    u32 lo = base.get() | 0x800;
     MSR msr(APIC_BASE_MSR);
     MSR msr(APIC_BASE_MSR);
-    msr.set(lo, hi);
+    msr.set(base.get() | 0x800);
 }
 }
 
 
 void APIC::write_register(u32 offset, u32 value)
 void APIC::write_register(u32 offset, u32 value)