Răsfoiți Sursa

extract sysreg offsets

Zhuowei Zhang 3 ani în urmă
părinte
comite
925d107f78
5 a modificat fișierele cu 480 adăugiri și 2 ștergeri
  1. 34 2
      hv.m
  2. 404 0
      sysreg_offsets.h
  3. 1 0
      tools/build_get_sysreg_offsets.sh
  4. 22 0
      tools/gen_sysreg_offsets.py
  5. 19 0
      tools/get_sysreg_offsets.m

+ 34 - 2
hv.m

@@ -253,12 +253,43 @@ hv_return_t hv_vcpu_set_simd_fp_reg(hv_vcpu_t vcpu, hv_simd_fp_reg_t reg,
 }
 
 static bool find_sys_reg(hv_sys_reg_t sys_reg, uint64_t* offset, uint64_t* sync_mask) {
-  return false;
+  uint64_t o = 0;
+  uint64_t f = 0;
+  switch (sys_reg) {
+#include "sysreg_offsets.h"
+    default:
+      return false;
+  }
+  *offset = o;
+  *sync_mask = f;
+  return true;
 }
 
 static_assert(offsetof(arm_guest_rw_context_t, dbgregs.bp[0].bvr) == 0x450,
               "HV_SYS_REG_DBGBVR0_EL1");
 
+hv_return_t hv_vcpu_get_sys_reg(hv_vcpu_t vcpu, hv_sys_reg_t sys_reg, uint64_t *value) {
+  if (sys_reg >= HV_SYS_REG_ID_AA64ISAR0_EL1 && sys_reg <= HV_SYS_REG_ID_AA64MMFR2_EL1) {
+    printf("TODO(zhuowei): not implemented\n");
+    return HV_BAD_ARGUMENT;
+  }
+  // TODO(zhuowei): handle the special cases
+  uint64_t offset = 0;
+  uint64_t sync_mask = 0;
+  bool found = find_sys_reg(sys_reg, &offset, &sync_mask);
+  if (!found) {
+    return HV_BAD_ARGUMENT;
+  }
+  if (sync_mask) {
+    // TODO(zhuowei): HV_CALL_VCPU_SYSREGS_SYNC only when needed
+    hv_trap(HV_CALL_VCPU_SYSREGS_SYNC, 0);
+  }
+  struct hv_vcpu_zone* vcpu_zone = vcpus[vcpu].vcpu_zone;
+  *value = *(uint64_t*)((char*)(&vcpu_zone->rw) + offset);
+  return 0;
+}
+
+
 hv_return_t hv_vcpu_set_sys_reg(hv_vcpu_t vcpu, hv_sys_reg_t sys_reg, uint64_t value) {
   if (sys_reg >= HV_SYS_REG_ID_AA64ISAR0_EL1 && sys_reg <= HV_SYS_REG_ID_AA64MMFR2_EL1) {
     printf("TODO(zhuowei): not implemented\n");
@@ -272,7 +303,8 @@ hv_return_t hv_vcpu_set_sys_reg(hv_vcpu_t vcpu, hv_sys_reg_t sys_reg, uint64_t v
     return HV_BAD_ARGUMENT;
   }
   if (sync_mask) {
-    // TODO(zhuowei): HV_CALL_VCPU_SYSREGS_SYNC
+    // TODO(zhuowei): HV_CALL_VCPU_SYSREGS_SYNC only when needed
+    hv_trap(HV_CALL_VCPU_SYSREGS_SYNC, 0);
   }
   struct hv_vcpu_zone* vcpu_zone = vcpus[vcpu].vcpu_zone;
   *(uint64_t*)((char*)(&vcpu_zone->rw) + offset) = offset;

+ 404 - 0
sysreg_offsets.h

@@ -0,0 +1,404 @@
+case HV_SYS_REG_DBGBVR0_EL1:
+  o = 0x450;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBCR0_EL1:
+  o = 0x458;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWVR0_EL1:
+  o = 0x550;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWCR0_EL1:
+  o = 0x558;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBVR1_EL1:
+  o = 0x460;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBCR1_EL1:
+  o = 0x468;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWVR1_EL1:
+  o = 0x560;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWCR1_EL1:
+  o = 0x568;
+  f = 0x2;
+  break;
+case HV_SYS_REG_MDCCINT_EL1:
+  o = 0x650;
+  f = 0x2;
+  break;
+case HV_SYS_REG_MDSCR_EL1:
+  o = 0x350;
+  f = 0x0;
+  break;
+case HV_SYS_REG_DBGBVR2_EL1:
+  o = 0x470;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBCR2_EL1:
+  o = 0x478;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWVR2_EL1:
+  o = 0x570;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWCR2_EL1:
+  o = 0x578;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBVR3_EL1:
+  o = 0x480;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBCR3_EL1:
+  o = 0x488;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWVR3_EL1:
+  o = 0x580;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWCR3_EL1:
+  o = 0x588;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBVR4_EL1:
+  o = 0x490;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBCR4_EL1:
+  o = 0x498;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWVR4_EL1:
+  o = 0x590;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWCR4_EL1:
+  o = 0x598;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBVR5_EL1:
+  o = 0x4a0;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBCR5_EL1:
+  o = 0x4a8;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWVR5_EL1:
+  o = 0x5a0;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWCR5_EL1:
+  o = 0x5a8;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBVR6_EL1:
+  o = 0x4b0;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBCR6_EL1:
+  o = 0x4b8;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWVR6_EL1:
+  o = 0x5b0;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWCR6_EL1:
+  o = 0x5b8;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBVR7_EL1:
+  o = 0x4c0;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBCR7_EL1:
+  o = 0x4c8;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWVR7_EL1:
+  o = 0x5c0;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWCR7_EL1:
+  o = 0x5c8;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBVR8_EL1:
+  o = 0x4d0;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBCR8_EL1:
+  o = 0x4d8;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWVR8_EL1:
+  o = 0x5d0;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWCR8_EL1:
+  o = 0x5d8;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBVR9_EL1:
+  o = 0x4e0;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBCR9_EL1:
+  o = 0x4e8;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWVR9_EL1:
+  o = 0x5e0;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWCR9_EL1:
+  o = 0x5e8;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBVR10_EL1:
+  o = 0x4f0;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBCR10_EL1:
+  o = 0x4f8;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWVR10_EL1:
+  o = 0x5f0;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWCR10_EL1:
+  o = 0x5f8;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBVR11_EL1:
+  o = 0x500;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBCR11_EL1:
+  o = 0x508;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWVR11_EL1:
+  o = 0x600;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWCR11_EL1:
+  o = 0x608;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBVR12_EL1:
+  o = 0x510;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBCR12_EL1:
+  o = 0x518;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWVR12_EL1:
+  o = 0x610;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWCR12_EL1:
+  o = 0x618;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBVR13_EL1:
+  o = 0x520;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBCR13_EL1:
+  o = 0x528;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWVR13_EL1:
+  o = 0x620;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWCR13_EL1:
+  o = 0x628;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBVR14_EL1:
+  o = 0x530;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBCR14_EL1:
+  o = 0x538;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWVR14_EL1:
+  o = 0x630;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWCR14_EL1:
+  o = 0x638;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBVR15_EL1:
+  o = 0x540;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGBCR15_EL1:
+  o = 0x548;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWVR15_EL1:
+  o = 0x640;
+  f = 0x2;
+  break;
+case HV_SYS_REG_DBGWCR15_EL1:
+  o = 0x648;
+  f = 0x2;
+  break;
+case HV_SYS_REG_SCTLR_EL1:
+  o = 0x400;
+  f = 0x1;
+  break;
+case HV_SYS_REG_CPACR_EL1:
+  o = 0x408;
+  f = 0x1;
+  break;
+case HV_SYS_REG_TTBR0_EL1:
+  o = 0x3a0;
+  f = 0x1;
+  break;
+case HV_SYS_REG_TTBR1_EL1:
+  o = 0x3a8;
+  f = 0x1;
+  break;
+case HV_SYS_REG_TCR_EL1:
+  o = 0x3b0;
+  f = 0x1;
+  break;
+case HV_SYS_REG_APIAKEYLO_EL1:
+  o = 0x7d0;
+  f = 0x2000000000000000;
+  break;
+case HV_SYS_REG_APIAKEYHI_EL1:
+  o = 0x7c8;
+  f = 0x2000000000000000;
+  break;
+case HV_SYS_REG_APIBKEYLO_EL1:
+  o = 0x7e0;
+  f = 0x2000000000000000;
+  break;
+case HV_SYS_REG_APIBKEYHI_EL1:
+  o = 0x7d8;
+  f = 0x2000000000000000;
+  break;
+case HV_SYS_REG_APDAKEYLO_EL1:
+  o = 0x7f0;
+  f = 0x2000000000000000;
+  break;
+case HV_SYS_REG_APDAKEYHI_EL1:
+  o = 0x7e8;
+  f = 0x2000000000000000;
+  break;
+case HV_SYS_REG_APDBKEYLO_EL1:
+  o = 0x800;
+  f = 0x2000000000000000;
+  break;
+case HV_SYS_REG_APDBKEYHI_EL1:
+  o = 0x7f8;
+  f = 0x2000000000000000;
+  break;
+case HV_SYS_REG_APGAKEYLO_EL1:
+  o = 0x7c0;
+  f = 0x2000000000000000;
+  break;
+case HV_SYS_REG_APGAKEYHI_EL1:
+  o = 0x7b8;
+  f = 0x2000000000000000;
+  break;
+case HV_SYS_REG_SPSR_EL1:
+  o = 0x410;
+  f = 0x1;
+  break;
+case HV_SYS_REG_ELR_EL1:
+  o = 0x3b8;
+  f = 0x1;
+  break;
+case HV_SYS_REG_SP_EL0:
+  o = 0x370;
+  f = 0x0;
+  break;
+case HV_SYS_REG_AFSR0_EL1:
+  o = 0x418;
+  f = 0x1;
+  break;
+case HV_SYS_REG_AFSR1_EL1:
+  o = 0x420;
+  f = 0x1;
+  break;
+case HV_SYS_REG_ESR_EL1:
+  o = 0x3c8;
+  f = 0x1;
+  break;
+case HV_SYS_REG_FAR_EL1:
+  o = 0x3c0;
+  f = 0x1;
+  break;
+case HV_SYS_REG_PAR_EL1:
+  o = 0x380;
+  f = 0x0;
+  break;
+case HV_SYS_REG_MAIR_EL1:
+  o = 0x3d0;
+  f = 0x1;
+  break;
+case HV_SYS_REG_AMAIR_EL1:
+  o = 0x3d8;
+  f = 0x1;
+  break;
+case HV_SYS_REG_VBAR_EL1:
+  o = 0x3e0;
+  f = 0x1;
+  break;
+case HV_SYS_REG_CONTEXTIDR_EL1:
+  o = 0x428;
+  f = 0x1;
+  break;
+case HV_SYS_REG_TPIDR_EL1:
+  o = 0x358;
+  f = 0x0;
+  break;
+case HV_SYS_REG_CNTKCTL_EL1:
+  o = 0x440;
+  f = 0x1;
+  break;
+case HV_SYS_REG_CSSELR_EL1:
+  o = 0x388;
+  f = 0x0;
+  break;
+case HV_SYS_REG_TPIDR_EL0:
+  o = 0x360;
+  f = 0x0;
+  break;
+case HV_SYS_REG_TPIDRRO_EL0:
+  o = 0x368;
+  f = 0x0;
+  break;
+case HV_SYS_REG_CNTV_CTL_EL0:
+  o = 0x430;
+  f = 0x1;
+  break;
+case HV_SYS_REG_CNTV_CVAL_EL0:
+  o = 0x3e8;
+  f = 0x1;
+  break;
+case HV_SYS_REG_SP_EL1:
+  o = 0x378;
+  f = 0x0;
+  break;

+ 1 - 0
tools/build_get_sysreg_offsets.sh

@@ -0,0 +1 @@
+exec clang -Os -o get_sysreg_offsets -target arm64-apple-macos12 get_sysreg_offsets.m -fmodules

+ 22 - 0
tools/gen_sysreg_offsets.py

@@ -0,0 +1,22 @@
+with open("sysreg_offsets.txt", "r") as infile:
+    indata = [[int(part, 16) for part in line.split(" ")]
+              for line in infile.read().strip().split("\n")]
+hvheader = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Hypervisor.framework/Headers/hv_vcpu_types.h"
+with open(hvheader, "r") as infile:
+    headerlines = [
+        line.strip().split("=") for line in infile.read().split("\n")
+        if "HV_SYS_REG_" in line
+    ]
+headermap = dict([(int(a[1].rstrip(","), 16), a[0].strip())
+                  for a in headerlines])
+template = """case {}:
+  o = {};
+  f = {};
+  break;
+"""
+outstr = ""
+for entry in indata:
+    regname = headermap[entry[0]]
+    outstr += template.format(regname, hex(entry[1]), hex(entry[2]))
+with open("../sysreg_offsets.h", "w") as outfile:
+    outfile.write(outstr)

+ 19 - 0
tools/get_sysreg_offsets.m

@@ -0,0 +1,19 @@
+@import Darwin;
+@import Hypervisor;
+int main() {
+  // 12.3.1
+  const uint64_t kHvVcpuGetSysRegAddr = 0x00000001e383f020ull;
+  const uint64_t kFindSysRegAddr = 0x00000001e383f314ull;
+  int64_t find_sys_reg_offset = kFindSysRegAddr - kHvVcpuGetSysRegAddr;
+  uint64_t get_sys_reg_addr = (uint64_t)&hv_vcpu_get_sys_reg;
+  bool (*find_sys_reg)(uint32_t reg, uint64_t * offset, uint64_t * flags) =
+      (void*)(get_sys_reg_addr + find_sys_reg_offset);
+  for (uint32_t reg = 0; reg < 0x10000; reg++) {
+    uint64_t offset = 0;
+    uint64_t flags = 0;
+    bool found = find_sys_reg(reg, &offset, &flags);
+    if (found) {
+      printf("%x %llx %llx\n", reg, offset, flags);
+    }
+  }
+}