aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Cpu/AppleHv/HvVcpu.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Cpu/AppleHv/HvVcpu.cs')
-rw-r--r--src/Ryujinx.Cpu/AppleHv/HvVcpu.cs31
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();
+ }
}
}