HvVcpu.cs
1 using System.Diagnostics; 2 using System.Runtime.Versioning; 3 4 namespace Ryujinx.Cpu.AppleHv 5 { 6 [SupportedOSPlatform("macos")] 7 unsafe class HvVcpu 8 { 9 private const ulong InterruptIntervalNs = 16 * 1000000; // 16 ms 10 11 private static ulong _interruptTimeDeltaTicks = 0; 12 13 public readonly ulong Handle; 14 public readonly HvVcpuExit* ExitInfo; 15 public readonly IHvExecutionContext ShadowContext; 16 public readonly IHvExecutionContext NativeContext; 17 public readonly bool IsEphemeral; 18 19 public HvVcpu( 20 ulong handle, 21 HvVcpuExit* exitInfo, 22 IHvExecutionContext shadowContext, 23 IHvExecutionContext nativeContext, 24 bool isEphemeral) 25 { 26 Handle = handle; 27 ExitInfo = exitInfo; 28 ShadowContext = shadowContext; 29 NativeContext = nativeContext; 30 IsEphemeral = isEphemeral; 31 } 32 33 public void EnableAndUpdateVTimer() 34 { 35 // We need to ensure interrupts will be serviced, 36 // and for that we set up the VTime to trigger an interrupt at fixed intervals. 37 38 ulong deltaTicks = _interruptTimeDeltaTicks; 39 40 if (deltaTicks == 0) 41 { 42 // Calculate our time delta in ticks based on the current clock frequency. 43 44 int result = TimeApi.mach_timebase_info(out var timeBaseInfo); 45 46 Debug.Assert(result == 0); 47 48 deltaTicks = ((InterruptIntervalNs * timeBaseInfo.Denom) + (timeBaseInfo.Numer - 1)) / timeBaseInfo.Numer; 49 _interruptTimeDeltaTicks = deltaTicks; 50 } 51 52 HvApi.hv_vcpu_set_sys_reg(Handle, HvSysReg.CNTV_CTL_EL0, 1).ThrowOnError(); 53 HvApi.hv_vcpu_set_sys_reg(Handle, HvSysReg.CNTV_CVAL_EL0, TimeApi.mach_absolute_time() + deltaTicks).ThrowOnError(); 54 } 55 } 56 }