HvApi.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. using ARMeilleure.State;
  2. using System;
  3. using System.Runtime.InteropServices;
  4. namespace Ryujinx.Cpu.AppleHv
  5. {
  6. struct hv_vcpu_exit_exception_t
  7. {
  8. #pragma warning disable CS0649
  9. public ulong syndrome;
  10. public ulong virtual_address;
  11. public ulong physical_address;
  12. #pragma warning restore CS0649
  13. }
  14. struct hv_vcpu_exit_t
  15. {
  16. #pragma warning disable CS0649
  17. public uint reason;
  18. public hv_vcpu_exit_exception_t exception;
  19. #pragma warning restore CS0649
  20. }
  21. enum hv_reg_t : uint
  22. {
  23. HV_REG_X0,
  24. HV_REG_X1,
  25. HV_REG_X2,
  26. HV_REG_X3,
  27. HV_REG_X4,
  28. HV_REG_X5,
  29. HV_REG_X6,
  30. HV_REG_X7,
  31. HV_REG_X8,
  32. HV_REG_X9,
  33. HV_REG_X10,
  34. HV_REG_X11,
  35. HV_REG_X12,
  36. HV_REG_X13,
  37. HV_REG_X14,
  38. HV_REG_X15,
  39. HV_REG_X16,
  40. HV_REG_X17,
  41. HV_REG_X18,
  42. HV_REG_X19,
  43. HV_REG_X20,
  44. HV_REG_X21,
  45. HV_REG_X22,
  46. HV_REG_X23,
  47. HV_REG_X24,
  48. HV_REG_X25,
  49. HV_REG_X26,
  50. HV_REG_X27,
  51. HV_REG_X28,
  52. HV_REG_X29,
  53. HV_REG_FP = HV_REG_X29,
  54. HV_REG_X30,
  55. HV_REG_LR = HV_REG_X30,
  56. HV_REG_PC,
  57. HV_REG_FPCR,
  58. HV_REG_FPSR,
  59. HV_REG_CPSR,
  60. }
  61. enum hv_simd_fp_reg_t : uint
  62. {
  63. HV_SIMD_FP_REG_Q0,
  64. HV_SIMD_FP_REG_Q1,
  65. HV_SIMD_FP_REG_Q2,
  66. HV_SIMD_FP_REG_Q3,
  67. HV_SIMD_FP_REG_Q4,
  68. HV_SIMD_FP_REG_Q5,
  69. HV_SIMD_FP_REG_Q6,
  70. HV_SIMD_FP_REG_Q7,
  71. HV_SIMD_FP_REG_Q8,
  72. HV_SIMD_FP_REG_Q9,
  73. HV_SIMD_FP_REG_Q10,
  74. HV_SIMD_FP_REG_Q11,
  75. HV_SIMD_FP_REG_Q12,
  76. HV_SIMD_FP_REG_Q13,
  77. HV_SIMD_FP_REG_Q14,
  78. HV_SIMD_FP_REG_Q15,
  79. HV_SIMD_FP_REG_Q16,
  80. HV_SIMD_FP_REG_Q17,
  81. HV_SIMD_FP_REG_Q18,
  82. HV_SIMD_FP_REG_Q19,
  83. HV_SIMD_FP_REG_Q20,
  84. HV_SIMD_FP_REG_Q21,
  85. HV_SIMD_FP_REG_Q22,
  86. HV_SIMD_FP_REG_Q23,
  87. HV_SIMD_FP_REG_Q24,
  88. HV_SIMD_FP_REG_Q25,
  89. HV_SIMD_FP_REG_Q26,
  90. HV_SIMD_FP_REG_Q27,
  91. HV_SIMD_FP_REG_Q28,
  92. HV_SIMD_FP_REG_Q29,
  93. HV_SIMD_FP_REG_Q30,
  94. HV_SIMD_FP_REG_Q31,
  95. }
  96. enum hv_sys_reg_t : ushort
  97. {
  98. HV_SYS_REG_DBGBVR0_EL1 = 0x8004,
  99. HV_SYS_REG_DBGBCR0_EL1 = 0x8005,
  100. HV_SYS_REG_DBGWVR0_EL1 = 0x8006,
  101. HV_SYS_REG_DBGWCR0_EL1 = 0x8007,
  102. HV_SYS_REG_DBGBVR1_EL1 = 0x800c,
  103. HV_SYS_REG_DBGBCR1_EL1 = 0x800d,
  104. HV_SYS_REG_DBGWVR1_EL1 = 0x800e,
  105. HV_SYS_REG_DBGWCR1_EL1 = 0x800f,
  106. HV_SYS_REG_MDCCINT_EL1 = 0x8010,
  107. HV_SYS_REG_MDSCR_EL1 = 0x8012,
  108. HV_SYS_REG_DBGBVR2_EL1 = 0x8014,
  109. HV_SYS_REG_DBGBCR2_EL1 = 0x8015,
  110. HV_SYS_REG_DBGWVR2_EL1 = 0x8016,
  111. HV_SYS_REG_DBGWCR2_EL1 = 0x8017,
  112. HV_SYS_REG_DBGBVR3_EL1 = 0x801c,
  113. HV_SYS_REG_DBGBCR3_EL1 = 0x801d,
  114. HV_SYS_REG_DBGWVR3_EL1 = 0x801e,
  115. HV_SYS_REG_DBGWCR3_EL1 = 0x801f,
  116. HV_SYS_REG_DBGBVR4_EL1 = 0x8024,
  117. HV_SYS_REG_DBGBCR4_EL1 = 0x8025,
  118. HV_SYS_REG_DBGWVR4_EL1 = 0x8026,
  119. HV_SYS_REG_DBGWCR4_EL1 = 0x8027,
  120. HV_SYS_REG_DBGBVR5_EL1 = 0x802c,
  121. HV_SYS_REG_DBGBCR5_EL1 = 0x802d,
  122. HV_SYS_REG_DBGWVR5_EL1 = 0x802e,
  123. HV_SYS_REG_DBGWCR5_EL1 = 0x802f,
  124. HV_SYS_REG_DBGBVR6_EL1 = 0x8034,
  125. HV_SYS_REG_DBGBCR6_EL1 = 0x8035,
  126. HV_SYS_REG_DBGWVR6_EL1 = 0x8036,
  127. HV_SYS_REG_DBGWCR6_EL1 = 0x8037,
  128. HV_SYS_REG_DBGBVR7_EL1 = 0x803c,
  129. HV_SYS_REG_DBGBCR7_EL1 = 0x803d,
  130. HV_SYS_REG_DBGWVR7_EL1 = 0x803e,
  131. HV_SYS_REG_DBGWCR7_EL1 = 0x803f,
  132. HV_SYS_REG_DBGBVR8_EL1 = 0x8044,
  133. HV_SYS_REG_DBGBCR8_EL1 = 0x8045,
  134. HV_SYS_REG_DBGWVR8_EL1 = 0x8046,
  135. HV_SYS_REG_DBGWCR8_EL1 = 0x8047,
  136. HV_SYS_REG_DBGBVR9_EL1 = 0x804c,
  137. HV_SYS_REG_DBGBCR9_EL1 = 0x804d,
  138. HV_SYS_REG_DBGWVR9_EL1 = 0x804e,
  139. HV_SYS_REG_DBGWCR9_EL1 = 0x804f,
  140. HV_SYS_REG_DBGBVR10_EL1 = 0x8054,
  141. HV_SYS_REG_DBGBCR10_EL1 = 0x8055,
  142. HV_SYS_REG_DBGWVR10_EL1 = 0x8056,
  143. HV_SYS_REG_DBGWCR10_EL1 = 0x8057,
  144. HV_SYS_REG_DBGBVR11_EL1 = 0x805c,
  145. HV_SYS_REG_DBGBCR11_EL1 = 0x805d,
  146. HV_SYS_REG_DBGWVR11_EL1 = 0x805e,
  147. HV_SYS_REG_DBGWCR11_EL1 = 0x805f,
  148. HV_SYS_REG_DBGBVR12_EL1 = 0x8064,
  149. HV_SYS_REG_DBGBCR12_EL1 = 0x8065,
  150. HV_SYS_REG_DBGWVR12_EL1 = 0x8066,
  151. HV_SYS_REG_DBGWCR12_EL1 = 0x8067,
  152. HV_SYS_REG_DBGBVR13_EL1 = 0x806c,
  153. HV_SYS_REG_DBGBCR13_EL1 = 0x806d,
  154. HV_SYS_REG_DBGWVR13_EL1 = 0x806e,
  155. HV_SYS_REG_DBGWCR13_EL1 = 0x806f,
  156. HV_SYS_REG_DBGBVR14_EL1 = 0x8074,
  157. HV_SYS_REG_DBGBCR14_EL1 = 0x8075,
  158. HV_SYS_REG_DBGWVR14_EL1 = 0x8076,
  159. HV_SYS_REG_DBGWCR14_EL1 = 0x8077,
  160. HV_SYS_REG_DBGBVR15_EL1 = 0x807c,
  161. HV_SYS_REG_DBGBCR15_EL1 = 0x807d,
  162. HV_SYS_REG_DBGWVR15_EL1 = 0x807e,
  163. HV_SYS_REG_DBGWCR15_EL1 = 0x807f,
  164. HV_SYS_REG_MIDR_EL1 = 0xc000,
  165. HV_SYS_REG_MPIDR_EL1 = 0xc005,
  166. HV_SYS_REG_ID_AA64PFR0_EL1 = 0xc020,
  167. HV_SYS_REG_ID_AA64PFR1_EL1 = 0xc021,
  168. HV_SYS_REG_ID_AA64DFR0_EL1 = 0xc028,
  169. HV_SYS_REG_ID_AA64DFR1_EL1 = 0xc029,
  170. HV_SYS_REG_ID_AA64ISAR0_EL1 = 0xc030,
  171. HV_SYS_REG_ID_AA64ISAR1_EL1 = 0xc031,
  172. HV_SYS_REG_ID_AA64MMFR0_EL1 = 0xc038,
  173. HV_SYS_REG_ID_AA64MMFR1_EL1 = 0xc039,
  174. HV_SYS_REG_ID_AA64MMFR2_EL1 = 0xc03a,
  175. HV_SYS_REG_SCTLR_EL1 = 0xc080,
  176. HV_SYS_REG_CPACR_EL1 = 0xc082,
  177. HV_SYS_REG_TTBR0_EL1 = 0xc100,
  178. HV_SYS_REG_TTBR1_EL1 = 0xc101,
  179. HV_SYS_REG_TCR_EL1 = 0xc102,
  180. HV_SYS_REG_APIAKEYLO_EL1 = 0xc108,
  181. HV_SYS_REG_APIAKEYHI_EL1 = 0xc109,
  182. HV_SYS_REG_APIBKEYLO_EL1 = 0xc10a,
  183. HV_SYS_REG_APIBKEYHI_EL1 = 0xc10b,
  184. HV_SYS_REG_APDAKEYLO_EL1 = 0xc110,
  185. HV_SYS_REG_APDAKEYHI_EL1 = 0xc111,
  186. HV_SYS_REG_APDBKEYLO_EL1 = 0xc112,
  187. HV_SYS_REG_APDBKEYHI_EL1 = 0xc113,
  188. HV_SYS_REG_APGAKEYLO_EL1 = 0xc118,
  189. HV_SYS_REG_APGAKEYHI_EL1 = 0xc119,
  190. HV_SYS_REG_SPSR_EL1 = 0xc200,
  191. HV_SYS_REG_ELR_EL1 = 0xc201,
  192. HV_SYS_REG_SP_EL0 = 0xc208,
  193. HV_SYS_REG_AFSR0_EL1 = 0xc288,
  194. HV_SYS_REG_AFSR1_EL1 = 0xc289,
  195. HV_SYS_REG_ESR_EL1 = 0xc290,
  196. HV_SYS_REG_FAR_EL1 = 0xc300,
  197. HV_SYS_REG_PAR_EL1 = 0xc3a0,
  198. HV_SYS_REG_MAIR_EL1 = 0xc510,
  199. HV_SYS_REG_AMAIR_EL1 = 0xc518,
  200. HV_SYS_REG_VBAR_EL1 = 0xc600,
  201. HV_SYS_REG_CONTEXTIDR_EL1 = 0xc681,
  202. HV_SYS_REG_TPIDR_EL1 = 0xc684,
  203. HV_SYS_REG_CNTKCTL_EL1 = 0xc708,
  204. HV_SYS_REG_CSSELR_EL1 = 0xd000,
  205. HV_SYS_REG_TPIDR_EL0 = 0xde82,
  206. HV_SYS_REG_TPIDRRO_EL0 = 0xde83,
  207. HV_SYS_REG_CNTV_CTL_EL0 = 0xdf19,
  208. HV_SYS_REG_CNTV_CVAL_EL0 = 0xdf1a,
  209. HV_SYS_REG_SP_EL1 = 0xe208,
  210. }
  211. enum hv_memory_flags_t : ulong
  212. {
  213. HV_MEMORY_READ = 1UL << 0,
  214. HV_MEMORY_WRITE = 1UL << 1,
  215. HV_MEMORY_EXEC = 1UL << 2
  216. }
  217. enum hv_result_t : uint
  218. {
  219. HV_SUCCESS = 0,
  220. HV_ERROR = 0xfae94001,
  221. HV_BUSY = 0xfae94002,
  222. HV_BAD_ARGUMENT = 0xfae94003,
  223. HV_NO_RESOURCES = 0xfae94005,
  224. HV_NO_DEVICE = 0xfae94006,
  225. HV_DENIED = 0xfae94007,
  226. HV_UNSUPPORTED = 0xfae9400f
  227. }
  228. enum hv_interrupt_type_t : uint
  229. {
  230. HV_INTERRUPT_TYPE_IRQ,
  231. HV_INTERRUPT_TYPE_FIQ
  232. }
  233. struct hv_simd_fp_uchar16_t
  234. {
  235. public ulong Low;
  236. public ulong High;
  237. }
  238. static class HvResultExtensions
  239. {
  240. public static void ThrowOnError(this hv_result_t result)
  241. {
  242. if (result != hv_result_t.HV_SUCCESS)
  243. {
  244. throw new Exception($"Unexpected result \"{result}\".");
  245. }
  246. }
  247. }
  248. static partial class HvApi
  249. {
  250. public const string LibraryName = "/System/Library/Frameworks/Hypervisor.framework/Hypervisor";
  251. [LibraryImport(LibraryName, SetLastError = true)]
  252. public static partial hv_result_t hv_vm_get_max_vcpu_count(out uint max_vcpu_count);
  253. [LibraryImport(LibraryName, SetLastError = true)]
  254. public static partial hv_result_t hv_vm_create(IntPtr config);
  255. [LibraryImport(LibraryName, SetLastError = true)]
  256. public static partial hv_result_t hv_vm_destroy();
  257. [LibraryImport(LibraryName, SetLastError = true)]
  258. public static partial hv_result_t hv_vm_map(ulong addr, ulong ipa, ulong size, hv_memory_flags_t flags);
  259. [LibraryImport(LibraryName, SetLastError = true)]
  260. public static partial hv_result_t hv_vm_unmap(ulong ipa, ulong size);
  261. [LibraryImport(LibraryName, SetLastError = true)]
  262. public static partial hv_result_t hv_vm_protect(ulong ipa, ulong size, hv_memory_flags_t flags);
  263. [LibraryImport(LibraryName, SetLastError = true)]
  264. public unsafe static partial hv_result_t hv_vcpu_create(out ulong vcpu, ref hv_vcpu_exit_t* exit, IntPtr config);
  265. [LibraryImport(LibraryName, SetLastError = true)]
  266. public unsafe static partial hv_result_t hv_vcpu_destroy(ulong vcpu);
  267. [LibraryImport(LibraryName, SetLastError = true)]
  268. public static partial hv_result_t hv_vcpu_run(ulong vcpu);
  269. [LibraryImport(LibraryName, SetLastError = true)]
  270. public static partial hv_result_t hv_vcpus_exit(ref ulong vcpus, uint vcpu_count);
  271. [LibraryImport(LibraryName, SetLastError = true)]
  272. public static partial hv_result_t hv_vcpu_set_vtimer_mask(ulong vcpu, [MarshalAs(UnmanagedType.Bool)] bool vtimer_is_masked);
  273. [LibraryImport(LibraryName, SetLastError = true)]
  274. public static partial hv_result_t hv_vcpu_get_reg(ulong vcpu, hv_reg_t reg, out ulong value);
  275. [LibraryImport(LibraryName, SetLastError = true)]
  276. public static partial hv_result_t hv_vcpu_set_reg(ulong vcpu, hv_reg_t reg, ulong value);
  277. [LibraryImport(LibraryName, SetLastError = true)]
  278. public static partial hv_result_t hv_vcpu_get_simd_fp_reg(ulong vcpu, hv_simd_fp_reg_t reg, out hv_simd_fp_uchar16_t value);
  279. [LibraryImport(LibraryName, SetLastError = true)]
  280. public static partial hv_result_t hv_vcpu_set_simd_fp_reg(ulong vcpu, hv_simd_fp_reg_t reg, hv_simd_fp_uchar16_t value); // DO NOT USE DIRECTLY!
  281. [LibraryImport(LibraryName, SetLastError = true)]
  282. public static partial hv_result_t hv_vcpu_get_sys_reg(ulong vcpu, hv_sys_reg_t reg, out ulong value);
  283. [LibraryImport(LibraryName, SetLastError = true)]
  284. public static partial hv_result_t hv_vcpu_set_sys_reg(ulong vcpu, hv_sys_reg_t reg, ulong value);
  285. [LibraryImport(LibraryName, SetLastError = true)]
  286. public static partial hv_result_t hv_vcpu_get_pending_interrupt(ulong vcpu, hv_interrupt_type_t type, [MarshalAs(UnmanagedType.Bool)] out bool pending);
  287. [LibraryImport(LibraryName, SetLastError = true)]
  288. public static partial hv_result_t hv_vcpu_set_pending_interrupt(ulong vcpu, hv_interrupt_type_t type, [MarshalAs(UnmanagedType.Bool)] bool pending);
  289. }
  290. }