KernelInit.cs 4.7 KB

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