KernelInit.cs 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using Ryujinx.HLE.HOS.Kernel.Memory;
  2. using Ryujinx.Horizon.Common;
  3. using System;
  4. namespace Ryujinx.HLE.HOS.Kernel.Common
  5. {
  6. static class KernelInit
  7. {
  8. private readonly struct MemoryRegion
  9. {
  10. public ulong Address { get; }
  11. public ulong Size { get; }
  12. public ulong EndAddress => Address + Size;
  13. public MemoryRegion(ulong address, ulong size)
  14. {
  15. Address = address;
  16. Size = size;
  17. }
  18. }
  19. public static void InitializeResourceLimit(KResourceLimit resourceLimit, MemorySize size)
  20. {
  21. void EnsureSuccess(Result result)
  22. {
  23. if (result != Result.Success)
  24. {
  25. throw new InvalidOperationException($"Unexpected result \"{result}\".");
  26. }
  27. }
  28. ulong ramSize = KSystemControl.GetDramSize(size);
  29. EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Memory, (long)ramSize));
  30. EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Thread, 800));
  31. EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Event, 700));
  32. EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.TransferMemory, 200));
  33. EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Session, 900));
  34. if (!resourceLimit.Reserve(LimitableResource.Memory, 0) ||
  35. !resourceLimit.Reserve(LimitableResource.Memory, 0x60000))
  36. {
  37. throw new InvalidOperationException("Unexpected failure reserving memory on resource limit.");
  38. }
  39. }
  40. public static KMemoryRegionManager[] GetMemoryRegions(MemorySize size, MemoryArrange arrange)
  41. {
  42. ulong poolEnd = KSystemControl.GetDramEndAddress(size);
  43. ulong applicationPoolSize = KSystemControl.GetApplicationPoolSize(arrange);
  44. ulong appletPoolSize = KSystemControl.GetAppletPoolSize(arrange);
  45. MemoryRegion servicePool;
  46. MemoryRegion nvServicesPool;
  47. MemoryRegion appletPool;
  48. MemoryRegion applicationPool;
  49. ulong nvServicesPoolSize = KSystemControl.GetMinimumNonSecureSystemPoolSize();
  50. applicationPool = new MemoryRegion(poolEnd - applicationPoolSize, applicationPoolSize);
  51. ulong nvServicesPoolEnd = applicationPool.Address - appletPoolSize;
  52. nvServicesPool = new MemoryRegion(nvServicesPoolEnd - nvServicesPoolSize, nvServicesPoolSize);
  53. appletPool = new MemoryRegion(nvServicesPoolEnd, appletPoolSize);
  54. // Note: There is an extra region used by the kernel, however
  55. // since we are doing HLE we are not going to use that memory, so give all
  56. // the remaining memory space to services.
  57. ulong servicePoolSize = nvServicesPool.Address - DramMemoryMap.SlabHeapEnd;
  58. servicePool = new MemoryRegion(DramMemoryMap.SlabHeapEnd, servicePoolSize);
  59. return new KMemoryRegionManager[]
  60. {
  61. GetMemoryRegion(applicationPool),
  62. GetMemoryRegion(appletPool),
  63. GetMemoryRegion(servicePool),
  64. GetMemoryRegion(nvServicesPool)
  65. };
  66. }
  67. private static KMemoryRegionManager GetMemoryRegion(MemoryRegion region)
  68. {
  69. return new KMemoryRegionManager(region.Address, region.Size, region.EndAddress);
  70. }
  71. }
  72. }