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. }