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
This commit is contained in:
Mary 2022-01-29 22:18:03 +01:00 committed by GitHub
parent c52158b733
commit 20ce37dee6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 386 additions and 321 deletions

View File

@ -1,54 +1,50 @@
using Ryujinx.Cpu; using Ryujinx.Cpu;
using Ryujinx.HLE.HOS.Kernel.Process; using Ryujinx.HLE.HOS.Kernel.Process;
using System; using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Kernel.Common namespace Ryujinx.HLE.HOS.Kernel.Common
{ {
static class KernelTransfer static class KernelTransfer
{ {
public static bool UserToKernelInt32(KernelContext context, ulong address, out int value) public static bool UserToKernel<T>(out T value, ulong address) where T : unmanaged
{ {
KProcess currentProcess = KernelStatic.GetCurrentProcess(); KProcess currentProcess = KernelStatic.GetCurrentProcess();
if (currentProcess.CpuMemory.IsMapped(address) && if (currentProcess.CpuMemory.IsRangeMapped(address, (ulong)Unsafe.SizeOf<T>()))
currentProcess.CpuMemory.IsMapped(address + 3))
{ {
value = currentProcess.CpuMemory.Read<int>(address); value = currentProcess.CpuMemory.Read<T>(address);
return true; return true;
} }
value = 0; value = default;
return false; return false;
} }
public static bool UserToKernelInt32Array(KernelContext context, ulong address, Span<int> values) public static bool UserToKernelArray<T>(ulong address, Span<T> values) where T : unmanaged
{ {
KProcess currentProcess = KernelStatic.GetCurrentProcess(); KProcess currentProcess = KernelStatic.GetCurrentProcess();
for (int index = 0; index < values.Length; index++, address += 4) Span<byte> data = MemoryMarshal.Cast<T, byte>(values);
if (currentProcess.CpuMemory.IsRangeMapped(address, (ulong)data.Length))
{ {
if (currentProcess.CpuMemory.IsMapped(address) && currentProcess.CpuMemory.Read(address, data);
currentProcess.CpuMemory.IsMapped(address + 3))
{ return true;
values[index]= currentProcess.CpuMemory.Read<int>(address);
}
else
{
return false;
}
} }
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(); KProcess currentProcess = KernelStatic.GetCurrentProcess();
if (currentProcess.CpuMemory.IsMapped(address) && if (currentProcess.CpuMemory.IsRangeMapped(address, size))
currentProcess.CpuMemory.IsMapped(address + (ulong)size - 1))
{ {
value = MemoryHelper.ReadAsciiString(currentProcess.CpuMemory, address, size); value = MemoryHelper.ReadAsciiString(currentProcess.CpuMemory, address, size);
@ -60,27 +56,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Common
return false; return false;
} }
public static bool KernelToUserInt32(KernelContext context, ulong address, int value) public static bool KernelToUser<T>(ulong address, T value) where T: unmanaged
{ {
KProcess currentProcess = KernelStatic.GetCurrentProcess(); KProcess currentProcess = KernelStatic.GetCurrentProcess();
if (currentProcess.CpuMemory.IsMapped(address) && if (currentProcess.CpuMemory.IsRangeMapped(address, (ulong)Unsafe.SizeOf<T>()))
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))
{ {
currentProcess.CpuMemory.Write(address, value); currentProcess.CpuMemory.Write(address, value);

View File

@ -2682,7 +2682,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
return Context.MemoryManager.MemoryRegions[(int)_memRegion]; return Context.MemoryManager.MemoryRegions[(int)_memRegion];
} }
public long GetMmUsedPages() public ulong GetMmUsedPages()
{ {
lock (_blockManager) 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) public bool IsInvalidRegion(ulong address, ulong size)

View File

@ -5,8 +5,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
[Flags] [Flags]
enum KMemoryPermission : uint enum KMemoryPermission : uint
{ {
None = 0, None = 0,
Mask = uint.MaxValue, UserMask = Read | Write | Execute,
Mask = uint.MaxValue,
Read = 1 << 0, Read = 1 << 0,
Write = 1 << 1, Write = 1 << 1,

View File

@ -26,6 +26,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
KernelStack = 0x00002013, KernelStack = 0x00002013,
CodeReadOnly = 0x00402214, CodeReadOnly = 0x00402214,
CodeWritable = 0x00402015, CodeWritable = 0x00402015,
UserMask = 0xff,
Mask = 0xffffffff, Mask = 0xffffffff,
PermissionChangeAllowed = 1 << 8, PermissionChangeAllowed = 1 << 8,

View File

@ -45,7 +45,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
public KAddressArbiter AddressArbiter { get; private set; } public KAddressArbiter AddressArbiter { get; private set; }
public long[] RandomEntropy { get; private set; } public ulong[] RandomEntropy { get; private set; }
public KThread[] PinnedThreads { get; private set; } public KThread[] PinnedThreads { get; private set; }
private bool _signaled; private bool _signaled;
@ -102,7 +102,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
Capabilities = new KProcessCapabilities(); Capabilities = new KProcessCapabilities();
RandomEntropy = new long[KScheduler.CpuCoresCount]; RandomEntropy = new ulong[KScheduler.CpuCoresCount];
PinnedThreads = new KThread[KScheduler.CpuCoresCount]; PinnedThreads = new KThread[KScheduler.CpuCoresCount];
// TODO: Remove once we no longer need to initialize it externally. // 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) public bool IsCpuCoreAllowed(int core)
{ {
return (Capabilities.AllowedCpuCoresMask & (1L << core)) != 0; return (Capabilities.AllowedCpuCoresMask & (1UL << core)) != 0;
} }
public bool IsPriorityAllowed(int priority) public bool IsPriorityAllowed(int priority)
{ {
return (Capabilities.AllowedThreadPriosMask & (1L << priority)) != 0; return (Capabilities.AllowedThreadPriosMask & (1UL << priority)) != 0;
} }
public override bool IsSignaled() public override bool IsSignaled()

View File

@ -11,8 +11,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
public byte[] SvcAccessMask { get; private set; } public byte[] SvcAccessMask { get; private set; }
public byte[] IrqAccessMask { get; private set; } public byte[] IrqAccessMask { get; private set; }
public long AllowedCpuCoresMask { get; private set; } public ulong AllowedCpuCoresMask { get; private set; }
public long AllowedThreadPriosMask { get; private set; } public ulong AllowedThreadPriosMask { get; private set; }
public int DebuggingFlags { get; private set; } public int DebuggingFlags { get; private set; }
public int HandleTableSize { get; private set; } public int HandleTableSize { get; private set; }
@ -28,7 +28,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
public KernelResult InitializeForKernel(ReadOnlySpan<int> capabilities, KPageTableBase memoryManager) public KernelResult InitializeForKernel(ReadOnlySpan<int> capabilities, KPageTableBase memoryManager)
{ {
AllowedCpuCoresMask = 0xf; AllowedCpuCoresMask = 0xf;
AllowedThreadPriosMask = -1; AllowedThreadPriosMask = ulong.MaxValue;
DebuggingFlags &= ~3; DebuggingFlags &= ~3;
KernelReleaseVersion = KProcess.KernelVersionPacked; KernelReleaseVersion = KProcess.KernelVersionPacked;
@ -303,16 +303,16 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
return KernelResult.Success; return KernelResult.Success;
} }
private static long GetMaskFromMinMax(int min, int max) private static ulong GetMaskFromMinMax(int min, int max)
{ {
int range = max - min + 1; int range = max - min + 1;
if (range == 64) if (range == 64)
{ {
return -1L; return ulong.MaxValue;
} }
long mask = (1L << range) - 1; ulong mask = (1UL << range) - 1;
return mask << min; return mask << min;
} }

View File

@ -2,7 +2,7 @@ using System;
namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
{ {
public class InvalidSvcException : Exception class InvalidSvcException : Exception
{ {
public InvalidSvcException(string message) : base(message) { } public InvalidSvcException(string message) : base(message) { }
} }

View File

@ -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;
}
}
}

View File

@ -24,7 +24,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
// Process // Process
public KernelResult GetProcessId(int handle, out long pid) public KernelResult GetProcessId(out long pid, int handle)
{ {
KProcess currentProcess = KernelStatic.GetCurrentProcess(); KProcess currentProcess = KernelStatic.GetCurrentProcess();
@ -50,9 +50,9 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
} }
public KernelResult CreateProcess( public KernelResult CreateProcess(
out int handle,
ProcessCreationInfo info, ProcessCreationInfo info,
ReadOnlySpan<int> capabilities, ReadOnlySpan<int> capabilities,
out int handle,
IProcessContextFactory contextFactory, IProcessContextFactory contextFactory,
ThreadStart customThreadStart = null) ThreadStart customThreadStart = null)
{ {
@ -170,19 +170,19 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
// IPC // IPC
public KernelResult ConnectToNamedPort(ulong namePtr, out int handle) public KernelResult ConnectToNamedPort(out int handle, ulong namePtr)
{ {
handle = 0; handle = 0;
if (!KernelTransfer.UserToKernelString(_context, namePtr, 12, out string name)) if (!KernelTransfer.UserToKernelString(out string name, namePtr, 12))
{ {
return KernelResult.UserCopyFailed; 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; handle = 0;
@ -193,7 +193,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
KAutoObject autoObj = KAutoObject.FindNamedObject(_context, name); KAutoObject autoObj = KAutoObject.FindNamedObject(_context, name);
if (!(autoObj is KClientPort clientPort)) if (autoObj is not KClientPort clientPort)
{ {
return KernelResult.NotFound; return KernelResult.NotFound;
} }
@ -284,7 +284,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return result; 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; doneEventHandle = 0;
@ -355,10 +355,10 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
} }
public KernelResult CreateSession( public KernelResult CreateSession(
bool isLight,
ulong namePtr,
out int serverSessionHandle, out int serverSessionHandle,
out int clientSessionHandle) out int clientSessionHandle,
bool isLight,
ulong namePtr)
{ {
serverSessionHandle = 0; serverSessionHandle = 0;
clientSessionHandle = 0; clientSessionHandle = 0;
@ -420,7 +420,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return result; return result;
} }
public KernelResult AcceptSession(int portHandle, out int sessionHandle) public KernelResult AcceptSession(out int sessionHandle, int portHandle)
{ {
sessionHandle = 0; sessionHandle = 0;
@ -472,11 +472,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
} }
public KernelResult ReplyAndReceive( public KernelResult ReplyAndReceive(
out int handleIndex,
ulong handlesPtr, ulong handlesPtr,
int handlesCount, int handlesCount,
int replyTargetHandle, int replyTargetHandle,
long timeout, long timeout)
out int handleIndex)
{ {
handleIndex = 0; handleIndex = 0;
@ -501,7 +501,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
int[] handles = new int[handlesCount]; int[] handles = new int[handlesCount];
if (!KernelTransfer.UserToKernelInt32Array(_context, handlesPtr, handles)) if (!KernelTransfer.UserToKernelArray<int>(handlesPtr, handles))
{ {
return KernelResult.UserCopyFailed; return KernelResult.UserCopyFailed;
} }
@ -511,10 +511,10 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
timeout += KTimeManager.DefaultTimeIncrementNanoseconds; timeout += KTimeManager.DefaultTimeIncrementNanoseconds;
} }
return ReplyAndReceive(handles, replyTargetHandle, timeout, out handleIndex); return ReplyAndReceive(out handleIndex, handles, replyTargetHandle, timeout);
} }
public KernelResult ReplyAndReceive(ReadOnlySpan<int> handles, int replyTargetHandle, long timeout, out int handleIndex) public KernelResult ReplyAndReceive(out int handleIndex, ReadOnlySpan<int> handles, int replyTargetHandle, long timeout)
{ {
handleIndex = 0; handleIndex = 0;
@ -577,13 +577,13 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
} }
public KernelResult ReplyAndReceiveWithUserBuffer( public KernelResult ReplyAndReceiveWithUserBuffer(
out int handleIndex,
ulong handlesPtr, ulong handlesPtr,
ulong messagePtr, ulong messagePtr,
ulong messageSize, ulong messageSize,
int handlesCount, int handlesCount,
int replyTargetHandle, int replyTargetHandle,
long timeout, long timeout)
out int handleIndex)
{ {
handleIndex = 0; handleIndex = 0;
@ -615,7 +615,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
int[] handles = new int[handlesCount]; int[] handles = new int[handlesCount];
if (!KernelTransfer.UserToKernelInt32Array(_context, handlesPtr, handles)) if (!KernelTransfer.UserToKernelArray<int>(handlesPtr, handles))
{ {
currentProcess.MemoryManager.UnborrowIpcBuffer(messagePtr, messageSize); currentProcess.MemoryManager.UnborrowIpcBuffer(messagePtr, messageSize);
@ -681,11 +681,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
} }
public KernelResult CreatePort( public KernelResult CreatePort(
out int serverPortHandle,
out int clientPortHandle,
int maxSessions, int maxSessions,
bool isLight, bool isLight,
ulong namePtr, ulong namePtr)
out int serverPortHandle,
out int clientPortHandle)
{ {
serverPortHandle = clientPortHandle = 0; serverPortHandle = clientPortHandle = 0;
@ -715,11 +715,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return result; return result;
} }
public KernelResult ManageNamedPort(ulong namePtr, int maxSessions, out int handle) public KernelResult ManageNamedPort(out int handle, ulong namePtr, int maxSessions)
{ {
handle = 0; handle = 0;
if (!KernelTransfer.UserToKernelString(_context, namePtr, 12, out string name)) if (!KernelTransfer.UserToKernelString(out string name, namePtr, 12))
{ {
return KernelResult.UserCopyFailed; return KernelResult.UserCopyFailed;
} }
@ -729,10 +729,10 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return KernelResult.MaximumExceeded; 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; handle = 0;
@ -767,7 +767,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return result; return result;
} }
public KernelResult ConnectToPort(int clientPortHandle, out int clientSessionHandle) public KernelResult ConnectToPort(out int clientSessionHandle, int clientPortHandle)
{ {
clientSessionHandle = 0; clientSessionHandle = 0;
@ -820,18 +820,18 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
// Memory // Memory
public KernelResult SetHeapSize(ulong size, out ulong position) public KernelResult SetHeapSize(out ulong address, ulong size)
{ {
if ((size & 0xfffffffe001fffff) != 0) if ((size & 0xfffffffe001fffff) != 0)
{ {
position = 0; address = 0;
return KernelResult.InvalidSize; return KernelResult.InvalidSize;
} }
KProcess process = KernelStatic.GetCurrentProcess(); 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) public KernelResult SetMemoryPermission(ulong address, ulong size, KMemoryPermission permission)
@ -867,12 +867,12 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
} }
public KernelResult SetMemoryAttribute( public KernelResult SetMemoryAttribute(
ulong position, ulong address,
ulong size, ulong size,
MemoryAttribute attributeMask, MemoryAttribute attributeMask,
MemoryAttribute attributeValue) MemoryAttribute attributeValue)
{ {
if (!PageAligned(position)) if (!PageAligned(address))
{ {
return KernelResult.InvalidAddress; return KernelResult.InvalidAddress;
} }
@ -892,13 +892,13 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
KProcess process = KernelStatic.GetCurrentProcess(); KProcess process = KernelStatic.GetCurrentProcess();
if (!process.MemoryManager.InsideAddrSpace(position, size)) if (!process.MemoryManager.InsideAddrSpace(address, size))
{ {
return KernelResult.InvalidMemState; return KernelResult.InvalidMemState;
} }
KernelResult result = process.MemoryManager.SetMemoryAttribute( KernelResult result = process.MemoryManager.SetMemoryAttribute(
position, address,
size, size,
attributeMask, attributeMask,
attributeValue); attributeValue);
@ -978,20 +978,34 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return process.MemoryManager.Unmap(dst, src, size); 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(); KProcess process = KernelStatic.GetCurrentProcess();
KMemoryInfo blkInfo = process.MemoryManager.QueryMemory(position); KMemoryInfo blockInfo = process.MemoryManager.QueryMemory(address);
process.CpuMemory.Write(infoPtr + 0x00, blkInfo.Address); info = new MemoryInfo(
process.CpuMemory.Write(infoPtr + 0x08, blkInfo.Size); blockInfo.Address,
process.CpuMemory.Write(infoPtr + 0x10, (int)blkInfo.State & 0xff); blockInfo.Size,
process.CpuMemory.Write(infoPtr + 0x14, (int)blkInfo.Attribute); blockInfo.State & MemoryState.UserMask,
process.CpuMemory.Write(infoPtr + 0x18, (int)blkInfo.Permission); blockInfo.Attribute,
process.CpuMemory.Write(infoPtr + 0x1c, blkInfo.IpcRefCount); blockInfo.Permission & KMemoryPermission.UserMask,
process.CpuMemory.Write(infoPtr + 0x20, blkInfo.DeviceRefCount); blockInfo.IpcRefCount,
process.CpuMemory.Write(infoPtr + 0x24, 0); blockInfo.DeviceRefCount);
pageInfo = 0; pageInfo = 0;
@ -1084,7 +1098,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
currentProcess); 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; handle = 0;
@ -1414,9 +1428,9 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return targetProcess.MemoryManager.SetProcessMemoryPermission(src, size, permission); 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 // System
@ -1575,7 +1589,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
Logger.Warning?.Print(LogClass.KernelSvc, str); 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; value = 0;
@ -1621,30 +1635,30 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
case InfoType.CoreMask: value = process.Capabilities.AllowedCpuCoresMask; break; case InfoType.CoreMask: value = process.Capabilities.AllowedCpuCoresMask; break;
case InfoType.PriorityMask: value = process.Capabilities.AllowedThreadPriosMask; 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: case InfoType.AliasRegionSize:
value = (long)(process.MemoryManager.AliasRegionEnd - value = (process.MemoryManager.AliasRegionEnd -
process.MemoryManager.AliasRegionStart); break; process.MemoryManager.AliasRegionStart); break;
case InfoType.HeapRegionAddress: value = (long)process.MemoryManager.HeapRegionStart; break; case InfoType.HeapRegionAddress: value = process.MemoryManager.HeapRegionStart; break;
case InfoType.HeapRegionSize: case InfoType.HeapRegionSize:
value = (long)(process.MemoryManager.HeapRegionEnd - value = (process.MemoryManager.HeapRegionEnd -
process.MemoryManager.HeapRegionStart); break; 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: case InfoType.StackRegionSize:
value = (long)(process.MemoryManager.StackRegionEnd - value = (process.MemoryManager.StackRegionEnd -
process.MemoryManager.StackRegionStart); break; 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: case InfoType.SystemResourceSizeUsed:
if (process.PersonalMmHeapPagesCount != 0) if (process.PersonalMmHeapPagesCount != 0)
@ -1654,20 +1668,21 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
break; 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: case InfoType.FreeThreadCount:
if (process.ResourceLimit != null) 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 else
{ {
@ -1692,7 +1707,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return KernelResult.InvalidCombination; return KernelResult.InvalidCombination;
} }
value = KernelStatic.GetCurrentProcess().Debug ? 1 : 0; value = KernelStatic.GetCurrentProcess().Debug ? 1UL : 0UL;
break; break;
} }
@ -1743,7 +1758,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return KernelResult.InvalidCombination; return KernelResult.InvalidCombination;
} }
value = KTimeManager.ConvertHostTicksToTicks(_context.Schedulers[currentCore].TotalIdleTimeTicks); value = (ulong)KTimeManager.ConvertHostTicksToTicks(_context.Schedulers[currentCore].TotalIdleTimeTicks);
break; break;
} }
@ -1796,7 +1811,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
if (subId != -1) if (subId != -1)
{ {
value = KTimeManager.ConvertHostTicksToTicks(timeDelta); value = (ulong)KTimeManager.ConvertHostTicksToTicks(timeDelta);
} }
else else
{ {
@ -1807,7 +1822,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
totalTimeRunning += timeDelta; totalTimeRunning += timeDelta;
} }
value = KTimeManager.ConvertHostTicksToTicks(totalTimeRunning); value = (ulong)KTimeManager.ConvertHostTicksToTicks(totalTimeRunning);
} }
break; break;
@ -1844,7 +1859,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return result; return result;
} }
public KernelResult GetProcessList(ulong address, int maxCount, out int count) public KernelResult GetProcessList(out int count, ulong address, int maxCount)
{ {
count = 0; count = 0;
@ -1878,7 +1893,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
{ {
if (copyCount < maxCount) 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; return KernelResult.UserCopyFailed;
} }
@ -1893,7 +1908,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return KernelResult.Success; 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; value = 0;
@ -1949,7 +1964,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return KernelResult.Success; 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; limitValue = 0;
@ -1970,7 +1985,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return KernelResult.Success; 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; limitValue = 0;
@ -1991,7 +2006,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return KernelResult.Success; 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; peak = 0;
@ -2041,12 +2056,12 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
// Thread // Thread
public KernelResult CreateThread( public KernelResult CreateThread(
out int handle,
ulong entrypoint, ulong entrypoint,
ulong argsPtr, ulong argsPtr,
ulong stackTop, ulong stackTop,
int priority, int priority,
int cpuCore, int cpuCore)
out int handle)
{ {
handle = 0; 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(); KProcess process = KernelStatic.GetCurrentProcess();
@ -2190,7 +2205,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return KernelResult.Success; 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(); 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(); KProcess currentProcess = KernelStatic.GetCurrentProcess();
@ -2220,7 +2235,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
{ {
preferredCore = currentProcess.DefaultCpuCore; preferredCore = currentProcess.DefaultCpuCore;
affinityMask = 1 << preferredCore; affinityMask = 1UL << preferredCore;
} }
else else
{ {
@ -2242,7 +2257,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return KernelResult.InvalidCpuCore; return KernelResult.InvalidCpuCore;
} }
} }
else if ((affinityMask & (1 << preferredCore)) == 0) else if ((affinityMask & (1UL << preferredCore)) == 0)
{ {
return KernelResult.InvalidCombination; return KernelResult.InvalidCombination;
} }
@ -2265,7 +2280,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return KernelStatic.GetCurrentThread().CurrentCore; return KernelStatic.GetCurrentThread().CurrentCore;
} }
public KernelResult GetThreadId(int handle, out long threadUid) public KernelResult GetThreadId(out long threadUid, int handle)
{ {
KProcess process = KernelStatic.GetCurrentProcess(); KProcess process = KernelStatic.GetCurrentProcess();
@ -2331,96 +2346,21 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return KernelResult.InvalidThread; return KernelResult.InvalidThread;
} }
IVirtualMemoryManager memory = currentProcess.CpuMemory; KernelResult result = thread.GetThreadContext3(out ThreadContext context);
memory.Write(address + 0x0, thread.Context.GetX(0)); if (result == KernelResult.Success)
memory.Write(address + 0x8, thread.Context.GetX(1)); {
memory.Write(address + 0x10, thread.Context.GetX(2)); return KernelTransfer.KernelToUser(address, context)
memory.Write(address + 0x18, thread.Context.GetX(3)); ? KernelResult.Success
memory.Write(address + 0x20, thread.Context.GetX(4)); : KernelResult.InvalidMemState;
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));
memory.Write(address + 0x100, thread.LastPc); return result;
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);
} }
// Thread synchronization // 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; handleIndex = 0;
@ -2456,7 +2396,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
Span<int> handles = new Span<int>(currentThread.WaitSyncHandles).Slice(0, handlesCount); Span<int> handles = new Span<int>(currentThread.WaitSyncHandles).Slice(0, handlesCount);
if (!KernelTransfer.UserToKernelInt32Array(_context, handlesPtr, handles)) if (!KernelTransfer.UserToKernelArray(handlesPtr, handles))
{ {
return KernelResult.UserCopyFailed; return KernelResult.UserCopyFailed;
} }

View File

@ -17,7 +17,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
public KernelResult ConnectToNamedPort32([R(1)] uint namePtr, [R(1)] out int handle) 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) public KernelResult SendSyncRequest32([R(0)] int handle)
@ -36,17 +36,17 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
[R(1)] out int serverSessionHandle, [R(1)] out int serverSessionHandle,
[R(2)] out int clientSessionHandle) [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) 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( public KernelResult ReplyAndReceive32(
[R(0)] uint timeoutLow, [R(0)] uint timeoutLow,
[R(1)] ulong handlesPtr, [R(1)] uint handlesPtr,
[R(2)] int handlesCount, [R(2)] int handlesCount,
[R(3)] int replyTargetHandle, [R(3)] int replyTargetHandle,
[R(4)] uint timeoutHigh, [R(4)] uint timeoutHigh,
@ -54,7 +54,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
{ {
long timeout = (long)(timeoutLow | ((ulong)timeoutHigh << 32)); 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( public KernelResult CreatePort32(
@ -64,45 +64,45 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
[R(1)] out int serverPortHandle, [R(1)] out int serverPortHandle,
[R(2)] out int clientPortHandle) [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) 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) 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 // 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; return result;
} }
public KernelResult SetMemoryPermission32( public KernelResult SetMemoryPermission32(
[R(0)] ulong position, [R(0)] uint address,
[R(1)] ulong size, [R(1)] uint size,
[R(2)] KMemoryPermission permission) [R(2)] KMemoryPermission permission)
{ {
return _syscall.SetMemoryPermission(position, size, permission); return _syscall.SetMemoryPermission(address, size, permission);
} }
public KernelResult SetMemoryAttribute32( public KernelResult SetMemoryAttribute32(
[R(0)] uint position, [R(0)] uint address,
[R(1)] uint size, [R(1)] uint size,
[R(2)] MemoryAttribute attributeMask, [R(2)] MemoryAttribute attributeMask,
[R(3)] MemoryAttribute attributeValue) [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) 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); 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; pageInfo = (uint)pageInfo64;
@ -140,7 +140,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
[R(3)] KMemoryPermission permission, [R(3)] KMemoryPermission permission,
[R(1)] out int handle) [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) 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) 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); pidLow = (int)(pid & uint.MaxValue);
pidHigh = (int)(pid >> 32); pidHigh = (int)(pid >> 32);
@ -265,7 +265,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
{ {
long subId = (long)(subIdLow | ((ulong)subIdHigh << 32)); 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); valueHigh = (uint)(value >> 32);
valueLow = (uint)(value & uint.MaxValue); 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) 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) 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)); 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); valueHigh = (int)(value >> 32);
valueLow = (int)(value & uint.MaxValue); 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) 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); limitValueHigh = (int)(limitValue >> 32);
limitValueLow = (int)(limitValue & uint.MaxValue); 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) 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); limitValueHigh = (int)(limitValue >> 32);
limitValueLow = (int)(limitValue & uint.MaxValue); 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) 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); peakHigh = (int)(peak >> 32);
peakLow = (int)(peak & uint.MaxValue); peakLow = (int)(peak & uint.MaxValue);
@ -359,7 +359,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
[R(4)] int cpuCore, [R(4)] int cpuCore,
[R(1)] out int handle) [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) 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) 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) 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); 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); affinityMaskLow = (uint)(affinityMask & uint.MaxValue);
affinityMaskHigh = (int)(affinityMask >> 32); affinityMaskHigh = (uint)(affinityMask >> 32);
return result; return result;
} }
public KernelResult SetThreadCoreMask32([R(0)] int handle, [R(1)] int preferredCore, [R(2)] uint affinityMaskLow, [R(3)] uint affinityMaskHigh) 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); return _syscall.SetThreadCoreMask(handle, preferredCore, affinityMask);
} }
@ -415,7 +415,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
{ {
long threadUid; long threadUid;
KernelResult result = _syscall.GetThreadId(handle, out threadUid); KernelResult result = _syscall.GetThreadId(out threadUid, handle);
threadUidLow = (uint)(threadUid >> 32); threadUidLow = (uint)(threadUid >> 32);
threadUidHigh = (uint)(threadUid & uint.MaxValue); threadUidHigh = (uint)(threadUid & uint.MaxValue);
@ -444,7 +444,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
{ {
long timeout = (long)(timeoutLow | ((ulong)timeoutHigh << 32)); 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) public KernelResult CancelSynchronization32([R(0)] int handle)

View File

@ -17,7 +17,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
public KernelResult ConnectToNamedPort64([R(1)] ulong namePtr, [R(1)] out int handle) 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) public KernelResult SendSyncRequest64([R(0)] int handle)
@ -36,7 +36,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
[R(3)] int handle, [R(3)] int handle,
[R(1)] out int doneEventHandle) [R(1)] out int doneEventHandle)
{ {
return _syscall.SendAsyncRequestWithUserBuffer(messagePtr, messageSize, handle, out doneEventHandle); return _syscall.SendAsyncRequestWithUserBuffer(out doneEventHandle, messagePtr, messageSize, handle);
} }
public KernelResult CreateSession64( public KernelResult CreateSession64(
@ -45,12 +45,12 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
[R(1)] out int serverSessionHandle, [R(1)] out int serverSessionHandle,
[R(2)] out int clientSessionHandle) [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) 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( public KernelResult ReplyAndReceive64(
@ -60,7 +60,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
[R(4)] long timeout, [R(4)] long timeout,
[R(1)] out int handleIndex) [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( public KernelResult ReplyAndReceiveWithUserBuffer64(
@ -73,13 +73,13 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
[R(1)] out int handleIndex) [R(1)] out int handleIndex)
{ {
return _syscall.ReplyAndReceiveWithUserBuffer( return _syscall.ReplyAndReceiveWithUserBuffer(
out handleIndex,
handlesPtr, handlesPtr,
messagePtr, messagePtr,
messageSize, messageSize,
handlesCount, handlesCount,
replyTargetHandle, replyTargetHandle,
timeout, timeout);
out handleIndex);
} }
public KernelResult CreatePort64( public KernelResult CreatePort64(
@ -89,41 +89,41 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
[R(1)] out int serverPortHandle, [R(1)] out int serverPortHandle,
[R(2)] out int clientPortHandle) [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) 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) 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 // 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( public KernelResult SetMemoryPermission64(
[R(0)] ulong position, [R(0)] ulong address,
[R(1)] ulong size, [R(1)] ulong size,
[R(2)] KMemoryPermission permission) [R(2)] KMemoryPermission permission)
{ {
return _syscall.SetMemoryPermission(position, size, permission); return _syscall.SetMemoryPermission(address, size, permission);
} }
public KernelResult SetMemoryAttribute64( public KernelResult SetMemoryAttribute64(
[R(0)] ulong position, [R(0)] ulong address,
[R(1)] ulong size, [R(1)] ulong size,
[R(2)] MemoryAttribute attributeMask, [R(2)] MemoryAttribute attributeMask,
[R(3)] MemoryAttribute attributeValue) [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) 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); 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) 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(3)] KMemoryPermission permission,
[R(1)] out int handle) [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) 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) 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) 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); _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) 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) 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) 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) 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) 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) 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) public KernelResult CreateResourceLimit64([R(1)] out int handle)
@ -302,7 +302,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
[R(5)] int cpuCore, [R(5)] int cpuCore,
[R(1)] out int handle) [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) 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) 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) 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); 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); 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) 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) 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) 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) public KernelResult CancelSynchronization64([R(0)] int handle)

View File

@ -0,0 +1,22 @@
using ARMeilleure.State;
using Ryujinx.Common.Memory;
namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
{
struct ThreadContext
{
public Array29<ulong> 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<V128> FpuRegisters;
public uint Fpcr;
public uint Fpsr;
public ulong Tpidr;
}
}

View File

@ -35,7 +35,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
KProcess currentProcess = KernelStatic.GetCurrentProcess(); KProcess currentProcess = KernelStatic.GetCurrentProcess();
if (!KernelTransfer.UserToKernelInt32(_context, mutexAddress, out int mutexValue)) if (!KernelTransfer.UserToKernel(out int mutexValue, mutexAddress))
{ {
_context.CriticalSection.Leave(); _context.CriticalSection.Leave();
@ -88,7 +88,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
KernelResult result = KernelResult.Success; KernelResult result = KernelResult.Success;
if (!KernelTransfer.KernelToUserInt32(_context, mutexAddress, mutexValue)) if (!KernelTransfer.KernelToUser(mutexAddress, mutexValue))
{ {
result = KernelResult.InvalidMemState; result = KernelResult.InvalidMemState;
} }
@ -123,9 +123,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
(int mutexValue, _) = MutexUnlock(currentThread, mutexAddress); (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(); _context.CriticalSection.Leave();
@ -201,7 +201,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
if (!_condVarThreads.Any(x => x.CondVarAddress == address)) if (!_condVarThreads.Any(x => x.CondVarAddress == address))
{ {
KernelTransfer.KernelToUserInt32(_context, address, 0); KernelTransfer.KernelToUser(address, 0);
} }
_context.CriticalSection.Leave(); _context.CriticalSection.Leave();
@ -290,7 +290,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
currentThread.SignaledObj = null; currentThread.SignaledObj = null;
currentThread.ObjSyncResult = KernelResult.TimedOut; currentThread.ObjSyncResult = KernelResult.TimedOut;
if (!KernelTransfer.UserToKernelInt32(_context, address, out int currentValue)) if (!KernelTransfer.UserToKernel(out int currentValue, address))
{ {
_context.CriticalSection.Leave(); _context.CriticalSection.Leave();
@ -363,7 +363,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
KProcess currentProcess = KernelStatic.GetCurrentProcess(); KProcess currentProcess = KernelStatic.GetCurrentProcess();
if (!KernelTransfer.UserToKernelInt32(_context, address, out int currentValue)) if (!KernelTransfer.UserToKernel(out int currentValue, address))
{ {
_context.CriticalSection.Leave(); _context.CriticalSection.Leave();

View File

@ -2,6 +2,7 @@ using Ryujinx.Common.Logging;
using Ryujinx.Cpu; using Ryujinx.Cpu;
using Ryujinx.HLE.HOS.Kernel.Common; using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Process; using Ryujinx.HLE.HOS.Kernel.Process;
using Ryujinx.HLE.HOS.Kernel.SupervisorCall;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Numerics; using System.Numerics;
@ -27,7 +28,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
public KThreadContext ThreadContext { get; private set; } public KThreadContext ThreadContext { get; private set; }
public int DynamicPriority { get; set; } public int DynamicPriority { get; set; }
public long AffinityMask { get; set; } public ulong AffinityMask { get; set; }
public long ThreadUid { get; private set; } public long ThreadUid { get; private set; }
@ -88,7 +89,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
public bool IsPinned { get; private set; } public bool IsPinned { get; private set; }
private long _originalAffinityMask; private ulong _originalAffinityMask;
private int _originalPreferredCore; private int _originalPreferredCore;
private int _originalBasePriority; private int _originalBasePriority;
private int _coreMigrationDisableCount; private int _coreMigrationDisableCount;
@ -147,7 +148,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
ThreadContext = new KThreadContext(); ThreadContext = new KThreadContext();
PreferredCore = cpuCore; PreferredCore = cpuCore;
AffinityMask |= 1L << cpuCore; AffinityMask |= 1UL << cpuCore;
SchedFlags = type == ThreadType.Dummy SchedFlags = type == ThreadType.Dummy
? ThreadSchedState.Running ? 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() public void CancelSynchronization()
{ {
KernelContext.CriticalSection.Enter(); KernelContext.CriticalSection.Enter();
@ -660,7 +744,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
KernelContext.CriticalSection.Leave(); KernelContext.CriticalSection.Leave();
} }
public KernelResult SetCoreAndAffinityMask(int newCore, long newAffinityMask) public KernelResult SetCoreAndAffinityMask(int newCore, ulong newAffinityMask)
{ {
lock (ActivityOperationLock) lock (ActivityOperationLock)
{ {
@ -673,7 +757,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
{ {
newCore = isCoreMigrationDisabled ? _originalPreferredCore : PreferredCore; newCore = isCoreMigrationDisabled ? _originalPreferredCore : PreferredCore;
if ((newAffinityMask & (1 << newCore)) == 0) if ((newAffinityMask & (1UL << newCore)) == 0)
{ {
KernelContext.CriticalSection.Leave(); KernelContext.CriticalSection.Leave();
@ -688,7 +772,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
} }
else else
{ {
long oldAffinityMask = AffinityMask; ulong oldAffinityMask = AffinityMask;
PreferredCore = newCore; PreferredCore = newCore;
AffinityMask = newAffinityMask; AffinityMask = newAffinityMask;
@ -701,7 +785,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
{ {
if (PreferredCore < 0) if (PreferredCore < 0)
{ {
ActiveCore = sizeof(ulong) * 8 - 1 - BitOperations.LeadingZeroCount((ulong)AffinityMask); ActiveCore = sizeof(ulong) * 8 - 1 - BitOperations.LeadingZeroCount(AffinityMask);
} }
else else
{ {
@ -733,7 +817,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
int coreNumber = GetEffectiveRunningCore(); int coreNumber = GetEffectiveRunningCore();
bool isPinnedThreadCurrentlyRunning = coreNumber >= 0; bool isPinnedThreadCurrentlyRunning = coreNumber >= 0;
if (isPinnedThreadCurrentlyRunning && ((1 << coreNumber) & AffinityMask) == 0) if (isPinnedThreadCurrentlyRunning && ((1UL << coreNumber) & AffinityMask) == 0)
{ {
if (IsPinned) if (IsPinned)
{ {
@ -1077,7 +1161,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
KernelContext.ThreadReselectionRequested = true; 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) if (SchedFlags != ThreadSchedState.Running || DynamicPriority >= KScheduler.PrioritiesCount || !IsSchedulable)
{ {
@ -1259,7 +1343,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
ActiveCore = CurrentCore; ActiveCore = CurrentCore;
PreferredCore = CurrentCore; PreferredCore = CurrentCore;
AffinityMask = 1 << CurrentCore; AffinityMask = 1UL << CurrentCore;
if (activeCore != CurrentCore || _originalAffinityMask != AffinityMask) if (activeCore != CurrentCore || _originalAffinityMask != AffinityMask)
{ {
@ -1282,7 +1366,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
IsPinned = false; IsPinned = false;
_coreMigrationDisableCount--; _coreMigrationDisableCount--;
long affinityMask = AffinityMask; ulong affinityMask = AffinityMask;
int activeCore = ActiveCore; int activeCore = ActiveCore;
PreferredCore = _originalPreferredCore; PreferredCore = _originalPreferredCore;
@ -1290,7 +1374,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
if (AffinityMask != affinityMask) if (AffinityMask != affinityMask)
{ {
if ((AffinityMask & 1 << ActiveCore) != 0) if ((AffinityMask & 1UL << ActiveCore) != 0)
{ {
if (PreferredCore >= 0) if (PreferredCore >= 0)
{ {

View File

@ -210,7 +210,7 @@ namespace Ryujinx.HLE.HOS.Services
} }
else 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); obj.Server.AddSessionObj(serverSessionHandle, obj);

View File

@ -323,7 +323,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv
_clientMemory = context.Process.HandleTable.GetKProcess(clientHandle).CpuMemory; _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); context.ResponseData.Write((uint)NvResult.Success);

View File

@ -87,7 +87,7 @@ namespace Ryujinx.HLE.HOS.Services
if (SmObjectFactory != null) if (SmObjectFactory != null)
{ {
_context.Syscall.ManageNamedPort("sm:", 50, out int serverPortHandle); _context.Syscall.ManageNamedPort(out int serverPortHandle, "sm:", 50);
AddPort(serverPortHandle, SmObjectFactory); AddPort(serverPortHandle, SmObjectFactory);
} }
@ -96,7 +96,7 @@ namespace Ryujinx.HLE.HOS.Services
KThread thread = KernelStatic.GetCurrentThread(); KThread thread = KernelStatic.GetCurrentThread();
ulong messagePtr = thread.TlsAddress; 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 + 0x0, 0);
_selfProcess.CpuMemory.Write(messagePtr + 0x4, 2 << 10); _selfProcess.CpuMemory.Write(messagePtr + 0x4, 2 << 10);
@ -114,7 +114,7 @@ namespace Ryujinx.HLE.HOS.Services
sessionHandles.CopyTo(handles, portHandles.Length); sessionHandles.CopyTo(handles, portHandles.Length);
// We still need a timeout here to allow the service to pick up and listen new sessions... // 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(); thread.HandlePostSyscall();
@ -140,7 +140,7 @@ namespace Ryujinx.HLE.HOS.Services
if (rc == KernelResult.Success) if (rc == KernelResult.Success)
{ {
// We got a new connection, accept the session to allow servicing future requests. // 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(); IpcService obj = _ports[handles[signaledIndex]].Invoke();
@ -247,7 +247,7 @@ namespace Ryujinx.HLE.HOS.Services
case 4: case 4:
int unknown = reqReader.ReadInt32(); 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]); AddSessionObj(dupServerSessionHandle, _sessions[serverSessionHandle]);