HvApi.cs
1 using System; 2 using System.Runtime.InteropServices; 3 using System.Runtime.Versioning; 4 5 namespace Ryujinx.Cpu.AppleHv 6 { 7 struct HvVcpuExitException 8 { 9 #pragma warning disable CS0649 // Field is never assigned to 10 public ulong Syndrome; 11 public ulong VirtualAddress; 12 public ulong PhysicalAddress; 13 #pragma warning restore CS0649 14 } 15 16 enum HvExitReason : uint 17 { 18 Canceled, 19 Exception, 20 VTimerActivated, 21 Unknown, 22 } 23 24 struct HvVcpuExit 25 { 26 #pragma warning disable CS0649 // Field is never assigned to 27 public HvExitReason Reason; 28 public HvVcpuExitException Exception; 29 #pragma warning restore CS0649 30 } 31 32 enum HvReg : uint 33 { 34 X0, 35 X1, 36 X2, 37 X3, 38 X4, 39 X5, 40 X6, 41 X7, 42 X8, 43 X9, 44 X10, 45 X11, 46 X12, 47 X13, 48 X14, 49 X15, 50 X16, 51 X17, 52 X18, 53 X19, 54 X20, 55 X21, 56 X22, 57 X23, 58 X24, 59 X25, 60 X26, 61 X27, 62 X28, 63 X29, 64 FP = X29, 65 X30, 66 LR = X30, 67 PC, 68 FPCR, 69 FPSR, 70 CPSR, 71 } 72 73 enum HvSimdFPReg : uint 74 { 75 Q0, 76 Q1, 77 Q2, 78 Q3, 79 Q4, 80 Q5, 81 Q6, 82 Q7, 83 Q8, 84 Q9, 85 Q10, 86 Q11, 87 Q12, 88 Q13, 89 Q14, 90 Q15, 91 Q16, 92 Q17, 93 Q18, 94 Q19, 95 Q20, 96 Q21, 97 Q22, 98 Q23, 99 Q24, 100 Q25, 101 Q26, 102 Q27, 103 Q28, 104 Q29, 105 Q30, 106 Q31, 107 } 108 109 enum HvSysReg : ushort 110 { 111 DBGBVR0_EL1 = 0x8004, 112 DBGBCR0_EL1 = 0x8005, 113 DBGWVR0_EL1 = 0x8006, 114 DBGWCR0_EL1 = 0x8007, 115 DBGBVR1_EL1 = 0x800c, 116 DBGBCR1_EL1 = 0x800d, 117 DBGWVR1_EL1 = 0x800e, 118 DBGWCR1_EL1 = 0x800f, 119 MDCCINT_EL1 = 0x8010, 120 MDSCR_EL1 = 0x8012, 121 DBGBVR2_EL1 = 0x8014, 122 DBGBCR2_EL1 = 0x8015, 123 DBGWVR2_EL1 = 0x8016, 124 DBGWCR2_EL1 = 0x8017, 125 DBGBVR3_EL1 = 0x801c, 126 DBGBCR3_EL1 = 0x801d, 127 DBGWVR3_EL1 = 0x801e, 128 DBGWCR3_EL1 = 0x801f, 129 DBGBVR4_EL1 = 0x8024, 130 DBGBCR4_EL1 = 0x8025, 131 DBGWVR4_EL1 = 0x8026, 132 DBGWCR4_EL1 = 0x8027, 133 DBGBVR5_EL1 = 0x802c, 134 DBGBCR5_EL1 = 0x802d, 135 DBGWVR5_EL1 = 0x802e, 136 DBGWCR5_EL1 = 0x802f, 137 DBGBVR6_EL1 = 0x8034, 138 DBGBCR6_EL1 = 0x8035, 139 DBGWVR6_EL1 = 0x8036, 140 DBGWCR6_EL1 = 0x8037, 141 DBGBVR7_EL1 = 0x803c, 142 DBGBCR7_EL1 = 0x803d, 143 DBGWVR7_EL1 = 0x803e, 144 DBGWCR7_EL1 = 0x803f, 145 DBGBVR8_EL1 = 0x8044, 146 DBGBCR8_EL1 = 0x8045, 147 DBGWVR8_EL1 = 0x8046, 148 DBGWCR8_EL1 = 0x8047, 149 DBGBVR9_EL1 = 0x804c, 150 DBGBCR9_EL1 = 0x804d, 151 DBGWVR9_EL1 = 0x804e, 152 DBGWCR9_EL1 = 0x804f, 153 DBGBVR10_EL1 = 0x8054, 154 DBGBCR10_EL1 = 0x8055, 155 DBGWVR10_EL1 = 0x8056, 156 DBGWCR10_EL1 = 0x8057, 157 DBGBVR11_EL1 = 0x805c, 158 DBGBCR11_EL1 = 0x805d, 159 DBGWVR11_EL1 = 0x805e, 160 DBGWCR11_EL1 = 0x805f, 161 DBGBVR12_EL1 = 0x8064, 162 DBGBCR12_EL1 = 0x8065, 163 DBGWVR12_EL1 = 0x8066, 164 DBGWCR12_EL1 = 0x8067, 165 DBGBVR13_EL1 = 0x806c, 166 DBGBCR13_EL1 = 0x806d, 167 DBGWVR13_EL1 = 0x806e, 168 DBGWCR13_EL1 = 0x806f, 169 DBGBVR14_EL1 = 0x8074, 170 DBGBCR14_EL1 = 0x8075, 171 DBGWVR14_EL1 = 0x8076, 172 DBGWCR14_EL1 = 0x8077, 173 DBGBVR15_EL1 = 0x807c, 174 DBGBCR15_EL1 = 0x807d, 175 DBGWVR15_EL1 = 0x807e, 176 DBGWCR15_EL1 = 0x807f, 177 MIDR_EL1 = 0xc000, 178 MPIDR_EL1 = 0xc005, 179 ID_AA64PFR0_EL1 = 0xc020, 180 ID_AA64PFR1_EL1 = 0xc021, 181 ID_AA64DFR0_EL1 = 0xc028, 182 ID_AA64DFR1_EL1 = 0xc029, 183 ID_AA64ISAR0_EL1 = 0xc030, 184 ID_AA64ISAR1_EL1 = 0xc031, 185 ID_AA64MMFR0_EL1 = 0xc038, 186 ID_AA64MMFR1_EL1 = 0xc039, 187 ID_AA64MMFR2_EL1 = 0xc03a, 188 SCTLR_EL1 = 0xc080, 189 CPACR_EL1 = 0xc082, 190 TTBR0_EL1 = 0xc100, 191 TTBR1_EL1 = 0xc101, 192 TCR_EL1 = 0xc102, 193 APIAKEYLO_EL1 = 0xc108, 194 APIAKEYHI_EL1 = 0xc109, 195 APIBKEYLO_EL1 = 0xc10a, 196 APIBKEYHI_EL1 = 0xc10b, 197 APDAKEYLO_EL1 = 0xc110, 198 APDAKEYHI_EL1 = 0xc111, 199 APDBKEYLO_EL1 = 0xc112, 200 APDBKEYHI_EL1 = 0xc113, 201 APGAKEYLO_EL1 = 0xc118, 202 APGAKEYHI_EL1 = 0xc119, 203 SPSR_EL1 = 0xc200, 204 ELR_EL1 = 0xc201, 205 SP_EL0 = 0xc208, 206 AFSR0_EL1 = 0xc288, 207 AFSR1_EL1 = 0xc289, 208 ESR_EL1 = 0xc290, 209 FAR_EL1 = 0xc300, 210 PAR_EL1 = 0xc3a0, 211 MAIR_EL1 = 0xc510, 212 AMAIR_EL1 = 0xc518, 213 VBAR_EL1 = 0xc600, 214 CONTEXTIDR_EL1 = 0xc681, 215 TPIDR_EL1 = 0xc684, 216 CNTKCTL_EL1 = 0xc708, 217 CSSELR_EL1 = 0xd000, 218 TPIDR_EL0 = 0xde82, 219 TPIDRRO_EL0 = 0xde83, 220 CNTV_CTL_EL0 = 0xdf19, 221 CNTV_CVAL_EL0 = 0xdf1a, 222 SP_EL1 = 0xe208, 223 } 224 225 enum HvMemoryFlags : ulong 226 { 227 Read = 1UL << 0, 228 Write = 1UL << 1, 229 Exec = 1UL << 2, 230 } 231 232 enum HvResult : uint 233 { 234 Success = 0, 235 Error = 0xfae94001, 236 Busy = 0xfae94002, 237 BadArgument = 0xfae94003, 238 NoResources = 0xfae94005, 239 NoDevice = 0xfae94006, 240 Denied = 0xfae94007, 241 Unsupported = 0xfae9400f, 242 } 243 244 enum HvInterruptType : uint 245 { 246 IRQ, 247 FIQ, 248 } 249 250 struct HvSimdFPUchar16 251 { 252 public ulong Low; 253 public ulong High; 254 } 255 256 static class HvResultExtensions 257 { 258 public static void ThrowOnError(this HvResult result) 259 { 260 if (result != HvResult.Success) 261 { 262 throw new Exception($"Unexpected result \"{result}\"."); 263 } 264 } 265 } 266 267 [SupportedOSPlatform("macos")] 268 static partial class HvApi 269 { 270 public const string LibraryName = "/System/Library/Frameworks/Hypervisor.framework/Hypervisor"; 271 272 [LibraryImport(LibraryName, SetLastError = true)] 273 public static partial HvResult hv_vm_get_max_vcpu_count(out uint max_vcpu_count); 274 275 [LibraryImport(LibraryName, SetLastError = true)] 276 public static partial HvResult hv_vm_create(IntPtr config); 277 278 [LibraryImport(LibraryName, SetLastError = true)] 279 public static partial HvResult hv_vm_destroy(); 280 281 [LibraryImport(LibraryName, SetLastError = true)] 282 public static partial HvResult hv_vm_map(ulong addr, ulong ipa, ulong size, HvMemoryFlags flags); 283 284 [LibraryImport(LibraryName, SetLastError = true)] 285 public static partial HvResult hv_vm_unmap(ulong ipa, ulong size); 286 287 [LibraryImport(LibraryName, SetLastError = true)] 288 public static partial HvResult hv_vm_protect(ulong ipa, ulong size, HvMemoryFlags flags); 289 290 [LibraryImport(LibraryName, SetLastError = true)] 291 public unsafe static partial HvResult hv_vcpu_create(out ulong vcpu, ref HvVcpuExit* exit, IntPtr config); 292 293 [LibraryImport(LibraryName, SetLastError = true)] 294 public unsafe static partial HvResult hv_vcpu_destroy(ulong vcpu); 295 296 [LibraryImport(LibraryName, SetLastError = true)] 297 public static partial HvResult hv_vcpu_run(ulong vcpu); 298 299 [LibraryImport(LibraryName, SetLastError = true)] 300 public static partial HvResult hv_vcpus_exit(ref ulong vcpus, uint vcpu_count); 301 302 [LibraryImport(LibraryName, SetLastError = true)] 303 public static partial HvResult hv_vcpu_set_vtimer_mask(ulong vcpu, [MarshalAs(UnmanagedType.Bool)] bool vtimer_is_masked); 304 305 [LibraryImport(LibraryName, SetLastError = true)] 306 public static partial HvResult hv_vcpu_get_reg(ulong vcpu, HvReg reg, out ulong value); 307 308 [LibraryImport(LibraryName, SetLastError = true)] 309 public static partial HvResult hv_vcpu_set_reg(ulong vcpu, HvReg reg, ulong value); 310 311 [LibraryImport(LibraryName, SetLastError = true)] 312 public static partial HvResult hv_vcpu_get_simd_fp_reg(ulong vcpu, HvSimdFPReg reg, out HvSimdFPUchar16 value); 313 314 [LibraryImport(LibraryName, SetLastError = true)] 315 public static partial HvResult hv_vcpu_set_simd_fp_reg(ulong vcpu, HvSimdFPReg reg, HvSimdFPUchar16 value); // DO NOT USE DIRECTLY! 316 317 [LibraryImport(LibraryName, SetLastError = true)] 318 public static partial HvResult hv_vcpu_get_sys_reg(ulong vcpu, HvSysReg reg, out ulong value); 319 320 [LibraryImport(LibraryName, SetLastError = true)] 321 public static partial HvResult hv_vcpu_set_sys_reg(ulong vcpu, HvSysReg reg, ulong value); 322 323 [LibraryImport(LibraryName, SetLastError = true)] 324 public static partial HvResult hv_vcpu_get_pending_interrupt(ulong vcpu, HvInterruptType type, [MarshalAs(UnmanagedType.Bool)] out bool pending); 325 326 [LibraryImport(LibraryName, SetLastError = true)] 327 public static partial HvResult hv_vcpu_set_pending_interrupt(ulong vcpu, HvInterruptType type, [MarshalAs(UnmanagedType.Bool)] bool pending); 328 } 329 }