diff options
Diffstat (limited to 'Ryujinx.Cpu/AppleHv/HvVm.cs')
-rw-r--r-- | Ryujinx.Cpu/AppleHv/HvVm.cs | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/Ryujinx.Cpu/AppleHv/HvVm.cs b/Ryujinx.Cpu/AppleHv/HvVm.cs new file mode 100644 index 00000000..d91abff9 --- /dev/null +++ b/Ryujinx.Cpu/AppleHv/HvVm.cs @@ -0,0 +1,68 @@ +using Ryujinx.Memory; +using System; + +namespace Ryujinx.Cpu.AppleHv +{ + 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 object _lock = new object(); + + 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 = hv_memory_flags_t.HV_MEMORY_READ | hv_memory_flags_t.HV_MEMORY_WRITE | hv_memory_flags_t.HV_MEMORY_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); + } + } + } +}
\ No newline at end of file |