Ryujinx/src/Ryujinx.Cpu/AppleHv/HvVm.cs
gdkchan ddc9ae2a83
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
2023-09-26 01:18:32 +02:00

70 lines
1.9 KiB
C#

using Ryujinx.Memory;
using System;
using System.Runtime.Versioning;
namespace Ryujinx.Cpu.AppleHv
{
[SupportedOSPlatform("macos")]
static class HvVm
{
// This alignment allows us to use larger blocks on the page table.
private const ulong AsIpaAlignment = 1UL << 30;
private static int _addressSpaces;
private static HvIpaAllocator _ipaAllocator;
private static readonly object _lock = new();
public static (ulong, HvIpaAllocator) CreateAddressSpace(MemoryBlock block)
{
HvIpaAllocator ipaAllocator;
lock (_lock)
{
if (++_addressSpaces == 1)
{
HvApi.hv_vm_create(IntPtr.Zero).ThrowOnError();
_ipaAllocator = ipaAllocator = new HvIpaAllocator();
}
else
{
ipaAllocator = _ipaAllocator;
}
}
ulong baseAddress;
lock (ipaAllocator)
{
baseAddress = ipaAllocator.Allocate(block.Size, AsIpaAlignment);
}
var rwx = HvMemoryFlags.Read | HvMemoryFlags.Write | HvMemoryFlags.Exec;
HvApi.hv_vm_map((ulong)block.Pointer, baseAddress, block.Size, rwx).ThrowOnError();
return (baseAddress, ipaAllocator);
}
public static void DestroyAddressSpace(ulong address, ulong size)
{
HvApi.hv_vm_unmap(address, size);
HvIpaAllocator ipaAllocator;
lock (_lock)
{
if (--_addressSpaces == 0)
{
HvApi.hv_vm_destroy().ThrowOnError();
}
ipaAllocator = _ipaAllocator;
}
lock (ipaAllocator)
{
ipaAllocator.Free(address, size);
}
}
}
}