From 20ce37dee6158ede18ad699338ecea083728423b Mon Sep 17 00:00:00 2001 From: Mary Date: Sat, 29 Jan 2022 22:18:03 +0100 Subject: [PATCH] kernel: A bit of refactoring and fix GetThreadContext3 correctness (#3042) * Start refactoring kernel a bit and import some changes from kernel decoupling PR * kernel: Put output always at the start in Syscall functions * kernel: Rewrite GetThreadContext3 to use a structure and to be accurate * kernel: make KernelTransfer use generic types and simplify * Fix some warning and do not use getters on MemoryInfo * Address gdkchan's comment * GetThreadContext3: use correct pause flag --- .../HOS/Kernel/Common/KernelTransfer.cs | 56 ++-- .../HOS/Kernel/Memory/KPageTableBase.cs | 6 +- .../HOS/Kernel/Memory/MemoryPermission.cs | 5 +- Ryujinx.HLE/HOS/Kernel/Memory/MemoryState.cs | 1 + Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs | 8 +- .../Kernel/Process/KProcessCapabilities.cs | 12 +- .../SupervisorCall/InvalidSvcException.cs | 2 +- .../HOS/Kernel/SupervisorCall/MemoryInfo.cs | 37 +++ .../HOS/Kernel/SupervisorCall/Syscall.cs | 284 +++++++----------- .../HOS/Kernel/SupervisorCall/Syscall32.cs | 70 ++--- .../HOS/Kernel/SupervisorCall/Syscall64.cs | 68 ++--- .../Kernel/SupervisorCall/ThreadContext.cs | 22 ++ .../HOS/Kernel/Threading/KAddressArbiter.cs | 14 +- Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs | 108 ++++++- Ryujinx.HLE/HOS/Services/IpcService.cs | 2 +- Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs | 2 +- Ryujinx.HLE/HOS/Services/ServerBase.cs | 10 +- 17 files changed, 386 insertions(+), 321 deletions(-) create mode 100644 Ryujinx.HLE/HOS/Kernel/SupervisorCall/MemoryInfo.cs create mode 100644 Ryujinx.HLE/HOS/Kernel/SupervisorCall/ThreadContext.cs diff --git a/Ryujinx.HLE/HOS/Kernel/Common/KernelTransfer.cs b/Ryujinx.HLE/HOS/Kernel/Common/KernelTransfer.cs index 53e539a23..cbc276c50 100644 --- a/Ryujinx.HLE/HOS/Kernel/Common/KernelTransfer.cs +++ b/Ryujinx.HLE/HOS/Kernel/Common/KernelTransfer.cs @@ -1,54 +1,50 @@ using Ryujinx.Cpu; using Ryujinx.HLE.HOS.Kernel.Process; using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Kernel.Common { static class KernelTransfer { - public static bool UserToKernelInt32(KernelContext context, ulong address, out int value) + public static bool UserToKernel(out T value, ulong address) where T : unmanaged { KProcess currentProcess = KernelStatic.GetCurrentProcess(); - if (currentProcess.CpuMemory.IsMapped(address) && - currentProcess.CpuMemory.IsMapped(address + 3)) + if (currentProcess.CpuMemory.IsRangeMapped(address, (ulong)Unsafe.SizeOf())) { - value = currentProcess.CpuMemory.Read(address); + value = currentProcess.CpuMemory.Read(address); return true; } - value = 0; + value = default; return false; } - public static bool UserToKernelInt32Array(KernelContext context, ulong address, Span values) + public static bool UserToKernelArray(ulong address, Span values) where T : unmanaged { KProcess currentProcess = KernelStatic.GetCurrentProcess(); - for (int index = 0; index < values.Length; index++, address += 4) + Span data = MemoryMarshal.Cast(values); + + if (currentProcess.CpuMemory.IsRangeMapped(address, (ulong)data.Length)) { - if (currentProcess.CpuMemory.IsMapped(address) && - currentProcess.CpuMemory.IsMapped(address + 3)) - { - values[index]= currentProcess.CpuMemory.Read(address); - } - else - { - return false; - } + currentProcess.CpuMemory.Read(address, data); + + return true; } - return true; + return false; } - public static bool UserToKernelString(KernelContext context, ulong address, int size, out string value) + public static bool UserToKernelString(out string value, ulong address, uint size) { KProcess currentProcess = KernelStatic.GetCurrentProcess(); - if (currentProcess.CpuMemory.IsMapped(address) && - currentProcess.CpuMemory.IsMapped(address + (ulong)size - 1)) + if (currentProcess.CpuMemory.IsRangeMapped(address, size)) { value = MemoryHelper.ReadAsciiString(currentProcess.CpuMemory, address, size); @@ -60,27 +56,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Common return false; } - public static bool KernelToUserInt32(KernelContext context, ulong address, int value) + public static bool KernelToUser(ulong address, T value) where T: unmanaged { KProcess currentProcess = KernelStatic.GetCurrentProcess(); - if (currentProcess.CpuMemory.IsMapped(address) && - currentProcess.CpuMemory.IsMapped(address + 3)) - { - currentProcess.CpuMemory.Write(address, value); - - return true; - } - - return false; - } - - public static bool KernelToUserInt64(KernelContext context, ulong address, long value) - { - KProcess currentProcess = KernelStatic.GetCurrentProcess(); - - if (currentProcess.CpuMemory.IsMapped(address) && - currentProcess.CpuMemory.IsMapped(address + 7)) + if (currentProcess.CpuMemory.IsRangeMapped(address, (ulong)Unsafe.SizeOf())) { currentProcess.CpuMemory.Write(address, value); diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs index ff87ecb79..fb3d669de 100644 --- a/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs +++ b/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs @@ -2682,7 +2682,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory return Context.MemoryManager.MemoryRegions[(int)_memRegion]; } - public long GetMmUsedPages() + public ulong GetMmUsedPages() { lock (_blockManager) { @@ -2690,9 +2690,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory } } - private long GetMmUsedSize() + private ulong GetMmUsedSize() { - return _blockManager.BlocksCount * KMemoryBlockSize; + return (ulong)(_blockManager.BlocksCount * KMemoryBlockSize); } public bool IsInvalidRegion(ulong address, ulong size) diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/MemoryPermission.cs b/Ryujinx.HLE/HOS/Kernel/Memory/MemoryPermission.cs index 12300e4f7..563b817d8 100644 --- a/Ryujinx.HLE/HOS/Kernel/Memory/MemoryPermission.cs +++ b/Ryujinx.HLE/HOS/Kernel/Memory/MemoryPermission.cs @@ -5,8 +5,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory [Flags] enum KMemoryPermission : uint { - None = 0, - Mask = uint.MaxValue, + None = 0, + UserMask = Read | Write | Execute, + Mask = uint.MaxValue, Read = 1 << 0, Write = 1 << 1, diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/MemoryState.cs b/Ryujinx.HLE/HOS/Kernel/Memory/MemoryState.cs index f7161a88c..d3b61780c 100644 --- a/Ryujinx.HLE/HOS/Kernel/Memory/MemoryState.cs +++ b/Ryujinx.HLE/HOS/Kernel/Memory/MemoryState.cs @@ -26,6 +26,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory KernelStack = 0x00002013, CodeReadOnly = 0x00402214, CodeWritable = 0x00402015, + UserMask = 0xff, Mask = 0xffffffff, PermissionChangeAllowed = 1 << 8, diff --git a/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs b/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs index be45f02aa..20b3a4973 100644 --- a/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs +++ b/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs @@ -45,7 +45,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process public KAddressArbiter AddressArbiter { get; private set; } - public long[] RandomEntropy { get; private set; } + public ulong[] RandomEntropy { get; private set; } public KThread[] PinnedThreads { get; private set; } private bool _signaled; @@ -102,7 +102,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process Capabilities = new KProcessCapabilities(); - RandomEntropy = new long[KScheduler.CpuCoresCount]; + RandomEntropy = new ulong[KScheduler.CpuCoresCount]; PinnedThreads = new KThread[KScheduler.CpuCoresCount]; // TODO: Remove once we no longer need to initialize it externally. @@ -868,12 +868,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Process public bool IsCpuCoreAllowed(int core) { - return (Capabilities.AllowedCpuCoresMask & (1L << core)) != 0; + return (Capabilities.AllowedCpuCoresMask & (1UL << core)) != 0; } public bool IsPriorityAllowed(int priority) { - return (Capabilities.AllowedThreadPriosMask & (1L << priority)) != 0; + return (Capabilities.AllowedThreadPriosMask & (1UL << priority)) != 0; } public override bool IsSignaled() diff --git a/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs b/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs index 28944c4f5..55e839ab0 100644 --- a/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs +++ b/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs @@ -11,8 +11,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process public byte[] SvcAccessMask { get; private set; } public byte[] IrqAccessMask { get; private set; } - public long AllowedCpuCoresMask { get; private set; } - public long AllowedThreadPriosMask { get; private set; } + public ulong AllowedCpuCoresMask { get; private set; } + public ulong AllowedThreadPriosMask { get; private set; } public int DebuggingFlags { get; private set; } public int HandleTableSize { get; private set; } @@ -28,7 +28,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process public KernelResult InitializeForKernel(ReadOnlySpan capabilities, KPageTableBase memoryManager) { AllowedCpuCoresMask = 0xf; - AllowedThreadPriosMask = -1; + AllowedThreadPriosMask = ulong.MaxValue; DebuggingFlags &= ~3; KernelReleaseVersion = KProcess.KernelVersionPacked; @@ -303,16 +303,16 @@ namespace Ryujinx.HLE.HOS.Kernel.Process return KernelResult.Success; } - private static long GetMaskFromMinMax(int min, int max) + private static ulong GetMaskFromMinMax(int min, int max) { int range = max - min + 1; if (range == 64) { - return -1L; + return ulong.MaxValue; } - long mask = (1L << range) - 1; + ulong mask = (1UL << range) - 1; return mask << min; } diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/InvalidSvcException.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/InvalidSvcException.cs index b78a22847..f2e28bb7b 100644 --- a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/InvalidSvcException.cs +++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/InvalidSvcException.cs @@ -2,7 +2,7 @@ using System; namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall { - public class InvalidSvcException : Exception + class InvalidSvcException : Exception { public InvalidSvcException(string message) : base(message) { } } diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/MemoryInfo.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/MemoryInfo.cs new file mode 100644 index 000000000..a71cce1fe --- /dev/null +++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/MemoryInfo.cs @@ -0,0 +1,37 @@ +using Ryujinx.HLE.HOS.Kernel.Memory; + +namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall +{ + struct MemoryInfo + { + public ulong Address; + public ulong Size; + public MemoryState State; + public MemoryAttribute Attribute; + public KMemoryPermission Permission; + public int IpcRefCount; + public int DeviceRefCount; +#pragma warning disable CS0414 + private int _padding; +#pragma warning restore CS0414 + + public MemoryInfo( + ulong address, + ulong size, + MemoryState state, + MemoryAttribute attribute, + KMemoryPermission permission, + int ipcRefCount, + int deviceRefCount) + { + Address = address; + Size = size; + State = state; + Attribute = attribute; + Permission = permission; + IpcRefCount = ipcRefCount; + DeviceRefCount = deviceRefCount; + _padding = 0; + } + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs index 2dd9d8070..c022d6e29 100644 --- a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs +++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs @@ -24,7 +24,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall // Process - public KernelResult GetProcessId(int handle, out long pid) + public KernelResult GetProcessId(out long pid, int handle) { KProcess currentProcess = KernelStatic.GetCurrentProcess(); @@ -50,9 +50,9 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall } public KernelResult CreateProcess( + out int handle, ProcessCreationInfo info, ReadOnlySpan capabilities, - out int handle, IProcessContextFactory contextFactory, ThreadStart customThreadStart = null) { @@ -170,19 +170,19 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall // IPC - public KernelResult ConnectToNamedPort(ulong namePtr, out int handle) + public KernelResult ConnectToNamedPort(out int handle, ulong namePtr) { handle = 0; - if (!KernelTransfer.UserToKernelString(_context, namePtr, 12, out string name)) + if (!KernelTransfer.UserToKernelString(out string name, namePtr, 12)) { return KernelResult.UserCopyFailed; } - return ConnectToNamedPort(name, out handle); + return ConnectToNamedPort(out handle, name); } - public KernelResult ConnectToNamedPort(string name, out int handle) + public KernelResult ConnectToNamedPort(out int handle, string name) { handle = 0; @@ -193,7 +193,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall KAutoObject autoObj = KAutoObject.FindNamedObject(_context, name); - if (!(autoObj is KClientPort clientPort)) + if (autoObj is not KClientPort clientPort) { return KernelResult.NotFound; } @@ -284,7 +284,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return result; } - public KernelResult SendAsyncRequestWithUserBuffer(ulong messagePtr, ulong messageSize, int handle, out int doneEventHandle) + public KernelResult SendAsyncRequestWithUserBuffer(out int doneEventHandle, ulong messagePtr, ulong messageSize, int handle) { doneEventHandle = 0; @@ -355,10 +355,10 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall } public KernelResult CreateSession( - bool isLight, - ulong namePtr, out int serverSessionHandle, - out int clientSessionHandle) + out int clientSessionHandle, + bool isLight, + ulong namePtr) { serverSessionHandle = 0; clientSessionHandle = 0; @@ -420,7 +420,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return result; } - public KernelResult AcceptSession(int portHandle, out int sessionHandle) + public KernelResult AcceptSession(out int sessionHandle, int portHandle) { sessionHandle = 0; @@ -472,11 +472,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall } public KernelResult ReplyAndReceive( + out int handleIndex, ulong handlesPtr, int handlesCount, int replyTargetHandle, - long timeout, - out int handleIndex) + long timeout) { handleIndex = 0; @@ -501,7 +501,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall int[] handles = new int[handlesCount]; - if (!KernelTransfer.UserToKernelInt32Array(_context, handlesPtr, handles)) + if (!KernelTransfer.UserToKernelArray(handlesPtr, handles)) { return KernelResult.UserCopyFailed; } @@ -511,10 +511,10 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall timeout += KTimeManager.DefaultTimeIncrementNanoseconds; } - return ReplyAndReceive(handles, replyTargetHandle, timeout, out handleIndex); + return ReplyAndReceive(out handleIndex, handles, replyTargetHandle, timeout); } - public KernelResult ReplyAndReceive(ReadOnlySpan handles, int replyTargetHandle, long timeout, out int handleIndex) + public KernelResult ReplyAndReceive(out int handleIndex, ReadOnlySpan handles, int replyTargetHandle, long timeout) { handleIndex = 0; @@ -577,13 +577,13 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall } public KernelResult ReplyAndReceiveWithUserBuffer( + out int handleIndex, ulong handlesPtr, ulong messagePtr, ulong messageSize, int handlesCount, int replyTargetHandle, - long timeout, - out int handleIndex) + long timeout) { handleIndex = 0; @@ -615,7 +615,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall int[] handles = new int[handlesCount]; - if (!KernelTransfer.UserToKernelInt32Array(_context, handlesPtr, handles)) + if (!KernelTransfer.UserToKernelArray(handlesPtr, handles)) { currentProcess.MemoryManager.UnborrowIpcBuffer(messagePtr, messageSize); @@ -681,11 +681,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall } public KernelResult CreatePort( + out int serverPortHandle, + out int clientPortHandle, int maxSessions, bool isLight, - ulong namePtr, - out int serverPortHandle, - out int clientPortHandle) + ulong namePtr) { serverPortHandle = clientPortHandle = 0; @@ -715,11 +715,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return result; } - public KernelResult ManageNamedPort(ulong namePtr, int maxSessions, out int handle) + public KernelResult ManageNamedPort(out int handle, ulong namePtr, int maxSessions) { handle = 0; - if (!KernelTransfer.UserToKernelString(_context, namePtr, 12, out string name)) + if (!KernelTransfer.UserToKernelString(out string name, namePtr, 12)) { return KernelResult.UserCopyFailed; } @@ -729,10 +729,10 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return KernelResult.MaximumExceeded; } - return ManageNamedPort(name, maxSessions, out handle); + return ManageNamedPort(out handle, name, maxSessions); } - public KernelResult ManageNamedPort(string name, int maxSessions, out int handle) + public KernelResult ManageNamedPort(out int handle, string name, int maxSessions) { handle = 0; @@ -767,7 +767,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return result; } - public KernelResult ConnectToPort(int clientPortHandle, out int clientSessionHandle) + public KernelResult ConnectToPort(out int clientSessionHandle, int clientPortHandle) { clientSessionHandle = 0; @@ -820,18 +820,18 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall // Memory - public KernelResult SetHeapSize(ulong size, out ulong position) + public KernelResult SetHeapSize(out ulong address, ulong size) { if ((size & 0xfffffffe001fffff) != 0) { - position = 0; + address = 0; return KernelResult.InvalidSize; } KProcess process = KernelStatic.GetCurrentProcess(); - return process.MemoryManager.SetHeapSize(size, out position); + return process.MemoryManager.SetHeapSize(size, out address); } public KernelResult SetMemoryPermission(ulong address, ulong size, KMemoryPermission permission) @@ -867,12 +867,12 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall } public KernelResult SetMemoryAttribute( - ulong position, + ulong address, ulong size, MemoryAttribute attributeMask, MemoryAttribute attributeValue) { - if (!PageAligned(position)) + if (!PageAligned(address)) { return KernelResult.InvalidAddress; } @@ -892,13 +892,13 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall KProcess process = KernelStatic.GetCurrentProcess(); - if (!process.MemoryManager.InsideAddrSpace(position, size)) + if (!process.MemoryManager.InsideAddrSpace(address, size)) { return KernelResult.InvalidMemState; } KernelResult result = process.MemoryManager.SetMemoryAttribute( - position, + address, size, attributeMask, attributeValue); @@ -978,20 +978,34 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return process.MemoryManager.Unmap(dst, src, size); } - public KernelResult QueryMemory(ulong infoPtr, ulong position, out ulong pageInfo) + public KernelResult QueryMemory(ulong infoPtr, out ulong pageInfo, ulong address) + { + KernelResult result = QueryMemory(out MemoryInfo info, out pageInfo, address); + + if (result == KernelResult.Success) + { + return KernelTransfer.KernelToUser(infoPtr, info) + ? KernelResult.Success + : KernelResult.InvalidMemState; + } + + return result; + } + + public KernelResult QueryMemory(out MemoryInfo info, out ulong pageInfo, ulong address) { KProcess process = KernelStatic.GetCurrentProcess(); - KMemoryInfo blkInfo = process.MemoryManager.QueryMemory(position); + KMemoryInfo blockInfo = process.MemoryManager.QueryMemory(address); - process.CpuMemory.Write(infoPtr + 0x00, blkInfo.Address); - process.CpuMemory.Write(infoPtr + 0x08, blkInfo.Size); - process.CpuMemory.Write(infoPtr + 0x10, (int)blkInfo.State & 0xff); - process.CpuMemory.Write(infoPtr + 0x14, (int)blkInfo.Attribute); - process.CpuMemory.Write(infoPtr + 0x18, (int)blkInfo.Permission); - process.CpuMemory.Write(infoPtr + 0x1c, blkInfo.IpcRefCount); - process.CpuMemory.Write(infoPtr + 0x20, blkInfo.DeviceRefCount); - process.CpuMemory.Write(infoPtr + 0x24, 0); + info = new MemoryInfo( + blockInfo.Address, + blockInfo.Size, + blockInfo.State & MemoryState.UserMask, + blockInfo.Attribute, + blockInfo.Permission & KMemoryPermission.UserMask, + blockInfo.IpcRefCount, + blockInfo.DeviceRefCount); pageInfo = 0; @@ -1084,7 +1098,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall currentProcess); } - public KernelResult CreateTransferMemory(ulong address, ulong size, KMemoryPermission permission, out int handle) + public KernelResult CreateTransferMemory(out int handle, ulong address, ulong size, KMemoryPermission permission) { handle = 0; @@ -1414,9 +1428,9 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return targetProcess.MemoryManager.SetProcessMemoryPermission(src, size, permission); } - private static bool PageAligned(ulong position) + private static bool PageAligned(ulong address) { - return (position & (KPageTableBase.PageSize - 1)) == 0; + return (address & (KPageTableBase.PageSize - 1)) == 0; } // System @@ -1575,7 +1589,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall Logger.Warning?.Print(LogClass.KernelSvc, str); } - public KernelResult GetInfo(InfoType id, int handle, long subId, out long value) + public KernelResult GetInfo(out ulong value, InfoType id, int handle, long subId) { value = 0; @@ -1621,30 +1635,30 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall case InfoType.CoreMask: value = process.Capabilities.AllowedCpuCoresMask; break; case InfoType.PriorityMask: value = process.Capabilities.AllowedThreadPriosMask; break; - case InfoType.AliasRegionAddress: value = (long)process.MemoryManager.AliasRegionStart; break; + case InfoType.AliasRegionAddress: value = process.MemoryManager.AliasRegionStart; break; case InfoType.AliasRegionSize: - value = (long)(process.MemoryManager.AliasRegionEnd - - process.MemoryManager.AliasRegionStart); break; + value = (process.MemoryManager.AliasRegionEnd - + process.MemoryManager.AliasRegionStart); break; - case InfoType.HeapRegionAddress: value = (long)process.MemoryManager.HeapRegionStart; break; + case InfoType.HeapRegionAddress: value = process.MemoryManager.HeapRegionStart; break; case InfoType.HeapRegionSize: - value = (long)(process.MemoryManager.HeapRegionEnd - - process.MemoryManager.HeapRegionStart); break; + value = (process.MemoryManager.HeapRegionEnd - + process.MemoryManager.HeapRegionStart); break; - case InfoType.TotalMemorySize: value = (long)process.GetMemoryCapacity(); break; + case InfoType.TotalMemorySize: value = process.GetMemoryCapacity(); break; - case InfoType.UsedMemorySize: value = (long)process.GetMemoryUsage(); break; + case InfoType.UsedMemorySize: value = process.GetMemoryUsage(); break; - case InfoType.AslrRegionAddress: value = (long)process.MemoryManager.GetAddrSpaceBaseAddr(); break; + case InfoType.AslrRegionAddress: value = process.MemoryManager.GetAddrSpaceBaseAddr(); break; - case InfoType.AslrRegionSize: value = (long)process.MemoryManager.GetAddrSpaceSize(); break; + case InfoType.AslrRegionSize: value = process.MemoryManager.GetAddrSpaceSize(); break; - case InfoType.StackRegionAddress: value = (long)process.MemoryManager.StackRegionStart; break; + case InfoType.StackRegionAddress: value = process.MemoryManager.StackRegionStart; break; case InfoType.StackRegionSize: - value = (long)(process.MemoryManager.StackRegionEnd - - process.MemoryManager.StackRegionStart); break; + value = (process.MemoryManager.StackRegionEnd - + process.MemoryManager.StackRegionStart); break; - case InfoType.SystemResourceSizeTotal: value = (long)process.PersonalMmHeapPagesCount * KPageTableBase.PageSize; break; + case InfoType.SystemResourceSizeTotal: value = process.PersonalMmHeapPagesCount * KPageTableBase.PageSize; break; case InfoType.SystemResourceSizeUsed: if (process.PersonalMmHeapPagesCount != 0) @@ -1654,20 +1668,21 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall break; - case InfoType.ProgramId: value = (long)process.TitleId; break; + case InfoType.ProgramId: value = process.TitleId; break; - case InfoType.UserExceptionContextAddress: value = (long)process.UserExceptionContextAddress; break; + case InfoType.UserExceptionContextAddress: value = process.UserExceptionContextAddress; break; - case InfoType.TotalNonSystemMemorySize: value = (long)process.GetMemoryCapacityWithoutPersonalMmHeap(); break; + case InfoType.TotalNonSystemMemorySize: value = process.GetMemoryCapacityWithoutPersonalMmHeap(); break; - case InfoType.UsedNonSystemMemorySize: value = (long)process.GetMemoryUsageWithoutPersonalMmHeap(); break; + case InfoType.UsedNonSystemMemorySize: value = process.GetMemoryUsageWithoutPersonalMmHeap(); break; - case InfoType.IsApplication: value = process.IsApplication ? 1 : 0; break; + case InfoType.IsApplication: value = process.IsApplication ? 1UL : 0UL; break; case InfoType.FreeThreadCount: if (process.ResourceLimit != null) { - value = process.ResourceLimit.GetLimitValue(LimitableResource.Thread) - process.ResourceLimit.GetCurrentValue(LimitableResource.Thread); + value = (ulong)(process.ResourceLimit.GetLimitValue(LimitableResource.Thread) - + process.ResourceLimit.GetCurrentValue(LimitableResource.Thread)); } else { @@ -1692,7 +1707,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return KernelResult.InvalidCombination; } - value = KernelStatic.GetCurrentProcess().Debug ? 1 : 0; + value = KernelStatic.GetCurrentProcess().Debug ? 1UL : 0UL; break; } @@ -1743,7 +1758,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return KernelResult.InvalidCombination; } - value = KTimeManager.ConvertHostTicksToTicks(_context.Schedulers[currentCore].TotalIdleTimeTicks); + value = (ulong)KTimeManager.ConvertHostTicksToTicks(_context.Schedulers[currentCore].TotalIdleTimeTicks); break; } @@ -1796,7 +1811,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall if (subId != -1) { - value = KTimeManager.ConvertHostTicksToTicks(timeDelta); + value = (ulong)KTimeManager.ConvertHostTicksToTicks(timeDelta); } else { @@ -1807,7 +1822,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall totalTimeRunning += timeDelta; } - value = KTimeManager.ConvertHostTicksToTicks(totalTimeRunning); + value = (ulong)KTimeManager.ConvertHostTicksToTicks(totalTimeRunning); } break; @@ -1844,7 +1859,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return result; } - public KernelResult GetProcessList(ulong address, int maxCount, out int count) + public KernelResult GetProcessList(out int count, ulong address, int maxCount) { count = 0; @@ -1878,7 +1893,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall { if (copyCount < maxCount) { - if (!KernelTransfer.KernelToUserInt64(_context, address + (ulong)copyCount * 8, process.Pid)) + if (!KernelTransfer.KernelToUser(address + (ulong)copyCount * 8, process.Pid)) { return KernelResult.UserCopyFailed; } @@ -1893,7 +1908,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return KernelResult.Success; } - public KernelResult GetSystemInfo(uint id, int handle, long subId, out long value) + public KernelResult GetSystemInfo(out long value, uint id, int handle, long subId) { value = 0; @@ -1949,7 +1964,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return KernelResult.Success; } - public KernelResult GetResourceLimitLimitValue(int handle, LimitableResource resource, out long limitValue) + public KernelResult GetResourceLimitLimitValue(out long limitValue, int handle, LimitableResource resource) { limitValue = 0; @@ -1970,7 +1985,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return KernelResult.Success; } - public KernelResult GetResourceLimitCurrentValue(int handle, LimitableResource resource, out long limitValue) + public KernelResult GetResourceLimitCurrentValue(out long limitValue, int handle, LimitableResource resource) { limitValue = 0; @@ -1991,7 +2006,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return KernelResult.Success; } - public KernelResult GetResourceLimitPeakValue(int handle, LimitableResource resource, out long peak) + public KernelResult GetResourceLimitPeakValue(out long peak, int handle, LimitableResource resource) { peak = 0; @@ -2041,12 +2056,12 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall // Thread public KernelResult CreateThread( + out int handle, ulong entrypoint, ulong argsPtr, ulong stackTop, int priority, - int cpuCore, - out int handle) + int cpuCore) { handle = 0; @@ -2152,7 +2167,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall } } - public KernelResult GetThreadPriority(int handle, out int priority) + public KernelResult GetThreadPriority(out int priority, int handle) { KProcess process = KernelStatic.GetCurrentProcess(); @@ -2190,7 +2205,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return KernelResult.Success; } - public KernelResult GetThreadCoreMask(int handle, out int preferredCore, out long affinityMask) + public KernelResult GetThreadCoreMask(out int preferredCore, out ulong affinityMask, int handle) { KProcess process = KernelStatic.GetCurrentProcess(); @@ -2212,7 +2227,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall } } - public KernelResult SetThreadCoreMask(int handle, int preferredCore, long affinityMask) + public KernelResult SetThreadCoreMask(int handle, int preferredCore, ulong affinityMask) { KProcess currentProcess = KernelStatic.GetCurrentProcess(); @@ -2220,7 +2235,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall { preferredCore = currentProcess.DefaultCpuCore; - affinityMask = 1 << preferredCore; + affinityMask = 1UL << preferredCore; } else { @@ -2242,7 +2257,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return KernelResult.InvalidCpuCore; } } - else if ((affinityMask & (1 << preferredCore)) == 0) + else if ((affinityMask & (1UL << preferredCore)) == 0) { return KernelResult.InvalidCombination; } @@ -2265,7 +2280,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return KernelStatic.GetCurrentThread().CurrentCore; } - public KernelResult GetThreadId(int handle, out long threadUid) + public KernelResult GetThreadId(out long threadUid, int handle) { KProcess process = KernelStatic.GetCurrentProcess(); @@ -2331,96 +2346,21 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return KernelResult.InvalidThread; } - IVirtualMemoryManager memory = currentProcess.CpuMemory; + KernelResult result = thread.GetThreadContext3(out ThreadContext context); - memory.Write(address + 0x0, thread.Context.GetX(0)); - memory.Write(address + 0x8, thread.Context.GetX(1)); - memory.Write(address + 0x10, thread.Context.GetX(2)); - memory.Write(address + 0x18, thread.Context.GetX(3)); - memory.Write(address + 0x20, thread.Context.GetX(4)); - memory.Write(address + 0x28, thread.Context.GetX(5)); - memory.Write(address + 0x30, thread.Context.GetX(6)); - memory.Write(address + 0x38, thread.Context.GetX(7)); - memory.Write(address + 0x40, thread.Context.GetX(8)); - memory.Write(address + 0x48, thread.Context.GetX(9)); - memory.Write(address + 0x50, thread.Context.GetX(10)); - memory.Write(address + 0x58, thread.Context.GetX(11)); - memory.Write(address + 0x60, thread.Context.GetX(12)); - memory.Write(address + 0x68, thread.Context.GetX(13)); - memory.Write(address + 0x70, thread.Context.GetX(14)); - memory.Write(address + 0x78, thread.Context.GetX(15)); - memory.Write(address + 0x80, thread.Context.GetX(16)); - memory.Write(address + 0x88, thread.Context.GetX(17)); - memory.Write(address + 0x90, thread.Context.GetX(18)); - memory.Write(address + 0x98, thread.Context.GetX(19)); - memory.Write(address + 0xa0, thread.Context.GetX(20)); - memory.Write(address + 0xa8, thread.Context.GetX(21)); - memory.Write(address + 0xb0, thread.Context.GetX(22)); - memory.Write(address + 0xb8, thread.Context.GetX(23)); - memory.Write(address + 0xc0, thread.Context.GetX(24)); - memory.Write(address + 0xc8, thread.Context.GetX(25)); - memory.Write(address + 0xd0, thread.Context.GetX(26)); - memory.Write(address + 0xd8, thread.Context.GetX(27)); - memory.Write(address + 0xe0, thread.Context.GetX(28)); - memory.Write(address + 0xe8, thread.Context.GetX(29)); - memory.Write(address + 0xf0, thread.Context.GetX(30)); - memory.Write(address + 0xf8, thread.Context.GetX(31)); + if (result == KernelResult.Success) + { + return KernelTransfer.KernelToUser(address, context) + ? KernelResult.Success + : KernelResult.InvalidMemState; + } - memory.Write(address + 0x100, thread.LastPc); - - memory.Write(address + 0x108, (ulong)GetPsr(thread.Context)); - - memory.Write(address + 0x110, thread.Context.GetV(0)); - memory.Write(address + 0x120, thread.Context.GetV(1)); - memory.Write(address + 0x130, thread.Context.GetV(2)); - memory.Write(address + 0x140, thread.Context.GetV(3)); - memory.Write(address + 0x150, thread.Context.GetV(4)); - memory.Write(address + 0x160, thread.Context.GetV(5)); - memory.Write(address + 0x170, thread.Context.GetV(6)); - memory.Write(address + 0x180, thread.Context.GetV(7)); - memory.Write(address + 0x190, thread.Context.GetV(8)); - memory.Write(address + 0x1a0, thread.Context.GetV(9)); - memory.Write(address + 0x1b0, thread.Context.GetV(10)); - memory.Write(address + 0x1c0, thread.Context.GetV(11)); - memory.Write(address + 0x1d0, thread.Context.GetV(12)); - memory.Write(address + 0x1e0, thread.Context.GetV(13)); - memory.Write(address + 0x1f0, thread.Context.GetV(14)); - memory.Write(address + 0x200, thread.Context.GetV(15)); - memory.Write(address + 0x210, thread.Context.GetV(16)); - memory.Write(address + 0x220, thread.Context.GetV(17)); - memory.Write(address + 0x230, thread.Context.GetV(18)); - memory.Write(address + 0x240, thread.Context.GetV(19)); - memory.Write(address + 0x250, thread.Context.GetV(20)); - memory.Write(address + 0x260, thread.Context.GetV(21)); - memory.Write(address + 0x270, thread.Context.GetV(22)); - memory.Write(address + 0x280, thread.Context.GetV(23)); - memory.Write(address + 0x290, thread.Context.GetV(24)); - memory.Write(address + 0x2a0, thread.Context.GetV(25)); - memory.Write(address + 0x2b0, thread.Context.GetV(26)); - memory.Write(address + 0x2c0, thread.Context.GetV(27)); - memory.Write(address + 0x2d0, thread.Context.GetV(28)); - memory.Write(address + 0x2e0, thread.Context.GetV(29)); - memory.Write(address + 0x2f0, thread.Context.GetV(30)); - memory.Write(address + 0x300, thread.Context.GetV(31)); - - memory.Write(address + 0x310, (int)thread.Context.Fpcr); - memory.Write(address + 0x314, (int)thread.Context.Fpsr); - memory.Write(address + 0x318, thread.Context.Tpidr); - - return KernelResult.Success; - } - - private static int GetPsr(ARMeilleure.State.ExecutionContext context) - { - return (context.GetPstateFlag(ARMeilleure.State.PState.NFlag) ? (1 << (int)ARMeilleure.State.PState.NFlag) : 0) | - (context.GetPstateFlag(ARMeilleure.State.PState.ZFlag) ? (1 << (int)ARMeilleure.State.PState.ZFlag) : 0) | - (context.GetPstateFlag(ARMeilleure.State.PState.CFlag) ? (1 << (int)ARMeilleure.State.PState.CFlag) : 0) | - (context.GetPstateFlag(ARMeilleure.State.PState.VFlag) ? (1 << (int)ARMeilleure.State.PState.VFlag) : 0); + return result; } // Thread synchronization - public KernelResult WaitSynchronization(ulong handlesPtr, int handlesCount, long timeout, out int handleIndex) + public KernelResult WaitSynchronization(out int handleIndex, ulong handlesPtr, int handlesCount, long timeout) { handleIndex = 0; @@ -2456,7 +2396,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall Span handles = new Span(currentThread.WaitSyncHandles).Slice(0, handlesCount); - if (!KernelTransfer.UserToKernelInt32Array(_context, handlesPtr, handles)) + if (!KernelTransfer.UserToKernelArray(handlesPtr, handles)) { return KernelResult.UserCopyFailed; } diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall32.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall32.cs index d955807d8..f1b5b0e56 100644 --- a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall32.cs +++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall32.cs @@ -17,7 +17,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall public KernelResult ConnectToNamedPort32([R(1)] uint namePtr, [R(1)] out int handle) { - return _syscall.ConnectToNamedPort(namePtr, out handle); + return _syscall.ConnectToNamedPort(out handle, namePtr); } public KernelResult SendSyncRequest32([R(0)] int handle) @@ -36,17 +36,17 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall [R(1)] out int serverSessionHandle, [R(2)] out int clientSessionHandle) { - return _syscall.CreateSession(isLight, namePtr, out serverSessionHandle, out clientSessionHandle); + return _syscall.CreateSession(out serverSessionHandle, out clientSessionHandle, isLight, namePtr); } public KernelResult AcceptSession32([R(1)] int portHandle, [R(1)] out int sessionHandle) { - return _syscall.AcceptSession(portHandle, out sessionHandle); + return _syscall.AcceptSession(out sessionHandle, portHandle); } public KernelResult ReplyAndReceive32( [R(0)] uint timeoutLow, - [R(1)] ulong handlesPtr, + [R(1)] uint handlesPtr, [R(2)] int handlesCount, [R(3)] int replyTargetHandle, [R(4)] uint timeoutHigh, @@ -54,7 +54,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall { long timeout = (long)(timeoutLow | ((ulong)timeoutHigh << 32)); - return _syscall.ReplyAndReceive(handlesPtr, handlesCount, replyTargetHandle, timeout, out handleIndex); + return _syscall.ReplyAndReceive(out handleIndex, handlesPtr, handlesCount, replyTargetHandle, timeout); } public KernelResult CreatePort32( @@ -64,45 +64,45 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall [R(1)] out int serverPortHandle, [R(2)] out int clientPortHandle) { - return _syscall.CreatePort(maxSessions, isLight, namePtr, out serverPortHandle, out clientPortHandle); + return _syscall.CreatePort(out serverPortHandle, out clientPortHandle, maxSessions, isLight, namePtr); } public KernelResult ManageNamedPort32([R(1)] uint namePtr, [R(2)] int maxSessions, [R(1)] out int handle) { - return _syscall.ManageNamedPort(namePtr, maxSessions, out handle); + return _syscall.ManageNamedPort(out handle, namePtr, maxSessions); } public KernelResult ConnectToPort32([R(1)] int clientPortHandle, [R(1)] out int clientSessionHandle) { - return _syscall.ConnectToPort(clientPortHandle, out clientSessionHandle); + return _syscall.ConnectToPort(out clientSessionHandle, clientPortHandle); } // Memory - public KernelResult SetHeapSize32([R(1)] uint size, [R(1)] out uint position) + public KernelResult SetHeapSize32([R(1)] uint size, [R(1)] out uint address) { - KernelResult result = _syscall.SetHeapSize(size, out ulong temporaryPosition); + KernelResult result = _syscall.SetHeapSize(out ulong address64, size); - position = (uint)temporaryPosition; + address = (uint)address64; return result; } public KernelResult SetMemoryPermission32( - [R(0)] ulong position, - [R(1)] ulong size, + [R(0)] uint address, + [R(1)] uint size, [R(2)] KMemoryPermission permission) { - return _syscall.SetMemoryPermission(position, size, permission); + return _syscall.SetMemoryPermission(address, size, permission); } public KernelResult SetMemoryAttribute32( - [R(0)] uint position, + [R(0)] uint address, [R(1)] uint size, [R(2)] MemoryAttribute attributeMask, [R(3)] MemoryAttribute attributeValue) { - return _syscall.SetMemoryAttribute(position, size, attributeMask, attributeValue); + return _syscall.SetMemoryAttribute(address, size, attributeMask, attributeValue); } public KernelResult MapMemory32([R(0)] uint dst, [R(1)] uint src, [R(2)] uint size) @@ -115,9 +115,9 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return _syscall.UnmapMemory(dst, src, size); } - public KernelResult QueryMemory32([R(0)] uint infoPtr, [R(1)] uint r1, [R(2)] uint position, [R(1)] out uint pageInfo) + public KernelResult QueryMemory32([R(0)] uint infoPtr, [R(1)] uint r1, [R(2)] uint address, [R(1)] out uint pageInfo) { - KernelResult result = _syscall.QueryMemory(infoPtr, position, out ulong pageInfo64); + KernelResult result = _syscall.QueryMemory(infoPtr, out ulong pageInfo64, address); pageInfo = (uint)pageInfo64; @@ -140,7 +140,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall [R(3)] KMemoryPermission permission, [R(1)] out int handle) { - return _syscall.CreateTransferMemory(address, size, permission, out handle); + return _syscall.CreateTransferMemory(out handle, address, size, permission); } public KernelResult MapTransferMemory32([R(0)] int handle, [R(1)] uint address, [R(2)] uint size, [R(3)] KMemoryPermission permission) @@ -237,7 +237,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall public KernelResult GetProcessId32([R(1)] int handle, [R(1)] out int pidLow, [R(2)] out int pidHigh) { - KernelResult result = _syscall.GetProcessId(handle, out long pid); + KernelResult result = _syscall.GetProcessId(out long pid, handle); pidLow = (int)(pid & uint.MaxValue); pidHigh = (int)(pid >> 32); @@ -265,7 +265,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall { long subId = (long)(subIdLow | ((ulong)subIdHigh << 32)); - KernelResult result = _syscall.GetInfo(id, handle, subId, out long value); + KernelResult result = _syscall.GetInfo(out ulong value, id, handle, subId); valueHigh = (uint)(value >> 32); valueLow = (uint)(value & uint.MaxValue); @@ -280,14 +280,14 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall public KernelResult GetProcessList32([R(1)] ulong address, [R(2)] int maxCount, [R(1)] out int count) { - return _syscall.GetProcessList(address, maxCount, out count); + return _syscall.GetProcessList(out count, address, maxCount); } public KernelResult GetSystemInfo32([R(1)] uint subIdLow, [R(2)] uint id, [R(3)] int handle, [R(3)] uint subIdHigh, [R(1)] out int valueLow, [R(2)] out int valueHigh) { long subId = (long)(subIdLow | ((ulong)subIdHigh << 32)); - KernelResult result = _syscall.GetSystemInfo(id, handle, subId, out long value); + KernelResult result = _syscall.GetSystemInfo(out long value, id, handle, subId); valueHigh = (int)(value >> 32); valueLow = (int)(value & uint.MaxValue); @@ -297,7 +297,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall public KernelResult GetResourceLimitLimitValue32([R(1)] int handle, [R(2)] LimitableResource resource, [R(1)] out int limitValueLow, [R(2)] out int limitValueHigh) { - KernelResult result = _syscall.GetResourceLimitLimitValue(handle, resource, out long limitValue); + KernelResult result = _syscall.GetResourceLimitLimitValue(out long limitValue, handle, resource); limitValueHigh = (int)(limitValue >> 32); limitValueLow = (int)(limitValue & uint.MaxValue); @@ -307,7 +307,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall public KernelResult GetResourceLimitCurrentValue32([R(1)] int handle, [R(2)] LimitableResource resource, [R(1)] out int limitValueLow, [R(2)] out int limitValueHigh) { - KernelResult result = _syscall.GetResourceLimitCurrentValue(handle, resource, out long limitValue); + KernelResult result = _syscall.GetResourceLimitCurrentValue(out long limitValue, handle, resource); limitValueHigh = (int)(limitValue >> 32); limitValueLow = (int)(limitValue & uint.MaxValue); @@ -317,7 +317,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall public KernelResult GetResourceLimitPeakValue32([R(1)] int handle, [R(2)] LimitableResource resource, [R(1)] out int peakLow, [R(2)] out int peakHigh) { - KernelResult result = _syscall.GetResourceLimitPeakValue(handle, resource, out long peak); + KernelResult result = _syscall.GetResourceLimitPeakValue(out long peak, handle, resource); peakHigh = (int)(peak >> 32); peakLow = (int)(peak & uint.MaxValue); @@ -359,7 +359,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall [R(4)] int cpuCore, [R(1)] out int handle) { - return _syscall.CreateThread(entrypoint, argsPtr, stackTop, priority, cpuCore, out handle); + return _syscall.CreateThread(out handle, entrypoint, argsPtr, stackTop, priority, cpuCore); } public KernelResult StartThread32([R(0)] int handle) @@ -381,7 +381,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall public KernelResult GetThreadPriority32([R(1)] int handle, [R(1)] out int priority) { - return _syscall.GetThreadPriority(handle, out priority); + return _syscall.GetThreadPriority(out priority, handle); } public KernelResult SetThreadPriority32([R(0)] int handle, [R(1)] int priority) @@ -389,19 +389,19 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return _syscall.SetThreadPriority(handle, priority); } - public KernelResult GetThreadCoreMask32([R(2)] int handle, [R(1)] out int preferredCore, [R(2)] out int affinityMaskLow, [R(3)] out int affinityMaskHigh) + public KernelResult GetThreadCoreMask32([R(2)] int handle, [R(1)] out int preferredCore, [R(2)] out uint affinityMaskLow, [R(3)] out uint affinityMaskHigh) { - KernelResult result = _syscall.GetThreadCoreMask(handle, out preferredCore, out long affinityMask); + KernelResult result = _syscall.GetThreadCoreMask(out preferredCore, out ulong affinityMask, handle); - affinityMaskLow = (int)(affinityMask & uint.MaxValue); - affinityMaskHigh = (int)(affinityMask >> 32); + affinityMaskLow = (uint)(affinityMask & uint.MaxValue); + affinityMaskHigh = (uint)(affinityMask >> 32); return result; } public KernelResult SetThreadCoreMask32([R(0)] int handle, [R(1)] int preferredCore, [R(2)] uint affinityMaskLow, [R(3)] uint affinityMaskHigh) { - long affinityMask = (long)(affinityMaskLow | ((ulong)affinityMaskHigh << 32)); + ulong affinityMask = affinityMaskLow | ((ulong)affinityMaskHigh << 32); return _syscall.SetThreadCoreMask(handle, preferredCore, affinityMask); } @@ -415,7 +415,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall { long threadUid; - KernelResult result = _syscall.GetThreadId(handle, out threadUid); + KernelResult result = _syscall.GetThreadId(out threadUid, handle); threadUidLow = (uint)(threadUid >> 32); threadUidHigh = (uint)(threadUid & uint.MaxValue); @@ -444,7 +444,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall { long timeout = (long)(timeoutLow | ((ulong)timeoutHigh << 32)); - return _syscall.WaitSynchronization(handlesPtr, handlesCount, timeout, out handleIndex); + return _syscall.WaitSynchronization(out handleIndex, handlesPtr, handlesCount, timeout); } public KernelResult CancelSynchronization32([R(0)] int handle) diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall64.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall64.cs index fc826552b..fcb2a702f 100644 --- a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall64.cs +++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall64.cs @@ -17,7 +17,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall public KernelResult ConnectToNamedPort64([R(1)] ulong namePtr, [R(1)] out int handle) { - return _syscall.ConnectToNamedPort(namePtr, out handle); + return _syscall.ConnectToNamedPort(out handle, namePtr); } public KernelResult SendSyncRequest64([R(0)] int handle) @@ -36,7 +36,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall [R(3)] int handle, [R(1)] out int doneEventHandle) { - return _syscall.SendAsyncRequestWithUserBuffer(messagePtr, messageSize, handle, out doneEventHandle); + return _syscall.SendAsyncRequestWithUserBuffer(out doneEventHandle, messagePtr, messageSize, handle); } public KernelResult CreateSession64( @@ -45,12 +45,12 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall [R(1)] out int serverSessionHandle, [R(2)] out int clientSessionHandle) { - return _syscall.CreateSession(isLight, namePtr, out serverSessionHandle, out clientSessionHandle); + return _syscall.CreateSession(out serverSessionHandle, out clientSessionHandle, isLight, namePtr); } public KernelResult AcceptSession64([R(1)] int portHandle, [R(1)] out int sessionHandle) { - return _syscall.AcceptSession(portHandle, out sessionHandle); + return _syscall.AcceptSession(out sessionHandle, portHandle); } public KernelResult ReplyAndReceive64( @@ -60,7 +60,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall [R(4)] long timeout, [R(1)] out int handleIndex) { - return _syscall.ReplyAndReceive(handlesPtr, handlesCount, replyTargetHandle, timeout, out handleIndex); + return _syscall.ReplyAndReceive(out handleIndex, handlesPtr, handlesCount, replyTargetHandle, timeout); } public KernelResult ReplyAndReceiveWithUserBuffer64( @@ -73,13 +73,13 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall [R(1)] out int handleIndex) { return _syscall.ReplyAndReceiveWithUserBuffer( + out handleIndex, handlesPtr, messagePtr, messageSize, handlesCount, replyTargetHandle, - timeout, - out handleIndex); + timeout); } public KernelResult CreatePort64( @@ -89,41 +89,41 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall [R(1)] out int serverPortHandle, [R(2)] out int clientPortHandle) { - return _syscall.CreatePort(maxSessions, isLight, namePtr, out serverPortHandle, out clientPortHandle); + return _syscall.CreatePort(out serverPortHandle, out clientPortHandle, maxSessions, isLight, namePtr); } public KernelResult ManageNamedPort64([R(1)] ulong namePtr, [R(2)] int maxSessions, [R(1)] out int handle) { - return _syscall.ManageNamedPort(namePtr, maxSessions, out handle); + return _syscall.ManageNamedPort(out handle, namePtr, maxSessions); } public KernelResult ConnectToPort64([R(1)] int clientPortHandle, [R(1)] out int clientSessionHandle) { - return _syscall.ConnectToPort(clientPortHandle, out clientSessionHandle); + return _syscall.ConnectToPort(out clientSessionHandle, clientPortHandle); } // Memory - public KernelResult SetHeapSize64([R(1)] ulong size, [R(1)] out ulong position) + public KernelResult SetHeapSize64([R(1)] ulong size, [R(1)] out ulong address) { - return _syscall.SetHeapSize(size, out position); + return _syscall.SetHeapSize(out address, size); } public KernelResult SetMemoryPermission64( - [R(0)] ulong position, + [R(0)] ulong address, [R(1)] ulong size, [R(2)] KMemoryPermission permission) { - return _syscall.SetMemoryPermission(position, size, permission); + return _syscall.SetMemoryPermission(address, size, permission); } public KernelResult SetMemoryAttribute64( - [R(0)] ulong position, + [R(0)] ulong address, [R(1)] ulong size, [R(2)] MemoryAttribute attributeMask, [R(3)] MemoryAttribute attributeValue) { - return _syscall.SetMemoryAttribute(position, size, attributeMask, attributeValue); + return _syscall.SetMemoryAttribute(address, size, attributeMask, attributeValue); } public KernelResult MapMemory64([R(0)] ulong dst, [R(1)] ulong src, [R(2)] ulong size) @@ -136,9 +136,9 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return _syscall.UnmapMemory(dst, src, size); } - public KernelResult QueryMemory64([R(0)] ulong infoPtr, [R(2)] ulong position, [R(1)] out ulong pageInfo) + public KernelResult QueryMemory64([R(0)] ulong infoPtr, [R(2)] ulong address, [R(1)] out ulong pageInfo) { - return _syscall.QueryMemory(infoPtr, position, out pageInfo); + return _syscall.QueryMemory(infoPtr, out pageInfo, address); } public KernelResult MapSharedMemory64([R(0)] int handle, [R(1)] ulong address, [R(2)] ulong size, [R(3)] KMemoryPermission permission) @@ -157,7 +157,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall [R(3)] KMemoryPermission permission, [R(1)] out int handle) { - return _syscall.CreateTransferMemory(address, size, permission, out handle); + return _syscall.CreateTransferMemory(out handle, address, size, permission); } public KernelResult MapTransferMemory64([R(0)] int handle, [R(1)] ulong address, [R(2)] ulong size, [R(3)] KMemoryPermission permission) @@ -234,7 +234,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall public KernelResult GetProcessId64([R(1)] int handle, [R(1)] out long pid) { - return _syscall.GetProcessId(handle, out pid); + return _syscall.GetProcessId(out pid, handle); } public void Break64([R(0)] ulong reason, [R(1)] ulong x1, [R(2)] ulong info) @@ -247,9 +247,9 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall _syscall.OutputDebugString(strPtr, size); } - public KernelResult GetInfo64([R(1)] InfoType id, [R(2)] int handle, [R(3)] long subId, [R(1)] out long value) + public KernelResult GetInfo64([R(1)] InfoType id, [R(2)] int handle, [R(3)] long subId, [R(1)] out ulong value) { - return _syscall.GetInfo(id, handle, subId, out value); + return _syscall.GetInfo(out value, id, handle, subId); } public KernelResult CreateEvent64([R(1)] out int wEventHandle, [R(2)] out int rEventHandle) @@ -259,27 +259,27 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall public KernelResult GetProcessList64([R(1)] ulong address, [R(2)] int maxCount, [R(1)] out int count) { - return _syscall.GetProcessList(address, maxCount, out count); + return _syscall.GetProcessList(out count, address, maxCount); } public KernelResult GetSystemInfo64([R(1)] uint id, [R(2)] int handle, [R(3)] long subId, [R(1)] out long value) { - return _syscall.GetSystemInfo(id, handle, subId, out value); + return _syscall.GetSystemInfo(out value, id, handle, subId); } public KernelResult GetResourceLimitLimitValue64([R(1)] int handle, [R(2)] LimitableResource resource, [R(1)] out long limitValue) { - return _syscall.GetResourceLimitLimitValue(handle, resource, out limitValue); + return _syscall.GetResourceLimitLimitValue(out limitValue, handle, resource); } public KernelResult GetResourceLimitCurrentValue64([R(1)] int handle, [R(2)] LimitableResource resource, [R(1)] out long limitValue) { - return _syscall.GetResourceLimitCurrentValue(handle, resource, out limitValue); + return _syscall.GetResourceLimitCurrentValue(out limitValue, handle, resource); } public KernelResult GetResourceLimitPeakValue64([R(1)] int handle, [R(2)] LimitableResource resource, [R(1)] out long peak) { - return _syscall.GetResourceLimitPeakValue(handle, resource, out peak); + return _syscall.GetResourceLimitPeakValue(out peak, handle, resource); } public KernelResult CreateResourceLimit64([R(1)] out int handle) @@ -302,7 +302,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall [R(5)] int cpuCore, [R(1)] out int handle) { - return _syscall.CreateThread(entrypoint, argsPtr, stackTop, priority, cpuCore, out handle); + return _syscall.CreateThread(out handle, entrypoint, argsPtr, stackTop, priority, cpuCore); } public KernelResult StartThread64([R(0)] int handle) @@ -322,7 +322,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall public KernelResult GetThreadPriority64([R(1)] int handle, [R(1)] out int priority) { - return _syscall.GetThreadPriority(handle, out priority); + return _syscall.GetThreadPriority(out priority, handle); } public KernelResult SetThreadPriority64([R(0)] int handle, [R(1)] int priority) @@ -330,12 +330,12 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return _syscall.SetThreadPriority(handle, priority); } - public KernelResult GetThreadCoreMask64([R(2)] int handle, [R(1)] out int preferredCore, [R(2)] out long affinityMask) + public KernelResult GetThreadCoreMask64([R(2)] int handle, [R(1)] out int preferredCore, [R(2)] out ulong affinityMask) { - return _syscall.GetThreadCoreMask(handle, out preferredCore, out affinityMask); + return _syscall.GetThreadCoreMask(out preferredCore, out affinityMask, handle); } - public KernelResult SetThreadCoreMask64([R(0)] int handle, [R(1)] int preferredCore, [R(2)] long affinityMask) + public KernelResult SetThreadCoreMask64([R(0)] int handle, [R(1)] int preferredCore, [R(2)] ulong affinityMask) { return _syscall.SetThreadCoreMask(handle, preferredCore, affinityMask); } @@ -347,7 +347,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall public KernelResult GetThreadId64([R(1)] int handle, [R(1)] out long threadUid) { - return _syscall.GetThreadId(handle, out threadUid); + return _syscall.GetThreadId(out threadUid, handle); } public KernelResult SetThreadActivity64([R(0)] int handle, [R(1)] bool pause) @@ -364,7 +364,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall public KernelResult WaitSynchronization64([R(1)] ulong handlesPtr, [R(2)] int handlesCount, [R(3)] long timeout, [R(1)] out int handleIndex) { - return _syscall.WaitSynchronization(handlesPtr, handlesCount, timeout, out handleIndex); + return _syscall.WaitSynchronization(out handleIndex, handlesPtr, handlesCount, timeout); } public KernelResult CancelSynchronization64([R(0)] int handle) diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/ThreadContext.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/ThreadContext.cs new file mode 100644 index 000000000..b524406af --- /dev/null +++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/ThreadContext.cs @@ -0,0 +1,22 @@ +using ARMeilleure.State; +using Ryujinx.Common.Memory; + +namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall +{ + struct ThreadContext + { + public Array29 Registers; + public ulong Fp; + public ulong Lr; + public ulong Sp; + public ulong Pc; + public uint Pstate; +#pragma warning disable CS0169 + private uint _padding; +#pragma warning restore CS0169 + public Array32 FpuRegisters; + public uint Fpcr; + public uint Fpsr; + public ulong Tpidr; + } +} diff --git a/Ryujinx.HLE/HOS/Kernel/Threading/KAddressArbiter.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KAddressArbiter.cs index 3fd07f90d..f53b43b3c 100644 --- a/Ryujinx.HLE/HOS/Kernel/Threading/KAddressArbiter.cs +++ b/Ryujinx.HLE/HOS/Kernel/Threading/KAddressArbiter.cs @@ -35,7 +35,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading KProcess currentProcess = KernelStatic.GetCurrentProcess(); - if (!KernelTransfer.UserToKernelInt32(_context, mutexAddress, out int mutexValue)) + if (!KernelTransfer.UserToKernel(out int mutexValue, mutexAddress)) { _context.CriticalSection.Leave(); @@ -88,7 +88,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading KernelResult result = KernelResult.Success; - if (!KernelTransfer.KernelToUserInt32(_context, mutexAddress, mutexValue)) + if (!KernelTransfer.KernelToUser(mutexAddress, mutexValue)) { result = KernelResult.InvalidMemState; } @@ -123,9 +123,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading (int mutexValue, _) = MutexUnlock(currentThread, mutexAddress); - KernelTransfer.KernelToUserInt32(_context, condVarAddress, 1); + KernelTransfer.KernelToUser(condVarAddress, 1); - if (!KernelTransfer.KernelToUserInt32(_context, mutexAddress, mutexValue)) + if (!KernelTransfer.KernelToUser(mutexAddress, mutexValue)) { _context.CriticalSection.Leave(); @@ -201,7 +201,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading if (!_condVarThreads.Any(x => x.CondVarAddress == address)) { - KernelTransfer.KernelToUserInt32(_context, address, 0); + KernelTransfer.KernelToUser(address, 0); } _context.CriticalSection.Leave(); @@ -290,7 +290,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading currentThread.SignaledObj = null; currentThread.ObjSyncResult = KernelResult.TimedOut; - if (!KernelTransfer.UserToKernelInt32(_context, address, out int currentValue)) + if (!KernelTransfer.UserToKernel(out int currentValue, address)) { _context.CriticalSection.Leave(); @@ -363,7 +363,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading KProcess currentProcess = KernelStatic.GetCurrentProcess(); - if (!KernelTransfer.UserToKernelInt32(_context, address, out int currentValue)) + if (!KernelTransfer.UserToKernel(out int currentValue, address)) { _context.CriticalSection.Leave(); diff --git a/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs index cf95b0154..16744c437 100644 --- a/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs +++ b/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs @@ -2,6 +2,7 @@ using Ryujinx.Common.Logging; using Ryujinx.Cpu; using Ryujinx.HLE.HOS.Kernel.Common; using Ryujinx.HLE.HOS.Kernel.Process; +using Ryujinx.HLE.HOS.Kernel.SupervisorCall; using System; using System.Collections.Generic; using System.Numerics; @@ -27,7 +28,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading public KThreadContext ThreadContext { get; private set; } public int DynamicPriority { get; set; } - public long AffinityMask { get; set; } + public ulong AffinityMask { get; set; } public long ThreadUid { get; private set; } @@ -88,7 +89,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading public bool IsPinned { get; private set; } - private long _originalAffinityMask; + private ulong _originalAffinityMask; private int _originalPreferredCore; private int _originalBasePriority; private int _coreMigrationDisableCount; @@ -147,7 +148,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading ThreadContext = new KThreadContext(); PreferredCore = cpuCore; - AffinityMask |= 1L << cpuCore; + AffinityMask |= 1UL << cpuCore; SchedFlags = type == ThreadType.Dummy ? ThreadSchedState.Running @@ -629,6 +630,89 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading } } + public KernelResult GetThreadContext3(out ThreadContext context) + { + context = default; + + lock (ActivityOperationLock) + { + KernelContext.CriticalSection.Enter(); + + if ((_forcePauseFlags & ThreadSchedState.ThreadPauseFlag) == 0) + { + KernelContext.CriticalSection.Leave(); + + return KernelResult.InvalidState; + } + + if (!TerminationRequested) + { + context = GetCurrentContext(); + } + + KernelContext.CriticalSection.Leave(); + } + + return KernelResult.Success; + } + + private static uint GetPsr(ARMeilleure.State.ExecutionContext context) + { + return (context.GetPstateFlag(ARMeilleure.State.PState.NFlag) ? (1U << (int)ARMeilleure.State.PState.NFlag) : 0U) | + (context.GetPstateFlag(ARMeilleure.State.PState.ZFlag) ? (1U << (int)ARMeilleure.State.PState.ZFlag) : 0U) | + (context.GetPstateFlag(ARMeilleure.State.PState.CFlag) ? (1U << (int)ARMeilleure.State.PState.CFlag) : 0U) | + (context.GetPstateFlag(ARMeilleure.State.PState.VFlag) ? (1U << (int)ARMeilleure.State.PState.VFlag) : 0U); + } + + private ThreadContext GetCurrentContext() + { + const int MaxRegistersAArch32 = 15; + const int MaxFpuRegistersAArch32 = 16; + + ThreadContext context = new ThreadContext(); + + if (Owner.Flags.HasFlag(ProcessCreationFlags.Is64Bit)) + { + for (int i = 0; i < context.Registers.Length; i++) + { + context.Registers[i] = Context.GetX(i); + } + + for (int i = 0; i < context.FpuRegisters.Length; i++) + { + context.FpuRegisters[i] = Context.GetV(i); + } + + context.Fp = Context.GetX(29); + context.Lr = Context.GetX(30); + context.Sp = Context.GetX(31); + context.Pc = (ulong)LastPc; + context.Pstate = GetPsr(Context); + context.Tpidr = (ulong)Context.Tpidr; + } + else + { + for (int i = 0; i < MaxRegistersAArch32; i++) + { + context.Registers[i] = (uint)Context.GetX(i); + } + + for (int i = 0; i < MaxFpuRegistersAArch32; i++) + { + context.FpuRegisters[i] = Context.GetV(i); + } + + context.Pc = (uint)LastPc; + context.Pstate = GetPsr(Context); + context.Tpidr = (uint)Context.Tpidr; + } + + context.Fpcr = (uint)Context.Fpcr; + context.Fpsr = (uint)Context.Fpsr; + + return context; + } + public void CancelSynchronization() { KernelContext.CriticalSection.Enter(); @@ -660,7 +744,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading KernelContext.CriticalSection.Leave(); } - public KernelResult SetCoreAndAffinityMask(int newCore, long newAffinityMask) + public KernelResult SetCoreAndAffinityMask(int newCore, ulong newAffinityMask) { lock (ActivityOperationLock) { @@ -673,7 +757,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading { newCore = isCoreMigrationDisabled ? _originalPreferredCore : PreferredCore; - if ((newAffinityMask & (1 << newCore)) == 0) + if ((newAffinityMask & (1UL << newCore)) == 0) { KernelContext.CriticalSection.Leave(); @@ -688,7 +772,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading } else { - long oldAffinityMask = AffinityMask; + ulong oldAffinityMask = AffinityMask; PreferredCore = newCore; AffinityMask = newAffinityMask; @@ -701,7 +785,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading { if (PreferredCore < 0) { - ActiveCore = sizeof(ulong) * 8 - 1 - BitOperations.LeadingZeroCount((ulong)AffinityMask); + ActiveCore = sizeof(ulong) * 8 - 1 - BitOperations.LeadingZeroCount(AffinityMask); } else { @@ -733,7 +817,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading int coreNumber = GetEffectiveRunningCore(); bool isPinnedThreadCurrentlyRunning = coreNumber >= 0; - if (isPinnedThreadCurrentlyRunning && ((1 << coreNumber) & AffinityMask) == 0) + if (isPinnedThreadCurrentlyRunning && ((1UL << coreNumber) & AffinityMask) == 0) { if (IsPinned) { @@ -1077,7 +1161,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading KernelContext.ThreadReselectionRequested = true; } - private void AdjustSchedulingForNewAffinity(long oldAffinityMask, int oldCore) + private void AdjustSchedulingForNewAffinity(ulong oldAffinityMask, int oldCore) { if (SchedFlags != ThreadSchedState.Running || DynamicPriority >= KScheduler.PrioritiesCount || !IsSchedulable) { @@ -1259,7 +1343,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading ActiveCore = CurrentCore; PreferredCore = CurrentCore; - AffinityMask = 1 << CurrentCore; + AffinityMask = 1UL << CurrentCore; if (activeCore != CurrentCore || _originalAffinityMask != AffinityMask) { @@ -1282,7 +1366,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading IsPinned = false; _coreMigrationDisableCount--; - long affinityMask = AffinityMask; + ulong affinityMask = AffinityMask; int activeCore = ActiveCore; PreferredCore = _originalPreferredCore; @@ -1290,7 +1374,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading if (AffinityMask != affinityMask) { - if ((AffinityMask & 1 << ActiveCore) != 0) + if ((AffinityMask & 1UL << ActiveCore) != 0) { if (PreferredCore >= 0) { diff --git a/Ryujinx.HLE/HOS/Services/IpcService.cs b/Ryujinx.HLE/HOS/Services/IpcService.cs index 01ee11584..108a4f700 100644 --- a/Ryujinx.HLE/HOS/Services/IpcService.cs +++ b/Ryujinx.HLE/HOS/Services/IpcService.cs @@ -210,7 +210,7 @@ namespace Ryujinx.HLE.HOS.Services } else { - context.Device.System.KernelContext.Syscall.CreateSession(false, 0, out int serverSessionHandle, out int clientSessionHandle); + context.Device.System.KernelContext.Syscall.CreateSession(out int serverSessionHandle, out int clientSessionHandle, false, 0); obj.Server.AddSessionObj(serverSessionHandle, obj); diff --git a/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs b/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs index 00bc34418..b70f6cb79 100644 --- a/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs +++ b/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs @@ -323,7 +323,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv _clientMemory = context.Process.HandleTable.GetKProcess(clientHandle).CpuMemory; - context.Device.System.KernelContext.Syscall.GetProcessId(clientHandle, out _owner); + context.Device.System.KernelContext.Syscall.GetProcessId(out _owner, clientHandle); context.ResponseData.Write((uint)NvResult.Success); diff --git a/Ryujinx.HLE/HOS/Services/ServerBase.cs b/Ryujinx.HLE/HOS/Services/ServerBase.cs index 695394a59..cf7da2f41 100644 --- a/Ryujinx.HLE/HOS/Services/ServerBase.cs +++ b/Ryujinx.HLE/HOS/Services/ServerBase.cs @@ -87,7 +87,7 @@ namespace Ryujinx.HLE.HOS.Services if (SmObjectFactory != null) { - _context.Syscall.ManageNamedPort("sm:", 50, out int serverPortHandle); + _context.Syscall.ManageNamedPort(out int serverPortHandle, "sm:", 50); AddPort(serverPortHandle, SmObjectFactory); } @@ -96,7 +96,7 @@ namespace Ryujinx.HLE.HOS.Services KThread thread = KernelStatic.GetCurrentThread(); ulong messagePtr = thread.TlsAddress; - _context.Syscall.SetHeapSize(0x200000, out ulong heapAddr); + _context.Syscall.SetHeapSize(out ulong heapAddr, 0x200000); _selfProcess.CpuMemory.Write(messagePtr + 0x0, 0); _selfProcess.CpuMemory.Write(messagePtr + 0x4, 2 << 10); @@ -114,7 +114,7 @@ namespace Ryujinx.HLE.HOS.Services sessionHandles.CopyTo(handles, portHandles.Length); // We still need a timeout here to allow the service to pick up and listen new sessions... - var rc = _context.Syscall.ReplyAndReceive(handles, replyTargetHandle, 1000000L, out int signaledIndex); + var rc = _context.Syscall.ReplyAndReceive(out int signaledIndex, handles, replyTargetHandle, 1000000L); thread.HandlePostSyscall(); @@ -140,7 +140,7 @@ namespace Ryujinx.HLE.HOS.Services if (rc == KernelResult.Success) { // We got a new connection, accept the session to allow servicing future requests. - if (_context.Syscall.AcceptSession(handles[signaledIndex], out int serverSessionHandle) == KernelResult.Success) + if (_context.Syscall.AcceptSession(out int serverSessionHandle, handles[signaledIndex]) == KernelResult.Success) { IpcService obj = _ports[handles[signaledIndex]].Invoke(); @@ -247,7 +247,7 @@ namespace Ryujinx.HLE.HOS.Services case 4: int unknown = reqReader.ReadInt32(); - _context.Syscall.CreateSession(false, 0, out int dupServerSessionHandle, out int dupClientSessionHandle); + _context.Syscall.CreateSession(out int dupServerSessionHandle, out int dupClientSessionHandle, false, 0); AddSessionObj(dupServerSessionHandle, _sessions[serverSessionHandle]);