diff options
author | gdkchan <gab.dark.100@gmail.com> | 2020-12-01 20:23:43 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-02 00:23:43 +0100 |
commit | cf6cd714884c41e9550757e364c2f4f5b04fc7f3 (patch) | |
tree | bea748b4d1a350e5b8075d63ec9d39d49693829d /Ryujinx.HLE/HOS/Kernel/Process | |
parent | 461c24092ae6e148d896c18aa3e86220c89981f8 (diff) |
IPC refactor part 2: Use ReplyAndReceive on HLE services and remove special handling from kernel (#1458)
* IPC refactor part 2: Use ReplyAndReceive on HLE services and remove special handling from kernel
* Fix for applet transfer memory + some nits
* Keep handles if possible to avoid server handle table exhaustion
* Fix IPC ZeroFill bug
* am: Correctly implement CreateManagedDisplayLayer and implement CreateManagedDisplaySeparableLayer
CreateManagedDisplaySeparableLayer is requires since 10.x+ when appletResourceUserId != 0
* Make it exit properly
* Make ServiceNotImplementedException show the full message again
* Allow yielding execution to avoid starving other threads
* Only wait if active
* Merge IVirtualMemoryManager and IAddressSpaceManager
* Fix Ro loading data from the wrong process
Co-authored-by: Thog <me@thog.eu>
Diffstat (limited to 'Ryujinx.HLE/HOS/Kernel/Process')
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs | 10 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Process/IProcessContext.cs | 13 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Process/IProcessContextFactory.cs | 10 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs | 234 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs | 27 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Process/ProcessContext.cs | 25 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Process/ProcessContextFactory.cs | 13 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationFlags.cs | 38 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationInfo.cs | 46 |
9 files changed, 238 insertions, 178 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs b/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs index 376badfb..5ad33154 100644 --- a/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs +++ b/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs @@ -1,7 +1,7 @@ -using Ryujinx.Cpu; using Ryujinx.HLE.HOS.Diagnostics.Demangler; using Ryujinx.HLE.HOS.Kernel.Memory; using Ryujinx.HLE.Loaders.Elf; +using Ryujinx.Memory; using System.Collections.Generic; using System.Linq; using System.Text; @@ -224,7 +224,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process break; } - if (info.State == MemoryState.CodeStatic && info.Permission == MemoryPermission.ReadAndExecute) + if (info.State == MemoryState.CodeStatic && info.Permission == KMemoryPermission.ReadAndExecute) { LoadMod0Symbols(_owner.CpuMemory, info.Address); } @@ -235,7 +235,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process } } - private void LoadMod0Symbols(MemoryManager memory, ulong textOffset) + private void LoadMod0Symbols(IVirtualMemoryManager memory, ulong textOffset) { ulong mod0Offset = textOffset + memory.Read<uint>(textOffset + 4); @@ -319,7 +319,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process } } - private ElfSymbol GetSymbol64(MemoryManager memory, ulong address, ulong strTblAddr) + private ElfSymbol GetSymbol64(IVirtualMemoryManager memory, ulong address, ulong strTblAddr) { ElfSymbol64 sym = memory.Read<ElfSymbol64>(address); @@ -335,7 +335,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process return new ElfSymbol(name, sym.Info, sym.Other, sym.SectionIndex, sym.ValueAddress, sym.Size); } - private ElfSymbol GetSymbol32(MemoryManager memory, ulong address, ulong strTblAddr) + private ElfSymbol GetSymbol32(IVirtualMemoryManager memory, ulong address, ulong strTblAddr) { ElfSymbol32 sym = memory.Read<ElfSymbol32>(address); diff --git a/Ryujinx.HLE/HOS/Kernel/Process/IProcessContext.cs b/Ryujinx.HLE/HOS/Kernel/Process/IProcessContext.cs new file mode 100644 index 00000000..758ac6b1 --- /dev/null +++ b/Ryujinx.HLE/HOS/Kernel/Process/IProcessContext.cs @@ -0,0 +1,13 @@ +using ARMeilleure.State; +using Ryujinx.Memory; +using System; + +namespace Ryujinx.HLE.HOS.Kernel.Process +{ + interface IProcessContext : IDisposable + { + IVirtualMemoryManager AddressSpace { get; } + + void Execute(ExecutionContext context, ulong codeAddress); + } +} diff --git a/Ryujinx.HLE/HOS/Kernel/Process/IProcessContextFactory.cs b/Ryujinx.HLE/HOS/Kernel/Process/IProcessContextFactory.cs new file mode 100644 index 00000000..c438b570 --- /dev/null +++ b/Ryujinx.HLE/HOS/Kernel/Process/IProcessContextFactory.cs @@ -0,0 +1,10 @@ +using Ryujinx.Cpu; +using Ryujinx.Memory; + +namespace Ryujinx.HLE.HOS.Kernel.Process +{ + interface IProcessContextFactory + { + IProcessContext Create(MemoryBlock backingMemory, ulong addressSpaceSize, InvalidAccessHandler invalidAccessHandler); + } +} diff --git a/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs b/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs index d02e25a3..8e914f19 100644 --- a/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs +++ b/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs @@ -6,6 +6,7 @@ using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Kernel.Common; using Ryujinx.HLE.HOS.Kernel.Memory; using Ryujinx.HLE.HOS.Kernel.Threading; +using Ryujinx.Memory; using System; using System.Collections.Generic; using System.Linq; @@ -15,13 +16,13 @@ namespace Ryujinx.HLE.HOS.Kernel.Process { class KProcess : KSynchronizationObject { - public const int KernelVersionMajor = 10; - public const int KernelVersionMinor = 4; + public const int KernelVersionMajor = 10; + public const int KernelVersionMinor = 4; public const int KernelVersionRevision = 0; public const int KernelVersionPacked = - (KernelVersionMajor << 19) | - (KernelVersionMinor << 15) | + (KernelVersionMajor << 19) | + (KernelVersionMinor << 15) | (KernelVersionRevision << 0); public KMemoryManager MemoryManager { get; private set; } @@ -47,27 +48,27 @@ namespace Ryujinx.HLE.HOS.Kernel.Process public long[] RandomEntropy { get; private set; } private bool _signaled; - private bool _useSystemMemBlocks; public string Name { get; private set; } private int _threadCount; - public int MmuFlags { get; private set; } + public ProcessCreationFlags Flags { get; private set; } private MemoryRegion _memRegion; public KProcessCapabilities Capabilities { get; private set; } public ulong TitleId { get; private set; } - public long Pid { get; private set; } + public long Pid { get; private set; } - private long _creationTimestamp; + private long _creationTimestamp; private ulong _entrypoint; + private ThreadStart _customThreadStart; private ulong _imageSize; private ulong _mainThreadStackSize; private ulong _memoryUsageCapacity; - private int _version; + private int _version; public KHandleTable HandleTable { get; private set; } @@ -77,14 +78,15 @@ namespace Ryujinx.HLE.HOS.Kernel.Process public bool IsPaused { get; private set; } - public MemoryManager CpuMemory { get; private set; } - public CpuContext CpuContext { get; private set; } + private IProcessContextFactory _contextFactory; + public IProcessContext Context { get; private set; } + public IVirtualMemoryManager CpuMemory => Context.AddressSpace; public HleProcessDebugger Debugger { get; private set; } public KProcess(KernelContext context) : base(context) { - _processLock = new object(); + _processLock = new object(); _threadingLock = new object(); AddressArbiter = new KAddressArbiter(context); @@ -96,6 +98,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Process RandomEntropy = new long[KScheduler.CpuCoresCount]; + // TODO: Remove once we no longer need to initialize it externally. + HandleTable = new KHandleTable(context); + _threads = new LinkedList<KThread>(); Debugger = new HleProcessDebugger(this); @@ -103,25 +108,27 @@ namespace Ryujinx.HLE.HOS.Kernel.Process public KernelResult InitializeKip( ProcessCreationInfo creationInfo, - int[] caps, - KPageList pageList, - KResourceLimit resourceLimit, - MemoryRegion memRegion) + ReadOnlySpan<int> capabilities, + KPageList pageList, + KResourceLimit resourceLimit, + MemoryRegion memRegion, + IProcessContextFactory contextFactory) { ResourceLimit = resourceLimit; - _memRegion = memRegion; + _memRegion = memRegion; + _contextFactory = contextFactory ?? new ProcessContextFactory(); - AddressSpaceType addrSpaceType = (AddressSpaceType)((creationInfo.MmuFlags >> 1) & 7); + AddressSpaceType addrSpaceType = (AddressSpaceType)((int)(creationInfo.Flags & ProcessCreationFlags.AddressSpaceMask) >> (int)ProcessCreationFlags.AddressSpaceShift); - InitializeMemoryManager(addrSpaceType, memRegion); + InitializeMemoryManager(creationInfo.Flags); - bool aslrEnabled = ((creationInfo.MmuFlags >> 5) & 1) != 0; + bool aslrEnabled = creationInfo.Flags.HasFlag(ProcessCreationFlags.EnableAslr); ulong codeAddress = creationInfo.CodeAddress; ulong codeSize = (ulong)creationInfo.CodePagesCount * KMemoryManager.PageSize; - KMemoryBlockAllocator memoryBlockAllocator = (MmuFlags & 0x40) != 0 + KMemoryBlockAllocator memoryBlockAllocator = creationInfo.Flags.HasFlag(ProcessCreationFlags.IsApplication) ? KernelContext.LargeMemoryBlockAllocator : KernelContext.SmallMemoryBlockAllocator; @@ -139,7 +146,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process return result; } - if (!ValidateCodeAddressAndSize(codeAddress, codeSize)) + if (!MemoryManager.CanContain(codeAddress, codeSize, MemoryState.CodeStatic)) { return KernelResult.InvalidMemRange; } @@ -148,14 +155,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Process codeAddress, pageList, MemoryState.CodeStatic, - MemoryPermission.None); + KMemoryPermission.None); if (result != KernelResult.Success) { return result; } - result = Capabilities.InitializeForKernel(caps, MemoryManager); + result = Capabilities.InitializeForKernel(capabilities, MemoryManager); if (result != KernelResult.Success) { @@ -176,14 +183,17 @@ namespace Ryujinx.HLE.HOS.Kernel.Process public KernelResult Initialize( ProcessCreationInfo creationInfo, - int[] caps, - KResourceLimit resourceLimit, - MemoryRegion memRegion) + ReadOnlySpan<int> capabilities, + KResourceLimit resourceLimit, + MemoryRegion memRegion, + IProcessContextFactory contextFactory, + ThreadStart customThreadStart = null) { ResourceLimit = resourceLimit; - _memRegion = memRegion; + _memRegion = memRegion; + _contextFactory = contextFactory ?? new ProcessContextFactory(); - ulong personalMmHeapSize = GetPersonalMmHeapSize((ulong)creationInfo.PersonalMmHeapPagesCount, memRegion); + ulong personalMmHeapSize = GetPersonalMmHeapSize((ulong)creationInfo.SystemResourcePagesCount, memRegion); ulong codePagesCount = (ulong)creationInfo.CodePagesCount; @@ -205,7 +215,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process } } - PersonalMmHeapPagesCount = (ulong)creationInfo.PersonalMmHeapPagesCount; + PersonalMmHeapPagesCount = (ulong)creationInfo.SystemResourcePagesCount; KMemoryBlockAllocator memoryBlockAllocator; @@ -215,16 +225,16 @@ namespace Ryujinx.HLE.HOS.Kernel.Process } else { - memoryBlockAllocator = (MmuFlags & 0x40) != 0 + memoryBlockAllocator = creationInfo.Flags.HasFlag(ProcessCreationFlags.IsApplication) ? KernelContext.LargeMemoryBlockAllocator : KernelContext.SmallMemoryBlockAllocator; } - AddressSpaceType addrSpaceType = (AddressSpaceType)((creationInfo.MmuFlags >> 1) & 7); + AddressSpaceType addrSpaceType = (AddressSpaceType)((int)(creationInfo.Flags & ProcessCreationFlags.AddressSpaceMask) >> (int)ProcessCreationFlags.AddressSpaceShift); - InitializeMemoryManager(addrSpaceType, memRegion); + InitializeMemoryManager(creationInfo.Flags); - bool aslrEnabled = ((creationInfo.MmuFlags >> 5) & 1) != 0; + bool aslrEnabled = creationInfo.Flags.HasFlag(ProcessCreationFlags.EnableAslr); ulong codeAddress = creationInfo.CodeAddress; @@ -246,7 +256,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process return result; } - if (!ValidateCodeAddressAndSize(codeAddress, codeSize)) + if (!MemoryManager.CanContain(codeAddress, codeSize, MemoryState.CodeStatic)) { CleanUpForError(); @@ -257,7 +267,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process codeAddress, codePagesCount, MemoryState.CodeStatic, - MemoryPermission.None); + KMemoryPermission.None); if (result != KernelResult.Success) { @@ -266,7 +276,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process return result; } - result = Capabilities.InitializeForUser(caps, MemoryManager); + result = Capabilities.InitializeForUser(capabilities, MemoryManager); if (result != KernelResult.Success) { @@ -289,57 +299,15 @@ namespace Ryujinx.HLE.HOS.Kernel.Process CleanUpForError(); } - return result; - } - - private bool ValidateCodeAddressAndSize(ulong address, ulong size) - { - ulong codeRegionStart; - ulong codeRegionSize; - - switch (MemoryManager.AddrSpaceWidth) - { - case 32: - codeRegionStart = 0x200000; - codeRegionSize = 0x3fe00000; - break; - - case 36: - codeRegionStart = 0x8000000; - codeRegionSize = 0x78000000; - break; - - case 39: - codeRegionStart = 0x8000000; - codeRegionSize = 0x7ff8000000; - break; - - default: throw new InvalidOperationException("Invalid address space width on memory manager."); - } - - ulong endAddr = address + size; - - ulong codeRegionEnd = codeRegionStart + codeRegionSize; - - if (endAddr <= address || - endAddr - 1 > codeRegionEnd - 1) - { - return false; - } - - if (MemoryManager.InsideHeapRegion (address, size) || - MemoryManager.InsideAliasRegion(address, size)) - { - return false; - } + _customThreadStart = customThreadStart; - return true; + return result; } private KernelResult ParseProcessInfo(ProcessCreationInfo creationInfo) { // Ensure that the current kernel version is equal or above to the minimum required. - uint requiredKernelVersionMajor = (uint)Capabilities.KernelReleaseVersion >> 19; + uint requiredKernelVersionMajor = (uint)Capabilities.KernelReleaseVersion >> 19; uint requiredKernelVersionMinor = ((uint)Capabilities.KernelReleaseVersion >> 15) & 0xf; if (KernelContext.EnableVersionChecks) @@ -377,31 +345,29 @@ namespace Ryujinx.HLE.HOS.Kernel.Process _creationTimestamp = PerformanceCounter.ElapsedMilliseconds; - MmuFlags = creationInfo.MmuFlags; - _version = creationInfo.Version; - TitleId = creationInfo.TitleId; + Flags = creationInfo.Flags; + _version = creationInfo.Version; + TitleId = creationInfo.TitleId; _entrypoint = creationInfo.CodeAddress; - _imageSize = (ulong)creationInfo.CodePagesCount * KMemoryManager.PageSize; - - _useSystemMemBlocks = ((MmuFlags >> 6) & 1) != 0; + _imageSize = (ulong)creationInfo.CodePagesCount * KMemoryManager.PageSize; - switch ((AddressSpaceType)((MmuFlags >> 1) & 7)) + switch (Flags & ProcessCreationFlags.AddressSpaceMask) { - case AddressSpaceType.Addr32Bits: - case AddressSpaceType.Addr36Bits: - case AddressSpaceType.Addr39Bits: + case ProcessCreationFlags.AddressSpace32Bit: + case ProcessCreationFlags.AddressSpace64BitDeprecated: + case ProcessCreationFlags.AddressSpace64Bit: _memoryUsageCapacity = MemoryManager.HeapRegionEnd - MemoryManager.HeapRegionStart; break; - case AddressSpaceType.Addr32BitsNoMap: + case ProcessCreationFlags.AddressSpace32BitWithoutAlias: _memoryUsageCapacity = MemoryManager.HeapRegionEnd - MemoryManager.HeapRegionStart + MemoryManager.AliasRegionEnd - MemoryManager.AliasRegionStart; break; - default: throw new InvalidOperationException($"Invalid MMU flags value 0x{MmuFlags:x2}."); + default: throw new InvalidOperationException($"Invalid MMU flags value 0x{Flags:x2}."); } GenerateRandomEntropy(); @@ -469,7 +435,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process } ulong regionStart = MemoryManager.TlsIoRegionStart; - ulong regionSize = MemoryManager.TlsIoRegionEnd - regionStart; + ulong regionSize = MemoryManager.TlsIoRegionEnd - regionStart; ulong regionPagesCount = regionSize / KMemoryManager.PageSize; @@ -481,7 +447,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process regionStart, regionPagesCount, MemoryState.ThreadLocal, - MemoryPermission.ReadAndWrite, + KMemoryPermission.ReadAndWrite, out ulong tlsPageVa); if (result != KernelResult.Success) @@ -506,7 +472,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process KernelResult result = KernelResult.Success; - KTlsPageInfo pageInfo = null; + KTlsPageInfo pageInfo; if (_fullTlsPages.TryGetValue(tlsPageAddr, out pageInfo)) { @@ -594,8 +560,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process // Check if the needed size for the code and the stack will fit on the // memory usage capacity of this Process. Also check for possible overflow // on the above addition. - if (neededSize > _memoryUsageCapacity || - neededSize < stackSizeRounded) + if (neededSize > _memoryUsageCapacity || neededSize < stackSizeRounded) { threadResourceLimit?.Release(LimitableResource.Thread, 1); @@ -646,7 +611,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process ulong stackPagesCount = stackSizeRounded / KMemoryManager.PageSize; ulong regionStart = MemoryManager.StackRegionStart; - ulong regionSize = MemoryManager.StackRegionEnd - regionStart; + ulong regionSize = MemoryManager.StackRegionEnd - regionStart; ulong regionPagesCount = regionSize / KMemoryManager.PageSize; @@ -658,7 +623,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process regionStart, regionPagesCount, MemoryState.Stack, - MemoryPermission.ReadAndWrite, + KMemoryPermission.ReadAndWrite, out ulong stackBottom); if (result != KernelResult.Success) @@ -703,7 +668,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Process stackTop, mainThreadPriority, DefaultCpuCore, - this); + this, + ThreadType.User, + _customThreadStart); if (result != KernelResult.Success) { @@ -730,20 +697,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Process SetState(newState); - // TODO: We can't call KThread.Start from a non-guest thread. - // We will need to make some changes to allow the creation of - // dummy threads that will be used to initialize the current - // thread on KCoreContext so that GetCurrentThread doesn't fail. - /* Result = MainThread.Start(); + result = mainThread.Start(); - if (Result != KernelResult.Success) + if (result != KernelResult.Success) { - SetState(OldState); + SetState(oldState); CleanUpForError(); - } */ - - mainThread.Reschedule(ThreadSchedState.Running); + } if (result == KernelResult.Success) { @@ -760,7 +721,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process { if (State != newState) { - State = newState; + State = newState; _signaled = true; Signal(); @@ -769,23 +730,23 @@ namespace Ryujinx.HLE.HOS.Kernel.Process public KernelResult InitializeThread( KThread thread, - ulong entrypoint, - ulong argsPtr, - ulong stackTop, - int priority, - int cpuCore) + ulong entrypoint, + ulong argsPtr, + ulong stackTop, + int priority, + int cpuCore) { lock (_processLock) { - return thread.Initialize(entrypoint, argsPtr, stackTop, priority, cpuCore, this); + return thread.Initialize(entrypoint, argsPtr, stackTop, priority, cpuCore, this, ThreadType.User, null); } } public void SubscribeThreadEventHandlers(ARMeilleure.State.ExecutionContext context) { - context.Interrupt += InterruptHandler; + context.Interrupt += InterruptHandler; context.SupervisorCall += KernelContext.SyscallHandler.SvcCall; - context.Undefined += UndefinedInstructionHandler; + context.Undefined += UndefinedInstructionHandler; } private void InterruptHandler(object sender, EventArgs e) @@ -910,8 +871,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process { if (State >= ProcessState.Started) { - if (State == ProcessState.Started || - State == ProcessState.Crashed || + if (State == ProcessState.Started || + State == ProcessState.Crashed || State == ProcessState.Attached || State == ProcessState.DebugSuspended) { @@ -1072,23 +1033,25 @@ namespace Ryujinx.HLE.HOS.Kernel.Process return result; } - private void InitializeMemoryManager(AddressSpaceType addrSpaceType, MemoryRegion memRegion) + private void InitializeMemoryManager(ProcessCreationFlags flags) { - int addrSpaceBits = addrSpaceType switch + int addrSpaceBits = (flags & ProcessCreationFlags.AddressSpaceMask) switch { - AddressSpaceType.Addr32Bits => 32, - AddressSpaceType.Addr36Bits => 36, - AddressSpaceType.Addr32BitsNoMap => 32, - AddressSpaceType.Addr39Bits => 39, - _ => throw new ArgumentException(nameof(addrSpaceType)) + ProcessCreationFlags.AddressSpace32Bit => 32, + ProcessCreationFlags.AddressSpace64BitDeprecated => 36, + ProcessCreationFlags.AddressSpace32BitWithoutAlias => 32, + ProcessCreationFlags.AddressSpace64Bit => 39, + _ => 39 }; - CpuMemory = new MemoryManager(KernelContext.Memory, 1UL << addrSpaceBits, InvalidAccessHandler); - CpuContext = new CpuContext(CpuMemory); + Context = _contextFactory.Create(KernelContext.Memory, 1UL << addrSpaceBits, InvalidAccessHandler); // TODO: This should eventually be removed. // The GPU shouldn't depend on the CPU memory manager at all. - KernelContext.Device.Gpu.SetVmm(CpuMemory); + if (flags.HasFlag(ProcessCreationFlags.IsApplication)) + { + KernelContext.Device.Gpu.SetVmm((MemoryManager)CpuMemory); + } MemoryManager = new KMemoryManager(KernelContext, CpuMemory); } @@ -1109,9 +1072,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Process throw new UndefinedInstructionException(e.Address, e.OpCode); } - protected override void Destroy() - { - CpuMemory.Dispose(); - } + protected override void Destroy() => Context.Dispose(); } }
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs b/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs index 2396aea8..e1cdb30f 100644 --- a/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs +++ b/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs @@ -2,6 +2,7 @@ using Ryujinx.Common; using Ryujinx.HLE.HOS.Kernel.Common; using Ryujinx.HLE.HOS.Kernel.Memory; using Ryujinx.HLE.HOS.Kernel.Threading; +using System; namespace Ryujinx.HLE.HOS.Kernel.Process { @@ -24,29 +25,29 @@ namespace Ryujinx.HLE.HOS.Kernel.Process IrqAccessMask = new byte[0x80]; } - public KernelResult InitializeForKernel(int[] caps, KMemoryManager memoryManager) + public KernelResult InitializeForKernel(ReadOnlySpan<int> capabilities, KMemoryManager memoryManager) { AllowedCpuCoresMask = 0xf; AllowedThreadPriosMask = -1; DebuggingFlags &= ~3; KernelReleaseVersion = KProcess.KernelVersionPacked; - return Parse(caps, memoryManager); + return Parse(capabilities, memoryManager); } - public KernelResult InitializeForUser(int[] caps, KMemoryManager memoryManager) + public KernelResult InitializeForUser(ReadOnlySpan<int> capabilities, KMemoryManager memoryManager) { - return Parse(caps, memoryManager); + return Parse(capabilities, memoryManager); } - private KernelResult Parse(int[] caps, KMemoryManager memoryManager) + private KernelResult Parse(ReadOnlySpan<int> capabilities, KMemoryManager memoryManager) { int mask0 = 0; int mask1 = 0; - for (int index = 0; index < caps.Length; index++) + for (int index = 0; index < capabilities.Length; index++) { - int cap = caps[index]; + int cap = capabilities[index]; if (((cap + 1) & ~cap) != 0x40) { @@ -59,14 +60,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Process } else { - if ((uint)index + 1 >= caps.Length) + if ((uint)index + 1 >= capabilities.Length) { return KernelResult.InvalidCombination; } int prevCap = cap; - cap = caps[++index]; + cap = capabilities[++index]; if (((cap + 1) & ~cap) != 0x40) { @@ -91,9 +92,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Process return KernelResult.InvalidAddress; } - MemoryPermission perm = (prevCap >> 31) != 0 - ? MemoryPermission.Read - : MemoryPermission.ReadAndWrite; + KMemoryPermission perm = (prevCap >> 31) != 0 + ? KMemoryPermission.Read + : KMemoryPermission.ReadAndWrite; KernelResult result; @@ -216,7 +217,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process { long address = ((long)(uint)cap << 4) & 0xffffff000; - memoryManager.MapIoMemory(address, KMemoryManager.PageSize, MemoryPermission.ReadAndWrite); + memoryManager.MapIoMemory(address, KMemoryManager.PageSize, KMemoryPermission.ReadAndWrite); break; } diff --git a/Ryujinx.HLE/HOS/Kernel/Process/ProcessContext.cs b/Ryujinx.HLE/HOS/Kernel/Process/ProcessContext.cs new file mode 100644 index 00000000..54997cb7 --- /dev/null +++ b/Ryujinx.HLE/HOS/Kernel/Process/ProcessContext.cs @@ -0,0 +1,25 @@ +using ARMeilleure.State; +using Ryujinx.Memory; +using System; + +namespace Ryujinx.HLE.HOS.Kernel.Process +{ + class ProcessContext : IProcessContext + { + public IVirtualMemoryManager AddressSpace { get; } + + public ProcessContext(IVirtualMemoryManager asManager) + { + AddressSpace = asManager; + } + + public void Execute(ExecutionContext context, ulong codeAddress) + { + throw new NotSupportedException(); + } + + public void Dispose() + { + } + } +} diff --git a/Ryujinx.HLE/HOS/Kernel/Process/ProcessContextFactory.cs b/Ryujinx.HLE/HOS/Kernel/Process/ProcessContextFactory.cs new file mode 100644 index 00000000..03db62fa --- /dev/null +++ b/Ryujinx.HLE/HOS/Kernel/Process/ProcessContextFactory.cs @@ -0,0 +1,13 @@ +using Ryujinx.Cpu; +using Ryujinx.Memory; + +namespace Ryujinx.HLE.HOS.Kernel.Process +{ + class ProcessContextFactory : IProcessContextFactory + { + public IProcessContext Create(MemoryBlock backingMemory, ulong addressSpaceSize, InvalidAccessHandler invalidAccessHandler) + { + return new ProcessContext(new AddressSpaceManager(backingMemory, addressSpaceSize)); + } + } +} diff --git a/Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationFlags.cs b/Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationFlags.cs new file mode 100644 index 00000000..a34481e5 --- /dev/null +++ b/Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationFlags.cs @@ -0,0 +1,38 @@ +namespace Ryujinx.HLE.HOS.Kernel.Process +{ + enum ProcessCreationFlags + { + Is64Bit = 1 << 0, + + AddressSpaceShift = 1, + AddressSpace32Bit = 0 << AddressSpaceShift, + AddressSpace64BitDeprecated = 1 << AddressSpaceShift, + AddressSpace32BitWithoutAlias = 2 << AddressSpaceShift, + AddressSpace64Bit = 3 << AddressSpaceShift, + AddressSpaceMask = 7 << AddressSpaceShift, + + EnableDebug = 1 << 4, + EnableAslr = 1 << 5, + IsApplication = 1 << 6, + DeprecatedUseSecureMemory = 1 << 7, + + PoolPartitionShift = 7, + PoolPartitionApplication = 0 << PoolPartitionShift, + PoolPartitionApplet = 1 << PoolPartitionShift, + PoolPartitionSystem = 2 << PoolPartitionShift, + PoolPartitionSystemNonSecure = 3 << PoolPartitionShift, + PoolPartitionMask = 0xf << PoolPartitionShift, + + OptimizeMemoryAllocation = 1 << 11, + + All = + Is64Bit | + AddressSpaceMask | + EnableDebug | + EnableAslr | + IsApplication | + DeprecatedUseSecureMemory | + PoolPartitionMask | + OptimizeMemoryAllocation + } +} diff --git a/Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationInfo.cs b/Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationInfo.cs index a5820865..26c23b3b 100644 --- a/Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationInfo.cs +++ b/Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationInfo.cs @@ -2,36 +2,36 @@ namespace Ryujinx.HLE.HOS.Kernel.Process { struct ProcessCreationInfo { - public string Name { get; private set; } + public string Name { get; } - public int Version { get; private set; } - public ulong TitleId { get; private set; } + public int Version { get; } + public ulong TitleId { get; } - public ulong CodeAddress { get; private set; } - public int CodePagesCount { get; private set; } + public ulong CodeAddress { get; } + public int CodePagesCount { get; } - public int MmuFlags { get; private set; } - public int ResourceLimitHandle { get; private set; } - public int PersonalMmHeapPagesCount { get; private set; } + public ProcessCreationFlags Flags { get; } + public int ResourceLimitHandle { get; } + public int SystemResourcePagesCount { get; } public ProcessCreationInfo( string name, - int category, - ulong titleId, - ulong codeAddress, - int codePagesCount, - int mmuFlags, - int resourceLimitHandle, - int personalMmHeapPagesCount) + int version, + ulong titleId, + ulong codeAddress, + int codePagesCount, + ProcessCreationFlags flags, + int resourceLimitHandle, + int systemResourcePagesCount) { - Name = name; - Version = category; - TitleId = titleId; - CodeAddress = codeAddress; - CodePagesCount = codePagesCount; - MmuFlags = mmuFlags; - ResourceLimitHandle = resourceLimitHandle; - PersonalMmHeapPagesCount = personalMmHeapPagesCount; + Name = name; + Version = version; + TitleId = titleId; + CodeAddress = codeAddress; + CodePagesCount = codePagesCount; + Flags = flags; + ResourceLimitHandle = resourceLimitHandle; + SystemResourcePagesCount = systemResourcePagesCount; } } }
\ No newline at end of file |