Allow DRAM size to be increased from 4GB to 6GB (#2174)

* Allow DRAM size to be increased from 4GB to 6GB

* Add option on the UI
This commit is contained in:
gdkchan 2021-04-04 09:06:59 -03:00 committed by GitHub
parent 3bc107d491
commit 874540bb5c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 278 additions and 144 deletions

View file

@ -5,7 +5,21 @@ namespace Ryujinx.HLE.HOS.Kernel.Common
{
static class KernelInit
{
public static void InitializeResourceLimit(KResourceLimit resourceLimit)
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)
{
void EnsureSuccess(KernelResult result)
{
@ -15,11 +29,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Common
}
}
int kernelMemoryCfg = 0;
ulong ramSize = KSystemControl.GetDramSize(size);
long ramSize = GetRamSize(kernelMemoryCfg);
EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Memory, ramSize));
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));
@ -32,106 +44,45 @@ namespace Ryujinx.HLE.HOS.Kernel.Common
}
}
public static KMemoryRegionManager[] GetMemoryRegions()
public static KMemoryRegionManager[] GetMemoryRegions(MemorySize size, MemoryArrange arrange)
{
KMemoryArrange arrange = GetMemoryArrange();
ulong poolEnd = KSystemControl.GetDramEndAddress(size);
ulong applicationPoolSize = KSystemControl.GetApplicationPoolSize(arrange);
ulong appletPoolSize = KSystemControl.GetAppletPoolSize(arrange);
return new KMemoryRegionManager[]
{
GetMemoryRegion(arrange.Application),
GetMemoryRegion(arrange.Applet),
GetMemoryRegion(arrange.Service),
GetMemoryRegion(arrange.NvServices)
};
}
MemoryRegion servicePool;
MemoryRegion nvServicesPool;
MemoryRegion appletPool;
MemoryRegion applicationPool;
private static KMemoryRegionManager GetMemoryRegion(KMemoryArrangeRegion region)
{
return new KMemoryRegionManager(region.Address, region.Size, region.EndAddr);
}
ulong nvServicesPoolSize = KSystemControl.GetMinimumNonSecureSystemPoolSize();
private static KMemoryArrange GetMemoryArrange()
{
int mcEmemCfg = 0x1000;
applicationPool = new MemoryRegion(poolEnd - applicationPoolSize, applicationPoolSize);
ulong ememApertureSize = (ulong)(mcEmemCfg & 0x3fff) << 20;
ulong nvServicesPoolEnd = applicationPool.Address - appletPoolSize;
int kernelMemoryCfg = 0;
ulong ramSize = (ulong)GetRamSize(kernelMemoryCfg);
ulong ramPart0;
ulong ramPart1;
if (ramSize * 2 > ememApertureSize)
{
ramPart0 = ememApertureSize / 2;
ramPart1 = ememApertureSize / 2;
}
else
{
ramPart0 = ememApertureSize;
ramPart1 = 0;
}
int memoryArrange = 1;
ulong applicationRgSize;
switch (memoryArrange)
{
case 2: applicationRgSize = 0x80000000; break;
case 0x11:
case 0x21: applicationRgSize = 0x133400000; break;
default: applicationRgSize = 0xcd500000; break;
}
ulong appletRgSize;
switch (memoryArrange)
{
case 2: appletRgSize = 0x61200000; break;
case 3: appletRgSize = 0x1c000000; break;
case 0x11: appletRgSize = 0x23200000; break;
case 0x12:
case 0x21: appletRgSize = 0x89100000; break;
default: appletRgSize = 0x1fb00000; break;
}
KMemoryArrangeRegion serviceRg;
KMemoryArrangeRegion nvServicesRg;
KMemoryArrangeRegion appletRg;
KMemoryArrangeRegion applicationRg;
const ulong nvServicesRgSize = 0x29ba000;
ulong applicationRgEnd = DramMemoryMap.DramEnd; //- RamPart0;
applicationRg = new KMemoryArrangeRegion(applicationRgEnd - applicationRgSize, applicationRgSize);
ulong nvServicesRgEnd = applicationRg.Address - appletRgSize;
nvServicesRg = new KMemoryArrangeRegion(nvServicesRgEnd - nvServicesRgSize, nvServicesRgSize);
appletRg = new KMemoryArrangeRegion(nvServicesRgEnd, appletRgSize);
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 serviceRgSize = nvServicesRg.Address - DramMemoryMap.SlabHeapEnd;
ulong servicePoolSize = nvServicesPool.Address - DramMemoryMap.SlabHeapEnd;
serviceRg = new KMemoryArrangeRegion(DramMemoryMap.SlabHeapEnd, serviceRgSize);
servicePool = new MemoryRegion(DramMemoryMap.SlabHeapEnd, servicePoolSize);
return new KMemoryArrange(serviceRg, nvServicesRg, appletRg, applicationRg);
return new KMemoryRegionManager[]
{
GetMemoryRegion(applicationPool),
GetMemoryRegion(appletPool),
GetMemoryRegion(servicePool),
GetMemoryRegion(nvServicesPool)
};
}
private static long GetRamSize(int kernelMemoryCfg)
private static KMemoryRegionManager GetMemoryRegion(MemoryRegion region)
{
switch ((kernelMemoryCfg >> 16) & 3)
{
case 1: return 0x180000000;
case 2: return 0x200000000;
default: return 0x100000000;
}
return new KMemoryRegionManager(region.Address, region.Size, region.EndAddress);
}
}
}