浏览代码

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 年之前
父节点
当前提交
04a912f68f
共有 3 个文件被更改,包括 10 次插入9 次删除
  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"
                      : "=a"(low), "=d"(high)
                      : "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));
     }
 };

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

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

+ 3 - 6
Kernel/Interrupts/APIC.cpp

@@ -136,18 +136,15 @@ UNMAP_AFTER_INIT void APIC::initialize()
 
 PhysicalAddress APIC::get_base()
 {
-    u32 lo, hi;
     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)
 {
-    u32 hi = 0;
-    u32 lo = base.get() | 0x800;
     MSR msr(APIC_BASE_MSR);
-    msr.set(lo, hi);
+    msr.set(base.get() | 0x800);
 }
 
 void APIC::write_register(u32 offset, u32 value)