diff options
Diffstat (limited to 'src/Ryujinx.Cpu/AppleHv/HvVcpu.cs')
-rw-r--r-- | src/Ryujinx.Cpu/AppleHv/HvVcpu.cs | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/src/Ryujinx.Cpu/AppleHv/HvVcpu.cs b/src/Ryujinx.Cpu/AppleHv/HvVcpu.cs index 9c2cc0ff..ee91c478 100644 --- a/src/Ryujinx.Cpu/AppleHv/HvVcpu.cs +++ b/src/Ryujinx.Cpu/AppleHv/HvVcpu.cs @@ -1,7 +1,15 @@ +using System.Diagnostics; +using System.Runtime.Versioning; + namespace Ryujinx.Cpu.AppleHv { + [SupportedOSPlatform("macos")] unsafe class HvVcpu { + private const ulong InterruptIntervalNs = 16 * 1000000; // 16 ms + + private static ulong _interruptTimeDeltaTicks = 0; + public readonly ulong Handle; public readonly HvVcpuExit* ExitInfo; public readonly IHvExecutionContext ShadowContext; @@ -21,5 +29,28 @@ namespace Ryujinx.Cpu.AppleHv NativeContext = nativeContext; IsEphemeral = isEphemeral; } + + public void EnableAndUpdateVTimer() + { + // We need to ensure interrupts will be serviced, + // and for that we set up the VTime to trigger an interrupt at fixed intervals. + + ulong deltaTicks = _interruptTimeDeltaTicks; + + if (deltaTicks == 0) + { + // Calculate our time delta in ticks based on the current clock frequency. + + int result = TimeApi.mach_timebase_info(out var timeBaseInfo); + + Debug.Assert(result == 0); + + deltaTicks = ((InterruptIntervalNs * timeBaseInfo.Denom) + (timeBaseInfo.Numer - 1)) / timeBaseInfo.Numer; + _interruptTimeDeltaTicks = deltaTicks; + } + + HvApi.hv_vcpu_set_sys_reg(Handle, HvSysReg.CNTV_CTL_EL0, 1).ThrowOnError(); + HvApi.hv_vcpu_set_sys_reg(Handle, HvSysReg.CNTV_CVAL_EL0, TimeApi.mach_absolute_time() + deltaTicks).ThrowOnError(); + } } } |