2018-12-18 06:33:36 +01:00
|
|
|
using Ryujinx.HLE.HOS.Kernel.Memory;
|
2018-11-28 23:18:09 +01:00
|
|
|
using System;
|
|
|
|
|
2018-12-18 06:33:36 +01:00
|
|
|
namespace Ryujinx.HLE.HOS.Kernel.Common
|
2018-11-28 23:18:09 +01:00
|
|
|
{
|
|
|
|
static class KernelInit
|
|
|
|
{
|
2021-04-04 14:06:59 +02:00
|
|
|
private 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)
|
2018-11-28 23:18:09 +01:00
|
|
|
{
|
2018-12-06 12:16:24 +01:00
|
|
|
void EnsureSuccess(KernelResult result)
|
2018-11-28 23:18:09 +01:00
|
|
|
{
|
2018-12-06 12:16:24 +01:00
|
|
|
if (result != KernelResult.Success)
|
2018-11-28 23:18:09 +01:00
|
|
|
{
|
2018-12-06 12:16:24 +01:00
|
|
|
throw new InvalidOperationException($"Unexpected result \"{result}\".");
|
2018-11-28 23:18:09 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-04 14:06:59 +02:00
|
|
|
ulong ramSize = KSystemControl.GetDramSize(size);
|
2018-11-28 23:18:09 +01:00
|
|
|
|
2021-04-04 14:06:59 +02:00
|
|
|
EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Memory, (long)ramSize));
|
2018-12-06 12:16:24 +01:00
|
|
|
EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Thread, 800));
|
|
|
|
EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Event, 700));
|
|
|
|
EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.TransferMemory, 200));
|
|
|
|
EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Session, 900));
|
2018-11-28 23:18:09 +01:00
|
|
|
|
2018-12-06 12:16:24 +01:00
|
|
|
if (!resourceLimit.Reserve(LimitableResource.Memory, 0) ||
|
|
|
|
!resourceLimit.Reserve(LimitableResource.Memory, 0x60000))
|
2018-11-28 23:18:09 +01:00
|
|
|
{
|
|
|
|
throw new InvalidOperationException("Unexpected failure reserving memory on resource limit.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-04 14:06:59 +02:00
|
|
|
public static KMemoryRegionManager[] GetMemoryRegions(MemorySize size, MemoryArrange arrange)
|
2018-11-28 23:18:09 +01:00
|
|
|
{
|
2021-04-04 14:06:59 +02:00
|
|
|
ulong poolEnd = KSystemControl.GetDramEndAddress(size);
|
|
|
|
ulong applicationPoolSize = KSystemControl.GetApplicationPoolSize(arrange);
|
|
|
|
ulong appletPoolSize = KSystemControl.GetAppletPoolSize(arrange);
|
2018-11-28 23:18:09 +01:00
|
|
|
|
2021-04-04 14:06:59 +02:00
|
|
|
MemoryRegion servicePool;
|
|
|
|
MemoryRegion nvServicesPool;
|
|
|
|
MemoryRegion appletPool;
|
|
|
|
MemoryRegion applicationPool;
|
2018-11-28 23:18:09 +01:00
|
|
|
|
2021-04-04 14:06:59 +02:00
|
|
|
ulong nvServicesPoolSize = KSystemControl.GetMinimumNonSecureSystemPoolSize();
|
2018-11-28 23:18:09 +01:00
|
|
|
|
2021-04-04 14:06:59 +02:00
|
|
|
applicationPool = new MemoryRegion(poolEnd - applicationPoolSize, applicationPoolSize);
|
2018-11-28 23:18:09 +01:00
|
|
|
|
2021-04-04 14:06:59 +02:00
|
|
|
ulong nvServicesPoolEnd = applicationPool.Address - appletPoolSize;
|
2018-11-28 23:18:09 +01:00
|
|
|
|
2021-04-04 14:06:59 +02:00
|
|
|
nvServicesPool = new MemoryRegion(nvServicesPoolEnd - nvServicesPoolSize, nvServicesPoolSize);
|
|
|
|
appletPool = new MemoryRegion(nvServicesPoolEnd, appletPoolSize);
|
2018-11-28 23:18:09 +01:00
|
|
|
|
2019-07-02 04:39:22 +02:00
|
|
|
// 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.
|
2021-04-04 14:06:59 +02:00
|
|
|
ulong servicePoolSize = nvServicesPool.Address - DramMemoryMap.SlabHeapEnd;
|
2018-11-28 23:18:09 +01:00
|
|
|
|
2021-04-04 14:06:59 +02:00
|
|
|
servicePool = new MemoryRegion(DramMemoryMap.SlabHeapEnd, servicePoolSize);
|
2018-11-28 23:18:09 +01:00
|
|
|
|
2021-04-04 14:06:59 +02:00
|
|
|
return new KMemoryRegionManager[]
|
|
|
|
{
|
|
|
|
GetMemoryRegion(applicationPool),
|
|
|
|
GetMemoryRegion(appletPool),
|
|
|
|
GetMemoryRegion(servicePool),
|
|
|
|
GetMemoryRegion(nvServicesPool)
|
|
|
|
};
|
2018-11-28 23:18:09 +01:00
|
|
|
}
|
|
|
|
|
2021-04-04 14:06:59 +02:00
|
|
|
private static KMemoryRegionManager GetMemoryRegion(MemoryRegion region)
|
2018-11-28 23:18:09 +01:00
|
|
|
{
|
2021-04-04 14:06:59 +02:00
|
|
|
return new KMemoryRegionManager(region.Address, region.Size, region.EndAddress);
|
2018-11-28 23:18:09 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|