KernelInit.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. using Ryujinx.HLE.HOS.Kernel.Memory;
  2. using System;
  3. namespace Ryujinx.HLE.HOS.Kernel.Common
  4. {
  5. static class KernelInit
  6. {
  7. public static void InitializeResourceLimit(KResourceLimit resourceLimit)
  8. {
  9. void EnsureSuccess(KernelResult result)
  10. {
  11. if (result != KernelResult.Success)
  12. {
  13. throw new InvalidOperationException($"Unexpected result \"{result}\".");
  14. }
  15. }
  16. int kernelMemoryCfg = 0;
  17. long ramSize = GetRamSize(kernelMemoryCfg);
  18. EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Memory, ramSize));
  19. EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Thread, 800));
  20. EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Event, 700));
  21. EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.TransferMemory, 200));
  22. EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Session, 900));
  23. if (!resourceLimit.Reserve(LimitableResource.Memory, 0) ||
  24. !resourceLimit.Reserve(LimitableResource.Memory, 0x60000))
  25. {
  26. throw new InvalidOperationException("Unexpected failure reserving memory on resource limit.");
  27. }
  28. }
  29. public static KMemoryRegionManager[] GetMemoryRegions()
  30. {
  31. KMemoryArrange arrange = GetMemoryArrange();
  32. return new KMemoryRegionManager[]
  33. {
  34. GetMemoryRegion(arrange.Application),
  35. GetMemoryRegion(arrange.Applet),
  36. GetMemoryRegion(arrange.Service),
  37. GetMemoryRegion(arrange.NvServices)
  38. };
  39. }
  40. private static KMemoryRegionManager GetMemoryRegion(KMemoryArrangeRegion region)
  41. {
  42. return new KMemoryRegionManager(region.Address, region.Size, region.EndAddr);
  43. }
  44. private static KMemoryArrange GetMemoryArrange()
  45. {
  46. int mcEmemCfg = 0x1000;
  47. ulong ememApertureSize = (ulong)(mcEmemCfg & 0x3fff) << 20;
  48. int kernelMemoryCfg = 0;
  49. ulong ramSize = (ulong)GetRamSize(kernelMemoryCfg);
  50. ulong ramPart0;
  51. ulong ramPart1;
  52. if (ramSize * 2 > ememApertureSize)
  53. {
  54. ramPart0 = ememApertureSize / 2;
  55. ramPart1 = ememApertureSize / 2;
  56. }
  57. else
  58. {
  59. ramPart0 = ememApertureSize;
  60. ramPart1 = 0;
  61. }
  62. int memoryArrange = 1;
  63. ulong applicationRgSize;
  64. switch (memoryArrange)
  65. {
  66. case 2: applicationRgSize = 0x80000000; break;
  67. case 0x11:
  68. case 0x21: applicationRgSize = 0x133400000; break;
  69. default: applicationRgSize = 0xcd500000; break;
  70. }
  71. ulong appletRgSize;
  72. switch (memoryArrange)
  73. {
  74. case 2: appletRgSize = 0x61200000; break;
  75. case 3: appletRgSize = 0x1c000000; break;
  76. case 0x11: appletRgSize = 0x23200000; break;
  77. case 0x12:
  78. case 0x21: appletRgSize = 0x89100000; break;
  79. default: appletRgSize = 0x1fb00000; break;
  80. }
  81. KMemoryArrangeRegion serviceRg;
  82. KMemoryArrangeRegion nvServicesRg;
  83. KMemoryArrangeRegion appletRg;
  84. KMemoryArrangeRegion applicationRg;
  85. const ulong nvServicesRgSize = 0x29ba000;
  86. ulong applicationRgEnd = DramMemoryMap.DramEnd; //- RamPart0;
  87. applicationRg = new KMemoryArrangeRegion(applicationRgEnd - applicationRgSize, applicationRgSize);
  88. ulong nvServicesRgEnd = applicationRg.Address - appletRgSize;
  89. nvServicesRg = new KMemoryArrangeRegion(nvServicesRgEnd - nvServicesRgSize, nvServicesRgSize);
  90. appletRg = new KMemoryArrangeRegion(nvServicesRgEnd, appletRgSize);
  91. // Note: There is an extra region used by the kernel, however
  92. // since we are doing HLE we are not going to use that memory, so give all
  93. // the remaining memory space to services.
  94. ulong serviceRgSize = nvServicesRg.Address - DramMemoryMap.SlabHeapEnd;
  95. serviceRg = new KMemoryArrangeRegion(DramMemoryMap.SlabHeapEnd, serviceRgSize);
  96. return new KMemoryArrange(serviceRg, nvServicesRg, appletRg, applicationRg);
  97. }
  98. private static long GetRamSize(int kernelMemoryCfg)
  99. {
  100. switch ((kernelMemoryCfg >> 16) & 3)
  101. {
  102. case 1: return 0x180000000;
  103. case 2: return 0x200000000;
  104. default: return 0x100000000;
  105. }
  106. }
  107. }
  108. }