diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-05-13 22:00:29 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-05-13 22:00:29 -0300 |
| commit | b2b1d7dcd7bef8b78c7cea9d81339ba664fe7578 (patch) | |
| tree | 5ac5d5eaf103c4e72b4d418adab38b921fb28d11 /Ryujinx.Core/OsHle/Kernel/SvcThread.cs | |
| parent | 4546d1b9be1052bbf82858d97795b33355bf64da (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.cs | 85 |
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) |
