diff options
Diffstat (limited to 'src/Ryujinx.HLE/HOS/Kernel/Common/KernelInit.cs')
-rw-r--r-- | src/Ryujinx.HLE/HOS/Kernel/Common/KernelInit.cs | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/Ryujinx.HLE/HOS/Kernel/Common/KernelInit.cs b/src/Ryujinx.HLE/HOS/Kernel/Common/KernelInit.cs new file mode 100644 index 00000000..efa2a480 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Kernel/Common/KernelInit.cs @@ -0,0 +1,89 @@ +using Ryujinx.HLE.HOS.Kernel.Memory; +using Ryujinx.Horizon.Common; +using System; + +namespace Ryujinx.HLE.HOS.Kernel.Common +{ + static class KernelInit + { + private readonly struct MemoryRegion + { + public ulong Address { get; } + public ulong Size { get; } + + public ulong EndAddress => Address + Size; + + public MemoryRegion(ulong address, ulong size) + { + Address = address; + Size = size; + } + } + + public static void InitializeResourceLimit(KResourceLimit resourceLimit, MemorySize size) + { + void EnsureSuccess(Result result) + { + if (result != Result.Success) + { + throw new InvalidOperationException($"Unexpected result \"{result}\"."); + } + } + + ulong ramSize = KSystemControl.GetDramSize(size); + + EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Memory, (long)ramSize)); + EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Thread, 800)); + EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Event, 700)); + EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.TransferMemory, 200)); + EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Session, 900)); + + if (!resourceLimit.Reserve(LimitableResource.Memory, 0) || + !resourceLimit.Reserve(LimitableResource.Memory, 0x60000)) + { + throw new InvalidOperationException("Unexpected failure reserving memory on resource limit."); + } + } + + public static KMemoryRegionManager[] GetMemoryRegions(MemorySize size, MemoryArrange arrange) + { + ulong poolEnd = KSystemControl.GetDramEndAddress(size); + ulong applicationPoolSize = KSystemControl.GetApplicationPoolSize(arrange); + ulong appletPoolSize = KSystemControl.GetAppletPoolSize(arrange); + + MemoryRegion servicePool; + MemoryRegion nvServicesPool; + MemoryRegion appletPool; + MemoryRegion applicationPool; + + ulong nvServicesPoolSize = KSystemControl.GetMinimumNonSecureSystemPoolSize(); + + applicationPool = new MemoryRegion(poolEnd - applicationPoolSize, applicationPoolSize); + + ulong nvServicesPoolEnd = applicationPool.Address - appletPoolSize; + + nvServicesPool = new MemoryRegion(nvServicesPoolEnd - nvServicesPoolSize, nvServicesPoolSize); + appletPool = new MemoryRegion(nvServicesPoolEnd, appletPoolSize); + + // Note: There is an extra region used by the kernel, however + // since we are doing HLE we are not going to use that memory, so give all + // the remaining memory space to services. + ulong servicePoolSize = nvServicesPool.Address - DramMemoryMap.SlabHeapEnd; + + servicePool = new MemoryRegion(DramMemoryMap.SlabHeapEnd, servicePoolSize); + + return new KMemoryRegionManager[] + { + GetMemoryRegion(applicationPool), + GetMemoryRegion(appletPool), + GetMemoryRegion(servicePool), + GetMemoryRegion(nvServicesPool) + }; + } + + private static KMemoryRegionManager GetMemoryRegion(MemoryRegion region) + { + return new KMemoryRegionManager(region.Address, region.Size, region.EndAddress); + } + } +}
\ No newline at end of file |