/ src / Ryujinx.Cpu / AppleHv / HvApi.cs
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  }