/ src / Ryujinx.Cpu / AppleHv / HvVm.cs
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  }