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