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 }