HvVm.cs
1 using Ryujinx.Memory; 2 using System; 3 using System.Runtime.Versioning; 4 5 namespace Ryujinx.Cpu.AppleHv 6 { 7 [SupportedOSPlatform("macos")] 8 static class HvVm 9 { 10 // This alignment allows us to use larger blocks on the page table. 11 private const ulong AsIpaAlignment = 1UL << 30; 12 13 private static int _addressSpaces; 14 private static HvIpaAllocator _ipaAllocator; 15 private static readonly object _lock = new(); 16 17 public static (ulong, HvIpaAllocator) CreateAddressSpace(MemoryBlock block) 18 { 19 HvIpaAllocator ipaAllocator; 20 21 lock (_lock) 22 { 23 if (++_addressSpaces == 1) 24 { 25 HvApi.hv_vm_create(IntPtr.Zero).ThrowOnError(); 26 _ipaAllocator = ipaAllocator = new HvIpaAllocator(); 27 } 28 else 29 { 30 ipaAllocator = _ipaAllocator; 31 } 32 } 33 34 ulong baseAddress; 35 36 lock (ipaAllocator) 37 { 38 baseAddress = ipaAllocator.Allocate(block.Size, AsIpaAlignment); 39 } 40 41 var rwx = HvMemoryFlags.Read | HvMemoryFlags.Write | HvMemoryFlags.Exec; 42 43 HvApi.hv_vm_map((ulong)block.Pointer, baseAddress, block.Size, rwx).ThrowOnError(); 44 45 return (baseAddress, ipaAllocator); 46 } 47 48 public static void DestroyAddressSpace(ulong address, ulong size) 49 { 50 HvApi.hv_vm_unmap(address, size); 51 52 HvIpaAllocator ipaAllocator; 53 54 lock (_lock) 55 { 56 if (--_addressSpaces == 0) 57 { 58 HvApi.hv_vm_destroy().ThrowOnError(); 59 } 60 61 ipaAllocator = _ipaAllocator; 62 } 63 64 lock (ipaAllocator) 65 { 66 ipaAllocator.Free(address, size); 67 } 68 } 69 } 70 }