HvVm.cs 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. using Ryujinx.Memory;
  2. using System;
  3. namespace Ryujinx.Cpu.AppleHv
  4. {
  5. static class HvVm
  6. {
  7. // This alignment allows us to use larger blocks on the page table.
  8. private const ulong AsIpaAlignment = 1UL << 30;
  9. private static int _addressSpaces;
  10. private static HvIpaAllocator _ipaAllocator;
  11. private static object _lock = new object();
  12. public static (ulong, HvIpaAllocator) CreateAddressSpace(MemoryBlock block)
  13. {
  14. HvIpaAllocator ipaAllocator;
  15. lock (_lock)
  16. {
  17. if (++_addressSpaces == 1)
  18. {
  19. HvApi.hv_vm_create(IntPtr.Zero).ThrowOnError();
  20. _ipaAllocator = ipaAllocator = new HvIpaAllocator();
  21. }
  22. else
  23. {
  24. ipaAllocator = _ipaAllocator;
  25. }
  26. }
  27. ulong baseAddress;
  28. lock (ipaAllocator)
  29. {
  30. baseAddress = ipaAllocator.Allocate(block.Size, AsIpaAlignment);
  31. }
  32. var rwx = hv_memory_flags_t.HV_MEMORY_READ | hv_memory_flags_t.HV_MEMORY_WRITE | hv_memory_flags_t.HV_MEMORY_EXEC;
  33. HvApi.hv_vm_map((ulong)block.Pointer, baseAddress, block.Size, rwx).ThrowOnError();
  34. return (baseAddress, ipaAllocator);
  35. }
  36. public static void DestroyAddressSpace(ulong address, ulong size)
  37. {
  38. HvApi.hv_vm_unmap(address, size);
  39. HvIpaAllocator ipaAllocator;
  40. lock (_lock)
  41. {
  42. if (--_addressSpaces == 0)
  43. {
  44. HvApi.hv_vm_destroy().ThrowOnError();
  45. }
  46. ipaAllocator = _ipaAllocator;
  47. }
  48. lock (ipaAllocator)
  49. {
  50. ipaAllocator.Free(address, size);
  51. }
  52. }
  53. }
  54. }