diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2023-01-04 20:01:44 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-01-05 00:01:44 +0100 |
| commit | fc4b7cba2c083b3920f2d74e0cb4b08cf7a5a278 (patch) | |
| tree | baa5d9a71ee011ecbaeee9a67e037cb399eb7d0e /Ryujinx.HLE/HOS | |
| parent | 08831eecf77cedd3c4192ebab5a9c485fb15d51e (diff) | |
Make PPTC state non-static (#4157)
* Make PPTC state non-static
* DiskCacheLoadState can be null
Diffstat (limited to 'Ryujinx.HLE/HOS')
| -rw-r--r-- | Ryujinx.HLE/HOS/ApplicationLoader.cs | 55 | ||||
| -rw-r--r-- | Ryujinx.HLE/HOS/ArmProcessContext.cs | 23 | ||||
| -rw-r--r-- | Ryujinx.HLE/HOS/ArmProcessContextFactory.cs | 33 | ||||
| -rw-r--r-- | Ryujinx.HLE/HOS/ProgramLoader.cs | 92 |
4 files changed, 138 insertions, 65 deletions
diff --git a/Ryujinx.HLE/HOS/ApplicationLoader.cs b/Ryujinx.HLE/HOS/ApplicationLoader.cs index 61fcd0c3..06281b49 100644 --- a/Ryujinx.HLE/HOS/ApplicationLoader.cs +++ b/Ryujinx.HLE/HOS/ApplicationLoader.cs @@ -1,4 +1,3 @@ -using ARMeilleure.Translation.PTC; using LibHac; using LibHac.Account; using LibHac.Common; @@ -14,8 +13,8 @@ using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem.NcaUtils; using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; +using Ryujinx.Cpu; using Ryujinx.HLE.FileSystem; -using Ryujinx.HLE.HOS.Kernel.Process; using Ryujinx.HLE.Loaders.Executables; using Ryujinx.Memory; using System; @@ -67,6 +66,8 @@ namespace Ryujinx.HLE.HOS public string TitleIdText => TitleId.ToString("x16"); + public IDiskCacheLoadState DiskCacheLoadState { get; private set; } + public ApplicationLoader(Switch device) { _device = device; @@ -94,7 +95,7 @@ namespace Ryujinx.HLE.HOS EnsureSaveData(new ApplicationId(TitleId)); } - LoadExeFs(codeFs, metaData); + LoadExeFs(codeFs, string.Empty, metaData); } public static (Nca main, Nca patch, Nca control) GetGameData(VirtualFileSystem fileSystem, PartitionFileSystem pfs, int programIndex) @@ -302,12 +303,6 @@ namespace Ryujinx.HLE.HOS public void LoadServiceNca(string ncaFile) { - // Disable PPTC here as it does not support multiple processes running. - // TODO: This should be eventually removed and it should stop using global state and - // instead manage the cache per process. - Ptc.Close(); - PtcProfiler.Stop(); - FileStream file = new FileStream(ncaFile, FileMode.Open, FileAccess.Read); Nca mainNca = new Nca(_device.Configuration.VirtualFileSystem.KeySet, file.AsStorage(false)); @@ -369,16 +364,12 @@ namespace Ryujinx.HLE.HOS // Collect the nsos, ignoring ones that aren't used. NsoExecutable[] programs = nsos.Where(x => x != null).ToArray(); - MemoryManagerMode memoryManagerMode = _device.Configuration.MemoryManagerMode; - - if (!MemoryBlock.SupportsFlags(MemoryAllocationFlags.ViewCompatible)) - { - memoryManagerMode = MemoryManagerMode.SoftwarePageTable; - } + string displayVersion = _device.System.ContentManager.GetCurrentFirmwareVersion().VersionString; + bool usePtc = _device.System.EnablePtc; metaData.GetNpdm(out Npdm npdm).ThrowIfFailure(); - ProgramInfo programInfo = new ProgramInfo(in npdm, allowCodeMemoryForJit: false); - ProgramLoader.LoadNsos(_device.System.KernelContext, out _, metaData, programInfo, executables: programs); + ProgramInfo programInfo = new ProgramInfo(in npdm, displayVersion, usePtc, allowCodeMemoryForJit: false); + ProgramLoader.LoadNsos(_device.System.KernelContext, metaData, programInfo, executables: programs); string titleIdText = npdm.Aci.Value.ProgramId.Value.ToString("x16"); bool titleIs64Bit = (npdm.Meta.Value.Flags & 1) != 0; @@ -477,9 +468,11 @@ namespace Ryujinx.HLE.HOS _device.Configuration.VirtualFileSystem.ModLoader.GetModsBasePath(), _device.Configuration.VirtualFileSystem.ModLoader.GetSdModsBasePath()); + string displayVersion = string.Empty; + if (controlNca != null) { - ReadControlData(_device, controlNca, ref _controlData, ref _titleName, ref _displayVersion); + ReadControlData(_device, controlNca, ref _controlData, ref _titleName, ref displayVersion); } else { @@ -493,9 +486,11 @@ namespace Ryujinx.HLE.HOS string dummyTitleName = ""; BlitStruct<ApplicationControlProperty> dummyControl = new BlitStruct<ApplicationControlProperty>(1); - ReadControlData(_device, updateProgram0ControlNca, ref dummyControl, ref dummyTitleName, ref _displayVersion); + ReadControlData(_device, updateProgram0ControlNca, ref dummyControl, ref dummyTitleName, ref displayVersion); } + _displayVersion = displayVersion; + if (dataStorage == null) { Logger.Warning?.Print(LogClass.Loader, "No RomFS found in NCA"); @@ -515,7 +510,7 @@ namespace Ryujinx.HLE.HOS EnsureSaveData(new ApplicationId(TitleId & ~0xFul)); } - LoadExeFs(codeFs, metaData); + LoadExeFs(codeFs, displayVersion, metaData); Logger.Info?.Print(LogClass.Loader, $"Application Loaded: {TitleName} v{DisplayVersion} [{TitleIdText}] [{(TitleIs64Bit ? "64-bit" : "32-bit")}]"); } @@ -584,7 +579,7 @@ namespace Ryujinx.HLE.HOS } } - private void LoadExeFs(IFileSystem codeFs, MetaLoader metaData = null, bool isHomebrew = false) + private void LoadExeFs(IFileSystem codeFs, string displayVersion, MetaLoader metaData = null, bool isHomebrew = false) { if (_device.Configuration.VirtualFileSystem.ModLoader.ReplaceExefsPartition(TitleId, ref codeFs)) { @@ -649,23 +644,23 @@ namespace Ryujinx.HLE.HOS memoryManagerMode = MemoryManagerMode.SoftwarePageTable; } - Ptc.Initialize(TitleIdText, DisplayVersion, usePtc, memoryManagerMode); - // We allow it for nx-hbloader because it can be used to launch homebrew. bool allowCodeMemoryForJit = TitleId == 0x010000000000100DUL || isHomebrew; metaData.GetNpdm(out Npdm npdm).ThrowIfFailure(); - ProgramInfo programInfo = new ProgramInfo(in npdm, allowCodeMemoryForJit); - ProgramLoader.LoadNsos(_device.System.KernelContext, out ProcessTamperInfo tamperInfo, metaData, programInfo, executables: programs); + ProgramInfo programInfo = new ProgramInfo(in npdm, displayVersion, usePtc, allowCodeMemoryForJit); + ProgramLoadResult result = ProgramLoader.LoadNsos(_device.System.KernelContext, metaData, programInfo, executables: programs); + + DiskCacheLoadState = result.DiskCacheLoadState; - _device.Configuration.VirtualFileSystem.ModLoader.LoadCheats(TitleId, tamperInfo, _device.TamperMachine); + _device.Configuration.VirtualFileSystem.ModLoader.LoadCheats(TitleId, result.TamperInfo, _device.TamperMachine); } public void LoadProgram(string filePath) { MetaLoader metaData = GetDefaultNpdm(); metaData.GetNpdm(out Npdm npdm).ThrowIfFailure(); - ProgramInfo programInfo = new ProgramInfo(in npdm, allowCodeMemoryForJit: true); + ProgramInfo programInfo = new ProgramInfo(in npdm, string.Empty, diskCacheEnabled: false, allowCodeMemoryForJit: true); bool isNro = Path.GetExtension(filePath).ToLower() == ".nro"; @@ -761,9 +756,11 @@ namespace Ryujinx.HLE.HOS Graphics.Gpu.GraphicsConfig.TitleId = null; _device.Gpu.HostInitalized.Set(); - ProgramLoader.LoadNsos(_device.System.KernelContext, out ProcessTamperInfo tamperInfo, metaData, programInfo, executables: executable); + ProgramLoadResult result = ProgramLoader.LoadNsos(_device.System.KernelContext, metaData, programInfo, executables: executable); + + DiskCacheLoadState = result.DiskCacheLoadState; - _device.Configuration.VirtualFileSystem.ModLoader.LoadCheats(TitleId, tamperInfo, _device.TamperMachine); + _device.Configuration.VirtualFileSystem.ModLoader.LoadCheats(TitleId, result.TamperInfo, _device.TamperMachine); } private MetaLoader GetDefaultNpdm() diff --git a/Ryujinx.HLE/HOS/ArmProcessContext.cs b/Ryujinx.HLE/HOS/ArmProcessContext.cs index 072df0b6..6338edc1 100644 --- a/Ryujinx.HLE/HOS/ArmProcessContext.cs +++ b/Ryujinx.HLE/HOS/ArmProcessContext.cs @@ -6,7 +6,17 @@ using Ryujinx.Memory; namespace Ryujinx.HLE.HOS { - class ArmProcessContext<T> : IProcessContext where T : class, IVirtualMemoryManagerTracked, IMemoryManager + interface IArmProcessContext : IProcessContext + { + IDiskCacheLoadState Initialize( + string titleIdText, + string displayVersion, + bool diskCacheEnabled, + ulong codeAddress, + ulong codeSize); + } + + class ArmProcessContext<T> : IArmProcessContext where T : class, IVirtualMemoryManagerTracked, IMemoryManager { private readonly ulong _pid; private readonly GpuContext _gpuContext; @@ -40,6 +50,17 @@ namespace Ryujinx.HLE.HOS _cpuContext.Execute(context, codeAddress); } + public IDiskCacheLoadState Initialize( + string titleIdText, + string displayVersion, + bool diskCacheEnabled, + ulong codeAddress, + ulong codeSize) + { + _cpuContext.PrepareCodeRange(codeAddress, codeSize); + return _cpuContext.LoadDiskCache(titleIdText, displayVersion, diskCacheEnabled); + } + public void InvalidateCacheRegion(ulong address, ulong size) { _cpuContext.InvalidateCacheRegion(address, size); diff --git a/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs b/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs index 7d1c4e1d..5ecaf38e 100644 --- a/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs +++ b/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs @@ -13,11 +13,30 @@ namespace Ryujinx.HLE.HOS { private readonly ICpuEngine _cpuEngine; private readonly GpuContext _gpu; + private readonly string _titleIdText; + private readonly string _displayVersion; + private readonly bool _diskCacheEnabled; + private readonly ulong _codeAddress; + private readonly ulong _codeSize; - public ArmProcessContextFactory(ICpuEngine cpuEngine, GpuContext gpu) + public IDiskCacheLoadState DiskCacheLoadState { get; private set; } + + public ArmProcessContextFactory( + ICpuEngine cpuEngine, + GpuContext gpu, + string titleIdText, + string displayVersion, + bool diskCacheEnabled, + ulong codeAddress, + ulong codeSize) { _cpuEngine = cpuEngine; _gpu = gpu; + _titleIdText = titleIdText; + _displayVersion = displayVersion; + _diskCacheEnabled = diskCacheEnabled; + _codeAddress = codeAddress; + _codeSize = codeSize; } public IProcessContext Create(KernelContext context, ulong pid, ulong addressSpaceSize, InvalidAccessHandler invalidAccessHandler, bool for64Bit) @@ -29,21 +48,29 @@ namespace Ryujinx.HLE.HOS mode = MemoryManagerMode.SoftwarePageTable; } + IArmProcessContext processContext; + switch (mode) { case MemoryManagerMode.SoftwarePageTable: var memoryManager = new MemoryManager(context.Memory, addressSpaceSize, invalidAccessHandler); - return new ArmProcessContext<MemoryManager>(pid, _cpuEngine, _gpu, memoryManager, for64Bit); + processContext = new ArmProcessContext<MemoryManager>(pid, _cpuEngine, _gpu, memoryManager, for64Bit); + break; case MemoryManagerMode.HostMapped: case MemoryManagerMode.HostMappedUnsafe: bool unsafeMode = mode == MemoryManagerMode.HostMappedUnsafe; var memoryManagerHostMapped = new MemoryManagerHostMapped(context.Memory, addressSpaceSize, unsafeMode, invalidAccessHandler); - return new ArmProcessContext<MemoryManagerHostMapped>(pid, _cpuEngine, _gpu, memoryManagerHostMapped, for64Bit); + processContext = new ArmProcessContext<MemoryManagerHostMapped>(pid, _cpuEngine, _gpu, memoryManagerHostMapped, for64Bit); + break; default: throw new ArgumentOutOfRangeException(); } + + DiskCacheLoadState = processContext.Initialize(_titleIdText, _displayVersion, _diskCacheEnabled, _codeAddress, _codeSize); + + return processContext; } } } diff --git a/Ryujinx.HLE/HOS/ProgramLoader.cs b/Ryujinx.HLE/HOS/ProgramLoader.cs index b422fef7..09e1ac31 100644 --- a/Ryujinx.HLE/HOS/ProgramLoader.cs +++ b/Ryujinx.HLE/HOS/ProgramLoader.cs @@ -1,9 +1,9 @@ -using ARMeilleure.Translation.PTC; using LibHac.Loader; using LibHac.Ncm; using LibHac.Util; using Ryujinx.Common; using Ryujinx.Common.Logging; +using Ryujinx.Cpu; using Ryujinx.HLE.HOS.Kernel; using Ryujinx.HLE.HOS.Kernel.Common; using Ryujinx.HLE.HOS.Kernel.Memory; @@ -21,16 +21,40 @@ namespace Ryujinx.HLE.HOS { public string Name; public ulong ProgramId; - public bool AllowCodeMemoryForJit; + public readonly string TitleIdText; + public readonly string DisplayVersion; + public readonly bool DiskCacheEnabled; + public readonly bool AllowCodeMemoryForJit; - public ProgramInfo(in Npdm npdm, bool allowCodeMemoryForJit) + public ProgramInfo(in Npdm npdm, string displayVersion, bool diskCacheEnabled, bool allowCodeMemoryForJit) { + ulong programId = npdm.Aci.Value.ProgramId.Value; + Name = StringUtils.Utf8ZToString(npdm.Meta.Value.ProgramName); - ProgramId = npdm.Aci.Value.ProgramId.Value; + ProgramId = programId; + TitleIdText = programId.ToString("x16"); + DisplayVersion = displayVersion; + DiskCacheEnabled = diskCacheEnabled; AllowCodeMemoryForJit = allowCodeMemoryForJit; } } + struct ProgramLoadResult + { + public static ProgramLoadResult Failed => new ProgramLoadResult(false, null, null); + + public readonly bool Success; + public readonly ProcessTamperInfo TamperInfo; + public readonly IDiskCacheLoadState DiskCacheLoadState; + + public ProgramLoadResult(bool success, ProcessTamperInfo tamperInfo, IDiskCacheLoadState diskCacheLoadState) + { + Success = success; + TamperInfo = tamperInfo; + DiskCacheLoadState = diskCacheLoadState; + } + } + static class ProgramLoader { private const bool AslrEnabled = true; @@ -102,7 +126,14 @@ namespace Ryujinx.HLE.HOS KProcess process = new KProcess(context); - var processContextFactory = new ArmProcessContextFactory(context.Device.System.CpuEngine, context.Device.Gpu); + var processContextFactory = new ArmProcessContextFactory( + context.Device.System.CpuEngine, + context.Device.Gpu, + string.Empty, + string.Empty, + false, + codeAddress, + codeSize); result = process.InitializeKip( creationInfo, @@ -144,9 +175,8 @@ namespace Ryujinx.HLE.HOS return true; } - public static bool LoadNsos( + public static ProgramLoadResult LoadNsos( KernelContext context, - out ProcessTamperInfo tamperInfo, MetaLoader metaData, ProgramInfo programInfo, byte[] arguments = null, @@ -156,8 +186,7 @@ namespace Ryujinx.HLE.HOS if (rc.IsFailure()) { - tamperInfo = null; - return false; + return ProgramLoadResult.Failed; } ref readonly var meta = ref npdm.Meta.Value; @@ -212,9 +241,6 @@ namespace Ryujinx.HLE.HOS } } - PtcProfiler.StaticCodeStart = codeStart; - PtcProfiler.StaticCodeSize = (ulong)codeSize; - int codePagesCount = (int)(codeSize / KPageTableBase.PageSize); int personalMmHeapPagesCount = (int)(meta.SystemResourceSize / KPageTableBase.PageSize); @@ -263,9 +289,7 @@ namespace Ryujinx.HLE.HOS { Logger.Error?.Print(LogClass.Loader, $"Process initialization failed setting resource limit values."); - tamperInfo = null; - - return false; + return ProgramLoadResult.Failed; } KProcess process = new KProcess(context, programInfo.AllowCodeMemoryForJit); @@ -276,12 +300,17 @@ namespace Ryujinx.HLE.HOS { Logger.Error?.Print(LogClass.Loader, $"Process initialization failed due to invalid ACID flags."); - tamperInfo = null; - - return false; + return ProgramLoadResult.Failed; } - var processContextFactory = new ArmProcessContextFactory(context.Device.System.CpuEngine, context.Device.Gpu); + var processContextFactory = new ArmProcessContextFactory( + context.Device.System.CpuEngine, + context.Device.Gpu, + programInfo.TitleIdText, + programInfo.DisplayVersion, + programInfo.DiskCacheEnabled, + codeStart, + codeSize); result = process.Initialize( creationInfo, @@ -294,9 +323,7 @@ namespace Ryujinx.HLE.HOS { Logger.Error?.Print(LogClass.Loader, $"Process initialization returned error \"{result}\"."); - tamperInfo = null; - - return false; + return ProgramLoadResult.Failed; } for (int index = 0; index < executables.Length; index++) @@ -309,9 +336,7 @@ namespace Ryujinx.HLE.HOS { Logger.Error?.Print(LogClass.Loader, $"Process initialization returned error \"{result}\"."); - tamperInfo = null; - - return false; + return ProgramLoadResult.Failed; } } @@ -323,9 +348,7 @@ namespace Ryujinx.HLE.HOS { Logger.Error?.Print(LogClass.Loader, $"Process start returned error \"{result}\"."); - tamperInfo = null; - - return false; + return ProgramLoadResult.Failed; } context.Processes.TryAdd(process.Pid, process); @@ -333,10 +356,15 @@ namespace Ryujinx.HLE.HOS // Keep the build ids because the tamper machine uses them to know which process to associate a // tamper to and also keep the starting address of each executable inside a process because some // memory modifications are relative to this address. - tamperInfo = new ProcessTamperInfo(process, buildIds, nsoBase, process.MemoryManager.HeapRegionStart, - process.MemoryManager.AliasRegionStart, process.MemoryManager.CodeRegionStart); - - return true; + ProcessTamperInfo tamperInfo = new ProcessTamperInfo( + process, + buildIds, + nsoBase, + process.MemoryManager.HeapRegionStart, + process.MemoryManager.AliasRegionStart, + process.MemoryManager.CodeRegionStart); + + return new ProgramLoadResult(true, tamperInfo, processContextFactory.DiskCacheLoadState); } private static Result LoadIntoMemory(KProcess process, IExecutable image, ulong baseAddress) |
