Update to thog's latest SVC work
This commit is contained in:
commit
931a0dd0b9
6 changed files with 241 additions and 28 deletions
|
@ -101,6 +101,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return SendSyncRequest(messagePtr, size, handle);
|
||||
}
|
||||
|
||||
public KernelResult SendSyncRequestWithUserBuffer32([R(0)] uint messagePtr, [R(1)] uint size, [R(2)] int handle)
|
||||
{
|
||||
return SendSyncRequest(messagePtr, size, handle);
|
||||
}
|
||||
|
||||
private KernelResult SendSyncRequest(ulong messagePtr, ulong size, int handle)
|
||||
{
|
||||
byte[] messageData = _process.CpuMemory.ReadBytes((long)messagePtr, (long)size);
|
||||
|
@ -186,6 +191,15 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return CreateSession(isLight, namePtr, out serverSessionHandle, out clientSessionHandle);
|
||||
}
|
||||
|
||||
public KernelResult CreateSession32(
|
||||
[R(2)] bool isLight,
|
||||
[R(3)] uint namePtr,
|
||||
[R(1)] out int serverSessionHandle,
|
||||
[R(2)] out int clientSessionHandle)
|
||||
{
|
||||
return CreateSession(isLight, namePtr, out serverSessionHandle, out clientSessionHandle);
|
||||
}
|
||||
|
||||
private KernelResult CreateSession(
|
||||
bool isLight,
|
||||
ulong namePtr,
|
||||
|
@ -257,6 +271,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return AcceptSession(portHandle, out sessionHandle);
|
||||
}
|
||||
|
||||
public KernelResult AcceptSession32([R(1)] int portHandle, [R(1)] out int sessionHandle)
|
||||
{
|
||||
return AcceptSession(portHandle, out sessionHandle);
|
||||
}
|
||||
|
||||
private KernelResult AcceptSession(int portHandle, out int sessionHandle)
|
||||
{
|
||||
sessionHandle = 0;
|
||||
|
@ -314,6 +333,29 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
[R(3)] int replyTargetHandle,
|
||||
[R(4)] long timeout,
|
||||
[R(1)] out int handleIndex)
|
||||
{
|
||||
return ReplyAndReceive(handlesPtr, handlesCount, replyTargetHandle, timeout, out handleIndex);
|
||||
}
|
||||
|
||||
public KernelResult ReplyAndReceive32(
|
||||
[R(0)] uint timeoutLow,
|
||||
[R(1)] ulong handlesPtr,
|
||||
[R(2)] int handlesCount,
|
||||
[R(3)] int replyTargetHandle,
|
||||
[R(4)] uint timeoutHigh,
|
||||
[R(1)] out int handleIndex)
|
||||
{
|
||||
long timeout = (long)(timeoutLow | ((ulong)timeoutHigh << 32));
|
||||
|
||||
return ReplyAndReceive(handlesPtr, handlesCount, replyTargetHandle, timeout, out handleIndex);
|
||||
}
|
||||
|
||||
public KernelResult ReplyAndReceive(
|
||||
ulong handlesPtr,
|
||||
int handlesCount,
|
||||
int replyTargetHandle,
|
||||
long timeout,
|
||||
out int handleIndex)
|
||||
{
|
||||
handleIndex = 0;
|
||||
|
||||
|
@ -404,6 +446,16 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return CreatePort(maxSessions, isLight, namePtr, out serverPortHandle, out clientPortHandle);
|
||||
}
|
||||
|
||||
public KernelResult CreatePort32(
|
||||
[R(0)] uint namePtr,
|
||||
[R(2)] int maxSessions,
|
||||
[R(3)] bool isLight,
|
||||
[R(1)] out int serverPortHandle,
|
||||
[R(2)] out int clientPortHandle)
|
||||
{
|
||||
return CreatePort(maxSessions, isLight, namePtr, out serverPortHandle, out clientPortHandle);
|
||||
}
|
||||
|
||||
private KernelResult CreatePort(
|
||||
int maxSessions,
|
||||
bool isLight,
|
||||
|
@ -444,6 +496,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return ManageNamedPort(namePtr, maxSessions, out handle);
|
||||
}
|
||||
|
||||
public KernelResult ManageNamedPort32([R(1)] uint namePtr, [R(2)] int maxSessions, [R(1)] out int handle)
|
||||
{
|
||||
return ManageNamedPort(namePtr, maxSessions, out handle);
|
||||
}
|
||||
|
||||
private KernelResult ManageNamedPort(ulong namePtr, int maxSessions, out int handle)
|
||||
{
|
||||
handle = 0;
|
||||
|
@ -489,6 +546,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return ConnectToPort(clientPortHandle, out clientSessionHandle);
|
||||
}
|
||||
|
||||
public KernelResult ConnectToPort32([R(1)] int clientPortHandle, [R(1)] out int clientSessionHandle)
|
||||
{
|
||||
return ConnectToPort(clientPortHandle, out clientSessionHandle);
|
||||
}
|
||||
|
||||
private KernelResult ConnectToPort(int clientPortHandle, out int clientSessionHandle)
|
||||
{
|
||||
clientSessionHandle = 0;
|
||||
|
|
|
@ -180,9 +180,10 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
|
||||
public KernelResult QueryMemory32([R(0)] uint infoPtr, [R(1)] uint r1, [R(2)] uint position, [R(1)] out uint pageInfo)
|
||||
{
|
||||
// FIXME: Nintendo here bzero the pointer info structure and then copy every element one by one if QueryMemory succeed.
|
||||
KernelResult result = QueryMemory(infoPtr, position, out ulong pageInfo64);
|
||||
|
||||
pageInfo = (uint)pageInfo64;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -369,6 +370,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return MapPhysicalMemory(address, size);
|
||||
}
|
||||
|
||||
public KernelResult MapPhysicalMemory32([R(0)] uint address, [R(1)] uint size)
|
||||
{
|
||||
return MapPhysicalMemory(address, size);
|
||||
}
|
||||
|
||||
private KernelResult MapPhysicalMemory(ulong address, ulong size)
|
||||
{
|
||||
if (!PageAligned(address))
|
||||
|
@ -407,6 +413,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return UnmapPhysicalMemory(address, size);
|
||||
}
|
||||
|
||||
public KernelResult UnmapPhysicalMemory32([R(0)] uint address, [R(1)] uint size)
|
||||
{
|
||||
return UnmapPhysicalMemory(address, size);
|
||||
}
|
||||
|
||||
private KernelResult UnmapPhysicalMemory(ulong address, ulong size)
|
||||
{
|
||||
if (!PageAligned(address))
|
||||
|
@ -445,6 +456,15 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return MapProcessCodeMemory(handle, dst, src, size);
|
||||
}
|
||||
|
||||
public KernelResult MapProcessCodeMemory32([R(0)] int handle, [R(1)] uint srcLow, [R(2)] uint dstLow, [R(3)] uint dstHigh, [R(4)] uint srcHigh, [R(5)] uint sizeLow, [R(6)] uint sizeHigh)
|
||||
{
|
||||
ulong src = (srcLow | ((ulong)srcHigh << 32));
|
||||
ulong dst = (dstLow | ((ulong)dstHigh << 32));
|
||||
ulong size = (sizeLow | ((ulong)sizeHigh << 32));
|
||||
|
||||
return MapProcessCodeMemory(handle, dst, src, size);
|
||||
}
|
||||
|
||||
public KernelResult MapProcessCodeMemory(int handle, ulong dst, ulong src, ulong size)
|
||||
{
|
||||
if (!PageAligned(dst) || !PageAligned(src))
|
||||
|
@ -487,6 +507,15 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return UnmapProcessCodeMemory(handle, dst, src, size);
|
||||
}
|
||||
|
||||
public KernelResult UnmapProcessCodeMemory32([R(0)] int handle, [R(1)] uint srcLow, [R(2)] uint dstLow, [R(3)] uint dstHigh, [R(4)] uint srcHigh, [R(5)] uint sizeLow, [R(6)] uint sizeHigh)
|
||||
{
|
||||
ulong src = (srcLow | ((ulong)srcHigh << 32));
|
||||
ulong dst = (dstLow | ((ulong)dstHigh << 32));
|
||||
ulong size = (sizeLow | ((ulong)sizeHigh << 32));
|
||||
|
||||
return UnmapProcessCodeMemory(handle, dst, src, size);
|
||||
}
|
||||
|
||||
public KernelResult UnmapProcessCodeMemory(int handle, ulong dst, ulong src, ulong size)
|
||||
{
|
||||
if (!PageAligned(dst) || !PageAligned(src))
|
||||
|
@ -529,6 +558,20 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return SetProcessMemoryPermission(handle, src, size, permission);
|
||||
}
|
||||
|
||||
public KernelResult SetProcessMemoryPermission32(
|
||||
[R(0)] int handle,
|
||||
[R(1)] uint sizeLow,
|
||||
[R(2)] uint srcLow,
|
||||
[R(3)] uint srcHigh,
|
||||
[R(4)] uint sizeHigh,
|
||||
[R(5)] MemoryPermission permission)
|
||||
{
|
||||
ulong src = (srcLow | ((ulong)srcHigh << 32));
|
||||
ulong size = (sizeLow | ((ulong)sizeHigh << 32));
|
||||
|
||||
return SetProcessMemoryPermission(handle, src, size, permission);
|
||||
}
|
||||
|
||||
public KernelResult SetProcessMemoryPermission(int handle, ulong src, ulong size, MemoryPermission permission)
|
||||
{
|
||||
if (!PageAligned(src))
|
||||
|
|
|
@ -27,6 +27,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return TerminateProcess(handle);
|
||||
}
|
||||
|
||||
public KernelResult TerminateProcess32([R(0)] int handle)
|
||||
{
|
||||
return TerminateProcess(handle);
|
||||
}
|
||||
|
||||
private KernelResult TerminateProcess(int handle)
|
||||
{
|
||||
KProcess process = _process.HandleTable.GetObject<KProcess>(handle);
|
||||
|
@ -64,6 +69,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return SignalEvent(handle);
|
||||
}
|
||||
|
||||
public KernelResult SignalEvent32([R(0)] int handle)
|
||||
{
|
||||
return SignalEvent(handle);
|
||||
}
|
||||
|
||||
private KernelResult SignalEvent(int handle)
|
||||
{
|
||||
KWritableEvent writableEvent = _process.HandleTable.GetObject<KWritableEvent>(handle);
|
||||
|
@ -89,6 +99,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return ClearEvent(handle);
|
||||
}
|
||||
|
||||
public KernelResult ClearEvent32([R(0)] int handle)
|
||||
{
|
||||
return ClearEvent(handle);
|
||||
}
|
||||
|
||||
private KernelResult ClearEvent(int handle)
|
||||
{
|
||||
KernelResult result;
|
||||
|
@ -188,11 +203,29 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return _system.Scheduler.GetCurrentThread().Context.CntpctEl0;
|
||||
}
|
||||
|
||||
public void GetSystemTick32([R(0)] out uint resultLow, [R(1)] out uint resultHigh)
|
||||
{
|
||||
ulong result = _system.Scheduler.GetCurrentThread().Context.CntpctEl0;
|
||||
|
||||
resultLow = (uint)(result & uint.MaxValue);
|
||||
resultHigh = (uint)(result >> 32);
|
||||
}
|
||||
|
||||
public KernelResult GetProcessId64([R(1)] int handle, [R(1)] out long pid)
|
||||
{
|
||||
return GetProcessId(handle, out pid);
|
||||
}
|
||||
|
||||
public KernelResult GetProcessId32([R(1)] int handle, [R(1)] out int pidLow, [R(2)] out int pidHigh)
|
||||
{
|
||||
KernelResult result = GetProcessId(handle, out long pid);
|
||||
|
||||
pidLow = (int)(pid & uint.MaxValue);
|
||||
pidHigh = (int)(pid >> 32);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private KernelResult GetProcessId(int handle, out long pid)
|
||||
{
|
||||
KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
|
||||
|
@ -278,20 +311,18 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
}
|
||||
|
||||
public KernelResult GetInfo32(
|
||||
[R(0)] uint subIdLow,
|
||||
[R(1)] uint id,
|
||||
[R(2)] int handle,
|
||||
[R(3)] uint subIdHigh,
|
||||
[R(0)] uint subIdLow,
|
||||
[R(1)] uint id,
|
||||
[R(2)] int handle,
|
||||
[R(3)] uint subIdHigh,
|
||||
[R(1)] out uint valueLow,
|
||||
[R(2)] out uint valueHigh)
|
||||
{
|
||||
long value;
|
||||
|
||||
long subId = (long)(subIdLow | ((ulong)subIdHigh << 32));
|
||||
|
||||
KernelResult result = GetInfo(id, handle, subId, out value);
|
||||
KernelResult result = GetInfo(id, handle, subId, out long value);
|
||||
valueHigh = (uint)(value >> 32);
|
||||
valueLow = (uint)(value & 0xFFFFFFFF);
|
||||
valueLow = (uint)(value & uint.MaxValue);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -527,6 +558,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return CreateEvent(out wEventHandle, out rEventHandle);
|
||||
}
|
||||
|
||||
public KernelResult CreateEvent32([R(1)] out int wEventHandle, [R(2)] out int rEventHandle)
|
||||
{
|
||||
return CreateEvent(out wEventHandle, out rEventHandle);
|
||||
}
|
||||
|
||||
private KernelResult CreateEvent(out int wEventHandle, out int rEventHandle)
|
||||
{
|
||||
KEvent Event = new KEvent(_system);
|
||||
|
@ -555,6 +591,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return GetProcessList(address, maxCount, out count);
|
||||
}
|
||||
|
||||
public KernelResult GetProcessList32([R(1)] ulong address, [R(2)] int maxCount, [R(1)] out int count)
|
||||
{
|
||||
return GetProcessList(address, maxCount, out count);
|
||||
}
|
||||
|
||||
private KernelResult GetProcessList(ulong address, int maxCount, out int count)
|
||||
{
|
||||
count = 0;
|
||||
|
@ -609,6 +650,18 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return GetSystemInfo(id, handle, subId, out value);
|
||||
}
|
||||
|
||||
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 = GetSystemInfo(id, handle, subId, out long value);
|
||||
|
||||
valueHigh = (int)(value >> 32);
|
||||
valueLow = (int)(value & uint.MaxValue);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private KernelResult GetSystemInfo(uint id, int handle, long subId, out long value)
|
||||
{
|
||||
value = 0;
|
||||
|
@ -672,7 +725,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
[R(1)] uint sizeLow,
|
||||
[R(4)] uint sizeHigh)
|
||||
{
|
||||
//_process.CpuMemory.WriteBytes(addressLow, new byte[sizeLow]);
|
||||
// FIXME: This needs to be implemented as ARMv7 doesn't have any way to do cache maintenance operations on EL0. As we don't support (and don't actually need) to flush the cache, this is stubbed.
|
||||
return KernelResult.Success;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
{
|
||||
private const int SvcFuncMaxArguments64 = 8;
|
||||
private const int SvcFuncMaxArguments32 = 4;
|
||||
private const int SvcMax = 0x80;
|
||||
private const int SvcMax = 0x80;
|
||||
|
||||
public static Action<SvcHandler, ExecutionContext>[] SvcTable32 { get; }
|
||||
public static Action<SvcHandler, ExecutionContext>[] SvcTable64 { get; }
|
||||
|
@ -102,28 +102,51 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
{ 0x0b, nameof(SvcHandler.SleepThread32) },
|
||||
{ 0x0c, nameof(SvcHandler.GetThreadPriority32) },
|
||||
{ 0x0d, nameof(SvcHandler.SetThreadPriority32) },
|
||||
{ 0x0e, nameof(SvcHandler.GetThreadCoreMask32) },
|
||||
{ 0x0f, nameof(SvcHandler.SetThreadCoreMask32) },
|
||||
{ 0x10, nameof(SvcHandler.GetCurrentProcessorNumber32) },
|
||||
{ 0x11, nameof(SvcHandler.SignalEvent32) },
|
||||
{ 0x12, nameof(SvcHandler.ClearEvent32) },
|
||||
{ 0x13, nameof(SvcHandler.MapSharedMemory32) },
|
||||
{ 0x14, nameof(SvcHandler.UnmapSharedMemory32) },
|
||||
{ 0x15, nameof(SvcHandler.CreateTransferMemory32) },
|
||||
{ 0x16, nameof(SvcHandler.CloseHandle32) },
|
||||
{ 0x17, nameof(SvcHandler.ResetSignal32) },
|
||||
{ 0x18, nameof(SvcHandler.WaitSynchronization32) },
|
||||
{ 0x19, nameof(SvcHandler.CancelSynchronization32) },
|
||||
{ 0x1a, nameof(SvcHandler.ArbitrateLock32) },
|
||||
{ 0x1b, nameof(SvcHandler.ArbitrateUnlock32) },
|
||||
{ 0x1c, nameof(SvcHandler.WaitProcessWideKeyAtomic32) },
|
||||
{ 0x1d, nameof(SvcHandler.SignalProcessWideKey32) },
|
||||
{ 0x1e, nameof(SvcHandler.GetSystemTick32) },
|
||||
{ 0x1f, nameof(SvcHandler.ConnectToNamedPort32) },
|
||||
{ 0x21, nameof(SvcHandler.SendSyncRequest32) },
|
||||
{ 0x22, nameof(SvcHandler.SendSyncRequestWithUserBuffer32) },
|
||||
{ 0x24, nameof(SvcHandler.GetProcessId32) },
|
||||
{ 0x25, nameof(SvcHandler.GetThreadId32) },
|
||||
{ 0x26, nameof(SvcHandler.Break32) },
|
||||
{ 0x27, nameof(SvcHandler.OutputDebugString32) },
|
||||
{ 0x29, nameof(SvcHandler.GetInfo32) },
|
||||
{ 0x2c, nameof(SvcHandler.MapPhysicalMemory32) },
|
||||
{ 0x2d, nameof(SvcHandler.UnmapPhysicalMemory32) },
|
||||
{ 0x32, nameof(SvcHandler.SetThreadActivity32) },
|
||||
{ 0x33, nameof(SvcHandler.GetThreadContext332) },
|
||||
{ 0x34, nameof(SvcHandler.WaitForAddress32) },
|
||||
{ 0x35, nameof(SvcHandler.SignalToAddress32) },
|
||||
|
||||
{ 0x5F, nameof(SvcHandler.FlushProcessDataCache32) }
|
||||
{ 0x40, nameof(SvcHandler.CreateSession32) },
|
||||
{ 0x41, nameof(SvcHandler.AcceptSession32) },
|
||||
{ 0x43, nameof(SvcHandler.ReplyAndReceive32) },
|
||||
{ 0x45, nameof(SvcHandler.CreateEvent32) },
|
||||
{ 0x5F, nameof(SvcHandler.FlushProcessDataCache32) },
|
||||
{ 0x65, nameof(SvcHandler.GetProcessList32) },
|
||||
{ 0x6f, nameof(SvcHandler.GetSystemInfo32) },
|
||||
{ 0x70, nameof(SvcHandler.CreatePort32) },
|
||||
{ 0x71, nameof(SvcHandler.ManageNamedPort32) },
|
||||
{ 0x72, nameof(SvcHandler.ConnectToPort32) },
|
||||
{ 0x73, nameof(SvcHandler.SetProcessMemoryPermission32) },
|
||||
{ 0x77, nameof(SvcHandler.MapProcessCodeMemory32) },
|
||||
{ 0x78, nameof(SvcHandler.UnmapProcessCodeMemory32) },
|
||||
{ 0x7B, nameof(SvcHandler.TerminateProcess32) }
|
||||
};
|
||||
|
||||
foreach (KeyValuePair<int, string> value in svcFuncs32)
|
||||
|
@ -151,11 +174,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
switch (Type.GetTypeCode(sourceType))
|
||||
{
|
||||
case TypeCode.UInt32: generator.Emit(OpCodes.Conv_U4); break;
|
||||
case TypeCode.Int32: generator.Emit(OpCodes.Conv_I4); break;
|
||||
case TypeCode.Int32: generator.Emit(OpCodes.Conv_I4); break;
|
||||
case TypeCode.UInt16: generator.Emit(OpCodes.Conv_U2); break;
|
||||
case TypeCode.Int16: generator.Emit(OpCodes.Conv_I2); break;
|
||||
case TypeCode.Byte: generator.Emit(OpCodes.Conv_U1); break;
|
||||
case TypeCode.SByte: generator.Emit(OpCodes.Conv_I1); break;
|
||||
case TypeCode.Int16: generator.Emit(OpCodes.Conv_I2); break;
|
||||
case TypeCode.Byte: generator.Emit(OpCodes.Conv_U1); break;
|
||||
case TypeCode.SByte: generator.Emit(OpCodes.Conv_I1); break;
|
||||
|
||||
case TypeCode.Boolean:
|
||||
generator.Emit(OpCodes.Conv_I4);
|
||||
|
@ -253,7 +276,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
|
||||
argsFormat = argsFormat.Substring(0, argsFormat.Length - 1);
|
||||
|
||||
generator.Emit(OpCodes.Ldstr, argsFormat);
|
||||
generator.Emit(OpCodes.Ldstr, argsFormat);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -353,6 +376,12 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
for (int index = 0; index < locals.Count; index++)
|
||||
{
|
||||
(LocalBuilder local, RAttribute attribute) = locals[index];
|
||||
|
||||
if ((registerInUse & (1u << attribute.Index)) != 0)
|
||||
{
|
||||
throw new InvalidSvcException($"Method \"{svcName}\" has conflicting output values at register index \"{attribute.Index}\".");
|
||||
}
|
||||
|
||||
generator.Emit(OpCodes.Ldarg_1);
|
||||
generator.Emit(OpCodes.Ldc_I4, attribute.Index);
|
||||
generator.Emit(OpCodes.Ldloc, local);
|
||||
|
@ -421,8 +450,8 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
|
||||
private static void PrintResult(KernelResult result, string svcName)
|
||||
{
|
||||
if (result != KernelResult.Success &&
|
||||
result != KernelResult.TimedOut &&
|
||||
if (result != KernelResult.Success &&
|
||||
result != KernelResult.TimedOut &&
|
||||
result != KernelResult.Cancelled &&
|
||||
result != KernelResult.InvalidState)
|
||||
{
|
||||
|
|
|
@ -25,7 +25,6 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
[R(3)] uint stackTop,
|
||||
[R(0)] int priority,
|
||||
[R(4)] int cpuCore,
|
||||
|
||||
[R(1)] out int handle)
|
||||
{
|
||||
return CreateThread(entrypoint, argsPtr, stackTop, priority, cpuCore, out handle);
|
||||
|
@ -234,6 +233,16 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return GetThreadCoreMask(handle, out preferredCore, out affinityMask);
|
||||
}
|
||||
|
||||
public KernelResult GetThreadCoreMask32([R(2)] int handle, [R(1)] out int preferredCore, [R(2)] out int affinityMaskLow, [R(3)] out int affinityMaskHigh)
|
||||
{
|
||||
KernelResult result = GetThreadCoreMask(handle, out preferredCore, out long affinityMask);
|
||||
|
||||
affinityMaskLow = (int)(affinityMask >> 32);
|
||||
affinityMaskHigh = (int)(affinityMask & uint.MaxValue);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private KernelResult GetThreadCoreMask(int handle, out int preferredCore, out long affinityMask)
|
||||
{
|
||||
KThread thread = _process.HandleTable.GetKThread(handle);
|
||||
|
@ -334,7 +343,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
KernelResult result = GetThreadId(handle, out threadUid);
|
||||
|
||||
threadUidLow = (uint)(threadUid >> 32);
|
||||
threadUidHigh = (uint)(threadUid & 0xFFFFFFFF);
|
||||
threadUidHigh = (uint)(threadUid & uint.MaxValue);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -362,6 +371,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return SetThreadActivity(handle, pause);
|
||||
}
|
||||
|
||||
public KernelResult SetThreadActivity32([R(0)] int handle, [R(1)] bool pause)
|
||||
{
|
||||
return SetThreadActivity(handle, pause);
|
||||
}
|
||||
|
||||
private KernelResult SetThreadActivity(int handle, bool pause)
|
||||
{
|
||||
KThread thread = _process.HandleTable.GetObject<KThread>(handle);
|
||||
|
@ -389,6 +403,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return GetThreadContext3(address, handle);
|
||||
}
|
||||
|
||||
public KernelResult GetThreadContext332([R(0)] uint address, [R(1)] int handle)
|
||||
{
|
||||
return GetThreadContext3(address, handle);
|
||||
}
|
||||
|
||||
private KernelResult GetThreadContext3(ulong address, int handle)
|
||||
{
|
||||
KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
|
||||
|
|
|
@ -13,10 +13,10 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
}
|
||||
|
||||
public KernelResult WaitSynchronization32(
|
||||
[R(0)] uint timeoutLow,
|
||||
[R(1)] uint handlesPtr,
|
||||
[R(2)] int handlesCount,
|
||||
[R(3)] uint timeoutHigh,
|
||||
[R(0)] uint timeoutLow,
|
||||
[R(1)] uint handlesPtr,
|
||||
[R(2)] int handlesCount,
|
||||
[R(3)] uint timeoutHigh,
|
||||
[R(1)] out int handleIndex)
|
||||
{
|
||||
long timeout = (long)(timeoutLow | ((ulong)timeoutHigh << 32));
|
||||
|
@ -57,6 +57,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return CancelSynchronization(handle);
|
||||
}
|
||||
|
||||
public KernelResult CancelSynchronization32([R(0)] int handle)
|
||||
{
|
||||
return CancelSynchronization(handle);
|
||||
}
|
||||
|
||||
private KernelResult CancelSynchronization(int handle)
|
||||
{
|
||||
KThread thread = _process.HandleTable.GetKThread(handle);
|
||||
|
@ -76,7 +81,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return ArbitrateLock(ownerHandle, mutexAddress, requesterHandle);
|
||||
}
|
||||
|
||||
public KernelResult ArbitrateLock32([R(0)] int ownerHandle, [R(1)] ulong mutexAddress, [R(2)] int requesterHandle)
|
||||
public KernelResult ArbitrateLock32([R(0)] int ownerHandle, [R(1)] uint mutexAddress, [R(2)] int requesterHandle)
|
||||
{
|
||||
return ArbitrateLock(ownerHandle, mutexAddress, requesterHandle);
|
||||
}
|
||||
|
@ -137,11 +142,12 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
public KernelResult WaitProcessWideKeyAtomic32(
|
||||
[R(0)] uint mutexAddress,
|
||||
[R(1)] uint condVarAddress,
|
||||
[R(2)] int handle,
|
||||
[R(2)] int handle,
|
||||
[R(3)] uint timeoutLow,
|
||||
[R(4)] uint timeoutHigh)
|
||||
{
|
||||
long timeout = (long)(timeoutLow | ((ulong)timeoutHigh << 32));
|
||||
|
||||
return WaitProcessWideKeyAtomic(mutexAddress, condVarAddress, handle, timeout);
|
||||
}
|
||||
|
||||
|
@ -197,6 +203,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
public KernelResult WaitForAddress32([R(0)] uint address, [R(1)] ArbitrationType type, [R(2)] int value, [R(3)] uint timeoutLow, [R(4)] uint timeoutHigh)
|
||||
{
|
||||
long timeout = (long)(timeoutLow | ((ulong)timeoutHigh << 32));
|
||||
|
||||
return WaitForAddress(address, type, value, timeout);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue