aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Core/OsHle/Kernel/SvcThread.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-05-13 22:00:29 -0300
committergdkchan <gab.dark.100@gmail.com>2018-05-13 22:00:29 -0300
commitb2b1d7dcd7bef8b78c7cea9d81339ba664fe7578 (patch)
tree5ac5d5eaf103c4e72b4d418adab38b921fb28d11 /Ryujinx.Core/OsHle/Kernel/SvcThread.cs
parent4546d1b9be1052bbf82858d97795b33355bf64da (diff)
Better implementation of SetThreadCoreMask that allows changing the Core Mask (untested, no clue if it actually works)
Diffstat (limited to 'Ryujinx.Core/OsHle/Kernel/SvcThread.cs')
-rw-r--r--Ryujinx.Core/OsHle/Kernel/SvcThread.cs85
1 files changed, 83 insertions, 2 deletions
diff --git a/Ryujinx.Core/OsHle/Kernel/SvcThread.cs b/Ryujinx.Core/OsHle/Kernel/SvcThread.cs
index 71f3347a..94912f53 100644
--- a/Ryujinx.Core/OsHle/Kernel/SvcThread.cs
+++ b/Ryujinx.Core/OsHle/Kernel/SvcThread.cs
@@ -17,11 +17,28 @@ namespace Ryujinx.Core.OsHle.Kernel
int Priority = (int)ThreadState.X4;
int ProcessorId = (int)ThreadState.X5;
+ if ((uint)Priority > 0x3f)
+ {
+ Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid priority 0x{Priority:x8}!");
+
+ ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidPriority);
+
+ return;
+ }
+
if (ProcessorId == -2)
{
//TODO: Get this value from the NPDM file.
ProcessorId = 0;
}
+ else if ((uint)ProcessorId > 3)
+ {
+ Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid core id 0x{ProcessorId:x8}!");
+
+ ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidCoreId);
+
+ return;
+ }
int Handle = Process.MakeThread(
EntryPoint,
@@ -125,9 +142,73 @@ namespace Ryujinx.Core.OsHle.Kernel
private void SvcSetThreadCoreMask(AThreadState ThreadState)
{
- ThreadState.X0 = 0;
+ int Handle = (int)ThreadState.X0;
+ int IdealCore = (int)ThreadState.X1;
+ long CoreMask = (long)ThreadState.X2;
+
+ KThread Thread = GetThread(ThreadState.Tpidr, Handle);
+
+ if (IdealCore == -2)
+ {
+ //TODO: Get this value from the NPDM file.
+ IdealCore = 0;
+
+ CoreMask = 1 << IdealCore;
+ }
+ else if (IdealCore != -3)
+ {
+ if ((uint)IdealCore > 3)
+ {
+ Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid core id 0x{IdealCore:x8}!");
+
+ ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidCoreId);
+
+ return;
+ }
+
+ if ((CoreMask & (1 << IdealCore)) == 0)
+ {
+ Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid core mask 0x{CoreMask:x8}!");
+
+ ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidCoreMask);
- //TODO: Error codes.
+ return;
+ }
+ }
+
+ if (Thread == null)
+ {
+ Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid thread handle 0x{Handle:x8}!");
+
+ ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
+
+ return;
+ }
+
+ if (IdealCore == -3)
+ {
+ if ((CoreMask & (1 << Thread.IdealCore)) == 0)
+ {
+ Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid core mask 0x{CoreMask:x8}!");
+
+ ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidCoreMask);
+
+ return;
+ }
+ }
+ else
+ {
+ Thread.IdealCore = IdealCore;
+ }
+
+ Thread.CoreMask = (int)CoreMask;
+
+ KThread CurrThread = Process.GetThread(ThreadState.Tpidr);
+
+ Process.Scheduler.Yield(CurrThread);
+ Process.Scheduler.TryRunning(Thread);
+
+ ThreadState.X0 = 0;
}
private void SvcGetCurrentProcessorNumber(AThreadState ThreadState)