forked from Mirror/Ryujinx
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:
parent
3bc107d491
commit
874540bb5c
16 changed files with 278 additions and 144 deletions
|
@ -14,7 +14,7 @@ namespace Ryujinx.Configuration
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The current version of the file format
|
/// The current version of the file format
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int CurrentVersion = 22;
|
public const int CurrentVersion = 23;
|
||||||
|
|
||||||
public int Version { get; set; }
|
public int Version { get; set; }
|
||||||
|
|
||||||
|
@ -173,6 +173,11 @@ namespace Ryujinx.Configuration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public AudioBackend AudioBackend { get; set; }
|
public AudioBackend AudioBackend { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Expands the RAM amount on the emulated system from 4GB to 6GB
|
||||||
|
/// </summary>
|
||||||
|
public bool ExpandRam { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enable or disable ignoring missing services
|
/// Enable or disable ignoring missing services
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -218,6 +218,11 @@ namespace Ryujinx.Configuration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReactiveObject<AudioBackend> AudioBackend { get; private set; }
|
public ReactiveObject<AudioBackend> AudioBackend { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the amount of RAM available on the emulated system, and how it is distributed
|
||||||
|
/// </summary>
|
||||||
|
public ReactiveObject<bool> ExpandRam { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enable or disable ignoring missing services
|
/// Enable or disable ignoring missing services
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -234,6 +239,7 @@ namespace Ryujinx.Configuration
|
||||||
EnableFsIntegrityChecks = new ReactiveObject<bool>();
|
EnableFsIntegrityChecks = new ReactiveObject<bool>();
|
||||||
FsGlobalAccessLogMode = new ReactiveObject<int>();
|
FsGlobalAccessLogMode = new ReactiveObject<int>();
|
||||||
AudioBackend = new ReactiveObject<AudioBackend>();
|
AudioBackend = new ReactiveObject<AudioBackend>();
|
||||||
|
ExpandRam = new ReactiveObject<bool>();
|
||||||
IgnoreMissingServices = new ReactiveObject<bool>();
|
IgnoreMissingServices = new ReactiveObject<bool>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -433,6 +439,7 @@ namespace Ryujinx.Configuration
|
||||||
EnableFsIntegrityChecks = System.EnableFsIntegrityChecks,
|
EnableFsIntegrityChecks = System.EnableFsIntegrityChecks,
|
||||||
FsGlobalAccessLogMode = System.FsGlobalAccessLogMode,
|
FsGlobalAccessLogMode = System.FsGlobalAccessLogMode,
|
||||||
AudioBackend = System.AudioBackend,
|
AudioBackend = System.AudioBackend,
|
||||||
|
ExpandRam = System.ExpandRam,
|
||||||
IgnoreMissingServices = System.IgnoreMissingServices,
|
IgnoreMissingServices = System.IgnoreMissingServices,
|
||||||
GuiColumns = new GuiColumns
|
GuiColumns = new GuiColumns
|
||||||
{
|
{
|
||||||
|
@ -497,6 +504,7 @@ namespace Ryujinx.Configuration
|
||||||
System.EnableFsIntegrityChecks.Value = true;
|
System.EnableFsIntegrityChecks.Value = true;
|
||||||
System.FsGlobalAccessLogMode.Value = 0;
|
System.FsGlobalAccessLogMode.Value = 0;
|
||||||
System.AudioBackend.Value = AudioBackend.OpenAl;
|
System.AudioBackend.Value = AudioBackend.OpenAl;
|
||||||
|
System.ExpandRam.Value = false;
|
||||||
System.IgnoreMissingServices.Value = false;
|
System.IgnoreMissingServices.Value = false;
|
||||||
Ui.GuiColumns.FavColumn.Value = true;
|
Ui.GuiColumns.FavColumn.Value = true;
|
||||||
Ui.GuiColumns.IconColumn.Value = true;
|
Ui.GuiColumns.IconColumn.Value = true;
|
||||||
|
@ -838,6 +846,7 @@ namespace Ryujinx.Configuration
|
||||||
System.EnableFsIntegrityChecks.Value = configurationFileFormat.EnableFsIntegrityChecks;
|
System.EnableFsIntegrityChecks.Value = configurationFileFormat.EnableFsIntegrityChecks;
|
||||||
System.FsGlobalAccessLogMode.Value = configurationFileFormat.FsGlobalAccessLogMode;
|
System.FsGlobalAccessLogMode.Value = configurationFileFormat.FsGlobalAccessLogMode;
|
||||||
System.AudioBackend.Value = configurationFileFormat.AudioBackend;
|
System.AudioBackend.Value = configurationFileFormat.AudioBackend;
|
||||||
|
System.ExpandRam.Value = configurationFileFormat.ExpandRam;
|
||||||
System.IgnoreMissingServices.Value = configurationFileFormat.IgnoreMissingServices;
|
System.IgnoreMissingServices.Value = configurationFileFormat.IgnoreMissingServices;
|
||||||
Ui.GuiColumns.FavColumn.Value = configurationFileFormat.GuiColumns.FavColumn;
|
Ui.GuiColumns.FavColumn.Value = configurationFileFormat.GuiColumns.FavColumn;
|
||||||
Ui.GuiColumns.IconColumn.Value = configurationFileFormat.GuiColumns.IconColumn;
|
Ui.GuiColumns.IconColumn.Value = configurationFileFormat.GuiColumns.IconColumn;
|
||||||
|
|
|
@ -110,9 +110,13 @@ namespace Ryujinx.HLE.HOS
|
||||||
internal LibHac.Horizon LibHacHorizonServer { get; private set; }
|
internal LibHac.Horizon LibHacHorizonServer { get; private set; }
|
||||||
internal HorizonClient LibHacHorizonClient { 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;
|
Device = device;
|
||||||
|
|
||||||
|
|
72
Ryujinx.HLE/HOS/Kernel/Common/KSystemControl.cs
Normal file
72
Ryujinx.HLE/HOS/Kernel/Common/KSystemControl.cs
Normal file
|
@ -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}\".")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,21 @@ namespace Ryujinx.HLE.HOS.Kernel.Common
|
||||||
{
|
{
|
||||||
static class KernelInit
|
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)
|
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, (long)ramSize));
|
||||||
|
|
||||||
EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Memory, ramSize));
|
|
||||||
EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Thread, 800));
|
EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Thread, 800));
|
||||||
EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Event, 700));
|
EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.Event, 700));
|
||||||
EnsureSuccess(resourceLimit.SetLimitValue(LimitableResource.TransferMemory, 200));
|
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[]
|
MemoryRegion servicePool;
|
||||||
{
|
MemoryRegion nvServicesPool;
|
||||||
GetMemoryRegion(arrange.Application),
|
MemoryRegion appletPool;
|
||||||
GetMemoryRegion(arrange.Applet),
|
MemoryRegion applicationPool;
|
||||||
GetMemoryRegion(arrange.Service),
|
|
||||||
GetMemoryRegion(arrange.NvServices)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static KMemoryRegionManager GetMemoryRegion(KMemoryArrangeRegion region)
|
ulong nvServicesPoolSize = KSystemControl.GetMinimumNonSecureSystemPoolSize();
|
||||||
{
|
|
||||||
return new KMemoryRegionManager(region.Address, region.Size, region.EndAddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static KMemoryArrange GetMemoryArrange()
|
applicationPool = new MemoryRegion(poolEnd - applicationPoolSize, applicationPoolSize);
|
||||||
{
|
|
||||||
int mcEmemCfg = 0x1000;
|
|
||||||
|
|
||||||
ulong ememApertureSize = (ulong)(mcEmemCfg & 0x3fff) << 20;
|
ulong nvServicesPoolEnd = applicationPool.Address - appletPoolSize;
|
||||||
|
|
||||||
int kernelMemoryCfg = 0;
|
nvServicesPool = new MemoryRegion(nvServicesPoolEnd - nvServicesPoolSize, nvServicesPoolSize);
|
||||||
|
appletPool = new MemoryRegion(nvServicesPoolEnd, appletPoolSize);
|
||||||
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);
|
|
||||||
|
|
||||||
// Note: There is an extra region used by the kernel, however
|
// 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
|
// since we are doing HLE we are not going to use that memory, so give all
|
||||||
// the remaining memory space to services.
|
// 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)
|
return new KMemoryRegionManager(region.Address, region.Size, region.EndAddress);
|
||||||
{
|
|
||||||
case 1: return 0x180000000;
|
|
||||||
case 2: return 0x200000000;
|
|
||||||
default: return 0x100000000;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
12
Ryujinx.HLE/HOS/Kernel/Common/MemoryArrange.cs
Normal file
12
Ryujinx.HLE/HOS/Kernel/Common/MemoryArrange.cs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
namespace Ryujinx.HLE.HOS.Kernel.Common
|
||||||
|
{
|
||||||
|
enum MemoryArrange : byte
|
||||||
|
{
|
||||||
|
MemoryArrange4GB,
|
||||||
|
MemoryArrange4GBAppletDev,
|
||||||
|
MemoryArrange4GBSystemDev,
|
||||||
|
MemoryArrange6GB,
|
||||||
|
MemoryArrange6GBAppletDev,
|
||||||
|
MemoryArrange8GB
|
||||||
|
}
|
||||||
|
}
|
9
Ryujinx.HLE/HOS/Kernel/Common/MemroySize.cs
Normal file
9
Ryujinx.HLE/HOS/Kernel/Common/MemroySize.cs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
namespace Ryujinx.HLE.HOS.Kernel.Common
|
||||||
|
{
|
||||||
|
enum MemorySize : byte
|
||||||
|
{
|
||||||
|
MemorySize4GB = 0,
|
||||||
|
MemorySize6GB = 1,
|
||||||
|
MemorySize8GB = 2
|
||||||
|
}
|
||||||
|
}
|
|
@ -51,7 +51,11 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
private long _processId;
|
private long _processId;
|
||||||
private long _threadUid;
|
private long _threadUid;
|
||||||
|
|
||||||
public KernelContext(Switch device, MemoryBlock memory)
|
public KernelContext(
|
||||||
|
Switch device,
|
||||||
|
MemoryBlock memory,
|
||||||
|
MemorySize memorySize,
|
||||||
|
MemoryArrange memoryArrange)
|
||||||
{
|
{
|
||||||
Device = device;
|
Device = device;
|
||||||
Memory = memory;
|
Memory = memory;
|
||||||
|
@ -64,9 +68,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
|
|
||||||
ResourceLimit = new KResourceLimit(this);
|
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);
|
LargeMemoryBlockAllocator = new KMemoryBlockAllocator(KernelConstants.MemoryBlockAllocatorSize * 2);
|
||||||
SmallMemoryBlockAllocator = new KMemoryBlockAllocator(KernelConstants.MemoryBlockAllocatorSize);
|
SmallMemoryBlockAllocator = new KMemoryBlockAllocator(KernelConstants.MemoryBlockAllocatorSize);
|
||||||
|
|
|
@ -3,8 +3,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||||
static class DramMemoryMap
|
static class DramMemoryMap
|
||||||
{
|
{
|
||||||
public const ulong DramBase = 0x80000000;
|
public const ulong DramBase = 0x80000000;
|
||||||
public const ulong DramSize = 0x100000000;
|
|
||||||
public const ulong DramEnd = DramBase + DramSize;
|
|
||||||
|
|
||||||
public const ulong KernelReserveBase = DramBase + 0x60000;
|
public const ulong KernelReserveBase = DramBase + 0x60000;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
62
Ryujinx.HLE/MemoryConfiguration.cs
Normal file
62
Ryujinx.HLE/MemoryConfiguration.cs
Normal file
|
@ -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}\".")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,6 +24,8 @@ namespace Ryujinx.HLE
|
||||||
{
|
{
|
||||||
public class Switch : IDisposable
|
public class Switch : IDisposable
|
||||||
{
|
{
|
||||||
|
private MemoryConfiguration _memoryConfiguration;
|
||||||
|
|
||||||
public IHardwareDeviceDriver AudioDeviceDriver { get; private set; }
|
public IHardwareDeviceDriver AudioDeviceDriver { get; private set; }
|
||||||
|
|
||||||
internal MemoryBlock Memory { get; private set; }
|
internal MemoryBlock Memory { get; private set; }
|
||||||
|
@ -52,7 +54,13 @@ namespace Ryujinx.HLE
|
||||||
|
|
||||||
public bool EnableDeviceVsync { get; set; } = true;
|
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)
|
if (renderer == null)
|
||||||
{
|
{
|
||||||
|
@ -71,9 +79,11 @@ namespace Ryujinx.HLE
|
||||||
|
|
||||||
UserChannelPersistence = userChannelPersistence;
|
UserChannelPersistence = userChannelPersistence;
|
||||||
|
|
||||||
|
_memoryConfiguration = memoryConfiguration;
|
||||||
|
|
||||||
AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(audioDeviceDriver);
|
AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(audioDeviceDriver);
|
||||||
|
|
||||||
Memory = new MemoryBlock(1UL << 32);
|
Memory = new MemoryBlock(memoryConfiguration.ToDramSize());
|
||||||
|
|
||||||
Gpu = new GpuContext(renderer);
|
Gpu = new GpuContext(renderer);
|
||||||
|
|
||||||
|
@ -102,7 +112,7 @@ namespace Ryujinx.HLE
|
||||||
|
|
||||||
FileSystem = fileSystem;
|
FileSystem = fileSystem;
|
||||||
|
|
||||||
System = new Horizon(this, contentManager);
|
System = new Horizon(this, contentManager, memoryConfiguration);
|
||||||
System.InitializeServices();
|
System.InitializeServices();
|
||||||
|
|
||||||
Statistics = new PerformanceStatistics();
|
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, $"AudioBackend: {ConfigurationState.Instance.System.AudioBackend.Value}");
|
||||||
Logger.Info?.Print(LogClass.Application, $"IsDocked: {ConfigurationState.Instance.System.EnableDockedMode.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, $"Vsync: {ConfigurationState.Instance.Graphics.EnableVsync.Value}");
|
||||||
|
Logger.Info?.Print(LogClass.Application, $"MemoryConfiguration: {_memoryConfiguration}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IntegrityCheckLevel GetIntegrityCheckLevel()
|
public static IntegrityCheckLevel GetIntegrityCheckLevel()
|
||||||
|
|
|
@ -337,7 +337,17 @@ namespace Ryujinx.Ui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_emulationContext = new HLE.Switch(_virtualFileSystem, _contentManager, _userChannelPersistence, renderer, deviceDriver)
|
var memoryConfiguration = ConfigurationState.Instance.System.ExpandRam.Value
|
||||||
|
? HLE.MemoryConfiguration.MemoryConfiguration6GB
|
||||||
|
: HLE.MemoryConfiguration.MemoryConfiguration4GB;
|
||||||
|
|
||||||
|
_emulationContext = new HLE.Switch(
|
||||||
|
_virtualFileSystem,
|
||||||
|
_contentManager,
|
||||||
|
_userChannelPersistence,
|
||||||
|
renderer,
|
||||||
|
deviceDriver,
|
||||||
|
memoryConfiguration)
|
||||||
{
|
{
|
||||||
UiHandler = _uiHandler
|
UiHandler = _uiHandler
|
||||||
};
|
};
|
||||||
|
@ -664,7 +674,7 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
GlRendererWidget.Exit();
|
GlRendererWidget.Exit();
|
||||||
|
|
||||||
if(GlRendererWidget.Window != Window && GlRendererWidget.Window != null)
|
if (GlRendererWidget.Window != Window && GlRendererWidget.Window != null)
|
||||||
{
|
{
|
||||||
GlRendererWidget.Window.Dispose();
|
GlRendererWidget.Window.Dispose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ namespace Ryujinx.Ui.Windows
|
||||||
[GUI] CheckButton _shaderCacheToggle;
|
[GUI] CheckButton _shaderCacheToggle;
|
||||||
[GUI] CheckButton _ptcToggle;
|
[GUI] CheckButton _ptcToggle;
|
||||||
[GUI] CheckButton _fsicToggle;
|
[GUI] CheckButton _fsicToggle;
|
||||||
|
[GUI] CheckButton _expandRamToggle;
|
||||||
[GUI] CheckButton _ignoreToggle;
|
[GUI] CheckButton _ignoreToggle;
|
||||||
[GUI] CheckButton _directKeyboardAccess;
|
[GUI] CheckButton _directKeyboardAccess;
|
||||||
[GUI] ComboBoxText _systemLanguageSelect;
|
[GUI] ComboBoxText _systemLanguageSelect;
|
||||||
|
@ -214,6 +215,11 @@ namespace Ryujinx.Ui.Windows
|
||||||
_fsicToggle.Click();
|
_fsicToggle.Click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ConfigurationState.Instance.System.ExpandRam)
|
||||||
|
{
|
||||||
|
_expandRamToggle.Click();
|
||||||
|
}
|
||||||
|
|
||||||
if (ConfigurationState.Instance.System.IgnoreMissingServices)
|
if (ConfigurationState.Instance.System.IgnoreMissingServices)
|
||||||
{
|
{
|
||||||
_ignoreToggle.Click();
|
_ignoreToggle.Click();
|
||||||
|
@ -417,6 +423,7 @@ namespace Ryujinx.Ui.Windows
|
||||||
ConfigurationState.Instance.Graphics.EnableShaderCache.Value = _shaderCacheToggle.Active;
|
ConfigurationState.Instance.Graphics.EnableShaderCache.Value = _shaderCacheToggle.Active;
|
||||||
ConfigurationState.Instance.System.EnablePtc.Value = _ptcToggle.Active;
|
ConfigurationState.Instance.System.EnablePtc.Value = _ptcToggle.Active;
|
||||||
ConfigurationState.Instance.System.EnableFsIntegrityChecks.Value = _fsicToggle.Active;
|
ConfigurationState.Instance.System.EnableFsIntegrityChecks.Value = _fsicToggle.Active;
|
||||||
|
ConfigurationState.Instance.System.ExpandRam.Value = _expandRamToggle.Active;
|
||||||
ConfigurationState.Instance.System.IgnoreMissingServices.Value = _ignoreToggle.Active;
|
ConfigurationState.Instance.System.IgnoreMissingServices.Value = _ignoreToggle.Active;
|
||||||
ConfigurationState.Instance.Hid.EnableKeyboard.Value = _directKeyboardAccess.Active;
|
ConfigurationState.Instance.Hid.EnableKeyboard.Value = _directKeyboardAccess.Active;
|
||||||
ConfigurationState.Instance.Ui.EnableCustomTheme.Value = _custThemeToggle.Active;
|
ConfigurationState.Instance.Ui.EnableCustomTheme.Value = _custThemeToggle.Active;
|
||||||
|
|
|
@ -1625,6 +1625,24 @@
|
||||||
<property name="margin-left">10</property>
|
<property name="margin-left">10</property>
|
||||||
<property name="margin-right">10</property>
|
<property name="margin-right">10</property>
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCheckButton" id="_expandRamToggle">
|
||||||
|
<property name="label" translatable="yes">Expand DRAM size to 6GB</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="receives-default">False</property>
|
||||||
|
<property name="tooltip-text" translatable="yes">Expands the amount of memory on the emulated system from 4GB to 6GB</property>
|
||||||
|
<property name="halign">start</property>
|
||||||
|
<property name="margin-top">5</property>
|
||||||
|
<property name="margin-bottom">5</property>
|
||||||
|
<property name="draw-indicator">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckButton" id="_ignoreToggle">
|
<object class="GtkCheckButton" id="_ignoreToggle">
|
||||||
<property name="label" translatable="yes">Ignore Missing Services</property>
|
<property name="label" translatable="yes">Ignore Missing Services</property>
|
||||||
|
@ -1640,7 +1658,7 @@
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">True</property>
|
<property name="fill">True</property>
|
||||||
<property name="position">0</property>
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
|
Loading…
Reference in a new issue