diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2023-09-25 20:18:32 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-26 01:18:32 +0200 |
| commit | ddc9ae2a8380668273c21a75b11b833be76eebed (patch) | |
| tree | 64fceb7529be32a9b6965e4380004029c444efc6 /src/Ryujinx.Cpu/AppleHv/HvVcpu.cs | |
| parent | d6d3cdd5739e6b8f8df36bf393e440f4857fb2b7 (diff) | |
Add VTimer as alternative interrupt method on Apple Hypervisor (#5663)
* Add VTimer as alternative interrupt method on Apple Hypervisor
* Fix naming violations on TimeApi
* Fix timer interval (was 16us rather than 16ms)
* Fix delta ticks calculation
* Missing ThrowOnError call
* Add SupportedOSPlatform attribute on AppleHv classes
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(); + } } } |
