KernelInit.cs 3.5 KB

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