aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Cpu/AppleHv/HvVm.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Cpu/AppleHv/HvVm.cs')
-rw-r--r--Ryujinx.Cpu/AppleHv/HvVm.cs68
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