diff options
author | gdkchan <gab.dark.100@gmail.com> | 2021-04-04 09:06:59 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-04 14:06:59 +0200 |
commit | 874540bb5c1c5737bc9b0bfdc96fe1cf12ff164d (patch) | |
tree | 68582881e7f4965d7e0938020a9f5dd1773f070a /Ryujinx.HLE | |
parent | 3bc107d491745a0d1f18e48d8c6c0f74565ae633 (diff) |
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
Diffstat (limited to 'Ryujinx.HLE')
-rw-r--r-- | Ryujinx.HLE/HOS/Horizon.cs | 8 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Common/KSystemControl.cs | 72 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Common/KernelInit.cs | 131 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Common/MemoryArrange.cs | 12 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Common/MemroySize.cs | 9 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/KernelContext.cs | 10 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Memory/DramMemoryMap.cs | 2 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrange.cs | 22 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrangeRegion.cs | 16 | ||||
-rw-r--r-- | Ryujinx.HLE/MemoryConfiguration.cs | 62 | ||||
-rw-r--r-- | Ryujinx.HLE/Switch.cs | 17 |
11 files changed, 223 insertions, 138 deletions
diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs index daa8dcc3..80f097f4 100644 --- a/Ryujinx.HLE/HOS/Horizon.cs +++ b/Ryujinx.HLE/HOS/Horizon.cs @@ -110,9 +110,13 @@ namespace Ryujinx.HLE.HOS internal LibHac.Horizon LibHacHorizonServer { get; private set; } internal HorizonClient LibHacHorizonClient { get; private set; } - public Horizon(Switch device, ContentManager contentManager) + public Horizon(Switch device, ContentManager contentManager, MemoryConfiguration memoryConfiguration) { - KernelContext = new KernelContext(device, device.Memory); + KernelContext = new KernelContext( + device, + device.Memory, + memoryConfiguration.ToKernelMemorySize(), + memoryConfiguration.ToKernelMemoryArrange()); Device = device; diff --git a/Ryujinx.HLE/HOS/Kernel/Common/KSystemControl.cs b/Ryujinx.HLE/HOS/Kernel/Common/KSystemControl.cs new file mode 100644 index 00000000..630baacf --- /dev/null +++ b/Ryujinx.HLE/HOS/Kernel/Common/KSystemControl.cs @@ -0,0 +1,72 @@ +using Ryujinx.HLE.HOS.Kernel.Memory; +using System; + +namespace Ryujinx.HLE.HOS.Kernel.Common +{ + static class KSystemControl + { + private const ulong Kb = 1024; + private const ulong Mb = 1024 * Kb; + private const ulong Gb = 1024 * Mb; + + private const ulong PageSize = 4 * Kb; + + private const ulong RequiredNonSecureSystemPoolSizeVi = 0x2238 * PageSize; + private const ulong RequiredNonSecureSystemPoolSizeNvservices = 0x710 * PageSize; + private const ulong RequiredNonSecureSystemPoolSizeOther = 0x80 * PageSize; + + private const ulong RequiredNonSecureSystemPoolSize = + RequiredNonSecureSystemPoolSizeVi + + RequiredNonSecureSystemPoolSizeNvservices + + RequiredNonSecureSystemPoolSizeOther; + + public static ulong GetApplicationPoolSize(MemoryArrange arrange) + { + return arrange switch + { + MemoryArrange.MemoryArrange4GB or + MemoryArrange.MemoryArrange4GBSystemDev or + MemoryArrange.MemoryArrange6GBAppletDev => 3285 * Mb, + MemoryArrange.MemoryArrange4GBAppletDev => 2048 * Mb, + MemoryArrange.MemoryArrange6GB or + MemoryArrange.MemoryArrange8GB => 4916 * Mb, + _ => throw new ArgumentException($"Invalid memory arrange \"{arrange}\".") + }; + } + + public static ulong GetAppletPoolSize(MemoryArrange arrange) + { + return arrange switch + { + MemoryArrange.MemoryArrange4GB => 507 * Mb, + MemoryArrange.MemoryArrange4GBAppletDev => 1554 * Mb, + MemoryArrange.MemoryArrange4GBSystemDev => 448 * Mb, + MemoryArrange.MemoryArrange6GB => 562 * Mb, + MemoryArrange.MemoryArrange6GBAppletDev or + MemoryArrange.MemoryArrange8GB => 2193 * Mb, + _ => throw new ArgumentException($"Invalid memory arrange \"{arrange}\".") + }; + } + + public static ulong GetMinimumNonSecureSystemPoolSize() + { + return RequiredNonSecureSystemPoolSize; + } + + public static ulong GetDramEndAddress(MemorySize size) + { + return DramMemoryMap.DramBase + GetDramSize(size); + } + + public static ulong GetDramSize(MemorySize size) + { + return size switch + { + MemorySize.MemorySize4GB => 4 * Gb, + MemorySize.MemorySize6GB => 6 * Gb, + MemorySize.MemorySize8GB => 8 * Gb, + _ => throw new ArgumentException($"Invalid memory size \"{size}\".") + }; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Kernel/Common/KernelInit.cs b/Ryujinx.HLE/HOS/Kernel/Common/KernelInit.cs index bbb75f18..1949df31 100644 --- a/Ryujinx.HLE/HOS/Kernel/Common/KernelInit.cs +++ b/Ryujinx.HLE/HOS/Kernel/Common/KernelInit.cs @@ -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; - - long ramSize = GetRamSize(kernelMemoryCfg); + ulong ramSize = KSystemControl.GetDramSize(size); - 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(); - - return new KMemoryRegionManager[] - { - GetMemoryRegion(arrange.Application), - GetMemoryRegion(arrange.Applet), - GetMemoryRegion(arrange.Service), - GetMemoryRegion(arrange.NvServices) - }; - } - - private static KMemoryRegionManager GetMemoryRegion(KMemoryArrangeRegion region) - { - return new KMemoryRegionManager(region.Address, region.Size, region.EndAddr); - } - - private static KMemoryArrange GetMemoryArrange() - { - int mcEmemCfg = 0x1000; - - ulong ememApertureSize = (ulong)(mcEmemCfg & 0x3fff) << 20; - - int kernelMemoryCfg = 0; - - ulong ramSize = (ulong)GetRamSize(kernelMemoryCfg); + ulong poolEnd = KSystemControl.GetDramEndAddress(size); + ulong applicationPoolSize = KSystemControl.GetApplicationPoolSize(arrange); + ulong appletPoolSize = KSystemControl.GetAppletPoolSize(arrange); - ulong ramPart0; - ulong ramPart1; + MemoryRegion servicePool; + MemoryRegion nvServicesPool; + MemoryRegion appletPool; + MemoryRegion applicationPool; - if (ramSize * 2 > ememApertureSize) - { - ramPart0 = ememApertureSize / 2; - ramPart1 = ememApertureSize / 2; - } - else - { - ramPart0 = ememApertureSize; - ramPart1 = 0; - } - - int memoryArrange = 1; + ulong nvServicesPoolSize = KSystemControl.GetMinimumNonSecureSystemPoolSize(); - ulong applicationRgSize; + applicationPool = new MemoryRegion(poolEnd - applicationPoolSize, applicationPoolSize); - 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; - } + ulong nvServicesPoolEnd = applicationPool.Address - appletPoolSize; - 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); } } }
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Kernel/Common/MemoryArrange.cs b/Ryujinx.HLE/HOS/Kernel/Common/MemoryArrange.cs new file mode 100644 index 00000000..136b0240 --- /dev/null +++ b/Ryujinx.HLE/HOS/Kernel/Common/MemoryArrange.cs @@ -0,0 +1,12 @@ +namespace Ryujinx.HLE.HOS.Kernel.Common +{ + enum MemoryArrange : byte + { + MemoryArrange4GB, + MemoryArrange4GBAppletDev, + MemoryArrange4GBSystemDev, + MemoryArrange6GB, + MemoryArrange6GBAppletDev, + MemoryArrange8GB + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Kernel/Common/MemroySize.cs b/Ryujinx.HLE/HOS/Kernel/Common/MemroySize.cs new file mode 100644 index 00000000..1148b0f4 --- /dev/null +++ b/Ryujinx.HLE/HOS/Kernel/Common/MemroySize.cs @@ -0,0 +1,9 @@ +namespace Ryujinx.HLE.HOS.Kernel.Common +{ + enum MemorySize : byte + { + MemorySize4GB = 0, + MemorySize6GB = 1, + MemorySize8GB = 2 + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Kernel/KernelContext.cs b/Ryujinx.HLE/HOS/Kernel/KernelContext.cs index cacb7fb3..b57b9504 100644 --- a/Ryujinx.HLE/HOS/Kernel/KernelContext.cs +++ b/Ryujinx.HLE/HOS/Kernel/KernelContext.cs @@ -51,7 +51,11 @@ namespace Ryujinx.HLE.HOS.Kernel private long _processId; private long _threadUid; - public KernelContext(Switch device, MemoryBlock memory) + public KernelContext( + Switch device, + MemoryBlock memory, + MemorySize memorySize, + MemoryArrange memoryArrange) { Device = device; Memory = memory; @@ -64,9 +68,9 @@ namespace Ryujinx.HLE.HOS.Kernel ResourceLimit = new KResourceLimit(this); - KernelInit.InitializeResourceLimit(ResourceLimit); + KernelInit.InitializeResourceLimit(ResourceLimit, memorySize); - MemoryRegions = KernelInit.GetMemoryRegions(); + MemoryRegions = KernelInit.GetMemoryRegions(memorySize, memoryArrange); LargeMemoryBlockAllocator = new KMemoryBlockAllocator(KernelConstants.MemoryBlockAllocatorSize * 2); SmallMemoryBlockAllocator = new KMemoryBlockAllocator(KernelConstants.MemoryBlockAllocatorSize); diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/DramMemoryMap.cs b/Ryujinx.HLE/HOS/Kernel/Memory/DramMemoryMap.cs index 261c2972..dea2a4ef 100644 --- a/Ryujinx.HLE/HOS/Kernel/Memory/DramMemoryMap.cs +++ b/Ryujinx.HLE/HOS/Kernel/Memory/DramMemoryMap.cs @@ -3,8 +3,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory static class DramMemoryMap { public const ulong DramBase = 0x80000000; - public const ulong DramSize = 0x100000000; - public const ulong DramEnd = DramBase + DramSize; public const ulong KernelReserveBase = DramBase + 0x60000; diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrange.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrange.cs deleted file mode 100644 index 7dfc2b77..00000000 --- a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrange.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace Ryujinx.HLE.HOS.Kernel.Memory -{ - class KMemoryArrange - { - public KMemoryArrangeRegion Service { get; private set; } - public KMemoryArrangeRegion NvServices { get; private set; } - public KMemoryArrangeRegion Applet { get; private set; } - public KMemoryArrangeRegion Application { get; private set; } - - public KMemoryArrange( - KMemoryArrangeRegion service, - KMemoryArrangeRegion nvServices, - KMemoryArrangeRegion applet, - KMemoryArrangeRegion application) - { - Service = service; - NvServices = nvServices; - Applet = applet; - Application = application; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrangeRegion.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrangeRegion.cs deleted file mode 100644 index eaf0fe5f..00000000 --- a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrangeRegion.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Ryujinx.HLE.HOS.Kernel.Memory -{ - struct KMemoryArrangeRegion - { - public ulong Address { get; private set; } - public ulong Size { get; private set; } - - public ulong EndAddr => Address + Size; - - public KMemoryArrangeRegion(ulong address, ulong size) - { - Address = address; - Size = size; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/MemoryConfiguration.cs b/Ryujinx.HLE/MemoryConfiguration.cs new file mode 100644 index 00000000..2a59e04f --- /dev/null +++ b/Ryujinx.HLE/MemoryConfiguration.cs @@ -0,0 +1,62 @@ +using Ryujinx.HLE.HOS.Kernel.Common; +using System; + +namespace Ryujinx.HLE +{ + public enum MemoryConfiguration + { + MemoryConfiguration4GB = 0, + MemoryConfiguration4GBAppletDev = 1, + MemoryConfiguration4GBSystemDev = 2, + MemoryConfiguration6GB = 3, + MemoryConfiguration6GBAppletDev = 4, + MemoryConfiguration8GB = 5 + } + + static class MemoryConfigurationExtensions + { + private const ulong Gb = 1024 * 1024 * 1024; + + public static MemoryArrange ToKernelMemoryArrange(this MemoryConfiguration configuration) + { + return configuration switch + { + MemoryConfiguration.MemoryConfiguration4GB => MemoryArrange.MemoryArrange4GB, + MemoryConfiguration.MemoryConfiguration4GBAppletDev => MemoryArrange.MemoryArrange4GBAppletDev, + MemoryConfiguration.MemoryConfiguration4GBSystemDev => MemoryArrange.MemoryArrange4GBSystemDev, + MemoryConfiguration.MemoryConfiguration6GB => MemoryArrange.MemoryArrange6GB, + MemoryConfiguration.MemoryConfiguration6GBAppletDev => MemoryArrange.MemoryArrange6GBAppletDev, + MemoryConfiguration.MemoryConfiguration8GB => MemoryArrange.MemoryArrange8GB, + _ => throw new AggregateException($"Invalid memory configuration \"{configuration}\".") + }; + } + + public static MemorySize ToKernelMemorySize(this MemoryConfiguration configuration) + { + return configuration switch + { + MemoryConfiguration.MemoryConfiguration4GB or + MemoryConfiguration.MemoryConfiguration4GBAppletDev or + MemoryConfiguration.MemoryConfiguration4GBSystemDev => MemorySize.MemorySize4GB, + MemoryConfiguration.MemoryConfiguration6GB or + MemoryConfiguration.MemoryConfiguration6GBAppletDev => MemorySize.MemorySize6GB, + MemoryConfiguration.MemoryConfiguration8GB => MemorySize.MemorySize8GB, + _ => throw new AggregateException($"Invalid memory configuration \"{configuration}\".") + }; + } + + public static ulong ToDramSize(this MemoryConfiguration configuration) + { + return configuration switch + { + MemoryConfiguration.MemoryConfiguration4GB or + MemoryConfiguration.MemoryConfiguration4GBAppletDev or + MemoryConfiguration.MemoryConfiguration4GBSystemDev => 4 * Gb, + MemoryConfiguration.MemoryConfiguration6GB or + MemoryConfiguration.MemoryConfiguration6GBAppletDev => 6 * Gb, + MemoryConfiguration.MemoryConfiguration8GB => 8 * Gb, + _ => throw new AggregateException($"Invalid memory configuration \"{configuration}\".") + }; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/Switch.cs b/Ryujinx.HLE/Switch.cs index 61c07769..6770b25e 100644 --- a/Ryujinx.HLE/Switch.cs +++ b/Ryujinx.HLE/Switch.cs @@ -24,6 +24,8 @@ namespace Ryujinx.HLE { public class Switch : IDisposable { + private MemoryConfiguration _memoryConfiguration; + public IHardwareDeviceDriver AudioDeviceDriver { get; private set; } internal MemoryBlock Memory { get; private set; } @@ -52,7 +54,13 @@ namespace Ryujinx.HLE public bool EnableDeviceVsync { get; set; } = true; - public Switch(VirtualFileSystem fileSystem, ContentManager contentManager, UserChannelPersistence userChannelPersistence, IRenderer renderer, IHardwareDeviceDriver audioDeviceDriver) + public Switch( + VirtualFileSystem fileSystem, + ContentManager contentManager, + UserChannelPersistence userChannelPersistence, + IRenderer renderer, + IHardwareDeviceDriver audioDeviceDriver, + MemoryConfiguration memoryConfiguration) { if (renderer == null) { @@ -71,9 +79,11 @@ namespace Ryujinx.HLE UserChannelPersistence = userChannelPersistence; + _memoryConfiguration = memoryConfiguration; + AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(audioDeviceDriver); - Memory = new MemoryBlock(1UL << 32); + Memory = new MemoryBlock(memoryConfiguration.ToDramSize()); Gpu = new GpuContext(renderer); @@ -102,7 +112,7 @@ namespace Ryujinx.HLE FileSystem = fileSystem; - System = new Horizon(this, contentManager); + System = new Horizon(this, contentManager, memoryConfiguration); System.InitializeServices(); Statistics = new PerformanceStatistics(); @@ -146,6 +156,7 @@ namespace Ryujinx.HLE Logger.Info?.Print(LogClass.Application, $"AudioBackend: {ConfigurationState.Instance.System.AudioBackend.Value}"); Logger.Info?.Print(LogClass.Application, $"IsDocked: {ConfigurationState.Instance.System.EnableDockedMode.Value}"); Logger.Info?.Print(LogClass.Application, $"Vsync: {ConfigurationState.Instance.Graphics.EnableVsync.Value}"); + Logger.Info?.Print(LogClass.Application, $"MemoryConfiguration: {_memoryConfiguration}"); } public static IntegrityCheckLevel GetIntegrityCheckLevel() |