diff --git a/Ryujinx.HLE/HOS/GlobalStateTable.cs b/Ryujinx.HLE/HOS/GlobalStateTable.cs
index a350dee2..5e5e5ecf 100644
--- a/Ryujinx.HLE/HOS/GlobalStateTable.cs
+++ b/Ryujinx.HLE/HOS/GlobalStateTable.cs
@@ -1,4 +1,4 @@
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Process;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 
diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs
index a5ea5354..5c2ca9b3 100644
--- a/Ryujinx.HLE/HOS/Horizon.cs
+++ b/Ryujinx.HLE/HOS/Horizon.cs
@@ -2,7 +2,10 @@ using LibHac;
 using Ryujinx.Common.Logging;
 using Ryujinx.HLE.FileSystem.Content;
 using Ryujinx.HLE.HOS.Font;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Memory;
+using Ryujinx.HLE.HOS.Kernel.Process;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using Ryujinx.HLE.HOS.SystemState;
 using Ryujinx.HLE.Loaders.Executables;
 using Ryujinx.HLE.Loaders.Npdm;
diff --git a/Ryujinx.HLE/HOS/Ipc/IpcHandler.cs b/Ryujinx.HLE/HOS/Ipc/IpcHandler.cs
index e5d19236..ecfa25ed 100644
--- a/Ryujinx.HLE/HOS/Ipc/IpcHandler.cs
+++ b/Ryujinx.HLE/HOS/Ipc/IpcHandler.cs
@@ -1,5 +1,7 @@
 using ChocolArm64.Memory;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Ipc;
+using Ryujinx.HLE.HOS.Kernel.Process;
 using System;
 using System.IO;
 
@@ -7,7 +9,7 @@ namespace Ryujinx.HLE.HOS.Ipc
 {
     static class IpcHandler
     {
-        public static long IpcCall(
+        public static KernelResult IpcCall(
             Switch        device,
             KProcess      process,
             MemoryManager memory,
@@ -100,7 +102,7 @@ namespace Ryujinx.HLE.HOS.Ipc
                 memory.WriteBytes(cmdPtr, response.GetBytes(cmdPtr));
             }
 
-            return 0;
+            return KernelResult.Success;
         }
 
         private static IpcMessage FillResponse(IpcMessage response, long result, params int[] values)
diff --git a/Ryujinx.HLE/HOS/Kernel/IKFutureSchedulerObject.cs b/Ryujinx.HLE/HOS/Kernel/Common/IKFutureSchedulerObject.cs
similarity index 65%
rename from Ryujinx.HLE/HOS/Kernel/IKFutureSchedulerObject.cs
rename to Ryujinx.HLE/HOS/Kernel/Common/IKFutureSchedulerObject.cs
index 6a255e65..473683ff 100644
--- a/Ryujinx.HLE/HOS/Kernel/IKFutureSchedulerObject.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Common/IKFutureSchedulerObject.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Common
 {
     interface IKFutureSchedulerObject
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KAutoObject.cs b/Ryujinx.HLE/HOS/Kernel/Common/KAutoObject.cs
similarity index 95%
rename from Ryujinx.HLE/HOS/Kernel/KAutoObject.cs
rename to Ryujinx.HLE/HOS/Kernel/Common/KAutoObject.cs
index f49beaac..ddb0c71f 100644
--- a/Ryujinx.HLE/HOS/Kernel/KAutoObject.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Common/KAutoObject.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Common
 {
     class KAutoObject
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KResourceLimit.cs b/Ryujinx.HLE/HOS/Kernel/Common/KResourceLimit.cs
similarity index 98%
rename from Ryujinx.HLE/HOS/Kernel/KResourceLimit.cs
rename to Ryujinx.HLE/HOS/Kernel/Common/KResourceLimit.cs
index 09c53e5b..01bba65f 100644
--- a/Ryujinx.HLE/HOS/Kernel/KResourceLimit.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Common/KResourceLimit.cs
@@ -1,7 +1,8 @@
 using Ryujinx.Common;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using System.Collections.Generic;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Common
 {
     class KResourceLimit
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KSynchronizationObject.cs b/Ryujinx.HLE/HOS/Kernel/Common/KSynchronizationObject.cs
similarity index 90%
rename from Ryujinx.HLE/HOS/Kernel/KSynchronizationObject.cs
rename to Ryujinx.HLE/HOS/Kernel/Common/KSynchronizationObject.cs
index 79f0673f..87e55312 100644
--- a/Ryujinx.HLE/HOS/Kernel/KSynchronizationObject.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Common/KSynchronizationObject.cs
@@ -1,6 +1,7 @@
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using System.Collections.Generic;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Common
 {
     class KSynchronizationObject : KAutoObject
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KTimeManager.cs b/Ryujinx.HLE/HOS/Kernel/Common/KTimeManager.cs
similarity index 98%
rename from Ryujinx.HLE/HOS/Kernel/KTimeManager.cs
rename to Ryujinx.HLE/HOS/Kernel/Common/KTimeManager.cs
index 0c2551a3..f6a9e6f9 100644
--- a/Ryujinx.HLE/HOS/Kernel/KTimeManager.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Common/KTimeManager.cs
@@ -4,7 +4,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Common
 {
     class KTimeManager : IDisposable
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KernelInit.cs b/Ryujinx.HLE/HOS/Kernel/Common/KernelInit.cs
similarity index 98%
rename from Ryujinx.HLE/HOS/Kernel/KernelInit.cs
rename to Ryujinx.HLE/HOS/Kernel/Common/KernelInit.cs
index a797951b..2a2aa743 100644
--- a/Ryujinx.HLE/HOS/Kernel/KernelInit.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Common/KernelInit.cs
@@ -1,6 +1,7 @@
+using Ryujinx.HLE.HOS.Kernel.Memory;
 using System;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Common
 {
     static class KernelInit
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KernelResult.cs b/Ryujinx.HLE/HOS/Kernel/Common/KernelResult.cs
similarity index 92%
rename from Ryujinx.HLE/HOS/Kernel/KernelResult.cs
rename to Ryujinx.HLE/HOS/Kernel/Common/KernelResult.cs
index 9870d175..cea24693 100644
--- a/Ryujinx.HLE/HOS/Kernel/KernelResult.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Common/KernelResult.cs
@@ -1,9 +1,10 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Common
 {
     enum KernelResult
     {
         Success            = 0,
         InvalidCapability  = 0x1c01,
+        ThreadNotStarted   = 0x7201,
         ThreadTerminating  = 0x7601,
         InvalidSize        = 0xca01,
         InvalidAddress     = 0xcc01,
diff --git a/Ryujinx.HLE/HOS/Kernel/Common/KernelTransfer.cs b/Ryujinx.HLE/HOS/Kernel/Common/KernelTransfer.cs
new file mode 100644
index 00000000..a29b1722
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Kernel/Common/KernelTransfer.cs
@@ -0,0 +1,72 @@
+using Ryujinx.HLE.HOS.Kernel.Process;
+using ChocolArm64.Memory;
+
+namespace Ryujinx.HLE.HOS.Kernel.Common
+{
+    static class KernelTransfer
+    {
+        public static bool UserToKernelInt32(Horizon system, ulong address, out int value)
+        {
+            KProcess currentProcess = system.Scheduler.GetCurrentProcess();
+
+            if (currentProcess.CpuMemory.IsMapped((long)address) &&
+                currentProcess.CpuMemory.IsMapped((long)address + 3))
+            {
+                value = currentProcess.CpuMemory.ReadInt32((long)address);
+
+                return true;
+            }
+
+            value = 0;
+
+            return false;
+        }
+
+        public static bool UserToKernelString(Horizon system, ulong address, int size, out string value)
+        {
+            KProcess currentProcess = system.Scheduler.GetCurrentProcess();
+
+            if (currentProcess.CpuMemory.IsMapped((long)address) &&
+                currentProcess.CpuMemory.IsMapped((long)address + size - 1))
+            {
+                value = MemoryHelper.ReadAsciiString(currentProcess.CpuMemory, (long)address, size);
+
+                return true;
+            }
+
+            value = null;
+
+            return false;
+        }
+
+        public static bool KernelToUserInt32(Horizon system, ulong address, int value)
+        {
+            KProcess currentProcess = system.Scheduler.GetCurrentProcess();
+
+            if (currentProcess.CpuMemory.IsMapped((long)address) &&
+                currentProcess.CpuMemory.IsMapped((long)address + 3))
+            {
+                currentProcess.CpuMemory.WriteInt32ToSharedAddr((long)address, value);
+
+                return true;
+            }
+
+            return false;
+        }
+
+        public static bool KernelToUserInt64(Horizon system, ulong address, long value)
+        {
+            KProcess currentProcess = system.Scheduler.GetCurrentProcess();
+
+            if (currentProcess.CpuMemory.IsMapped((long)address) &&
+                currentProcess.CpuMemory.IsMapped((long)address + 7))
+            {
+                currentProcess.CpuMemory.WriteInt64((long)address, value);
+
+                return true;
+            }
+
+            return false;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Kernel/LimitableResource.cs b/Ryujinx.HLE/HOS/Kernel/Common/LimitableResource.cs
similarity index 83%
rename from Ryujinx.HLE/HOS/Kernel/LimitableResource.cs
rename to Ryujinx.HLE/HOS/Kernel/Common/LimitableResource.cs
index baab4222..2e6a3e45 100644
--- a/Ryujinx.HLE/HOS/Kernel/LimitableResource.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Common/LimitableResource.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Common
 {
     enum LimitableResource : byte
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/MersenneTwister.cs b/Ryujinx.HLE/HOS/Kernel/Common/MersenneTwister.cs
similarity index 98%
rename from Ryujinx.HLE/HOS/Kernel/MersenneTwister.cs
rename to Ryujinx.HLE/HOS/Kernel/Common/MersenneTwister.cs
index 5307bdc9..6b686901 100644
--- a/Ryujinx.HLE/HOS/Kernel/MersenneTwister.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Common/MersenneTwister.cs
@@ -1,6 +1,6 @@
 using Ryujinx.Common;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Common
 {
     class MersenneTwister
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KClientPort.cs b/Ryujinx.HLE/HOS/Kernel/Ipc/KClientPort.cs
similarity index 91%
rename from Ryujinx.HLE/HOS/Kernel/KClientPort.cs
rename to Ryujinx.HLE/HOS/Kernel/Ipc/KClientPort.cs
index 57547627..ddfe2096 100644
--- a/Ryujinx.HLE/HOS/Kernel/KClientPort.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Ipc/KClientPort.cs
@@ -1,4 +1,6 @@
-namespace Ryujinx.HLE.HOS.Kernel
+using Ryujinx.HLE.HOS.Kernel.Common;
+
+namespace Ryujinx.HLE.HOS.Kernel.Ipc
 {
     class KClientPort : KSynchronizationObject
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KPort.cs b/Ryujinx.HLE/HOS/Kernel/Ipc/KPort.cs
similarity index 90%
rename from Ryujinx.HLE/HOS/Kernel/KPort.cs
rename to Ryujinx.HLE/HOS/Kernel/Ipc/KPort.cs
index a6c5b375..16e9a111 100644
--- a/Ryujinx.HLE/HOS/Kernel/KPort.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Ipc/KPort.cs
@@ -1,4 +1,6 @@
-namespace Ryujinx.HLE.HOS.Kernel
+using Ryujinx.HLE.HOS.Kernel.Common;
+
+namespace Ryujinx.HLE.HOS.Kernel.Ipc
 {
     class KPort : KAutoObject
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KServerPort.cs b/Ryujinx.HLE/HOS/Kernel/Ipc/KServerPort.cs
similarity index 77%
rename from Ryujinx.HLE/HOS/Kernel/KServerPort.cs
rename to Ryujinx.HLE/HOS/Kernel/Ipc/KServerPort.cs
index 0aa74e48..d4d3bcd2 100644
--- a/Ryujinx.HLE/HOS/Kernel/KServerPort.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Ipc/KServerPort.cs
@@ -1,4 +1,6 @@
-namespace Ryujinx.HLE.HOS.Kernel
+using Ryujinx.HLE.HOS.Kernel.Common;
+
+namespace Ryujinx.HLE.HOS.Kernel.Ipc
 {
     class KServerPort : KSynchronizationObject
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KSession.cs b/Ryujinx.HLE/HOS/Kernel/Ipc/KSession.cs
similarity index 94%
rename from Ryujinx.HLE/HOS/Kernel/KSession.cs
rename to Ryujinx.HLE/HOS/Kernel/Ipc/KSession.cs
index 361a7479..f2b30493 100644
--- a/Ryujinx.HLE/HOS/Kernel/KSession.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Ipc/KSession.cs
@@ -1,7 +1,7 @@
 using Ryujinx.HLE.HOS.Services;
 using System;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Ipc
 {
     class KSession : IDisposable
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KernelErr.cs b/Ryujinx.HLE/HOS/Kernel/KernelErr.cs
deleted file mode 100644
index e0b196f4..00000000
--- a/Ryujinx.HLE/HOS/Kernel/KernelErr.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-namespace Ryujinx.HLE.HOS.Kernel
-{
-    static class KernelErr
-    {
-        public const int ThreadTerminating = 59;
-        public const int InvalidSize       = 101;
-        public const int InvalidAddress    = 102;
-        public const int OutOfMemory       = 104;
-        public const int HandleTableFull   = 105;
-        public const int NoAccessPerm      = 106;
-        public const int InvalidPermission = 108;
-        public const int InvalidMemRange   = 110;
-        public const int InvalidPriority   = 112;
-        public const int InvalidCoreId     = 113;
-        public const int InvalidHandle     = 114;
-        public const int InvalidMaskValue  = 116;
-        public const int Timeout           = 117;
-        public const int Cancelled         = 118;
-        public const int CountOutOfRange   = 119;
-        public const int InvalidEnumValue  = 120;
-        public const int InvalidThread     = 122;
-        public const int InvalidState      = 125;
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Kernel/KernelTransfer.cs b/Ryujinx.HLE/HOS/Kernel/KernelTransfer.cs
deleted file mode 100644
index c0ce72c0..00000000
--- a/Ryujinx.HLE/HOS/Kernel/KernelTransfer.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-using ChocolArm64.Memory;
-
-namespace Ryujinx.HLE.HOS.Kernel
-{
-    static class KernelTransfer
-    {
-        public static bool UserToKernelInt32(Horizon system, long address, out int value)
-        {
-            KProcess currentProcess = system.Scheduler.GetCurrentProcess();
-
-            if (currentProcess.CpuMemory.IsMapped(address) &&
-                currentProcess.CpuMemory.IsMapped(address + 3))
-            {
-                value = currentProcess.CpuMemory.ReadInt32(address);
-
-                return true;
-            }
-
-            value = 0;
-
-            return false;
-        }
-
-        public static bool UserToKernelString(Horizon system, long address, int size, out string value)
-        {
-            KProcess currentProcess = system.Scheduler.GetCurrentProcess();
-
-            if (currentProcess.CpuMemory.IsMapped(address) &&
-                currentProcess.CpuMemory.IsMapped(address + size - 1))
-            {
-                value = MemoryHelper.ReadAsciiString(currentProcess.CpuMemory, address, size);
-
-                return true;
-            }
-
-            value = null;
-
-            return false;
-        }
-
-        public static bool KernelToUserInt32(Horizon system, long address, int value)
-        {
-            KProcess currentProcess = system.Scheduler.GetCurrentProcess();
-
-            if (currentProcess.CpuMemory.IsMapped(address) &&
-                currentProcess.CpuMemory.IsMapped(address + 3))
-            {
-                currentProcess.CpuMemory.WriteInt32ToSharedAddr(address, value);
-
-                return true;
-            }
-
-            return false;
-        }
-
-        public static bool KernelToUserInt64(Horizon system, long address, long value)
-        {
-            KProcess currentProcess = system.Scheduler.GetCurrentProcess();
-
-            if (currentProcess.CpuMemory.IsMapped(address) &&
-                currentProcess.CpuMemory.IsMapped(address + 7))
-            {
-                currentProcess.CpuMemory.WriteInt64(address, value);
-
-                return true;
-            }
-
-            return false;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Kernel/AddressSpaceType.cs b/Ryujinx.HLE/HOS/Kernel/Memory/AddressSpaceType.cs
similarity index 79%
rename from Ryujinx.HLE/HOS/Kernel/AddressSpaceType.cs
rename to Ryujinx.HLE/HOS/Kernel/Memory/AddressSpaceType.cs
index 6f7b230e..8395c577 100644
--- a/Ryujinx.HLE/HOS/Kernel/AddressSpaceType.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/AddressSpaceType.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Memory
 {
     enum AddressSpaceType
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/DramMemoryMap.cs b/Ryujinx.HLE/HOS/Kernel/Memory/DramMemoryMap.cs
similarity index 92%
rename from Ryujinx.HLE/HOS/Kernel/DramMemoryMap.cs
rename to Ryujinx.HLE/HOS/Kernel/Memory/DramMemoryMap.cs
index b20a83e2..261c2972 100644
--- a/Ryujinx.HLE/HOS/Kernel/DramMemoryMap.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/DramMemoryMap.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Memory
 {
     static class DramMemoryMap
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KMemoryArrange.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrange.cs
similarity index 94%
rename from Ryujinx.HLE/HOS/Kernel/KMemoryArrange.cs
rename to Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrange.cs
index de8bf3b1..7dfc2b77 100644
--- a/Ryujinx.HLE/HOS/Kernel/KMemoryArrange.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrange.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Memory
 {
     class KMemoryArrange
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KMemoryArrangeRegion.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrangeRegion.cs
similarity index 89%
rename from Ryujinx.HLE/HOS/Kernel/KMemoryArrangeRegion.cs
rename to Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrangeRegion.cs
index 4fe58d73..eaf0fe5f 100644
--- a/Ryujinx.HLE/HOS/Kernel/KMemoryArrangeRegion.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryArrangeRegion.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Memory
 {
     struct KMemoryArrangeRegion
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KMemoryBlock.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryBlock.cs
similarity index 96%
rename from Ryujinx.HLE/HOS/Kernel/KMemoryBlock.cs
rename to Ryujinx.HLE/HOS/Kernel/Memory/KMemoryBlock.cs
index 44b7a683..89a19498 100644
--- a/Ryujinx.HLE/HOS/Kernel/KMemoryBlock.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryBlock.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Memory
 {
     class KMemoryBlock
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KMemoryBlockAllocator.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryBlockAllocator.cs
similarity index 90%
rename from Ryujinx.HLE/HOS/Kernel/KMemoryBlockAllocator.cs
rename to Ryujinx.HLE/HOS/Kernel/Memory/KMemoryBlockAllocator.cs
index 375685e6..ae68bf39 100644
--- a/Ryujinx.HLE/HOS/Kernel/KMemoryBlockAllocator.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryBlockAllocator.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Memory
 {
     class KMemoryBlockAllocator
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KMemoryInfo.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryInfo.cs
similarity index 96%
rename from Ryujinx.HLE/HOS/Kernel/KMemoryInfo.cs
rename to Ryujinx.HLE/HOS/Kernel/Memory/KMemoryInfo.cs
index 0372e0d3..226ce77c 100644
--- a/Ryujinx.HLE/HOS/Kernel/KMemoryInfo.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryInfo.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Memory
 {
     class KMemoryInfo
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KMemoryManager.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs
similarity index 99%
rename from Ryujinx.HLE/HOS/Kernel/KMemoryManager.cs
rename to Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs
index 831844c7..fb5dec04 100644
--- a/Ryujinx.HLE/HOS/Kernel/KMemoryManager.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs
@@ -1,9 +1,11 @@
 using ChocolArm64.Memory;
 using Ryujinx.Common;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Process;
 using System;
 using System.Collections.Generic;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Memory
 {
     class KMemoryManager
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KMemoryRegionBlock.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryRegionBlock.cs
similarity index 96%
rename from Ryujinx.HLE/HOS/Kernel/KMemoryRegionBlock.cs
rename to Ryujinx.HLE/HOS/Kernel/Memory/KMemoryRegionBlock.cs
index f7e85e9a..3334ff43 100644
--- a/Ryujinx.HLE/HOS/Kernel/KMemoryRegionBlock.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryRegionBlock.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Memory
 {
     class KMemoryRegionBlock
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KMemoryRegionManager.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryRegionManager.cs
similarity index 99%
rename from Ryujinx.HLE/HOS/Kernel/KMemoryRegionManager.cs
rename to Ryujinx.HLE/HOS/Kernel/Memory/KMemoryRegionManager.cs
index b9265b13..777e9aa9 100644
--- a/Ryujinx.HLE/HOS/Kernel/KMemoryRegionManager.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryRegionManager.cs
@@ -1,6 +1,7 @@
 using Ryujinx.Common;
+using Ryujinx.HLE.HOS.Kernel.Common;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Memory
 {
     class KMemoryRegionManager
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KPageList.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KPageList.cs
similarity index 96%
rename from Ryujinx.HLE/HOS/Kernel/KPageList.cs
rename to Ryujinx.HLE/HOS/Kernel/Memory/KPageList.cs
index b24d126f..f0935dcc 100644
--- a/Ryujinx.HLE/HOS/Kernel/KPageList.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/KPageList.cs
@@ -1,7 +1,8 @@
+using Ryujinx.HLE.HOS.Kernel.Common;
 using System.Collections;
 using System.Collections.Generic;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Memory
 {
     class KPageList : IEnumerable<KPageNode>
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KPageNode.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KPageNode.cs
similarity index 86%
rename from Ryujinx.HLE/HOS/Kernel/KPageNode.cs
rename to Ryujinx.HLE/HOS/Kernel/Memory/KPageNode.cs
index 5cdb1c49..ada41687 100644
--- a/Ryujinx.HLE/HOS/Kernel/KPageNode.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/KPageNode.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Memory
 {
     struct KPageNode
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KSharedMemory.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KSharedMemory.cs
similarity index 94%
rename from Ryujinx.HLE/HOS/Kernel/KSharedMemory.cs
rename to Ryujinx.HLE/HOS/Kernel/Memory/KSharedMemory.cs
index 0e9f8840..f2a05bda 100644
--- a/Ryujinx.HLE/HOS/Kernel/KSharedMemory.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/KSharedMemory.cs
@@ -1,6 +1,8 @@
 using Ryujinx.Common;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Process;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Memory
 {
     class KSharedMemory
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KSlabHeap.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KSlabHeap.cs
similarity index 96%
rename from Ryujinx.HLE/HOS/Kernel/KSlabHeap.cs
rename to Ryujinx.HLE/HOS/Kernel/Memory/KSlabHeap.cs
index 84c4dc01..9051e84c 100644
--- a/Ryujinx.HLE/HOS/Kernel/KSlabHeap.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/KSlabHeap.cs
@@ -1,6 +1,6 @@
 using System.Collections.Generic;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Memory
 {
     class KSlabHeap
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KTransferMemory.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KTransferMemory.cs
similarity index 87%
rename from Ryujinx.HLE/HOS/Kernel/KTransferMemory.cs
rename to Ryujinx.HLE/HOS/Kernel/Memory/KTransferMemory.cs
index d8837851..02367e89 100644
--- a/Ryujinx.HLE/HOS/Kernel/KTransferMemory.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/KTransferMemory.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Memory
 {
     class KTransferMemory
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/MemoryAttribute.cs b/Ryujinx.HLE/HOS/Kernel/Memory/MemoryAttribute.cs
similarity index 91%
rename from Ryujinx.HLE/HOS/Kernel/MemoryAttribute.cs
rename to Ryujinx.HLE/HOS/Kernel/Memory/MemoryAttribute.cs
index 8f3197cb..42407ffe 100644
--- a/Ryujinx.HLE/HOS/Kernel/MemoryAttribute.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/MemoryAttribute.cs
@@ -1,6 +1,6 @@
 using System;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Memory
 {
     [Flags]
     enum MemoryAttribute  : byte
diff --git a/Ryujinx.HLE/HOS/Kernel/MemoryOperation.cs b/Ryujinx.HLE/HOS/Kernel/Memory/MemoryOperation.cs
similarity index 79%
rename from Ryujinx.HLE/HOS/Kernel/MemoryOperation.cs
rename to Ryujinx.HLE/HOS/Kernel/Memory/MemoryOperation.cs
index b9350121..7f7f29de 100644
--- a/Ryujinx.HLE/HOS/Kernel/MemoryOperation.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/MemoryOperation.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Memory
 {
     enum MemoryOperation
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/MemoryPermission.cs b/Ryujinx.HLE/HOS/Kernel/Memory/MemoryPermission.cs
similarity index 87%
rename from Ryujinx.HLE/HOS/Kernel/MemoryPermission.cs
rename to Ryujinx.HLE/HOS/Kernel/Memory/MemoryPermission.cs
index 63539c2e..0ad90abd 100644
--- a/Ryujinx.HLE/HOS/Kernel/MemoryPermission.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/MemoryPermission.cs
@@ -1,6 +1,6 @@
 using System;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Memory
 {
     [Flags]
     enum MemoryPermission : byte
diff --git a/Ryujinx.HLE/HOS/Kernel/MemoryRegion.cs b/Ryujinx.HLE/HOS/Kernel/Memory/MemoryRegion.cs
similarity index 77%
rename from Ryujinx.HLE/HOS/Kernel/MemoryRegion.cs
rename to Ryujinx.HLE/HOS/Kernel/Memory/MemoryRegion.cs
index ea4f33c9..ad719bde 100644
--- a/Ryujinx.HLE/HOS/Kernel/MemoryRegion.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/MemoryRegion.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Memory
 {
     enum MemoryRegion
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/MemoryState.cs b/Ryujinx.HLE/HOS/Kernel/Memory/MemoryState.cs
similarity index 97%
rename from Ryujinx.HLE/HOS/Kernel/MemoryState.cs
rename to Ryujinx.HLE/HOS/Kernel/Memory/MemoryState.cs
index e2ce27ef..f7161a88 100644
--- a/Ryujinx.HLE/HOS/Kernel/MemoryState.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/MemoryState.cs
@@ -1,6 +1,6 @@
 using System;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Memory
 {
     [Flags]
     enum MemoryState : uint
diff --git a/Ryujinx.HLE/HOS/Kernel/HleProcessDebugger.cs b/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs
similarity index 99%
rename from Ryujinx.HLE/HOS/Kernel/HleProcessDebugger.cs
rename to Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs
index fd3ac1f5..30fa4a5f 100644
--- a/Ryujinx.HLE/HOS/Kernel/HleProcessDebugger.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs
@@ -2,13 +2,14 @@ using ChocolArm64.Memory;
 using ChocolArm64.State;
 using Ryujinx.Common.Logging;
 using Ryujinx.HLE.HOS.Diagnostics.Demangler;
+using Ryujinx.HLE.HOS.Kernel.Memory;
 using Ryujinx.HLE.Loaders.Elf;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Process
 {
     class HleProcessDebugger
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KContextIdManager.cs b/Ryujinx.HLE/HOS/Kernel/Process/KContextIdManager.cs
similarity index 98%
rename from Ryujinx.HLE/HOS/Kernel/KContextIdManager.cs
rename to Ryujinx.HLE/HOS/Kernel/Process/KContextIdManager.cs
index 80a1c1c7..0392b930 100644
--- a/Ryujinx.HLE/HOS/Kernel/KContextIdManager.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/KContextIdManager.cs
@@ -1,7 +1,7 @@
 using Ryujinx.Common;
 using System;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Process
 {
     class KContextIdManager
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KHandleEntry.cs b/Ryujinx.HLE/HOS/Kernel/Process/KHandleEntry.cs
similarity index 88%
rename from Ryujinx.HLE/HOS/Kernel/KHandleEntry.cs
rename to Ryujinx.HLE/HOS/Kernel/Process/KHandleEntry.cs
index 42e59329..87137d0f 100644
--- a/Ryujinx.HLE/HOS/Kernel/KHandleEntry.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/KHandleEntry.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Process
 {
     class KHandleEntry
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KHandleTable.cs b/Ryujinx.HLE/HOS/Kernel/Process/KHandleTable.cs
similarity index 97%
rename from Ryujinx.HLE/HOS/Kernel/KHandleTable.cs
rename to Ryujinx.HLE/HOS/Kernel/Process/KHandleTable.cs
index 88d0c513..413edf94 100644
--- a/Ryujinx.HLE/HOS/Kernel/KHandleTable.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/KHandleTable.cs
@@ -1,6 +1,8 @@
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using System;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Process
 {
     class KHandleTable
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KProcess.cs b/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
similarity index 99%
rename from Ryujinx.HLE/HOS/Kernel/KProcess.cs
rename to Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
index 6d91f41c..0d77a495 100644
--- a/Ryujinx.HLE/HOS/Kernel/KProcess.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
@@ -3,12 +3,16 @@ using ChocolArm64.Events;
 using ChocolArm64.Memory;
 using Ryujinx.Common;
 using Ryujinx.Common.Logging;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Memory;
+using Ryujinx.HLE.HOS.Kernel.SupervisorCall;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Process
 {
     class KProcess : KSynchronizationObject
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KProcessCapabilities.cs b/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs
similarity index 98%
rename from Ryujinx.HLE/HOS/Kernel/KProcessCapabilities.cs
rename to Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs
index 4dc8500c..033f0a2c 100644
--- a/Ryujinx.HLE/HOS/Kernel/KProcessCapabilities.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs
@@ -1,6 +1,9 @@
 using Ryujinx.Common;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Memory;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Process
 {
     class KProcessCapabilities
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KTlsPageInfo.cs b/Ryujinx.HLE/HOS/Kernel/Process/KTlsPageInfo.cs
similarity index 95%
rename from Ryujinx.HLE/HOS/Kernel/KTlsPageInfo.cs
rename to Ryujinx.HLE/HOS/Kernel/Process/KTlsPageInfo.cs
index ff5ecf13..5ce5a299 100644
--- a/Ryujinx.HLE/HOS/Kernel/KTlsPageInfo.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/KTlsPageInfo.cs
@@ -1,4 +1,6 @@
-namespace Ryujinx.HLE.HOS.Kernel
+using Ryujinx.HLE.HOS.Kernel.Memory;
+
+namespace Ryujinx.HLE.HOS.Kernel.Process
 {
     class KTlsPageInfo
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KTlsPageManager.cs b/Ryujinx.HLE/HOS/Kernel/Process/KTlsPageManager.cs
similarity index 94%
rename from Ryujinx.HLE/HOS/Kernel/KTlsPageManager.cs
rename to Ryujinx.HLE/HOS/Kernel/Process/KTlsPageManager.cs
index 75f595eb..03174e5b 100644
--- a/Ryujinx.HLE/HOS/Kernel/KTlsPageManager.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/KTlsPageManager.cs
@@ -1,6 +1,7 @@
+using Ryujinx.HLE.HOS.Kernel.Memory;
 using System;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Process
 {
     class KTlsPageManager
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/ProcessCreationInfo.cs b/Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationInfo.cs
similarity index 96%
rename from Ryujinx.HLE/HOS/Kernel/ProcessCreationInfo.cs
rename to Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationInfo.cs
index 7b2e8b72..ba9f54bf 100644
--- a/Ryujinx.HLE/HOS/Kernel/ProcessCreationInfo.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationInfo.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Process
 {
     struct ProcessCreationInfo
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/ProcessState.cs b/Ryujinx.HLE/HOS/Kernel/Process/ProcessState.cs
similarity index 87%
rename from Ryujinx.HLE/HOS/Kernel/ProcessState.cs
rename to Ryujinx.HLE/HOS/Kernel/Process/ProcessState.cs
index 98ff4207..5ef3077e 100644
--- a/Ryujinx.HLE/HOS/Kernel/ProcessState.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/ProcessState.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Process
 {
     enum ProcessState : byte
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/InvalidSvcException.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/InvalidSvcException.cs
new file mode 100644
index 00000000..b78a2284
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/InvalidSvcException.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
+{
+    public class InvalidSvcException : Exception
+    {
+        public InvalidSvcException(string message) : base(message) { }
+    }
+}
diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcHandler.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcHandler.cs
new file mode 100644
index 00000000..08340b06
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcHandler.cs
@@ -0,0 +1,61 @@
+using ChocolArm64.Events;
+using ChocolArm64.Memory;
+using ChocolArm64.State;
+using Ryujinx.HLE.HOS.Ipc;
+using Ryujinx.HLE.HOS.Kernel.Ipc;
+using Ryujinx.HLE.HOS.Kernel.Process;
+using Ryujinx.HLE.HOS.Kernel.Threading;
+using System;
+
+namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
+{
+    partial class SvcHandler
+    {
+        private Switch        _device;
+        private KProcess      _process;
+        private Horizon       _system;
+        private MemoryManager _memory;
+
+        private struct HleIpcMessage
+        {
+            public KThread    Thread     { get; private set; }
+            public KSession   Session    { get; private set; }
+            public IpcMessage Message    { get; private set; }
+            public long       MessagePtr { get; private set; }
+
+            public HleIpcMessage(
+                KThread    thread,
+                KSession   session,
+                IpcMessage message,
+                long       messagePtr)
+            {
+                Thread     = thread;
+                Session    = session;
+                Message    = message;
+                MessagePtr = messagePtr;
+            }
+        }
+
+        public SvcHandler(Switch device, KProcess process)
+        {
+            _device  = device;
+            _process = process;
+            _system  = device.System;
+            _memory  = process.CpuMemory;
+        }
+
+        public void SvcCall(object sender, InstExceptionEventArgs e)
+        {
+            Action<SvcHandler, CpuThreadState> svcFunc = SvcTable.GetSvcFunc(e.Id);
+
+            if (svcFunc == null)
+            {
+                throw new NotImplementedException($"SVC 0x{e.Id:X4} is not implemented.");
+            }
+
+            CpuThreadState threadState = (CpuThreadState)sender;
+
+            svcFunc(this, threadState);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcMemory.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcMemory.cs
new file mode 100644
index 00000000..e6590522
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcMemory.cs
@@ -0,0 +1,394 @@
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Memory;
+using Ryujinx.HLE.HOS.Kernel.Process;
+
+namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
+{
+    partial class SvcHandler
+    {
+        public KernelResult SetHeapSize64(ulong size, out ulong position)
+        {
+            return SetHeapSize(size, out position);
+        }
+
+        private KernelResult SetHeapSize(ulong size, out ulong position)
+        {
+            if ((size & 0xfffffffe001fffff) != 0)
+            {
+                position = 0;
+
+                return KernelResult.InvalidSize;
+            }
+
+            return _process.MemoryManager.SetHeapSize(size, out position);
+        }
+
+        public KernelResult SetMemoryAttribute64(
+            ulong           position,
+            ulong           size,
+            MemoryAttribute attributeMask,
+            MemoryAttribute attributeValue)
+        {
+            return SetMemoryAttribute(position, size, attributeMask, attributeValue);
+        }
+
+        private KernelResult SetMemoryAttribute(
+            ulong           position,
+            ulong           size,
+            MemoryAttribute attributeMask,
+            MemoryAttribute attributeValue)
+        {
+            if (!PageAligned(position))
+            {
+                return KernelResult.InvalidAddress;
+            }
+
+            if (!PageAligned(size) || size == 0)
+            {
+                return KernelResult.InvalidSize;
+            }
+
+            MemoryAttribute attributes = attributeMask | attributeValue;
+
+            if (attributes != attributeMask ||
+               (attributes | MemoryAttribute.Uncached) != MemoryAttribute.Uncached)
+            {
+                return KernelResult.InvalidCombination;
+            }
+
+            KernelResult result = _process.MemoryManager.SetMemoryAttribute(
+                position,
+                size,
+                attributeMask,
+                attributeValue);
+
+            if (result == KernelResult.Success)
+            {
+                _memory.StopObservingRegion((long)position, (long)size);
+            }
+
+            return result;
+        }
+
+        public KernelResult MapMemory64(ulong dst, ulong src, ulong size)
+        {
+            return MapMemory(dst, src, size);
+        }
+
+        private KernelResult MapMemory(ulong dst, ulong src, ulong size)
+        {
+            if (!PageAligned(src | dst))
+            {
+                return KernelResult.InvalidAddress;
+            }
+
+            if (!PageAligned(size) || size == 0)
+            {
+                return KernelResult.InvalidSize;
+            }
+
+            if (src + size <= src || dst + size <= dst)
+            {
+                return KernelResult.InvalidMemState;
+            }
+
+            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
+
+            if (!currentProcess.MemoryManager.InsideAddrSpace(src, size))
+            {
+                return KernelResult.InvalidMemState;
+            }
+
+            if (currentProcess.MemoryManager.OutsideStackRegion(dst, size) ||
+                currentProcess.MemoryManager.InsideHeapRegion  (dst, size) ||
+                currentProcess.MemoryManager.InsideAliasRegion (dst, size))
+            {
+                return KernelResult.InvalidMemRange;
+            }
+
+            return _process.MemoryManager.Map(dst, src, size);
+        }
+
+        public KernelResult UnmapMemory64(ulong dst, ulong src, ulong size)
+        {
+            return UnmapMemory(dst, src, size);
+        }
+
+        private KernelResult UnmapMemory(ulong dst, ulong src, ulong size)
+        {
+            if (!PageAligned(src | dst))
+            {
+                return KernelResult.InvalidAddress;
+            }
+
+            if (!PageAligned(size) || size == 0)
+            {
+                return KernelResult.InvalidSize;
+            }
+
+            if (src + size <= src || dst + size <= dst)
+            {
+                return KernelResult.InvalidMemState;
+            }
+
+            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
+
+            if (!currentProcess.MemoryManager.InsideAddrSpace(src, size))
+            {
+                return KernelResult.InvalidMemState;
+            }
+
+            if (currentProcess.MemoryManager.OutsideStackRegion(dst, size) ||
+                currentProcess.MemoryManager.InsideHeapRegion  (dst, size) ||
+                currentProcess.MemoryManager.InsideAliasRegion (dst, size))
+            {
+                return KernelResult.InvalidMemRange;
+            }
+
+            return _process.MemoryManager.Unmap(dst, src, size);
+        }
+
+        public KernelResult QueryMemory64(ulong infoPtr, ulong x1, ulong position)
+        {
+            return QueryMemory(infoPtr, position);
+        }
+
+        private KernelResult QueryMemory(ulong infoPtr, ulong position)
+        {
+            KMemoryInfo blkInfo = _process.MemoryManager.QueryMemory(position);
+
+            _memory.WriteUInt64((long)infoPtr + 0x00, blkInfo.Address);
+            _memory.WriteUInt64((long)infoPtr + 0x08, blkInfo.Size);
+            _memory.WriteInt32 ((long)infoPtr + 0x10, (int)blkInfo.State & 0xff);
+            _memory.WriteInt32 ((long)infoPtr + 0x14, (int)blkInfo.Attribute);
+            _memory.WriteInt32 ((long)infoPtr + 0x18, (int)blkInfo.Permission);
+            _memory.WriteInt32 ((long)infoPtr + 0x1c, blkInfo.IpcRefCount);
+            _memory.WriteInt32 ((long)infoPtr + 0x20, blkInfo.DeviceRefCount);
+            _memory.WriteInt32 ((long)infoPtr + 0x24, 0);
+
+            return KernelResult.Success;
+        }
+
+        public KernelResult MapSharedMemory64(int handle, ulong address, ulong size, MemoryPermission permission)
+        {
+            return MapSharedMemory(handle, address, size, permission);
+        }
+
+        private KernelResult MapSharedMemory(int handle, ulong address, ulong size, MemoryPermission permission)
+        {
+            if (!PageAligned(address))
+            {
+                return KernelResult.InvalidAddress;
+            }
+
+            if (!PageAligned(size) || size == 0)
+            {
+                return KernelResult.InvalidSize;
+            }
+
+            if (address + size <= address)
+            {
+                return KernelResult.InvalidMemState;
+            }
+
+            if ((permission | MemoryPermission.Write) != MemoryPermission.ReadAndWrite)
+            {
+                return KernelResult.InvalidPermission;
+            }
+
+            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
+
+            KSharedMemory sharedMemory = currentProcess.HandleTable.GetObject<KSharedMemory>(handle);
+
+            if (sharedMemory == null)
+            {
+                return KernelResult.InvalidHandle;
+            }
+
+            if (currentProcess.MemoryManager.IsInvalidRegion  (address, size) ||
+                currentProcess.MemoryManager.InsideHeapRegion (address, size) ||
+                currentProcess.MemoryManager.InsideAliasRegion(address, size))
+            {
+                return KernelResult.InvalidMemRange;
+            }
+
+            return sharedMemory.MapIntoProcess(
+                currentProcess.MemoryManager,
+                address,
+                size,
+                currentProcess,
+                permission);
+        }
+
+        public KernelResult UnmapSharedMemory64(int handle, ulong address, ulong size)
+        {
+            return UnmapSharedMemory(handle, address, size);
+        }
+
+        private KernelResult UnmapSharedMemory(int handle, ulong address, ulong size)
+        {
+            if (!PageAligned(address))
+            {
+                return KernelResult.InvalidAddress;
+            }
+
+            if (!PageAligned(size) || size == 0)
+            {
+                return KernelResult.InvalidSize;
+            }
+
+            if (address + size <= address)
+            {
+                return KernelResult.InvalidMemState;
+            }
+
+            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
+
+            KSharedMemory sharedMemory = currentProcess.HandleTable.GetObject<KSharedMemory>(handle);
+
+            if (sharedMemory == null)
+            {
+                return KernelResult.InvalidHandle;
+            }
+
+            if (currentProcess.MemoryManager.IsInvalidRegion  (address, size) ||
+                currentProcess.MemoryManager.InsideHeapRegion (address, size) ||
+                currentProcess.MemoryManager.InsideAliasRegion(address, size))
+            {
+                return KernelResult.InvalidMemRange;
+            }
+
+            return sharedMemory.UnmapFromProcess(
+                currentProcess.MemoryManager,
+                address,
+                size,
+                currentProcess);
+        }
+
+        public KernelResult CreateTransferMemory64(
+            ulong            address,
+            ulong            size,
+            MemoryPermission permission,
+            out int          handle)
+        {
+            return CreateTransferMemory(address, size, permission, out handle);
+        }
+
+        private KernelResult CreateTransferMemory(ulong address, ulong size, MemoryPermission permission, out int handle)
+        {
+            handle = 0;
+
+            if (!PageAligned(address))
+            {
+                return KernelResult.InvalidAddress;
+            }
+
+            if (!PageAligned(size) || size == 0)
+            {
+                return KernelResult.InvalidSize;
+            }
+
+            if (address + size <= address)
+            {
+                return KernelResult.InvalidMemState;
+            }
+
+            if (permission > MemoryPermission.ReadAndWrite || permission == MemoryPermission.Write)
+            {
+                return KernelResult.InvalidPermission;
+            }
+
+            KernelResult result = _process.MemoryManager.ReserveTransferMemory(address, size, permission);
+
+            if (result != KernelResult.Success)
+            {
+                return result;
+            }
+
+            KTransferMemory transferMemory = new KTransferMemory(address, size);
+
+            return _process.HandleTable.GenerateHandle(transferMemory, out handle);
+        }
+
+        public KernelResult MapPhysicalMemory64(ulong address, ulong size)
+        {
+            return MapPhysicalMemory(address, size);
+        }
+
+        private KernelResult MapPhysicalMemory(ulong address, ulong size)
+        {
+            if (!PageAligned(address))
+            {
+                return KernelResult.InvalidAddress;
+            }
+
+            if (!PageAligned(size) || size == 0)
+            {
+                return KernelResult.InvalidSize;
+            }
+
+            if (address + size <= address)
+            {
+                return KernelResult.InvalidMemRange;
+            }
+
+            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
+
+            if ((currentProcess.PersonalMmHeapPagesCount & 0xfffffffffffff) == 0)
+            {
+                return KernelResult.InvalidState;
+            }
+
+            if (!currentProcess.MemoryManager.InsideAddrSpace   (address, size) ||
+                 currentProcess.MemoryManager.OutsideAliasRegion(address, size))
+            {
+                return KernelResult.InvalidMemRange;
+            }
+
+            return _process.MemoryManager.MapPhysicalMemory(address, size);
+        }
+
+        public KernelResult UnmapPhysicalMemory64(ulong address, ulong size)
+        {
+            return MapPhysicalMemory(address, size);
+        }
+
+        private KernelResult UnmapPhysicalMemory(ulong address, ulong size)
+        {
+            if (!PageAligned(address))
+            {
+                return KernelResult.InvalidAddress;
+            }
+
+            if (!PageAligned(size) || size == 0)
+            {
+                return KernelResult.InvalidSize;
+            }
+
+            if (address + size <= address)
+            {
+                return KernelResult.InvalidMemRange;
+            }
+
+            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
+
+            if ((currentProcess.PersonalMmHeapPagesCount & 0xfffffffffffff) == 0)
+            {
+                return KernelResult.InvalidState;
+            }
+
+            if (!currentProcess.MemoryManager.InsideAddrSpace   (address, size) ||
+                 currentProcess.MemoryManager.OutsideAliasRegion(address, size))
+            {
+                return KernelResult.InvalidMemRange;
+            }
+
+            return _process.MemoryManager.UnmapPhysicalMemory(address, size);
+        }
+
+        private static bool PageAligned(ulong position)
+        {
+            return (position & (KMemoryManager.PageSize - 1)) == 0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Kernel/SvcSystem.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcSystem.cs
similarity index 74%
rename from Ryujinx.HLE/HOS/Kernel/SvcSystem.cs
rename to Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcSystem.cs
index e42c2b4e..b0563356 100644
--- a/Ryujinx.HLE/HOS/Kernel/SvcSystem.cs
+++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcSystem.cs
@@ -1,27 +1,33 @@
 using ChocolArm64.Memory;
-using ChocolArm64.State;
 using Ryujinx.Common;
 using Ryujinx.Common.Logging;
 using Ryujinx.HLE.Exceptions;
 using Ryujinx.HLE.HOS.Ipc;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Ipc;
+using Ryujinx.HLE.HOS.Kernel.Memory;
+using Ryujinx.HLE.HOS.Kernel.Process;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using Ryujinx.HLE.HOS.Services;
-using System;
 using System.Threading;
 
-using static Ryujinx.HLE.HOS.ErrorCode;
-
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
 {
     partial class SvcHandler
     {
-        private void SvcExitProcess(CpuThreadState threadState)
+        public void ExitProcess64()
+        {
+            ExitProcess();
+        }
+
+        private void ExitProcess()
         {
             _system.Scheduler.GetCurrentProcess().Terminate();
         }
 
-        private void SignalEvent64(CpuThreadState threadState)
+        public KernelResult SignalEvent64(int handle)
         {
-            threadState.X0 = (ulong)SignalEvent((int)threadState.X0);
+            return SignalEvent(handle);
         }
 
         private KernelResult SignalEvent(int handle)
@@ -41,17 +47,12 @@ namespace Ryujinx.HLE.HOS.Kernel
                 result = KernelResult.InvalidHandle;
             }
 
-            if (result != KernelResult.Success)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, "Operation failed with error: " + result + "!");
-            }
-
             return result;
         }
 
-        private void ClearEvent64(CpuThreadState threadState)
+        public KernelResult ClearEvent64(int handle)
         {
-            threadState.X0 = (ulong)ClearEvent((int)threadState.X0);
+            return ClearEvent(handle);
         }
 
         private KernelResult ClearEvent(int handle)
@@ -71,29 +72,23 @@ namespace Ryujinx.HLE.HOS.Kernel
                 result = writableEvent.Clear();
             }
 
-            if (result != KernelResult.Success)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, "Operation failed with error: " + result + "!");
-            }
-
             return result;
         }
 
-        private void SvcCloseHandle(CpuThreadState threadState)
+        public KernelResult CloseHandle64(int handle)
         {
-            int handle = (int)threadState.X0;
+            return CloseHandle(handle);
+        }
 
+        private KernelResult CloseHandle(int handle)
+        {
             object obj = _process.HandleTable.GetObject<object>(handle);
 
             _process.HandleTable.CloseHandle(handle);
 
             if (obj == null)
             {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid handle 0x{handle:x8}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
-
-                return;
+                return KernelResult.InvalidHandle;
             }
 
             if (obj is KSession session)
@@ -107,12 +102,12 @@ namespace Ryujinx.HLE.HOS.Kernel
                     transferMemory.Size);
             }
 
-            threadState.X0 = 0;
+            return KernelResult.Success;
         }
 
-        private void ResetSignal64(CpuThreadState threadState)
+        public KernelResult ResetSignal64(int handle)
         {
-            threadState.X0 = (ulong)ResetSignal((int)threadState.X0);
+            return ResetSignal(handle);
         }
 
         private KernelResult ResetSignal(int handle)
@@ -141,60 +136,43 @@ namespace Ryujinx.HLE.HOS.Kernel
                 }
             }
 
-            if (result == KernelResult.InvalidState)
-            {
-                Logger.PrintDebug(LogClass.KernelSvc, "Operation failed with error: " + result + "!");
-            }
-            else if (result != KernelResult.Success)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, "Operation failed with error: " + result + "!");
-            }
-
             return result;
         }
 
-        private void SvcGetSystemTick(CpuThreadState threadState)
+        public ulong GetSystemTick64()
         {
-            threadState.X0 = threadState.CntpctEl0;
+            return _system.Scheduler.GetCurrentThread().Context.ThreadState.CntpctEl0;
         }
 
-        private void SvcConnectToNamedPort(CpuThreadState threadState)
+        public KernelResult ConnectToNamedPort64(ulong namePtr, out int handle)
         {
-            long stackPtr = (long)threadState.X0;
-            long namePtr  = (long)threadState.X1;
+            return ConnectToNamedPort(namePtr, out handle);
+        }
 
-            string name = MemoryHelper.ReadAsciiString(_memory, namePtr, 8);
+        private KernelResult ConnectToNamedPort(ulong namePtr, out int handle)
+        {
+            string name = MemoryHelper.ReadAsciiString(_memory, (long)namePtr, 8);
 
             //TODO: Validate that app has perms to access the service, and that the service
             //actually exists, return error codes otherwise.
             KSession session = new KSession(ServiceFactory.MakeService(_system, name), name);
 
-            if (_process.HandleTable.GenerateHandle(session, out int handle) != KernelResult.Success)
-            {
-                throw new InvalidOperationException("Out of handles!");
-            }
-
-            threadState.X0 = 0;
-            threadState.X1 = (uint)handle;
+            return _process.HandleTable.GenerateHandle(session, out handle);
         }
 
-        private void SvcSendSyncRequest(CpuThreadState threadState)
+        public KernelResult SendSyncRequest64(int handle)
         {
-            SendSyncRequest(threadState, threadState.Tpidr, 0x100, (int)threadState.X0);
+            return SendSyncRequest((ulong)_system.Scheduler.GetCurrentThread().Context.ThreadState.Tpidr, 0x100, handle);
         }
 
-        private void SvcSendSyncRequestWithUserBuffer(CpuThreadState threadState)
+        public KernelResult SendSyncRequestWithUserBuffer64(ulong messagePtr, ulong size, int handle)
         {
-            SendSyncRequest(
-                      threadState,
-                (long)threadState.X0,
-                (long)threadState.X1,
-                 (int)threadState.X2);
+            return SendSyncRequest(messagePtr, size, handle);
         }
 
-        private void SendSyncRequest(CpuThreadState threadState, long messagePtr, long size, int handle)
+        private KernelResult SendSyncRequest(ulong messagePtr, ulong size, int handle)
         {
-            byte[] messageData = _memory.ReadBytes(messagePtr, size);
+            byte[] messageData = _memory.ReadBytes((long)messagePtr, (long)size);
 
             KSession session = _process.HandleTable.GetObject<KSession>(handle);
 
@@ -205,29 +183,29 @@ namespace Ryujinx.HLE.HOS.Kernel
                 KThread currentThread = _system.Scheduler.GetCurrentThread();
 
                 currentThread.SignaledObj   = null;
-                currentThread.ObjSyncResult = 0;
+                currentThread.ObjSyncResult = KernelResult.Success;
 
                 currentThread.Reschedule(ThreadSchedState.Paused);
 
-                IpcMessage message = new IpcMessage(messageData, messagePtr);
+                IpcMessage message = new IpcMessage(messageData, (long)messagePtr);
 
                 ThreadPool.QueueUserWorkItem(ProcessIpcRequest, new HleIpcMessage(
                     currentThread,
                     session,
                     message,
-                    messagePtr));
+                    (long)messagePtr));
 
                 _system.ThreadCounter.AddCount();
 
                 _system.CriticalSection.Leave();
 
-                threadState.X0 = (ulong)currentThread.ObjSyncResult;
+                return currentThread.ObjSyncResult;
             }
             else
             {
                 Logger.PrintWarning(LogClass.KernelSvc, $"Invalid session handle 0x{handle:x8}!");
 
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
+                return KernelResult.InvalidHandle;
             }
         }
 
@@ -235,7 +213,7 @@ namespace Ryujinx.HLE.HOS.Kernel
         {
             HleIpcMessage ipcMessage = (HleIpcMessage)state;
 
-            ipcMessage.Thread.ObjSyncResult = (int)IpcHandler.IpcCall(
+            ipcMessage.Thread.ObjSyncResult = IpcHandler.IpcCall(
                 _device,
                 _process,
                 _memory,
@@ -248,14 +226,9 @@ namespace Ryujinx.HLE.HOS.Kernel
             ipcMessage.Thread.Reschedule(ThreadSchedState.Running);
         }
 
-        private void GetProcessId64(CpuThreadState threadState)
+        public KernelResult GetProcessId64(int handle, out long pid)
         {
-            int handle = (int)threadState.X1;
-
-            KernelResult result = GetProcessId(handle, out long pid);
-
-            threadState.X0 = (ulong)result;
-            threadState.X1 = (ulong)pid;
+            return GetProcessId(handle, out pid);
         }
 
         private KernelResult GetProcessId(int handle, out long pid)
@@ -283,15 +256,16 @@ namespace Ryujinx.HLE.HOS.Kernel
                 : KernelResult.InvalidHandle;
         }
 
-        private void SvcBreak(CpuThreadState threadState)
+        public void Break64(ulong reason, ulong x1, ulong info)
         {
-            long reason  = (long)threadState.X0;
-            long unknown = (long)threadState.X1;
-            long info    = (long)threadState.X2;
+            Break(reason);
+        }
 
+        private void Break(ulong reason)
+        {
             KThread currentThread = _system.Scheduler.GetCurrentThread();
 
-            if ((reason & (1 << 31)) == 0)
+            if ((reason & (1UL << 31)) == 0)
             {
                 currentThread.PrintGuestStackTrace();
 
@@ -305,29 +279,21 @@ namespace Ryujinx.HLE.HOS.Kernel
             }
         }
 
-        private void SvcOutputDebugString(CpuThreadState threadState)
+        public void OutputDebugString64(ulong strPtr, ulong size)
         {
-            long position = (long)threadState.X0;
-            long size     = (long)threadState.X1;
-
-            string str = MemoryHelper.ReadAsciiString(_memory, position, size);
-
-            Logger.PrintWarning(LogClass.KernelSvc, str);
-
-            threadState.X0 = 0;
+            OutputDebugString(strPtr, size);
         }
 
-        private void GetInfo64(CpuThreadState threadState)
+        private void OutputDebugString(ulong strPtr, ulong size)
         {
-            long stackPtr = (long)threadState.X0;
-            uint id       = (uint)threadState.X1;
-            int  handle   =  (int)threadState.X2;
-            long subId    = (long)threadState.X3;
+            string str = MemoryHelper.ReadAsciiString(_memory, (long)strPtr, (long)size);
 
-            KernelResult result = GetInfo(id, handle, subId, out long value);
+            Logger.PrintWarning(LogClass.KernelSvc, str);
+        }
 
-            threadState.X0 = (ulong)result;
-            threadState.X1 = (ulong)value;
+        public KernelResult GetInfo64(uint id, int handle, long subId, out long value)
+        {
+            return GetInfo(id, handle, subId, out value);
         }
 
         private KernelResult GetInfo(uint id, int handle, long subId, out long value)
@@ -556,13 +522,9 @@ namespace Ryujinx.HLE.HOS.Kernel
             return KernelResult.Success;
         }
 
-        private void CreateEvent64(CpuThreadState state)
+        public KernelResult CreateEvent64(out int wEventHandle, out int rEventHandle)
         {
-            KernelResult result = CreateEvent(out int wEventHandle, out int rEventHandle);
-
-            state.X0 = (ulong)result;
-            state.X1 = (ulong)wEventHandle;
-            state.X2 = (ulong)rEventHandle;
+            return CreateEvent(out wEventHandle, out rEventHandle);
         }
 
         private KernelResult CreateEvent(out int wEventHandle, out int rEventHandle)
@@ -588,15 +550,9 @@ namespace Ryujinx.HLE.HOS.Kernel
             return result;
         }
 
-        private void GetProcessList64(CpuThreadState state)
+        public KernelResult GetProcessList64(ulong address, int maxCount, out int count)
         {
-            ulong address =      state.X1;
-            int   maxOut  = (int)state.X2;
-
-            KernelResult result = GetProcessList(address, maxOut, out int count);
-
-            state.X0 = (ulong)result;
-            state.X1 = (ulong)count;
+            return GetProcessList(address, maxCount, out count);
         }
 
         private KernelResult GetProcessList(ulong address, int maxCount, out int count)
@@ -633,7 +589,7 @@ namespace Ryujinx.HLE.HOS.Kernel
                 {
                     if (copyCount < maxCount)
                     {
-                        if (!KernelTransfer.KernelToUserInt64(_system, (long)address + copyCount * 8, process.Pid))
+                        if (!KernelTransfer.KernelToUserInt64(_system, address + (ulong)copyCount * 8, process.Pid))
                         {
                             return KernelResult.UserCopyFailed;
                         }
@@ -648,16 +604,9 @@ namespace Ryujinx.HLE.HOS.Kernel
             return KernelResult.Success;
         }
 
-        private void GetSystemInfo64(CpuThreadState state)
+        public KernelResult GetSystemInfo64(uint id, int handle, long subId, out long value)
         {
-            uint id     = (uint)state.X1;
-            int  handle =  (int)state.X2;
-            long subId  = (long)state.X3;
-
-            KernelResult result = GetSystemInfo(id, handle, subId, out long value);
-
-            state.X0 = (ulong)result;
-            state.X1 = (ulong)value;
+            return GetSystemInfo(id, handle, subId, out value);
         }
 
         private KernelResult GetSystemInfo(uint id, int handle, long subId, out long value)
@@ -716,28 +665,20 @@ namespace Ryujinx.HLE.HOS.Kernel
             return KernelResult.Success;
         }
 
-        private void CreatePort64(CpuThreadState state)
+        public KernelResult CreatePort64(
+            int     maxSessions,
+            bool    isLight,
+            ulong   namePtr,
+            out int serverPortHandle,
+            out int clientPortHandle)
         {
-            int  maxSessions =  (int)state.X2;
-            bool isLight     =      (state.X3 & 1) != 0;
-            long nameAddress = (long)state.X4;
-
-            KernelResult result = CreatePort(
-                maxSessions,
-                isLight,
-                nameAddress,
-                out int serverPortHandle,
-                out int clientPortHandle);
-
-            state.X0 = (ulong)result;
-            state.X1 = (ulong)serverPortHandle;
-            state.X2 = (ulong)clientPortHandle;
+            return CreatePort(maxSessions, isLight, namePtr, out serverPortHandle, out clientPortHandle);
         }
 
         private KernelResult CreatePort(
             int     maxSessions,
             bool    isLight,
-            long    nameAddress,
+            ulong   namePtr,
             out int serverPortHandle,
             out int clientPortHandle)
         {
@@ -750,7 +691,7 @@ namespace Ryujinx.HLE.HOS.Kernel
 
             KPort port = new KPort(_system);
 
-            port.Initialize(maxSessions, isLight, nameAddress);
+            port.Initialize(maxSessions, isLight, (long)namePtr);
 
             KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
 
@@ -771,22 +712,16 @@ namespace Ryujinx.HLE.HOS.Kernel
             return result;
         }
 
-        private void ManageNamedPort64(CpuThreadState state)
+        public KernelResult ManageNamedPort64(ulong namePtr, int maxSessions, out int handle)
         {
-            long nameAddress = (long)state.X1;
-            int  maxSessions =  (int)state.X2;
-
-            KernelResult result = ManageNamedPort(nameAddress, maxSessions, out int handle);
-
-            state.X0 = (ulong)result;
-            state.X1 = (ulong)handle;
+            return ManageNamedPort(namePtr, maxSessions, out handle);
         }
 
-        private KernelResult ManageNamedPort(long nameAddress, int maxSessions, out int handle)
+        private KernelResult ManageNamedPort(ulong namePtr, int maxSessions, out int handle)
         {
             handle = 0;
 
-            if (!KernelTransfer.UserToKernelString(_system, nameAddress, 12, out string name))
+            if (!KernelTransfer.UserToKernelString(_system, namePtr, 12, out string name))
             {
                 return KernelResult.UserCopyFailed;
             }
diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs
new file mode 100644
index 00000000..a6111777
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs
@@ -0,0 +1,340 @@
+using ChocolArm64.State;
+using Ryujinx.Common.Logging;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Reflection.Emit;
+
+namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
+{
+    static class SvcTable
+    {
+        private const int SvcFuncMaxArguments = 8;
+
+        private static Dictionary<int, string> _svcFuncs64;
+
+        private static Action<SvcHandler, CpuThreadState>[] _svcTable64;
+
+        static SvcTable()
+        {
+            _svcFuncs64 = new Dictionary<int, string>
+            {
+                { 0x01, nameof(SvcHandler.SetHeapSize64)                   },
+                { 0x03, nameof(SvcHandler.SetMemoryAttribute64)            },
+                { 0x04, nameof(SvcHandler.MapMemory64)                     },
+                { 0x05, nameof(SvcHandler.UnmapMemory64)                   },
+                { 0x06, nameof(SvcHandler.QueryMemory64)                   },
+                { 0x07, nameof(SvcHandler.ExitProcess64)                   },
+                { 0x08, nameof(SvcHandler.CreateThread64)                  },
+                { 0x09, nameof(SvcHandler.StartThread64)                   },
+                { 0x0a, nameof(SvcHandler.ExitThread64)                    },
+                { 0x0b, nameof(SvcHandler.SleepThread64)                   },
+                { 0x0c, nameof(SvcHandler.GetThreadPriority64)             },
+                { 0x0d, nameof(SvcHandler.SetThreadPriority64)             },
+                { 0x0e, nameof(SvcHandler.GetThreadCoreMask64)             },
+                { 0x0f, nameof(SvcHandler.SetThreadCoreMask64)             },
+                { 0x10, nameof(SvcHandler.GetCurrentProcessorNumber64)     },
+                { 0x11, nameof(SvcHandler.SignalEvent64)                   },
+                { 0x12, nameof(SvcHandler.ClearEvent64)                    },
+                { 0x13, nameof(SvcHandler.MapSharedMemory64)               },
+                { 0x14, nameof(SvcHandler.UnmapSharedMemory64)             },
+                { 0x15, nameof(SvcHandler.CreateTransferMemory64)          },
+                { 0x16, nameof(SvcHandler.CloseHandle64)                   },
+                { 0x17, nameof(SvcHandler.ResetSignal64)                   },
+                { 0x18, nameof(SvcHandler.WaitSynchronization64)           },
+                { 0x19, nameof(SvcHandler.CancelSynchronization64)         },
+                { 0x1a, nameof(SvcHandler.ArbitrateLock64)                 },
+                { 0x1b, nameof(SvcHandler.ArbitrateUnlock64)               },
+                { 0x1c, nameof(SvcHandler.WaitProcessWideKeyAtomic64)      },
+                { 0x1d, nameof(SvcHandler.SignalProcessWideKey64)          },
+                { 0x1e, nameof(SvcHandler.GetSystemTick64)                 },
+                { 0x1f, nameof(SvcHandler.ConnectToNamedPort64)            },
+                { 0x21, nameof(SvcHandler.SendSyncRequest64)               },
+                { 0x22, nameof(SvcHandler.SendSyncRequestWithUserBuffer64) },
+                { 0x24, nameof(SvcHandler.GetProcessId64)                  },
+                { 0x25, nameof(SvcHandler.GetThreadId64)                   },
+                { 0x26, nameof(SvcHandler.Break64)                         },
+                { 0x27, nameof(SvcHandler.OutputDebugString64)             },
+                { 0x29, nameof(SvcHandler.GetInfo64)                       },
+                { 0x2c, nameof(SvcHandler.MapPhysicalMemory64)             },
+                { 0x2d, nameof(SvcHandler.UnmapPhysicalMemory64)           },
+                { 0x32, nameof(SvcHandler.SetThreadActivity64)             },
+                { 0x33, nameof(SvcHandler.GetThreadContext364)             },
+                { 0x34, nameof(SvcHandler.WaitForAddress64)                },
+                { 0x35, nameof(SvcHandler.SignalToAddress64)               },
+                { 0x45, nameof(SvcHandler.CreateEvent64)                   },
+                { 0x65, nameof(SvcHandler.GetProcessList64)                },
+                { 0x6f, nameof(SvcHandler.GetSystemInfo64)                 },
+                { 0x70, nameof(SvcHandler.CreatePort64)                    },
+                { 0x71, nameof(SvcHandler.ManageNamedPort64)               }
+            };
+
+            _svcTable64 = new Action<SvcHandler, CpuThreadState>[0x80];
+        }
+
+        public static Action<SvcHandler, CpuThreadState> GetSvcFunc(int svcId)
+        {
+            if (_svcTable64[svcId] != null)
+            {
+                return _svcTable64[svcId];
+            }
+
+            if (_svcFuncs64.TryGetValue(svcId, out string svcName))
+            {
+                return _svcTable64[svcId] = GenerateMethod(svcName);
+            }
+
+            return null;
+        }
+
+        private static Action<SvcHandler, CpuThreadState> GenerateMethod(string svcName)
+        {
+            Type[] argTypes = new Type[] { typeof(SvcHandler), typeof(CpuThreadState) };
+
+            DynamicMethod method = new DynamicMethod(svcName, null, argTypes);
+
+            MethodInfo methodInfo = typeof(SvcHandler).GetMethod(svcName);
+
+            ParameterInfo[] methodArgs = methodInfo.GetParameters();
+
+            if (methodArgs.Length > SvcFuncMaxArguments)
+            {
+                throw new InvalidOperationException($"Method \"{svcName}\" has too many arguments, max is 8.");
+            }
+
+            ILGenerator generator = method.GetILGenerator();
+
+            void ConvertToArgType(Type sourceType)
+            {
+                CheckIfTypeIsSupported(sourceType, svcName);
+
+                switch (Type.GetTypeCode(sourceType))
+                {
+                    case TypeCode.UInt32: generator.Emit(OpCodes.Conv_U4); 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.Boolean:
+                        generator.Emit(OpCodes.Conv_I4);
+                        generator.Emit(OpCodes.Ldc_I4_1);
+                        generator.Emit(OpCodes.And);
+                        break;
+                }
+            }
+
+            void ConvertToFieldType(Type sourceType)
+            {
+                CheckIfTypeIsSupported(sourceType, svcName);
+
+                switch (Type.GetTypeCode(sourceType))
+                {
+                    case TypeCode.UInt32:
+                    case TypeCode.Int32:
+                    case TypeCode.UInt16:
+                    case TypeCode.Int16:
+                    case TypeCode.Byte:
+                    case TypeCode.SByte:
+                    case TypeCode.Boolean:
+                        generator.Emit(OpCodes.Conv_U8);
+                        break;
+                }
+            }
+
+            //For functions returning output values, the first registers
+            //are used to hold pointers where the value will be stored,
+            //so they can't be used to pass argument and we must
+            //skip them.
+            int byRefArgsCount = 0;
+
+            for (int index = 0; index < methodArgs.Length; index++)
+            {
+                if (methodArgs[index].ParameterType.IsByRef)
+                {
+                    byRefArgsCount++;
+                }
+            }
+
+            //Print all the arguments for debugging purposes.
+            int inputArgsCount = methodArgs.Length - byRefArgsCount;
+
+            generator.Emit(OpCodes.Ldc_I4_S, inputArgsCount);
+
+            generator.Emit(OpCodes.Newarr, typeof(object));
+
+            string argsFormat = svcName;
+
+            for (int index = 0; index < inputArgsCount; index++)
+            {
+                argsFormat += $" {methodArgs[index].Name}: 0x{{{index}:X8}},";
+
+                generator.Emit(OpCodes.Dup);
+                generator.Emit(OpCodes.Ldc_I4_S, index);
+                generator.Emit(OpCodes.Conv_I);
+
+                generator.Emit(OpCodes.Ldarg_1);
+                generator.Emit(OpCodes.Ldfld, GetStateFieldX(byRefArgsCount + index));
+
+                generator.Emit(OpCodes.Box, typeof(ulong));
+
+                generator.Emit(OpCodes.Stelem_Ref);
+            }
+
+            argsFormat = argsFormat.Substring(0, argsFormat.Length - 1);
+
+            generator.Emit(OpCodes.Ldstr, argsFormat);
+
+            BindingFlags staticNonPublic = BindingFlags.NonPublic | BindingFlags.Static;
+
+            MethodInfo printArgsMethod = typeof(SvcTable).GetMethod(nameof(PrintArguments), staticNonPublic);
+
+            generator.Emit(OpCodes.Call, printArgsMethod);
+
+            //Call the SVC function handler.
+            generator.Emit(OpCodes.Ldarg_0);
+
+            List<LocalBuilder> locals = new List<LocalBuilder>();
+
+            for (int index = 0; index < methodArgs.Length; index++)
+            {
+                Type argType = methodArgs[index].ParameterType;
+
+                if (argType.IsByRef)
+                {
+                    argType = argType.GetElementType();
+
+                    LocalBuilder local = generator.DeclareLocal(argType);
+
+                    locals.Add(local);
+
+                    if (!methodArgs[index].IsOut)
+                    {
+                        throw new InvalidOperationException($"Method \"{svcName}\" has a invalid ref type \"{argType.Name}\".");
+                    }
+
+                    generator.Emit(OpCodes.Ldloca_S, (byte)local.LocalIndex);
+                }
+                else
+                {
+                    generator.Emit(OpCodes.Ldarg_1);
+                    generator.Emit(OpCodes.Ldfld, GetStateFieldX(byRefArgsCount + index));
+
+                    ConvertToArgType(argType);
+                }
+            }
+
+            generator.Emit(OpCodes.Call, methodInfo);
+
+            int outRegIndex = 0;
+
+            Type retType = methodInfo.ReturnType;
+
+            //Print result code.
+            if (retType == typeof(KernelResult))
+            {
+                MethodInfo printResultMethod = typeof(SvcTable).GetMethod(nameof(PrintResult), staticNonPublic);
+
+                generator.Emit(OpCodes.Dup);
+                generator.Emit(OpCodes.Ldstr, svcName);
+                generator.Emit(OpCodes.Call, printResultMethod);
+            }
+
+            //Save return value into register X0 (when the method has a return value).
+            if (retType != typeof(void))
+            {
+                CheckIfTypeIsSupported(retType, svcName);
+
+                LocalBuilder tempLocal = generator.DeclareLocal(retType);
+
+                generator.Emit(OpCodes.Stloc, tempLocal);
+                generator.Emit(OpCodes.Ldarg_1);
+                generator.Emit(OpCodes.Ldloc, tempLocal);
+
+                ConvertToFieldType(retType);
+
+                generator.Emit(OpCodes.Stfld, GetStateFieldX(outRegIndex++));
+            }
+
+            for (int index = 0; index < locals.Count; index++)
+            {
+                generator.Emit(OpCodes.Ldarg_1);
+                generator.Emit(OpCodes.Ldloc, locals[index]);
+
+                ConvertToFieldType(locals[index].LocalType);
+
+                generator.Emit(OpCodes.Stfld, GetStateFieldX(outRegIndex++));
+            }
+
+            //Zero out the remaining unused registers.
+            while (outRegIndex < SvcFuncMaxArguments)
+            {
+                generator.Emit(OpCodes.Ldarg_1);
+                generator.Emit(OpCodes.Ldc_I8, 0L);
+                generator.Emit(OpCodes.Stfld, GetStateFieldX(outRegIndex++));
+            }
+
+            generator.Emit(OpCodes.Ret);
+
+            return (Action<SvcHandler, CpuThreadState>)method.CreateDelegate(typeof(Action<SvcHandler, CpuThreadState>));
+        }
+
+        private static FieldInfo GetStateFieldX(int index)
+        {
+            switch (index)
+            {
+                case 0: return typeof(CpuThreadState).GetField(nameof(CpuThreadState.X0));
+                case 1: return typeof(CpuThreadState).GetField(nameof(CpuThreadState.X1));
+                case 2: return typeof(CpuThreadState).GetField(nameof(CpuThreadState.X2));
+                case 3: return typeof(CpuThreadState).GetField(nameof(CpuThreadState.X3));
+                case 4: return typeof(CpuThreadState).GetField(nameof(CpuThreadState.X4));
+                case 5: return typeof(CpuThreadState).GetField(nameof(CpuThreadState.X5));
+                case 6: return typeof(CpuThreadState).GetField(nameof(CpuThreadState.X6));
+                case 7: return typeof(CpuThreadState).GetField(nameof(CpuThreadState.X7));
+            }
+
+            throw new ArgumentOutOfRangeException(nameof(index));
+        }
+
+        private static void CheckIfTypeIsSupported(Type type, string svcName)
+        {
+            switch (Type.GetTypeCode(type))
+            {
+                case TypeCode.UInt64:
+                case TypeCode.Int64:
+                case TypeCode.UInt32:
+                case TypeCode.Int32:
+                case TypeCode.UInt16:
+                case TypeCode.Int16:
+                case TypeCode.Byte:
+                case TypeCode.SByte:
+                case TypeCode.Boolean:
+                    return;
+            }
+
+            throw new InvalidSvcException($"Method \"{svcName}\" has a invalid ref type \"{type.Name}\".");
+        }
+
+        private static void PrintResult(KernelResult result, string svcName)
+        {
+            if (result != KernelResult.Success   &&
+                result != KernelResult.TimedOut  &&
+                result != KernelResult.Cancelled &&
+                result != KernelResult.InvalidState)
+            {
+                Logger.PrintWarning(LogClass.KernelSvc, $"{svcName} returned error {result}.");
+            }
+            else
+            {
+                Logger.PrintDebug(LogClass.KernelSvc, $"{svcName} returned result {result}.");
+            }
+        }
+
+        private static void PrintArguments(object[] argValues, string format)
+        {
+            Logger.PrintDebug(LogClass.KernelSvc, string.Format(format, argValues));
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcThread.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcThread.cs
new file mode 100644
index 00000000..1e1927fe
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcThread.cs
@@ -0,0 +1,420 @@
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Process;
+using Ryujinx.HLE.HOS.Kernel.Threading;
+
+namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
+{
+    partial class SvcHandler
+    {
+        public KernelResult CreateThread64(
+            ulong   entrypoint,
+            ulong   argsPtr,
+            ulong   stackTop,
+            int     priority,
+            int     cpuCore,
+            out int handle)
+        {
+            return CreateThread(entrypoint, argsPtr, stackTop, priority, cpuCore, out handle);
+        }
+
+        private KernelResult CreateThread(
+            ulong   entrypoint,
+            ulong   argsPtr,
+            ulong   stackTop,
+            int     priority,
+            int     cpuCore,
+            out int handle)
+        {
+            handle = 0;
+
+            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
+
+            if (cpuCore == -2)
+            {
+                cpuCore = currentProcess.DefaultCpuCore;
+            }
+
+            if ((uint)cpuCore >= KScheduler.CpuCoresCount || !currentProcess.IsCpuCoreAllowed(cpuCore))
+            {
+                return KernelResult.InvalidCpuCore;
+            }
+
+            if ((uint)priority >= KScheduler.PrioritiesCount || !currentProcess.IsPriorityAllowed(priority))
+            {
+                return KernelResult.InvalidPriority;
+            }
+
+            long timeout = KTimeManager.ConvertMillisecondsToNanoseconds(100);
+
+            if (currentProcess.ResourceLimit != null &&
+               !currentProcess.ResourceLimit.Reserve(LimitableResource.Thread, 1, timeout))
+            {
+                return KernelResult.ResLimitExceeded;
+            }
+
+            KThread thread = new KThread(_system);
+
+            KernelResult result = currentProcess.InitializeThread(
+                thread,
+                entrypoint,
+                argsPtr,
+                stackTop,
+                priority,
+                cpuCore);
+
+            if (result != KernelResult.Success)
+            {
+                currentProcess.ResourceLimit?.Release(LimitableResource.Thread, 1);
+
+                return result;
+            }
+
+            result = _process.HandleTable.GenerateHandle(thread, out handle);
+
+            if (result != KernelResult.Success)
+            {
+                thread.Terminate();
+
+                currentProcess.ResourceLimit?.Release(LimitableResource.Thread, 1);
+            }
+
+            return result;
+        }
+
+        public KernelResult StartThread64(int handle)
+        {
+            return StartThread(handle);
+        }
+
+        private KernelResult StartThread(int handle)
+        {
+            KThread thread = _process.HandleTable.GetObject<KThread>(handle);
+
+            if (thread != null)
+            {
+                return thread.Start();
+            }
+            else
+            {
+                return KernelResult.InvalidHandle;
+            }
+        }
+
+        public void ExitThread64()
+        {
+            ExitThread();
+        }
+
+        private void ExitThread()
+        {
+            KThread currentThread = _system.Scheduler.GetCurrentThread();
+
+            _system.Scheduler.ExitThread(currentThread);
+
+            currentThread.Exit();
+        }
+
+        public void SleepThread64(long timeout)
+        {
+            SleepThread(timeout);
+        }
+
+        private void SleepThread(long timeout)
+        {
+            KThread currentThread = _system.Scheduler.GetCurrentThread();
+
+            if (timeout < 1)
+            {
+                switch (timeout)
+                {
+                    case  0: currentThread.Yield();                        break;
+                    case -1: currentThread.YieldWithLoadBalancing();       break;
+                    case -2: currentThread.YieldAndWaitForLoadBalancing(); break;
+                }
+            }
+            else
+            {
+                currentThread.Sleep(timeout);
+            }
+        }
+
+        public KernelResult GetThreadPriority64(int handle, out int priority)
+        {
+            return GetThreadPriority(handle, out priority);
+        }
+
+        private KernelResult GetThreadPriority(int handle, out int priority)
+        {
+            KThread thread = _process.HandleTable.GetKThread(handle);
+
+            if (thread != null)
+            {
+                priority = thread.DynamicPriority;
+
+                return KernelResult.Success;
+            }
+            else
+            {
+                priority = 0;
+
+                return KernelResult.InvalidHandle;
+            }
+        }
+
+        public KernelResult SetThreadPriority64(int handle, int priority)
+        {
+            return SetThreadPriority(handle, priority);
+        }
+
+        public KernelResult SetThreadPriority(int handle, int priority)
+        {
+            //TODO: NPDM check.
+
+            KThread thread = _process.HandleTable.GetKThread(handle);
+
+            if (thread == null)
+            {
+                return KernelResult.InvalidHandle;
+            }
+
+            thread.SetPriority(priority);
+
+            return KernelResult.Success;
+        }
+
+        public KernelResult GetThreadCoreMask64(int handle, out int preferredCore, out long affinityMask)
+        {
+            return GetThreadCoreMask(handle, out preferredCore, out affinityMask);
+        }
+
+        private KernelResult GetThreadCoreMask(int handle, out int preferredCore, out long affinityMask)
+        {
+            KThread thread = _process.HandleTable.GetKThread(handle);
+
+            if (thread != null)
+            {
+                preferredCore = thread.PreferredCore;
+                affinityMask  = thread.AffinityMask;
+
+                return KernelResult.Success;
+            }
+            else
+            {
+                preferredCore = 0;
+                affinityMask  = 0;
+
+                return KernelResult.InvalidHandle;
+            }
+        }
+
+        public KernelResult SetThreadCoreMask64(int handle, int preferredCore, long affinityMask)
+        {
+            return SetThreadCoreMask(handle, preferredCore, affinityMask);
+        }
+
+        private KernelResult SetThreadCoreMask(int handle, int preferredCore, long affinityMask)
+        {
+            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
+
+            if (preferredCore == -2)
+            {
+                preferredCore = currentProcess.DefaultCpuCore;
+
+                affinityMask = 1 << preferredCore;
+            }
+            else
+            {
+                if ((currentProcess.Capabilities.AllowedCpuCoresMask | affinityMask) !=
+                     currentProcess.Capabilities.AllowedCpuCoresMask)
+                {
+                    return KernelResult.InvalidCpuCore;
+                }
+
+                if (affinityMask == 0)
+                {
+                    return KernelResult.InvalidCombination;
+                }
+
+                if ((uint)preferredCore > 3)
+                {
+                    if ((preferredCore | 2) != -1)
+                    {
+                        return KernelResult.InvalidCpuCore;
+                    }
+                }
+                else if ((affinityMask & (1 << preferredCore)) == 0)
+                {
+                    return KernelResult.InvalidCombination;
+                }
+            }
+
+            KThread thread = _process.HandleTable.GetKThread(handle);
+
+            if (thread == null)
+            {
+                return KernelResult.InvalidHandle;
+            }
+
+            return thread.SetCoreAndAffinityMask(preferredCore, affinityMask);
+        }
+
+        public int GetCurrentProcessorNumber64()
+        {
+            return _system.Scheduler.GetCurrentThread().CurrentCore;
+        }
+
+        public KernelResult GetThreadId64(int handle, out long threadUid)
+        {
+            return GetThreadId(handle, out threadUid);
+        }
+
+        private KernelResult GetThreadId(int handle, out long threadUid)
+        {
+            KThread thread = _process.HandleTable.GetKThread(handle);
+
+            if (thread != null)
+            {
+                threadUid = thread.ThreadUid;
+
+                return KernelResult.Success;
+            }
+            else
+            {
+                threadUid = 0;
+
+                return KernelResult.InvalidHandle;
+            }
+        }
+
+        public KernelResult SetThreadActivity64(int handle, bool pause)
+        {
+            return SetThreadActivity(handle, pause);
+        }
+
+        private KernelResult SetThreadActivity(int handle, bool pause)
+        {
+            KThread thread = _process.HandleTable.GetObject<KThread>(handle);
+
+            if (thread == null)
+            {
+                return KernelResult.InvalidHandle;
+            }
+
+            if (thread.Owner != _system.Scheduler.GetCurrentProcess())
+            {
+                return KernelResult.InvalidHandle;
+            }
+
+            if (thread == _system.Scheduler.GetCurrentThread())
+            {
+                return KernelResult.InvalidThread;
+            }
+
+            return thread.SetActivity(pause);
+        }
+
+        public KernelResult GetThreadContext364(ulong address, int handle)
+        {
+            return GetThreadContext3(address, handle);
+        }
+
+        private KernelResult GetThreadContext3(ulong address, int handle)
+        {
+            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
+            KThread  currentThread  = _system.Scheduler.GetCurrentThread();
+
+            KThread thread = _process.HandleTable.GetObject<KThread>(handle);
+
+            if (thread == null)
+            {
+                return KernelResult.InvalidHandle;
+            }
+
+            if (thread.Owner != currentProcess)
+            {
+                return KernelResult.InvalidHandle;
+            }
+
+            if (currentThread == thread)
+            {
+                return KernelResult.InvalidThread;
+            }
+
+            _memory.WriteUInt64((long)address + 0x0,  thread.Context.ThreadState.X0);
+            _memory.WriteUInt64((long)address + 0x8,  thread.Context.ThreadState.X1);
+            _memory.WriteUInt64((long)address + 0x10, thread.Context.ThreadState.X2);
+            _memory.WriteUInt64((long)address + 0x18, thread.Context.ThreadState.X3);
+            _memory.WriteUInt64((long)address + 0x20, thread.Context.ThreadState.X4);
+            _memory.WriteUInt64((long)address + 0x28, thread.Context.ThreadState.X5);
+            _memory.WriteUInt64((long)address + 0x30, thread.Context.ThreadState.X6);
+            _memory.WriteUInt64((long)address + 0x38, thread.Context.ThreadState.X7);
+            _memory.WriteUInt64((long)address + 0x40, thread.Context.ThreadState.X8);
+            _memory.WriteUInt64((long)address + 0x48, thread.Context.ThreadState.X9);
+            _memory.WriteUInt64((long)address + 0x50, thread.Context.ThreadState.X10);
+            _memory.WriteUInt64((long)address + 0x58, thread.Context.ThreadState.X11);
+            _memory.WriteUInt64((long)address + 0x60, thread.Context.ThreadState.X12);
+            _memory.WriteUInt64((long)address + 0x68, thread.Context.ThreadState.X13);
+            _memory.WriteUInt64((long)address + 0x70, thread.Context.ThreadState.X14);
+            _memory.WriteUInt64((long)address + 0x78, thread.Context.ThreadState.X15);
+            _memory.WriteUInt64((long)address + 0x80, thread.Context.ThreadState.X16);
+            _memory.WriteUInt64((long)address + 0x88, thread.Context.ThreadState.X17);
+            _memory.WriteUInt64((long)address + 0x90, thread.Context.ThreadState.X18);
+            _memory.WriteUInt64((long)address + 0x98, thread.Context.ThreadState.X19);
+            _memory.WriteUInt64((long)address + 0xa0, thread.Context.ThreadState.X20);
+            _memory.WriteUInt64((long)address + 0xa8, thread.Context.ThreadState.X21);
+            _memory.WriteUInt64((long)address + 0xb0, thread.Context.ThreadState.X22);
+            _memory.WriteUInt64((long)address + 0xb8, thread.Context.ThreadState.X23);
+            _memory.WriteUInt64((long)address + 0xc0, thread.Context.ThreadState.X24);
+            _memory.WriteUInt64((long)address + 0xc8, thread.Context.ThreadState.X25);
+            _memory.WriteUInt64((long)address + 0xd0, thread.Context.ThreadState.X26);
+            _memory.WriteUInt64((long)address + 0xd8, thread.Context.ThreadState.X27);
+            _memory.WriteUInt64((long)address + 0xe0, thread.Context.ThreadState.X28);
+            _memory.WriteUInt64((long)address + 0xe8, thread.Context.ThreadState.X29);
+            _memory.WriteUInt64((long)address + 0xf0, thread.Context.ThreadState.X30);
+            _memory.WriteUInt64((long)address + 0xf8, thread.Context.ThreadState.X31);
+
+            _memory.WriteInt64((long)address + 0x100, thread.LastPc);
+
+            _memory.WriteUInt64((long)address + 0x108, (ulong)thread.Context.ThreadState.Psr);
+
+            _memory.WriteVector128((long)address + 0x110, thread.Context.ThreadState.V0);
+            _memory.WriteVector128((long)address + 0x120, thread.Context.ThreadState.V1);
+            _memory.WriteVector128((long)address + 0x130, thread.Context.ThreadState.V2);
+            _memory.WriteVector128((long)address + 0x140, thread.Context.ThreadState.V3);
+            _memory.WriteVector128((long)address + 0x150, thread.Context.ThreadState.V4);
+            _memory.WriteVector128((long)address + 0x160, thread.Context.ThreadState.V5);
+            _memory.WriteVector128((long)address + 0x170, thread.Context.ThreadState.V6);
+            _memory.WriteVector128((long)address + 0x180, thread.Context.ThreadState.V7);
+            _memory.WriteVector128((long)address + 0x190, thread.Context.ThreadState.V8);
+            _memory.WriteVector128((long)address + 0x1a0, thread.Context.ThreadState.V9);
+            _memory.WriteVector128((long)address + 0x1b0, thread.Context.ThreadState.V10);
+            _memory.WriteVector128((long)address + 0x1c0, thread.Context.ThreadState.V11);
+            _memory.WriteVector128((long)address + 0x1d0, thread.Context.ThreadState.V12);
+            _memory.WriteVector128((long)address + 0x1e0, thread.Context.ThreadState.V13);
+            _memory.WriteVector128((long)address + 0x1f0, thread.Context.ThreadState.V14);
+            _memory.WriteVector128((long)address + 0x200, thread.Context.ThreadState.V15);
+            _memory.WriteVector128((long)address + 0x210, thread.Context.ThreadState.V16);
+            _memory.WriteVector128((long)address + 0x220, thread.Context.ThreadState.V17);
+            _memory.WriteVector128((long)address + 0x230, thread.Context.ThreadState.V18);
+            _memory.WriteVector128((long)address + 0x240, thread.Context.ThreadState.V19);
+            _memory.WriteVector128((long)address + 0x250, thread.Context.ThreadState.V20);
+            _memory.WriteVector128((long)address + 0x260, thread.Context.ThreadState.V21);
+            _memory.WriteVector128((long)address + 0x270, thread.Context.ThreadState.V22);
+            _memory.WriteVector128((long)address + 0x280, thread.Context.ThreadState.V23);
+            _memory.WriteVector128((long)address + 0x290, thread.Context.ThreadState.V24);
+            _memory.WriteVector128((long)address + 0x2a0, thread.Context.ThreadState.V25);
+            _memory.WriteVector128((long)address + 0x2b0, thread.Context.ThreadState.V26);
+            _memory.WriteVector128((long)address + 0x2c0, thread.Context.ThreadState.V27);
+            _memory.WriteVector128((long)address + 0x2d0, thread.Context.ThreadState.V28);
+            _memory.WriteVector128((long)address + 0x2e0, thread.Context.ThreadState.V29);
+            _memory.WriteVector128((long)address + 0x2f0, thread.Context.ThreadState.V30);
+            _memory.WriteVector128((long)address + 0x300, thread.Context.ThreadState.V31);
+
+            _memory.WriteInt32((long)address + 0x310, thread.Context.ThreadState.Fpcr);
+            _memory.WriteInt32((long)address + 0x314, thread.Context.ThreadState.Fpsr);
+            _memory.WriteInt64((long)address + 0x318, thread.Context.ThreadState.Tpidr);
+
+            return KernelResult.Success;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcThreadSync.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcThreadSync.cs
new file mode 100644
index 00000000..ecda9e2d
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcThreadSync.cs
@@ -0,0 +1,250 @@
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Process;
+using Ryujinx.HLE.HOS.Kernel.Threading;
+using System.Collections.Generic;
+
+namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
+{
+    partial class SvcHandler
+    {
+        public KernelResult WaitSynchronization64(ulong handlesPtr, int handlesCount, long timeout, out int handleIndex)
+        {
+            return WaitSynchronization(handlesPtr, handlesCount, timeout, out handleIndex);
+        }
+
+        private KernelResult WaitSynchronization(ulong handlesPtr, int handlesCount, long timeout, out int handleIndex)
+        {
+            handleIndex = 0;
+
+            if ((uint)handlesCount > 0x40)
+            {
+                return KernelResult.MaximumExceeded;
+            }
+
+            List<KSynchronizationObject> syncObjs = new List<KSynchronizationObject>();
+
+            for (int index = 0; index < handlesCount; index++)
+            {
+                int handle = _memory.ReadInt32((long)handlesPtr + index * 4);
+
+                KSynchronizationObject syncObj = _process.HandleTable.GetObject<KSynchronizationObject>(handle);
+
+                if (syncObj == null)
+                {
+                    break;
+                }
+
+                syncObjs.Add(syncObj);
+            }
+
+            return _system.Synchronization.WaitFor(syncObjs.ToArray(), timeout, out handleIndex);
+        }
+
+        public KernelResult CancelSynchronization64(int handle)
+        {
+            return CancelSynchronization(handle);
+        }
+
+        private KernelResult CancelSynchronization(int handle)
+        {
+            KThread thread = _process.HandleTable.GetKThread(handle);
+
+            if (thread == null)
+            {
+                return KernelResult.InvalidHandle;
+            }
+
+            thread.CancelSynchronization();
+
+            return KernelResult.Success;
+        }
+
+        public KernelResult ArbitrateLock64(int ownerHandle, ulong mutexAddress, int requesterHandle)
+        {
+            return ArbitrateLock(ownerHandle, mutexAddress, requesterHandle);
+        }
+
+        private KernelResult ArbitrateLock(int ownerHandle, ulong mutexAddress, int requesterHandle)
+        {
+            if (IsPointingInsideKernel(mutexAddress))
+            {
+                return KernelResult.InvalidMemState;
+            }
+
+            if (IsAddressNotWordAligned(mutexAddress))
+            {
+                return KernelResult.InvalidAddress;
+            }
+
+            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
+
+            return currentProcess.AddressArbiter.ArbitrateLock(ownerHandle, mutexAddress, requesterHandle);
+        }
+
+        public KernelResult ArbitrateUnlock64(ulong mutexAddress)
+        {
+            return ArbitrateUnlock(mutexAddress);
+        }
+
+        private KernelResult ArbitrateUnlock(ulong mutexAddress)
+        {
+            if (IsPointingInsideKernel(mutexAddress))
+            {
+                return KernelResult.InvalidMemState;
+            }
+
+            if (IsAddressNotWordAligned(mutexAddress))
+            {
+                return KernelResult.InvalidAddress;
+            }
+
+            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
+
+            return currentProcess.AddressArbiter.ArbitrateUnlock(mutexAddress);
+        }
+
+        public KernelResult WaitProcessWideKeyAtomic64(
+            ulong mutexAddress,
+            ulong condVarAddress,
+            int   handle,
+            long  timeout)
+        {
+            return WaitProcessWideKeyAtomic(mutexAddress, condVarAddress, handle, timeout);
+        }
+
+        private KernelResult WaitProcessWideKeyAtomic(
+            ulong mutexAddress,
+            ulong condVarAddress,
+            int   handle,
+            long  timeout)
+        {
+            if (IsPointingInsideKernel(mutexAddress))
+            {
+                return KernelResult.InvalidMemState;
+            }
+
+            if (IsAddressNotWordAligned(mutexAddress))
+            {
+                return KernelResult.InvalidAddress;
+            }
+
+            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
+
+            return currentProcess.AddressArbiter.WaitProcessWideKeyAtomic(
+                mutexAddress,
+                condVarAddress,
+                handle,
+                timeout);
+        }
+
+        public KernelResult SignalProcessWideKey64(ulong address, int count)
+        {
+            return SignalProcessWideKey(address, count);
+        }
+
+        private KernelResult SignalProcessWideKey(ulong address, int count)
+        {
+            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
+
+            currentProcess.AddressArbiter.SignalProcessWideKey(address, count);
+
+            return KernelResult.Success;
+        }
+
+        public KernelResult WaitForAddress64(ulong address, ArbitrationType type, int value, long timeout)
+        {
+            return WaitForAddress(address, type, value, timeout);
+        }
+
+        private KernelResult WaitForAddress(ulong address, ArbitrationType type, int value, long timeout)
+        {
+            if (IsPointingInsideKernel(address))
+            {
+                return KernelResult.InvalidMemState;
+            }
+
+            if (IsAddressNotWordAligned(address))
+            {
+                return KernelResult.InvalidAddress;
+            }
+
+            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
+
+            KernelResult result;
+
+            switch (type)
+            {
+                case ArbitrationType.WaitIfLessThan:
+                    result = currentProcess.AddressArbiter.WaitForAddressIfLessThan(address, value, false, timeout);
+                    break;
+
+                case ArbitrationType.DecrementAndWaitIfLessThan:
+                    result = currentProcess.AddressArbiter.WaitForAddressIfLessThan(address, value, true, timeout);
+                    break;
+
+                case ArbitrationType.WaitIfEqual:
+                    result = currentProcess.AddressArbiter.WaitForAddressIfEqual(address, value, timeout);
+                    break;
+
+                default:
+                    result = KernelResult.InvalidEnumValue;
+                    break;
+            }
+
+            return result;
+        }
+
+        public KernelResult SignalToAddress64(ulong address, SignalType type, int value, int count)
+        {
+            return SignalToAddress(address, type, value, count);
+        }
+
+        private KernelResult SignalToAddress(ulong address, SignalType type, int value, int count)
+        {
+            if (IsPointingInsideKernel(address))
+            {
+                return KernelResult.InvalidMemState;
+            }
+
+            if (IsAddressNotWordAligned(address))
+            {
+                return KernelResult.InvalidAddress;
+            }
+
+            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
+
+            KernelResult result;
+
+            switch (type)
+            {
+                case SignalType.Signal:
+                    result = currentProcess.AddressArbiter.Signal(address, count);
+                    break;
+
+                case SignalType.SignalAndIncrementIfEqual:
+                    result = currentProcess.AddressArbiter.SignalAndIncrementIfEqual(address, value, count);
+                    break;
+
+                case SignalType.SignalAndModifyIfEqual:
+                    result = currentProcess.AddressArbiter.SignalAndModifyIfEqual(address, value, count);
+                    break;
+
+                default:
+                    result = KernelResult.InvalidEnumValue;
+                    break;
+            }
+
+            return result;
+        }
+
+        private bool IsPointingInsideKernel(ulong address)
+        {
+            return (address + 0x1000000000) < 0xffffff000;
+        }
+
+        private bool IsAddressNotWordAligned(ulong address)
+        {
+            return (address & 3) != 0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Kernel/SvcHandler.cs b/Ryujinx.HLE/HOS/Kernel/SvcHandler.cs
deleted file mode 100644
index 78a0cc85..00000000
--- a/Ryujinx.HLE/HOS/Kernel/SvcHandler.cs
+++ /dev/null
@@ -1,122 +0,0 @@
-using ChocolArm64.Events;
-using ChocolArm64.Memory;
-using ChocolArm64.State;
-using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.Common.Logging;
-using System;
-using System.Collections.Generic;
-
-namespace Ryujinx.HLE.HOS.Kernel
-{
-    partial class SvcHandler
-    {
-        private delegate void SvcFunc(CpuThreadState threadState);
-
-        private Dictionary<int, SvcFunc> _svcFuncs;
-
-        private Switch        _device;
-        private KProcess      _process;
-        private Horizon       _system;
-        private MemoryManager _memory;
-
-        private struct HleIpcMessage
-        {
-            public KThread    Thread     { get; private set; }
-            public KSession   Session    { get; private set; }
-            public IpcMessage Message    { get; private set; }
-            public long       MessagePtr { get; private set; }
-
-            public HleIpcMessage(
-                KThread    thread,
-                KSession   session,
-                IpcMessage message,
-                long       messagePtr)
-            {
-                Thread     = thread;
-                Session    = session;
-                Message    = message;
-                MessagePtr = messagePtr;
-            }
-        }
-
-        public SvcHandler(Switch device, KProcess process)
-        {
-            _svcFuncs = new Dictionary<int, SvcFunc>
-            {
-                { 0x01, SvcSetHeapSize                   },
-                { 0x03, SvcSetMemoryAttribute            },
-                { 0x04, SvcMapMemory                     },
-                { 0x05, SvcUnmapMemory                   },
-                { 0x06, SvcQueryMemory                   },
-                { 0x07, SvcExitProcess                   },
-                { 0x08, CreateThread64                   },
-                { 0x09, SvcStartThread                   },
-                { 0x0a, SvcExitThread                    },
-                { 0x0b, SvcSleepThread                   },
-                { 0x0c, SvcGetThreadPriority             },
-                { 0x0d, SvcSetThreadPriority             },
-                { 0x0e, SvcGetThreadCoreMask             },
-                { 0x0f, SetThreadCoreMask64              },
-                { 0x10, SvcGetCurrentProcessorNumber     },
-                { 0x11, SignalEvent64                    },
-                { 0x12, ClearEvent64                     },
-                { 0x13, SvcMapSharedMemory               },
-                { 0x14, SvcUnmapSharedMemory             },
-                { 0x15, SvcCreateTransferMemory          },
-                { 0x16, SvcCloseHandle                   },
-                { 0x17, ResetSignal64                    },
-                { 0x18, SvcWaitSynchronization           },
-                { 0x19, SvcCancelSynchronization         },
-                { 0x1a, SvcArbitrateLock                 },
-                { 0x1b, SvcArbitrateUnlock               },
-                { 0x1c, SvcWaitProcessWideKeyAtomic      },
-                { 0x1d, SvcSignalProcessWideKey          },
-                { 0x1e, SvcGetSystemTick                 },
-                { 0x1f, SvcConnectToNamedPort            },
-                { 0x21, SvcSendSyncRequest               },
-                { 0x22, SvcSendSyncRequestWithUserBuffer },
-                { 0x24, GetProcessId64                   },
-                { 0x25, SvcGetThreadId                   },
-                { 0x26, SvcBreak                         },
-                { 0x27, SvcOutputDebugString             },
-                { 0x29, GetInfo64                        },
-                { 0x2c, SvcMapPhysicalMemory             },
-                { 0x2d, SvcUnmapPhysicalMemory           },
-                { 0x32, SvcSetThreadActivity             },
-                { 0x33, SvcGetThreadContext3             },
-                { 0x34, SvcWaitForAddress                },
-                { 0x35, SvcSignalToAddress               },
-                { 0x45, CreateEvent64                    },
-                { 0x65, GetProcessList64                 },
-                { 0x6f, GetSystemInfo64                  },
-                { 0x70, CreatePort64                     },
-                { 0x71, ManageNamedPort64                }
-            };
-
-            _device  = device;
-            _process = process;
-            _system  = device.System;
-            _memory  = process.CpuMemory;
-        }
-
-        public void SvcCall(object sender, InstExceptionEventArgs e)
-        {
-            CpuThreadState threadState = (CpuThreadState)sender;
-
-            if (_svcFuncs.TryGetValue(e.Id, out SvcFunc func))
-            {
-                Logger.PrintDebug(LogClass.KernelSvc, $"{func.Method.Name} called.");
-
-                func(threadState);
-
-                Logger.PrintDebug(LogClass.KernelSvc, $"{func.Method.Name} ended.");
-            }
-            else
-            {
-                //Process.PrintStackTrace(ThreadState);
-
-                throw new NotImplementedException($"0x{e.Id:x4}");
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Kernel/SvcMemory.cs b/Ryujinx.HLE/HOS/Kernel/SvcMemory.cs
deleted file mode 100644
index c99c1e98..00000000
--- a/Ryujinx.HLE/HOS/Kernel/SvcMemory.cs
+++ /dev/null
@@ -1,581 +0,0 @@
-using ChocolArm64.State;
-using Ryujinx.Common.Logging;
-
-using static Ryujinx.HLE.HOS.ErrorCode;
-
-namespace Ryujinx.HLE.HOS.Kernel
-{
-    partial class SvcHandler
-    {
-        private void SvcSetHeapSize(CpuThreadState threadState)
-        {
-            ulong size = threadState.X1;
-
-            if ((size & 0xfffffffe001fffff) != 0)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Heap size 0x{size:x16} is not aligned!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidSize);
-
-                return;
-            }
-
-            KernelResult result = _process.MemoryManager.SetHeapSize(size, out ulong position);
-
-            threadState.X0 = (ulong)result;
-
-            if (result == KernelResult.Success)
-            {
-                threadState.X1 = position;
-            }
-            else
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error \"{result}\".");
-            }
-        }
-
-        private void SvcSetMemoryAttribute(CpuThreadState threadState)
-        {
-            ulong position = threadState.X0;
-            ulong size     = threadState.X1;
-
-            if (!PageAligned(position))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{position:x16} is not page aligned!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
-
-                return;
-            }
-
-            if (!PageAligned(size) || size == 0)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Size 0x{size:x16} is not page aligned or is zero!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidSize);
-
-                return;
-            }
-
-            MemoryAttribute attributeMask  = (MemoryAttribute)threadState.X2;
-            MemoryAttribute attributeValue = (MemoryAttribute)threadState.X3;
-
-            MemoryAttribute attributes = attributeMask | attributeValue;
-
-            if (attributes != attributeMask ||
-               (attributes | MemoryAttribute.Uncached) != MemoryAttribute.Uncached)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, "Invalid memory attributes!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMaskValue);
-
-                return;
-            }
-
-            KernelResult result = _process.MemoryManager.SetMemoryAttribute(
-                position,
-                size,
-                attributeMask,
-                attributeValue);
-
-            if (result != KernelResult.Success)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error \"{result}\".");
-            }
-            else
-            {
-                _memory.StopObservingRegion((long)position, (long)size);
-            }
-
-            threadState.X0 = (ulong)result;
-        }
-
-        private void SvcMapMemory(CpuThreadState threadState)
-        {
-            ulong dst  = threadState.X0;
-            ulong src  = threadState.X1;
-            ulong size = threadState.X2;
-
-            if (!PageAligned(src | dst))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, "Addresses are not page aligned!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
-
-                return;
-            }
-
-            if (!PageAligned(size) || size == 0)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Size 0x{size:x16} is not page aligned or is zero!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidSize);
-
-                return;
-            }
-
-            if (src + size <= src || dst + size <= dst)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, "Addresses outside of range!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
-
-                return;
-            }
-
-            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
-
-            if (!currentProcess.MemoryManager.InsideAddrSpace(src, size))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Src address 0x{src:x16} out of range!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
-
-                return;
-            }
-
-            if (currentProcess.MemoryManager.OutsideStackRegion(dst, size) ||
-                currentProcess.MemoryManager.InsideHeapRegion  (dst, size) ||
-                currentProcess.MemoryManager.InsideAliasRegion (dst, size))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Dst address 0x{dst:x16} out of range!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange);
-
-                return;
-            }
-
-            KernelResult result = _process.MemoryManager.Map(dst, src, size);
-
-            if (result != KernelResult.Success)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{result:x}!");
-            }
-
-            threadState.X0 = (ulong)result;
-        }
-
-        private void SvcUnmapMemory(CpuThreadState threadState)
-        {
-            ulong dst  = threadState.X0;
-            ulong src  = threadState.X1;
-            ulong size = threadState.X2;
-
-            if (!PageAligned(src | dst))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, "Addresses are not page aligned!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
-
-                return;
-            }
-
-            if (!PageAligned(size) || size == 0)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Size 0x{size:x16} is not page aligned or is zero!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidSize);
-
-                return;
-            }
-
-            if (src + size <= src || dst + size <= dst)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, "Addresses outside of range!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
-
-                return;
-            }
-
-            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
-
-            if (!currentProcess.MemoryManager.InsideAddrSpace(src, size))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Src address 0x{src:x16} out of range!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
-
-                return;
-            }
-
-            if (currentProcess.MemoryManager.OutsideStackRegion(dst, size) ||
-                currentProcess.MemoryManager.InsideHeapRegion  (dst, size) ||
-                currentProcess.MemoryManager.InsideAliasRegion (dst, size))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Dst address 0x{dst:x16} out of range!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange);
-
-                return;
-            }
-
-            KernelResult result = _process.MemoryManager.Unmap(dst, src, size);
-
-            if (result != KernelResult.Success)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{result:x}!");
-            }
-
-            threadState.X0 = (ulong)result;
-        }
-
-        private void SvcQueryMemory(CpuThreadState threadState)
-        {
-            long  infoPtr  = (long)threadState.X0;
-            ulong position =       threadState.X2;
-
-            KMemoryInfo blkInfo = _process.MemoryManager.QueryMemory(position);
-
-            _memory.WriteUInt64(infoPtr + 0x00, blkInfo.Address);
-            _memory.WriteUInt64(infoPtr + 0x08, blkInfo.Size);
-            _memory.WriteInt32 (infoPtr + 0x10, (int)blkInfo.State & 0xff);
-            _memory.WriteInt32 (infoPtr + 0x14, (int)blkInfo.Attribute);
-            _memory.WriteInt32 (infoPtr + 0x18, (int)blkInfo.Permission);
-            _memory.WriteInt32 (infoPtr + 0x1c, blkInfo.IpcRefCount);
-            _memory.WriteInt32 (infoPtr + 0x20, blkInfo.DeviceRefCount);
-            _memory.WriteInt32 (infoPtr + 0x24, 0);
-
-            threadState.X0 = 0;
-            threadState.X1 = 0;
-        }
-
-        private void SvcMapSharedMemory(CpuThreadState threadState)
-        {
-            int   handle  =  (int)threadState.X0;
-            ulong address =       threadState.X1;
-            ulong size    =       threadState.X2;
-
-            if (!PageAligned(address))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{address:x16} is not page aligned!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
-
-                return;
-            }
-
-            if (!PageAligned(size) || size == 0)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Size 0x{size:x16} is not page aligned or is zero!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidSize);
-
-                return;
-            }
-
-            if (address + size <= address)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{address:x16} / size 0x{size:x16}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
-
-                return;
-            }
-
-            MemoryPermission permission = (MemoryPermission)threadState.X3;
-
-            if ((permission | MemoryPermission.Write) != MemoryPermission.ReadAndWrite)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid permission {permission}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidPermission);
-
-                return;
-            }
-
-            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
-
-            KSharedMemory sharedMemory = currentProcess.HandleTable.GetObject<KSharedMemory>(handle);
-
-            if (sharedMemory == null)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid shared memory handle 0x{handle:x8}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
-
-                return;
-            }
-
-            if (currentProcess.MemoryManager.IsInvalidRegion  (address, size) ||
-                currentProcess.MemoryManager.InsideHeapRegion (address, size) ||
-                currentProcess.MemoryManager.InsideAliasRegion(address, size))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{address:x16} out of range!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
-
-                return;
-            }
-
-            KernelResult result = sharedMemory.MapIntoProcess(
-                currentProcess.MemoryManager,
-                address,
-                size,
-                currentProcess,
-                permission);
-
-            if (result != KernelResult.Success)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error \"{result}\".");
-            }
-
-            threadState.X0 = (ulong)result;
-        }
-
-        private void SvcUnmapSharedMemory(CpuThreadState threadState)
-        {
-            int   handle  =  (int)threadState.X0;
-            ulong address =       threadState.X1;
-            ulong size    =       threadState.X2;
-
-            if (!PageAligned(address))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{address:x16} is not page aligned!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
-
-                return;
-            }
-
-            if (!PageAligned(size) || size == 0)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Size 0x{size:x16} is not page aligned or is zero!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidSize);
-
-                return;
-            }
-
-            if (address + size <= address)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{address:x16} / size 0x{size:x16}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
-
-                return;
-            }
-
-            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
-
-            KSharedMemory sharedMemory = currentProcess.HandleTable.GetObject<KSharedMemory>(handle);
-
-            if (sharedMemory == null)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid shared memory handle 0x{handle:x8}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
-
-                return;
-            }
-
-            if (currentProcess.MemoryManager.IsInvalidRegion  (address, size) ||
-                currentProcess.MemoryManager.InsideHeapRegion (address, size) ||
-                currentProcess.MemoryManager.InsideAliasRegion(address, size))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{address:x16} out of range!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
-
-                return;
-            }
-
-            KernelResult result = sharedMemory.UnmapFromProcess(
-                currentProcess.MemoryManager,
-                address,
-                size,
-                currentProcess);
-
-            if (result != KernelResult.Success)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error \"{result}\".");
-            }
-
-            threadState.X0 = (ulong)result;
-        }
-
-        private void SvcCreateTransferMemory(CpuThreadState threadState)
-        {
-            ulong address = threadState.X1;
-            ulong size    = threadState.X2;
-
-            if (!PageAligned(address))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{address:x16} is not page aligned!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
-
-                return;
-            }
-
-            if (!PageAligned(size) || size == 0)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Size 0x{size:x16} is not page aligned or is zero!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
-
-                return;
-            }
-
-            if (address + size <= address)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{address:x16} / size 0x{size:x16}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
-
-                return;
-            }
-
-            MemoryPermission permission = (MemoryPermission)threadState.X3;
-
-            if (permission > MemoryPermission.ReadAndWrite || permission == MemoryPermission.Write)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid permission {permission}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidPermission);
-
-                return;
-            }
-
-            _process.MemoryManager.ReserveTransferMemory(address, size, permission);
-
-            KTransferMemory transferMemory = new KTransferMemory(address, size);
-
-            KernelResult result = _process.HandleTable.GenerateHandle(transferMemory, out int handle);
-
-            threadState.X0 = (uint)result;
-            threadState.X1 = (ulong)handle;
-        }
-
-        private void SvcMapPhysicalMemory(CpuThreadState threadState)
-        {
-            ulong address = threadState.X0;
-            ulong size    = threadState.X1;
-
-            if (!PageAligned(address))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{address:x16} is not page aligned!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
-
-                return;
-            }
-
-            if (!PageAligned(size) || size == 0)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Size 0x{size:x16} is not page aligned or is zero!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidSize);
-
-                return;
-            }
-
-            if (address + size <= address)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{address:x16} / size 0x{size:x16}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
-
-                return;
-            }
-
-            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
-
-            if ((currentProcess.PersonalMmHeapPagesCount & 0xfffffffffffff) == 0)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"System resource size is zero.");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
-
-                return;
-            }
-
-            if (!currentProcess.MemoryManager.InsideAddrSpace   (address, size) ||
-                 currentProcess.MemoryManager.OutsideAliasRegion(address, size))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid address {address:x16}.");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
-
-                return;
-            }
-
-            KernelResult result = _process.MemoryManager.MapPhysicalMemory(address, size);
-
-            if (result != KernelResult.Success)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{result:x}!");
-            }
-
-            threadState.X0 = (ulong)result;
-        }
-
-        private void SvcUnmapPhysicalMemory(CpuThreadState threadState)
-        {
-            ulong address = threadState.X0;
-            ulong size    = threadState.X1;
-
-            if (!PageAligned(address))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{address:x16} is not page aligned!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
-
-                return;
-            }
-
-            if (!PageAligned(size) || size == 0)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Size 0x{size:x16} is not page aligned or is zero!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidSize);
-
-                return;
-            }
-
-            if (address + size <= address)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{address:x16} / size 0x{size:x16}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
-
-                return;
-            }
-
-            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
-
-            if ((currentProcess.PersonalMmHeapPagesCount & 0xfffffffffffff) == 0)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"System resource size is zero.");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
-
-                return;
-            }
-
-            if (!currentProcess.MemoryManager.InsideAddrSpace   (address, size) ||
-                 currentProcess.MemoryManager.OutsideAliasRegion(address, size))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid address {address:x16}.");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
-
-                return;
-            }
-
-            KernelResult result = _process.MemoryManager.UnmapPhysicalMemory(address, size);
-
-            if (result != KernelResult.Success)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{result:x}!");
-            }
-
-            threadState.X0 = (ulong)result;
-        }
-
-        private static bool PageAligned(ulong position)
-        {
-            return (position & (KMemoryManager.PageSize - 1)) == 0;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Kernel/SvcThread.cs b/Ryujinx.HLE/HOS/Kernel/SvcThread.cs
deleted file mode 100644
index 0121303d..00000000
--- a/Ryujinx.HLE/HOS/Kernel/SvcThread.cs
+++ /dev/null
@@ -1,464 +0,0 @@
-using ChocolArm64.State;
-using Ryujinx.Common.Logging;
-
-using static Ryujinx.HLE.HOS.ErrorCode;
-
-namespace Ryujinx.HLE.HOS.Kernel
-{
-    partial class SvcHandler
-    {
-        private void CreateThread64(CpuThreadState threadState)
-        {
-            ulong entrypoint =      threadState.X1;
-            ulong argsPtr    =      threadState.X2;
-            ulong stackTop   =      threadState.X3;
-            int   priority   = (int)threadState.X4;
-            int   cpuCore    = (int)threadState.X5;
-
-            KernelResult result = CreateThread(entrypoint, argsPtr, stackTop, priority, cpuCore, out int handle);
-
-            threadState.X0 = (ulong)result;
-            threadState.X1 = (ulong)handle;
-        }
-
-        private KernelResult CreateThread(
-            ulong   entrypoint,
-            ulong   argsPtr,
-            ulong   stackTop,
-            int     priority,
-            int     cpuCore,
-            out int handle)
-        {
-            handle = 0;
-
-            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
-
-            if (cpuCore == -2)
-            {
-                cpuCore = currentProcess.DefaultCpuCore;
-            }
-
-            if ((uint)cpuCore >= KScheduler.CpuCoresCount || !currentProcess.IsCpuCoreAllowed(cpuCore))
-            {
-                return KernelResult.InvalidCpuCore;
-            }
-
-            if ((uint)priority >= KScheduler.PrioritiesCount || !currentProcess.IsPriorityAllowed(priority))
-            {
-                return KernelResult.InvalidPriority;
-            }
-
-            long timeout = KTimeManager.ConvertMillisecondsToNanoseconds(100);
-
-            if (currentProcess.ResourceLimit != null &&
-               !currentProcess.ResourceLimit.Reserve(LimitableResource.Thread, 1, timeout))
-            {
-                return KernelResult.ResLimitExceeded;
-            }
-
-            KThread thread = new KThread(_system);
-
-            KernelResult result = currentProcess.InitializeThread(
-                thread,
-                entrypoint,
-                argsPtr,
-                stackTop,
-                priority,
-                cpuCore);
-
-            if (result != KernelResult.Success)
-            {
-                currentProcess.ResourceLimit?.Release(LimitableResource.Thread, 1);
-
-                return result;
-            }
-
-            result = _process.HandleTable.GenerateHandle(thread, out handle);
-
-            if (result != KernelResult.Success)
-            {
-                thread.Terminate();
-
-                currentProcess.ResourceLimit?.Release(LimitableResource.Thread, 1);
-            }
-
-            return result;
-        }
-
-        private void SvcStartThread(CpuThreadState threadState)
-        {
-            int handle = (int)threadState.X0;
-
-            KThread thread = _process.HandleTable.GetObject<KThread>(handle);
-
-            if (thread != null)
-            {
-                KernelResult result = thread.Start();
-
-                if (result != KernelResult.Success)
-                {
-                    Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error \"{result}\".");
-                }
-
-                threadState.X0 = (ulong)result;
-            }
-            else
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid thread handle 0x{handle:x8}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
-            }
-        }
-
-        private void SvcExitThread(CpuThreadState threadState)
-        {
-            KThread currentThread = _system.Scheduler.GetCurrentThread();
-
-            _system.Scheduler.ExitThread(currentThread);
-
-            currentThread.Exit();
-        }
-
-        private void SvcSleepThread(CpuThreadState threadState)
-        {
-            long timeout = (long)threadState.X0;
-
-            Logger.PrintDebug(LogClass.KernelSvc, "Timeout = 0x" + timeout.ToString("x16"));
-
-            KThread currentThread = _system.Scheduler.GetCurrentThread();
-
-            if (timeout < 1)
-            {
-                switch (timeout)
-                {
-                    case  0: currentThread.Yield();                        break;
-                    case -1: currentThread.YieldWithLoadBalancing();       break;
-                    case -2: currentThread.YieldAndWaitForLoadBalancing(); break;
-                }
-            }
-            else
-            {
-                currentThread.Sleep(timeout);
-
-                threadState.X0 = 0;
-            }
-        }
-
-        private void SvcGetThreadPriority(CpuThreadState threadState)
-        {
-            int handle = (int)threadState.X1;
-
-            KThread thread = _process.HandleTable.GetKThread(handle);
-
-            if (thread != null)
-            {
-                threadState.X0 = 0;
-                threadState.X1 = (ulong)thread.DynamicPriority;
-            }
-            else
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid thread handle 0x{handle:x8}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
-            }
-        }
-
-        private void SvcSetThreadPriority(CpuThreadState threadState)
-        {
-            int handle   = (int)threadState.X0;
-            int priority = (int)threadState.X1;
-
-            Logger.PrintDebug(LogClass.KernelSvc,
-                "Handle = 0x"   + handle  .ToString("x8") + ", " +
-                "Priority = 0x" + priority.ToString("x8"));
-
-            //TODO: NPDM check.
-
-            KThread thread = _process.HandleTable.GetKThread(handle);
-
-            if (thread == null)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid thread handle 0x{handle:x8}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
-
-                return;
-            }
-
-            thread.SetPriority(priority);
-
-            threadState.X0 = 0;
-        }
-
-        private void SvcGetThreadCoreMask(CpuThreadState threadState)
-        {
-            int handle = (int)threadState.X2;
-
-            Logger.PrintDebug(LogClass.KernelSvc, "Handle = 0x" + handle.ToString("x8"));
-
-            KThread thread = _process.HandleTable.GetKThread(handle);
-
-            if (thread != null)
-            {
-                threadState.X0 = 0;
-                threadState.X1 = (ulong)thread.PreferredCore;
-                threadState.X2 = (ulong)thread.AffinityMask;
-            }
-            else
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid thread handle 0x{handle:x8}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
-            }
-        }
-
-        private void SetThreadCoreMask64(CpuThreadState threadState)
-        {
-            int  handle        =  (int)threadState.X0;
-            int  preferredCore =  (int)threadState.X1;
-            long affinityMask  = (long)threadState.X2;
-
-            Logger.PrintDebug(LogClass.KernelSvc,
-                "Handle = 0x"        + handle       .ToString("x8") + ", " +
-                "PreferredCore = 0x" + preferredCore.ToString("x8") + ", " +
-                "AffinityMask = 0x"  + affinityMask .ToString("x16"));
-
-            KernelResult result = SetThreadCoreMask(handle, preferredCore, affinityMask);
-
-            if (result != KernelResult.Success)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error \"{result}\".");
-            }
-
-            threadState.X0 = (ulong)result;
-        }
-
-        private KernelResult SetThreadCoreMask(int handle, int preferredCore, long affinityMask)
-        {
-            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
-
-            if (preferredCore == -2)
-            {
-                preferredCore = currentProcess.DefaultCpuCore;
-
-                affinityMask = 1 << preferredCore;
-            }
-            else
-            {
-                if ((currentProcess.Capabilities.AllowedCpuCoresMask | affinityMask) !=
-                     currentProcess.Capabilities.AllowedCpuCoresMask)
-                {
-                    return KernelResult.InvalidCpuCore;
-                }
-
-                if (affinityMask == 0)
-                {
-                    return KernelResult.InvalidCombination;
-                }
-
-                if ((uint)preferredCore > 3)
-                {
-                    if ((preferredCore | 2) != -1)
-                    {
-                        return KernelResult.InvalidCpuCore;
-                    }
-                }
-                else if ((affinityMask & (1 << preferredCore)) == 0)
-                {
-                    return KernelResult.InvalidCombination;
-                }
-            }
-
-            KThread thread = _process.HandleTable.GetKThread(handle);
-
-            if (thread == null)
-            {
-                return KernelResult.InvalidHandle;
-            }
-
-            return thread.SetCoreAndAffinityMask(preferredCore, affinityMask);
-        }
-
-        private void SvcGetCurrentProcessorNumber(CpuThreadState threadState)
-        {
-            threadState.X0 = (ulong)_system.Scheduler.GetCurrentThread().CurrentCore;
-        }
-
-        private void SvcGetThreadId(CpuThreadState threadState)
-        {
-            int handle = (int)threadState.X1;
-
-            KThread thread = _process.HandleTable.GetKThread(handle);
-
-            if (thread != null)
-            {
-                threadState.X0 = 0;
-                threadState.X1 = (ulong)thread.ThreadUid;
-            }
-            else
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid thread handle 0x{handle:x8}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
-            }
-        }
-
-        private void SvcSetThreadActivity(CpuThreadState threadState)
-        {
-            int  handle = (int)threadState.X0;
-            bool pause  = (int)threadState.X1 == 1;
-
-            KThread thread = _process.HandleTable.GetObject<KThread>(handle);
-
-            if (thread == null)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid thread handle 0x{handle:x8}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
-
-                return;
-            }
-
-            if (thread.Owner != _system.Scheduler.GetCurrentProcess())
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid thread, it belongs to another process.");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
-
-                return;
-            }
-
-            if (thread == _system.Scheduler.GetCurrentThread())
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, "Invalid thread, current thread is not accepted.");
-
-                threadState.X0 = (ulong)KernelResult.InvalidThread;
-
-                return;
-            }
-
-            long result = thread.SetActivity(pause);
-
-            if (result != 0)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{result:x}!");
-            }
-
-            threadState.X0 = (ulong)result;
-        }
-
-        private void SvcGetThreadContext3(CpuThreadState threadState)
-        {
-            long position = (long)threadState.X0;
-            int  handle   =  (int)threadState.X1;
-
-            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
-            KThread  currentThread  = _system.Scheduler.GetCurrentThread();
-
-            KThread thread = _process.HandleTable.GetObject<KThread>(handle);
-
-            if (thread == null)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid thread handle 0x{handle:x8}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
-
-                return;
-            }
-
-            if (thread.Owner != currentProcess)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid thread, it belongs to another process.");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
-
-                return;
-            }
-
-            if (currentThread == thread)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, "Invalid thread, current thread is not accepted.");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidThread);
-
-                return;
-            }
-
-            _memory.WriteUInt64(position + 0x0,  thread.Context.ThreadState.X0);
-            _memory.WriteUInt64(position + 0x8,  thread.Context.ThreadState.X1);
-            _memory.WriteUInt64(position + 0x10, thread.Context.ThreadState.X2);
-            _memory.WriteUInt64(position + 0x18, thread.Context.ThreadState.X3);
-            _memory.WriteUInt64(position + 0x20, thread.Context.ThreadState.X4);
-            _memory.WriteUInt64(position + 0x28, thread.Context.ThreadState.X5);
-            _memory.WriteUInt64(position + 0x30, thread.Context.ThreadState.X6);
-            _memory.WriteUInt64(position + 0x38, thread.Context.ThreadState.X7);
-            _memory.WriteUInt64(position + 0x40, thread.Context.ThreadState.X8);
-            _memory.WriteUInt64(position + 0x48, thread.Context.ThreadState.X9);
-            _memory.WriteUInt64(position + 0x50, thread.Context.ThreadState.X10);
-            _memory.WriteUInt64(position + 0x58, thread.Context.ThreadState.X11);
-            _memory.WriteUInt64(position + 0x60, thread.Context.ThreadState.X12);
-            _memory.WriteUInt64(position + 0x68, thread.Context.ThreadState.X13);
-            _memory.WriteUInt64(position + 0x70, thread.Context.ThreadState.X14);
-            _memory.WriteUInt64(position + 0x78, thread.Context.ThreadState.X15);
-            _memory.WriteUInt64(position + 0x80, thread.Context.ThreadState.X16);
-            _memory.WriteUInt64(position + 0x88, thread.Context.ThreadState.X17);
-            _memory.WriteUInt64(position + 0x90, thread.Context.ThreadState.X18);
-            _memory.WriteUInt64(position + 0x98, thread.Context.ThreadState.X19);
-            _memory.WriteUInt64(position + 0xa0, thread.Context.ThreadState.X20);
-            _memory.WriteUInt64(position + 0xa8, thread.Context.ThreadState.X21);
-            _memory.WriteUInt64(position + 0xb0, thread.Context.ThreadState.X22);
-            _memory.WriteUInt64(position + 0xb8, thread.Context.ThreadState.X23);
-            _memory.WriteUInt64(position + 0xc0, thread.Context.ThreadState.X24);
-            _memory.WriteUInt64(position + 0xc8, thread.Context.ThreadState.X25);
-            _memory.WriteUInt64(position + 0xd0, thread.Context.ThreadState.X26);
-            _memory.WriteUInt64(position + 0xd8, thread.Context.ThreadState.X27);
-            _memory.WriteUInt64(position + 0xe0, thread.Context.ThreadState.X28);
-            _memory.WriteUInt64(position + 0xe8, thread.Context.ThreadState.X29);
-            _memory.WriteUInt64(position + 0xf0, thread.Context.ThreadState.X30);
-            _memory.WriteUInt64(position + 0xf8, thread.Context.ThreadState.X31);
-
-            _memory.WriteInt64(position + 0x100, thread.LastPc);
-
-            _memory.WriteUInt64(position + 0x108, (ulong)thread.Context.ThreadState.Psr);
-
-            _memory.WriteVector128(position + 0x110, thread.Context.ThreadState.V0);
-            _memory.WriteVector128(position + 0x120, thread.Context.ThreadState.V1);
-            _memory.WriteVector128(position + 0x130, thread.Context.ThreadState.V2);
-            _memory.WriteVector128(position + 0x140, thread.Context.ThreadState.V3);
-            _memory.WriteVector128(position + 0x150, thread.Context.ThreadState.V4);
-            _memory.WriteVector128(position + 0x160, thread.Context.ThreadState.V5);
-            _memory.WriteVector128(position + 0x170, thread.Context.ThreadState.V6);
-            _memory.WriteVector128(position + 0x180, thread.Context.ThreadState.V7);
-            _memory.WriteVector128(position + 0x190, thread.Context.ThreadState.V8);
-            _memory.WriteVector128(position + 0x1a0, thread.Context.ThreadState.V9);
-            _memory.WriteVector128(position + 0x1b0, thread.Context.ThreadState.V10);
-            _memory.WriteVector128(position + 0x1c0, thread.Context.ThreadState.V11);
-            _memory.WriteVector128(position + 0x1d0, thread.Context.ThreadState.V12);
-            _memory.WriteVector128(position + 0x1e0, thread.Context.ThreadState.V13);
-            _memory.WriteVector128(position + 0x1f0, thread.Context.ThreadState.V14);
-            _memory.WriteVector128(position + 0x200, thread.Context.ThreadState.V15);
-            _memory.WriteVector128(position + 0x210, thread.Context.ThreadState.V16);
-            _memory.WriteVector128(position + 0x220, thread.Context.ThreadState.V17);
-            _memory.WriteVector128(position + 0x230, thread.Context.ThreadState.V18);
-            _memory.WriteVector128(position + 0x240, thread.Context.ThreadState.V19);
-            _memory.WriteVector128(position + 0x250, thread.Context.ThreadState.V20);
-            _memory.WriteVector128(position + 0x260, thread.Context.ThreadState.V21);
-            _memory.WriteVector128(position + 0x270, thread.Context.ThreadState.V22);
-            _memory.WriteVector128(position + 0x280, thread.Context.ThreadState.V23);
-            _memory.WriteVector128(position + 0x290, thread.Context.ThreadState.V24);
-            _memory.WriteVector128(position + 0x2a0, thread.Context.ThreadState.V25);
-            _memory.WriteVector128(position + 0x2b0, thread.Context.ThreadState.V26);
-            _memory.WriteVector128(position + 0x2c0, thread.Context.ThreadState.V27);
-            _memory.WriteVector128(position + 0x2d0, thread.Context.ThreadState.V28);
-            _memory.WriteVector128(position + 0x2e0, thread.Context.ThreadState.V29);
-            _memory.WriteVector128(position + 0x2f0, thread.Context.ThreadState.V30);
-            _memory.WriteVector128(position + 0x300, thread.Context.ThreadState.V31);
-
-            _memory.WriteInt32(position + 0x310, thread.Context.ThreadState.Fpcr);
-            _memory.WriteInt32(position + 0x314, thread.Context.ThreadState.Fpsr);
-            _memory.WriteInt64(position + 0x318, thread.Context.ThreadState.Tpidr);
-
-            threadState.X0 = 0;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Kernel/SvcThreadSync.cs b/Ryujinx.HLE/HOS/Kernel/SvcThreadSync.cs
deleted file mode 100644
index 11cfffe9..00000000
--- a/Ryujinx.HLE/HOS/Kernel/SvcThreadSync.cs
+++ /dev/null
@@ -1,373 +0,0 @@
-using ChocolArm64.State;
-using Ryujinx.Common.Logging;
-using System.Collections.Generic;
-
-using static Ryujinx.HLE.HOS.ErrorCode;
-
-namespace Ryujinx.HLE.HOS.Kernel
-{
-    partial class SvcHandler
-    {
-        private void SvcWaitSynchronization(CpuThreadState threadState)
-        {
-            long handlesPtr   = (long)threadState.X1;
-            int  handlesCount =  (int)threadState.X2;
-            long timeout      = (long)threadState.X3;
-
-            Logger.PrintDebug(LogClass.KernelSvc,
-                "HandlesPtr = 0x"   + handlesPtr  .ToString("x16") + ", " +
-                "HandlesCount = 0x" + handlesCount.ToString("x8")  + ", " +
-                "Timeout = 0x"      + timeout     .ToString("x16"));
-
-            if ((uint)handlesCount > 0x40)
-            {
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.CountOutOfRange);
-
-                return;
-            }
-
-            List<KSynchronizationObject> syncObjs = new List<KSynchronizationObject>();
-
-            for (int index = 0; index < handlesCount; index++)
-            {
-                int handle = _memory.ReadInt32(handlesPtr + index * 4);
-
-                Logger.PrintDebug(LogClass.KernelSvc, $"Sync handle 0x{handle:x8}");
-
-                KSynchronizationObject syncObj = _process.HandleTable.GetObject<KSynchronizationObject>(handle);
-
-                if (syncObj == null)
-                {
-                    break;
-                }
-
-                syncObjs.Add(syncObj);
-            }
-
-            int hndIndex = (int)threadState.X1;
-
-            ulong high = threadState.X1 & (0xffffffffUL << 32);
-
-            long result = _system.Synchronization.WaitFor(syncObjs.ToArray(), timeout, ref hndIndex);
-
-            if (result != 0)
-            {
-                if (result == MakeError(ErrorModule.Kernel, KernelErr.Timeout) ||
-                    result == MakeError(ErrorModule.Kernel, KernelErr.Cancelled))
-                {
-                    Logger.PrintDebug(LogClass.KernelSvc, $"Operation failed with error 0x{result:x}!");
-                }
-                else
-                {
-                    Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{result:x}!");
-                }
-            }
-
-            threadState.X0 = (ulong)result;
-            threadState.X1 = (uint)hndIndex | high;
-        }
-
-        private void SvcCancelSynchronization(CpuThreadState threadState)
-        {
-            int threadHandle = (int)threadState.X0;
-
-            Logger.PrintDebug(LogClass.KernelSvc, "ThreadHandle = 0x" + threadHandle.ToString("x8"));
-
-            KThread thread = _process.HandleTable.GetKThread(threadHandle);
-
-            if (thread == null)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid thread handle 0x{threadHandle:x8}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
-
-                return;
-            }
-
-            thread.CancelSynchronization();
-
-            threadState.X0 = 0;
-        }
-
-        private void SvcArbitrateLock(CpuThreadState threadState)
-        {
-            int  ownerHandle     =  (int)threadState.X0;
-            long mutexAddress    = (long)threadState.X1;
-            int  requesterHandle =  (int)threadState.X2;
-
-            Logger.PrintDebug(LogClass.KernelSvc,
-                "OwnerHandle = 0x"     + ownerHandle    .ToString("x8")  + ", " +
-                "MutexAddress = 0x"    + mutexAddress   .ToString("x16") + ", " +
-                "RequesterHandle = 0x" + requesterHandle.ToString("x8"));
-
-            if (IsPointingInsideKernel(mutexAddress))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid mutex address 0x{mutexAddress:x16}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
-
-                return;
-            }
-
-            if (IsAddressNotWordAligned(mutexAddress))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Unaligned mutex address 0x{mutexAddress:x16}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
-
-                return;
-            }
-
-            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
-
-            long result = currentProcess.AddressArbiter.ArbitrateLock(ownerHandle, mutexAddress, requesterHandle);
-
-            if (result != 0)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{result:x}!");
-            }
-
-            threadState.X0 = (ulong)result;
-        }
-
-        private void SvcArbitrateUnlock(CpuThreadState threadState)
-        {
-            long mutexAddress = (long)threadState.X0;
-
-            Logger.PrintDebug(LogClass.KernelSvc, "MutexAddress = 0x" + mutexAddress.ToString("x16"));
-
-            if (IsPointingInsideKernel(mutexAddress))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid mutex address 0x{mutexAddress:x16}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
-
-                return;
-            }
-
-            if (IsAddressNotWordAligned(mutexAddress))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Unaligned mutex address 0x{mutexAddress:x16}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
-
-                return;
-            }
-
-            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
-
-            long result = currentProcess.AddressArbiter.ArbitrateUnlock(mutexAddress);
-
-            if (result != 0)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{result:x}!");
-            }
-
-            threadState.X0 = (ulong)result;
-        }
-
-        private void SvcWaitProcessWideKeyAtomic(CpuThreadState threadState)
-        {
-            long  mutexAddress   = (long)threadState.X0;
-            long  condVarAddress = (long)threadState.X1;
-            int   threadHandle   =  (int)threadState.X2;
-            long  timeout        = (long)threadState.X3;
-
-            Logger.PrintDebug(LogClass.KernelSvc,
-                "MutexAddress = 0x"   + mutexAddress  .ToString("x16") + ", " +
-                "CondVarAddress = 0x" + condVarAddress.ToString("x16") + ", " +
-                "ThreadHandle = 0x"   + threadHandle  .ToString("x8")  + ", " +
-                "Timeout = 0x"        + timeout       .ToString("x16"));
-
-            if (IsPointingInsideKernel(mutexAddress))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid mutex address 0x{mutexAddress:x16}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
-
-                return;
-            }
-
-            if (IsAddressNotWordAligned(mutexAddress))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Unaligned mutex address 0x{mutexAddress:x16}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
-
-                return;
-            }
-
-            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
-
-            long result = currentProcess.AddressArbiter.WaitProcessWideKeyAtomic(
-                mutexAddress,
-                condVarAddress,
-                threadHandle,
-                timeout);
-
-            if (result != 0)
-            {
-                if (result == MakeError(ErrorModule.Kernel, KernelErr.Timeout))
-                {
-                    Logger.PrintDebug(LogClass.KernelSvc, $"Operation failed with error 0x{result:x}!");
-                }
-                else
-                {
-                    Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{result:x}!");
-                }
-            }
-
-            threadState.X0 = (ulong)result;
-        }
-
-        private void SvcSignalProcessWideKey(CpuThreadState threadState)
-        {
-            long address = (long)threadState.X0;
-            int  count   =  (int)threadState.X1;
-
-            Logger.PrintDebug(LogClass.KernelSvc,
-                "Address = 0x" + address.ToString("x16") + ", " +
-                "Count = 0x"   + count  .ToString("x8"));
-
-            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
-
-            currentProcess.AddressArbiter.SignalProcessWideKey(address, count);
-
-            threadState.X0 = 0;
-        }
-
-        private void SvcWaitForAddress(CpuThreadState threadState)
-        {
-            long            address =            (long)threadState.X0;
-            ArbitrationType type    = (ArbitrationType)threadState.X1;
-            int             value   =             (int)threadState.X2;
-            long            timeout =            (long)threadState.X3;
-
-            Logger.PrintDebug(LogClass.KernelSvc,
-                "Address = 0x" + address.ToString("x16") + ", " +
-                "Type = "      + type   .ToString()      + ", " +
-                "Value = 0x"   + value  .ToString("x8")  + ", " +
-                "Timeout = 0x" + timeout.ToString("x16"));
-
-            if (IsPointingInsideKernel(address))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid address 0x{address:x16}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
-
-                return;
-            }
-
-            if (IsAddressNotWordAligned(address))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Unaligned address 0x{address:x16}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
-
-                return;
-            }
-
-            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
-
-            long result;
-
-            switch (type)
-            {
-                case ArbitrationType.WaitIfLessThan:
-                    result = currentProcess.AddressArbiter.WaitForAddressIfLessThan(address, value, false, timeout);
-                    break;
-
-                case ArbitrationType.DecrementAndWaitIfLessThan:
-                    result = currentProcess.AddressArbiter.WaitForAddressIfLessThan(address, value, true, timeout);
-                    break;
-
-                case ArbitrationType.WaitIfEqual:
-                    result = currentProcess.AddressArbiter.WaitForAddressIfEqual(address, value, timeout);
-                    break;
-
-                default:
-                    result = MakeError(ErrorModule.Kernel, KernelErr.InvalidEnumValue);
-                    break;
-            }
-
-            if (result != 0)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{result:x}!");
-            }
-
-            threadState.X0 = (ulong)result;
-        }
-
-        private void SvcSignalToAddress(CpuThreadState threadState)
-        {
-            long       address =       (long)threadState.X0;
-            SignalType type    = (SignalType)threadState.X1;
-            int        value   =        (int)threadState.X2;
-            int        count   =        (int)threadState.X3;
-
-            Logger.PrintDebug(LogClass.KernelSvc,
-                "Address = 0x" + address.ToString("x16") + ", " +
-                "Type = "      + type   .ToString()      + ", " +
-                "Value = 0x"   + value  .ToString("x8")  + ", " +
-                "Count = 0x"   + count  .ToString("x8"));
-
-            if (IsPointingInsideKernel(address))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid address 0x{address:x16}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
-
-                return;
-            }
-
-            if (IsAddressNotWordAligned(address))
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Unaligned address 0x{address:x16}!");
-
-                threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
-
-                return;
-            }
-
-            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
-
-            long result;
-
-            switch (type)
-            {
-                case SignalType.Signal:
-                    result = currentProcess.AddressArbiter.Signal(address, count);
-                    break;
-
-                case SignalType.SignalAndIncrementIfEqual:
-                    result = currentProcess.AddressArbiter.SignalAndIncrementIfEqual(address, value, count);
-                    break;
-
-                case SignalType.SignalAndModifyIfEqual:
-                    result = currentProcess.AddressArbiter.SignalAndModifyIfEqual(address, value, count);
-                    break;
-
-                default:
-                    result = MakeError(ErrorModule.Kernel, KernelErr.InvalidEnumValue);
-                    break;
-            }
-
-            if (result != 0)
-            {
-                Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{result:x}!");
-            }
-
-            threadState.X0 = (ulong)result;
-        }
-
-        private bool IsPointingInsideKernel(long address)
-        {
-            return ((ulong)address + 0x1000000000) < 0xffffff000;
-        }
-
-        private bool IsAddressNotWordAligned(long address)
-        {
-            return (address & 3) != 0;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Kernel/ArbitrationType.cs b/Ryujinx.HLE/HOS/Kernel/Threading/ArbitrationType.cs
similarity index 78%
rename from Ryujinx.HLE/HOS/Kernel/ArbitrationType.cs
rename to Ryujinx.HLE/HOS/Kernel/Threading/ArbitrationType.cs
index b584d719..89c1bf1f 100644
--- a/Ryujinx.HLE/HOS/Kernel/ArbitrationType.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Threading/ArbitrationType.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Threading
 {
     enum ArbitrationType
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/HleCoreManager.cs b/Ryujinx.HLE/HOS/Kernel/Threading/HleCoreManager.cs
similarity index 97%
rename from Ryujinx.HLE/HOS/Kernel/HleCoreManager.cs
rename to Ryujinx.HLE/HOS/Kernel/Threading/HleCoreManager.cs
index 04017d6d..c2597990 100644
--- a/Ryujinx.HLE/HOS/Kernel/HleCoreManager.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Threading/HleCoreManager.cs
@@ -1,7 +1,7 @@
 using System.Collections.Concurrent;
 using System.Threading;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Threading
 {
     class HleCoreManager
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/HleScheduler.cs b/Ryujinx.HLE/HOS/Kernel/Threading/HleScheduler.cs
similarity index 99%
rename from Ryujinx.HLE/HOS/Kernel/HleScheduler.cs
rename to Ryujinx.HLE/HOS/Kernel/Threading/HleScheduler.cs
index 1a4c9dfe..835c2a2f 100644
--- a/Ryujinx.HLE/HOS/Kernel/HleScheduler.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Threading/HleScheduler.cs
@@ -1,7 +1,7 @@
 using System;
 using System.Threading;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Threading
 {
     partial class KScheduler
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KAddressArbiter.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KAddressArbiter.cs
similarity index 75%
rename from Ryujinx.HLE/HOS/Kernel/KAddressArbiter.cs
rename to Ryujinx.HLE/HOS/Kernel/Threading/KAddressArbiter.cs
index b4352485..faeea5c5 100644
--- a/Ryujinx.HLE/HOS/Kernel/KAddressArbiter.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Threading/KAddressArbiter.cs
@@ -1,9 +1,9 @@
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Process;
 using System.Collections.Generic;
 using System.Linq;
 
-using static Ryujinx.HLE.HOS.ErrorCode;
-
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Threading
 {
     class KAddressArbiter
     {
@@ -22,14 +22,14 @@ namespace Ryujinx.HLE.HOS.Kernel
             ArbiterThreads = new List<KThread>();
         }
 
-        public long ArbitrateLock(int ownerHandle, long mutexAddress, int requesterHandle)
+        public KernelResult ArbitrateLock(int ownerHandle, ulong mutexAddress, int requesterHandle)
         {
             KThread currentThread = _system.Scheduler.GetCurrentThread();
 
             _system.CriticalSection.Enter();
 
             currentThread.SignaledObj   = null;
-            currentThread.ObjSyncResult = 0;
+            currentThread.ObjSyncResult = KernelResult.Success;
 
             KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
 
@@ -37,7 +37,7 @@ namespace Ryujinx.HLE.HOS.Kernel
             {
                 _system.CriticalSection.Leave();
 
-                return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
+                return KernelResult.InvalidMemState;
             }
 
             if (mutexValue != (ownerHandle | HasListenersMask))
@@ -53,7 +53,7 @@ namespace Ryujinx.HLE.HOS.Kernel
             {
                 _system.CriticalSection.Leave();
 
-                return MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
+                return KernelResult.InvalidHandle;
             }
 
             currentThread.MutexAddress             = mutexAddress;
@@ -73,21 +73,21 @@ namespace Ryujinx.HLE.HOS.Kernel
 
             _system.CriticalSection.Leave();
 
-            return (uint)currentThread.ObjSyncResult;
+            return (KernelResult)currentThread.ObjSyncResult;
         }
 
-        public long ArbitrateUnlock(long mutexAddress)
+        public KernelResult ArbitrateUnlock(ulong mutexAddress)
         {
             _system.CriticalSection.Enter();
 
             KThread currentThread = _system.Scheduler.GetCurrentThread();
 
-            (long result, KThread newOwnerThread) = MutexUnlock(currentThread, mutexAddress);
+            (KernelResult result, KThread newOwnerThread) = MutexUnlock(currentThread, mutexAddress);
 
-            if (result != 0 && newOwnerThread != null)
+            if (result != KernelResult.Success && newOwnerThread != null)
             {
                 newOwnerThread.SignaledObj   = null;
-                newOwnerThread.ObjSyncResult = (int)result;
+                newOwnerThread.ObjSyncResult = result;
             }
 
             _system.CriticalSection.Leave();
@@ -95,30 +95,30 @@ namespace Ryujinx.HLE.HOS.Kernel
             return result;
         }
 
-        public long WaitProcessWideKeyAtomic(
-            long mutexAddress,
-            long condVarAddress,
-            int  threadHandle,
-            long timeout)
+        public KernelResult WaitProcessWideKeyAtomic(
+            ulong mutexAddress,
+            ulong condVarAddress,
+            int   threadHandle,
+            long  timeout)
         {
             _system.CriticalSection.Enter();
 
             KThread currentThread = _system.Scheduler.GetCurrentThread();
 
             currentThread.SignaledObj   = null;
-            currentThread.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Timeout);
+            currentThread.ObjSyncResult = KernelResult.TimedOut;
 
             if (currentThread.ShallBeTerminated ||
                 currentThread.SchedFlags == ThreadSchedState.TerminationPending)
             {
                 _system.CriticalSection.Leave();
 
-                return MakeError(ErrorModule.Kernel, KernelErr.ThreadTerminating);
+                return KernelResult.ThreadTerminating;
             }
 
-            (long result, _) = MutexUnlock(currentThread, mutexAddress);
+            (KernelResult result, _) = MutexUnlock(currentThread, mutexAddress);
 
-            if (result != 0)
+            if (result != KernelResult.Success)
             {
                 _system.CriticalSection.Leave();
 
@@ -159,10 +159,10 @@ namespace Ryujinx.HLE.HOS.Kernel
 
             _system.CriticalSection.Leave();
 
-            return (uint)currentThread.ObjSyncResult;
+            return (KernelResult)currentThread.ObjSyncResult;
         }
 
-        private (long, KThread) MutexUnlock(KThread currentThread, long mutexAddress)
+        private (KernelResult, KThread) MutexUnlock(KThread currentThread, ulong mutexAddress)
         {
             KThread newOwnerThread = currentThread.RelinquishMutex(mutexAddress, out int count);
 
@@ -178,22 +178,22 @@ namespace Ryujinx.HLE.HOS.Kernel
                 }
 
                 newOwnerThread.SignaledObj   = null;
-                newOwnerThread.ObjSyncResult = 0;
+                newOwnerThread.ObjSyncResult = KernelResult.Success;
 
                 newOwnerThread.ReleaseAndResume();
             }
 
-            long result = 0;
+            KernelResult result = KernelResult.Success;
 
             if (!KernelTransfer.KernelToUserInt32(_system, mutexAddress, mutexValue))
             {
-                result = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
+                result = KernelResult.InvalidMemState;
             }
 
             return (result, newOwnerThread);
         }
 
-        public void SignalProcessWideKey(long address, int count)
+        public void SignalProcessWideKey(ulong address, int count)
         {
             Queue<KThread> signaledThreads = new Queue<KThread>();
 
@@ -224,11 +224,11 @@ namespace Ryujinx.HLE.HOS.Kernel
 
         private KThread TryAcquireMutex(KThread requester)
         {
-            long address = requester.MutexAddress;
+            ulong address = requester.MutexAddress;
 
             KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
 
-            currentProcess.CpuMemory.SetExclusive(0, address);
+            currentProcess.CpuMemory.SetExclusive(0, (long)address);
 
             if (!KernelTransfer.UserToKernelInt32(_system, address, out int mutexValue))
             {
@@ -236,24 +236,24 @@ namespace Ryujinx.HLE.HOS.Kernel
                 currentProcess.CpuMemory.ClearExclusive(0);
 
                 requester.SignaledObj   = null;
-                requester.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
+                requester.ObjSyncResult = KernelResult.InvalidMemState;
 
                 return null;
             }
 
             while (true)
             {
-                if (currentProcess.CpuMemory.TestExclusive(0, address))
+                if (currentProcess.CpuMemory.TestExclusive(0, (long)address))
                 {
                     if (mutexValue != 0)
                     {
                         //Update value to indicate there is a mutex waiter now.
-                        currentProcess.CpuMemory.WriteInt32(address, mutexValue | HasListenersMask);
+                        currentProcess.CpuMemory.WriteInt32((long)address, mutexValue | HasListenersMask);
                     }
                     else
                     {
                         //No thread owning the mutex, assign to requesting thread.
-                        currentProcess.CpuMemory.WriteInt32(address, requester.ThreadHandleForUserMutex);
+                        currentProcess.CpuMemory.WriteInt32((long)address, requester.ThreadHandleForUserMutex);
                     }
 
                     currentProcess.CpuMemory.ClearExclusiveForStore(0);
@@ -261,16 +261,16 @@ namespace Ryujinx.HLE.HOS.Kernel
                     break;
                 }
 
-                currentProcess.CpuMemory.SetExclusive(0, address);
+                currentProcess.CpuMemory.SetExclusive(0, (long)address);
 
-                mutexValue = currentProcess.CpuMemory.ReadInt32(address);
+                mutexValue = currentProcess.CpuMemory.ReadInt32((long)address);
             }
 
             if (mutexValue == 0)
             {
                 //We now own the mutex.
                 requester.SignaledObj   = null;
-                requester.ObjSyncResult = 0;
+                requester.ObjSyncResult = KernelResult.Success;
 
                 requester.ReleaseAndResume();
 
@@ -290,7 +290,7 @@ namespace Ryujinx.HLE.HOS.Kernel
             {
                 //Invalid mutex owner.
                 requester.SignaledObj   = null;
-                requester.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
+                requester.ObjSyncResult = KernelResult.InvalidHandle;
 
                 requester.ReleaseAndResume();
             }
@@ -298,7 +298,7 @@ namespace Ryujinx.HLE.HOS.Kernel
             return mutexOwner;
         }
 
-        public long WaitForAddressIfEqual(long address, int value, long timeout)
+        public KernelResult WaitForAddressIfEqual(ulong address, int value, long timeout)
         {
             KThread currentThread = _system.Scheduler.GetCurrentThread();
 
@@ -309,17 +309,17 @@ namespace Ryujinx.HLE.HOS.Kernel
             {
                 _system.CriticalSection.Leave();
 
-                return MakeError(ErrorModule.Kernel, KernelErr.ThreadTerminating);
+                return KernelResult.ThreadTerminating;
             }
 
             currentThread.SignaledObj   = null;
-            currentThread.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Timeout);
+            currentThread.ObjSyncResult = KernelResult.TimedOut;
 
             if (!KernelTransfer.UserToKernelInt32(_system, address, out int currentValue))
             {
                 _system.CriticalSection.Leave();
 
-                return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
+                return KernelResult.InvalidMemState;
             }
 
             if (currentValue == value)
@@ -328,7 +328,7 @@ namespace Ryujinx.HLE.HOS.Kernel
                 {
                     _system.CriticalSection.Leave();
 
-                    return MakeError(ErrorModule.Kernel, KernelErr.Timeout);
+                    return KernelResult.TimedOut;
                 }
 
                 currentThread.MutexAddress         = address;
@@ -361,15 +361,19 @@ namespace Ryujinx.HLE.HOS.Kernel
 
                 _system.CriticalSection.Leave();
 
-                return currentThread.ObjSyncResult;
+                return (KernelResult)currentThread.ObjSyncResult;
             }
 
             _system.CriticalSection.Leave();
 
-            return MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
+            return KernelResult.InvalidState;
         }
 
-        public long WaitForAddressIfLessThan(long address, int value, bool shouldDecrement, long timeout)
+        public KernelResult WaitForAddressIfLessThan(
+            ulong address,
+            int   value,
+            bool  shouldDecrement,
+            long  timeout)
         {
             KThread currentThread = _system.Scheduler.GetCurrentThread();
 
@@ -380,40 +384,40 @@ namespace Ryujinx.HLE.HOS.Kernel
             {
                 _system.CriticalSection.Leave();
 
-                return MakeError(ErrorModule.Kernel, KernelErr.ThreadTerminating);
+                return KernelResult.ThreadTerminating;
             }
 
             currentThread.SignaledObj   = null;
-            currentThread.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Timeout);
+            currentThread.ObjSyncResult = KernelResult.TimedOut;
 
             KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
 
             //If ShouldDecrement is true, do atomic decrement of the value at Address.
-            currentProcess.CpuMemory.SetExclusive(0, address);
+            currentProcess.CpuMemory.SetExclusive(0, (long)address);
 
             if (!KernelTransfer.UserToKernelInt32(_system, address, out int currentValue))
             {
                 _system.CriticalSection.Leave();
 
-                return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
+                return KernelResult.InvalidMemState;
             }
 
             if (shouldDecrement)
             {
                 while (currentValue < value)
                 {
-                    if (currentProcess.CpuMemory.TestExclusive(0, address))
+                    if (currentProcess.CpuMemory.TestExclusive(0, (long)address))
                     {
-                        currentProcess.CpuMemory.WriteInt32(address, currentValue - 1);
+                        currentProcess.CpuMemory.WriteInt32((long)address, currentValue - 1);
 
                         currentProcess.CpuMemory.ClearExclusiveForStore(0);
 
                         break;
                     }
 
-                    currentProcess.CpuMemory.SetExclusive(0, address);
+                    currentProcess.CpuMemory.SetExclusive(0, (long)address);
 
-                    currentValue = currentProcess.CpuMemory.ReadInt32(address);
+                    currentValue = currentProcess.CpuMemory.ReadInt32((long)address);
                 }
             }
 
@@ -425,7 +429,7 @@ namespace Ryujinx.HLE.HOS.Kernel
                 {
                     _system.CriticalSection.Leave();
 
-                    return MakeError(ErrorModule.Kernel, KernelErr.Timeout);
+                    return KernelResult.TimedOut;
                 }
 
                 currentThread.MutexAddress         = address;
@@ -458,12 +462,12 @@ namespace Ryujinx.HLE.HOS.Kernel
 
                 _system.CriticalSection.Leave();
 
-                return currentThread.ObjSyncResult;
+                return (KernelResult)currentThread.ObjSyncResult;
             }
 
             _system.CriticalSection.Leave();
 
-            return MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
+            return KernelResult.InvalidState;
         }
 
         private void InsertSortedByPriority(List<KThread> threads, KThread thread)
@@ -490,7 +494,7 @@ namespace Ryujinx.HLE.HOS.Kernel
             }
         }
 
-        public long Signal(long address, int count)
+        public KernelResult Signal(ulong address, int count)
         {
             _system.CriticalSection.Enter();
 
@@ -498,38 +502,38 @@ namespace Ryujinx.HLE.HOS.Kernel
 
             _system.CriticalSection.Leave();
 
-            return 0;
+            return KernelResult.Success;
         }
 
-        public long SignalAndIncrementIfEqual(long address, int value, int count)
+        public KernelResult SignalAndIncrementIfEqual(ulong address, int value, int count)
         {
             _system.CriticalSection.Enter();
 
             KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
 
-            currentProcess.CpuMemory.SetExclusive(0, address);
+            currentProcess.CpuMemory.SetExclusive(0, (long)address);
 
             if (!KernelTransfer.UserToKernelInt32(_system, address, out int currentValue))
             {
                 _system.CriticalSection.Leave();
 
-                return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
+                return KernelResult.InvalidMemState;
             }
 
             while (currentValue == value)
             {
-                if (currentProcess.CpuMemory.TestExclusive(0, address))
+                if (currentProcess.CpuMemory.TestExclusive(0, (long)address))
                 {
-                    currentProcess.CpuMemory.WriteInt32(address, currentValue + 1);
+                    currentProcess.CpuMemory.WriteInt32((long)address, currentValue + 1);
 
                     currentProcess.CpuMemory.ClearExclusiveForStore(0);
 
                     break;
                 }
 
-                currentProcess.CpuMemory.SetExclusive(0, address);
+                currentProcess.CpuMemory.SetExclusive(0, (long)address);
 
-                currentValue = currentProcess.CpuMemory.ReadInt32(address);
+                currentValue = currentProcess.CpuMemory.ReadInt32((long)address);
             }
 
             currentProcess.CpuMemory.ClearExclusive(0);
@@ -538,17 +542,17 @@ namespace Ryujinx.HLE.HOS.Kernel
             {
                 _system.CriticalSection.Leave();
 
-                return MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
+                return KernelResult.InvalidState;
             }
 
             WakeArbiterThreads(address, count);
 
             _system.CriticalSection.Leave();
 
-            return 0;
+            return KernelResult.Success;
         }
 
-        public long SignalAndModifyIfEqual(long address, int value, int count)
+        public KernelResult SignalAndModifyIfEqual(ulong address, int value, int count)
         {
             _system.CriticalSection.Enter();
 
@@ -578,29 +582,29 @@ namespace Ryujinx.HLE.HOS.Kernel
 
             KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
 
-            currentProcess.CpuMemory.SetExclusive(0, address);
+            currentProcess.CpuMemory.SetExclusive(0, (long)address);
 
             if (!KernelTransfer.UserToKernelInt32(_system, address, out int currentValue))
             {
                 _system.CriticalSection.Leave();
 
-                return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
+                return KernelResult.InvalidMemState;
             }
 
             while (currentValue == value)
             {
-                if (currentProcess.CpuMemory.TestExclusive(0, address))
+                if (currentProcess.CpuMemory.TestExclusive(0, (long)address))
                 {
-                    currentProcess.CpuMemory.WriteInt32(address, currentValue + offset);
+                    currentProcess.CpuMemory.WriteInt32((long)address, currentValue + offset);
 
                     currentProcess.CpuMemory.ClearExclusiveForStore(0);
 
                     break;
                 }
 
-                currentProcess.CpuMemory.SetExclusive(0, address);
+                currentProcess.CpuMemory.SetExclusive(0, (long)address);
 
-                currentValue = currentProcess.CpuMemory.ReadInt32(address);
+                currentValue = currentProcess.CpuMemory.ReadInt32((long)address);
             }
 
             currentProcess.CpuMemory.ClearExclusive(0);
@@ -609,17 +613,17 @@ namespace Ryujinx.HLE.HOS.Kernel
             {
                 _system.CriticalSection.Leave();
 
-                return MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
+                return KernelResult.InvalidState;
             }
 
             WakeArbiterThreads(address, count);
 
             _system.CriticalSection.Leave();
 
-            return 0;
+            return KernelResult.Success;
         }
 
-        private void WakeArbiterThreads(long address, int count)
+        private void WakeArbiterThreads(ulong address, int count)
         {
             Queue<KThread> signaledThreads = new Queue<KThread>();
 
@@ -637,7 +641,7 @@ namespace Ryujinx.HLE.HOS.Kernel
             while (signaledThreads.TryDequeue(out KThread thread))
             {
                 thread.SignaledObj   = null;
-                thread.ObjSyncResult = 0;
+                thread.ObjSyncResult = KernelResult.Success;
 
                 thread.ReleaseAndResume();
 
diff --git a/Ryujinx.HLE/HOS/Kernel/KConditionVariable.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KConditionVariable.cs
similarity index 97%
rename from Ryujinx.HLE/HOS/Kernel/KConditionVariable.cs
rename to Ryujinx.HLE/HOS/Kernel/Threading/KConditionVariable.cs
index 15c96c24..41473643 100644
--- a/Ryujinx.HLE/HOS/Kernel/KConditionVariable.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Threading/KConditionVariable.cs
@@ -1,7 +1,7 @@
 using System.Collections.Generic;
 using System.Threading;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Threading
 {
     static class KConditionVariable
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KCoreContext.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KCoreContext.cs
similarity index 98%
rename from Ryujinx.HLE/HOS/Kernel/KCoreContext.cs
rename to Ryujinx.HLE/HOS/Kernel/Threading/KCoreContext.cs
index 4ca3c25a..81cd8883 100644
--- a/Ryujinx.HLE/HOS/Kernel/KCoreContext.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Threading/KCoreContext.cs
@@ -1,6 +1,6 @@
 using Ryujinx.Common;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Threading
 {
     class KCoreContext
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KCriticalSection.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KCriticalSection.cs
similarity index 98%
rename from Ryujinx.HLE/HOS/Kernel/KCriticalSection.cs
rename to Ryujinx.HLE/HOS/Kernel/Threading/KCriticalSection.cs
index a54dc6cb..841d0d69 100644
--- a/Ryujinx.HLE/HOS/Kernel/KCriticalSection.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Threading/KCriticalSection.cs
@@ -1,7 +1,7 @@
 using ChocolArm64;
 using System.Threading;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Threading
 {
     class KCriticalSection
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KEvent.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KEvent.cs
similarity index 88%
rename from Ryujinx.HLE/HOS/Kernel/KEvent.cs
rename to Ryujinx.HLE/HOS/Kernel/Threading/KEvent.cs
index aa2124ec..5bdb9c1d 100644
--- a/Ryujinx.HLE/HOS/Kernel/KEvent.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Threading/KEvent.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Threading
 {
     class KEvent
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KReadableEvent.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KReadableEvent.cs
similarity index 93%
rename from Ryujinx.HLE/HOS/Kernel/KReadableEvent.cs
rename to Ryujinx.HLE/HOS/Kernel/Threading/KReadableEvent.cs
index e1a3e63f..9821de35 100644
--- a/Ryujinx.HLE/HOS/Kernel/KReadableEvent.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Threading/KReadableEvent.cs
@@ -1,4 +1,6 @@
-namespace Ryujinx.HLE.HOS.Kernel
+using Ryujinx.HLE.HOS.Kernel.Common;
+
+namespace Ryujinx.HLE.HOS.Kernel.Threading
 {
     class KReadableEvent : KSynchronizationObject
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KScheduler.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KScheduler.cs
similarity index 98%
rename from Ryujinx.HLE/HOS/Kernel/KScheduler.cs
rename to Ryujinx.HLE/HOS/Kernel/Threading/KScheduler.cs
index f85b9e8c..60e15efa 100644
--- a/Ryujinx.HLE/HOS/Kernel/KScheduler.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Threading/KScheduler.cs
@@ -1,8 +1,9 @@
+using Ryujinx.HLE.HOS.Kernel.Process;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Threading
 {
     partial class KScheduler : IDisposable
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KSchedulingData.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KSchedulingData.cs
similarity index 99%
rename from Ryujinx.HLE/HOS/Kernel/KSchedulingData.cs
rename to Ryujinx.HLE/HOS/Kernel/Threading/KSchedulingData.cs
index 65116036..83c4a079 100644
--- a/Ryujinx.HLE/HOS/Kernel/KSchedulingData.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Threading/KSchedulingData.cs
@@ -1,6 +1,6 @@
 using System.Collections.Generic;
 
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Threading
 {
     class KSchedulingData
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/KSynchronization.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KSynchronization.cs
similarity index 82%
rename from Ryujinx.HLE/HOS/Kernel/KSynchronization.cs
rename to Ryujinx.HLE/HOS/Kernel/Threading/KSynchronization.cs
index 51b74a03..450155ce 100644
--- a/Ryujinx.HLE/HOS/Kernel/KSynchronization.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Threading/KSynchronization.cs
@@ -1,8 +1,7 @@
+using Ryujinx.HLE.HOS.Kernel.Common;
 using System.Collections.Generic;
 
-using static Ryujinx.HLE.HOS.ErrorCode;
-
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Threading
 {
     class KSynchronization
     {
@@ -13,9 +12,11 @@ namespace Ryujinx.HLE.HOS.Kernel
             _system = system;
         }
 
-        public long WaitFor(KSynchronizationObject[] syncObjs, long timeout, ref int hndIndex)
+        public KernelResult WaitFor(KSynchronizationObject[] syncObjs, long timeout, out int handleIndex)
         {
-            long result = MakeError(ErrorModule.Kernel, KernelErr.Timeout);
+            handleIndex = 0;
+
+            KernelResult result = KernelResult.TimedOut;
 
             _system.CriticalSection.Enter();
 
@@ -27,7 +28,7 @@ namespace Ryujinx.HLE.HOS.Kernel
                     continue;
                 }
 
-                hndIndex = index;
+                handleIndex = index;
 
                 _system.CriticalSection.Leave();
 
@@ -46,13 +47,13 @@ namespace Ryujinx.HLE.HOS.Kernel
             if (currentThread.ShallBeTerminated ||
                 currentThread.SchedFlags == ThreadSchedState.TerminationPending)
             {
-                result = MakeError(ErrorModule.Kernel, KernelErr.ThreadTerminating);
+                result = KernelResult.ThreadTerminating;
             }
             else if (currentThread.SyncCancelled)
             {
                 currentThread.SyncCancelled = false;
 
-                result = MakeError(ErrorModule.Kernel, KernelErr.Cancelled);
+                result = KernelResult.Cancelled;
             }
             else
             {
@@ -65,7 +66,7 @@ namespace Ryujinx.HLE.HOS.Kernel
 
                 currentThread.WaitingSync   = true;
                 currentThread.SignaledObj   = null;
-                currentThread.ObjSyncResult = (int)result;
+                currentThread.ObjSyncResult = result;
 
                 currentThread.Reschedule(ThreadSchedState.Paused);
 
@@ -85,9 +86,9 @@ namespace Ryujinx.HLE.HOS.Kernel
 
                 _system.CriticalSection.Enter();
 
-                result = (uint)currentThread.ObjSyncResult;
+                result = currentThread.ObjSyncResult;
 
-                hndIndex = -1;
+                handleIndex = -1;
 
                 for (int index = 0; index < syncObjs.Length; index++)
                 {
@@ -95,7 +96,7 @@ namespace Ryujinx.HLE.HOS.Kernel
 
                     if (syncObjs[index] == currentThread.SignaledObj)
                     {
-                        hndIndex = index;
+                        handleIndex = index;
                     }
                 }
             }
@@ -120,7 +121,7 @@ namespace Ryujinx.HLE.HOS.Kernel
                     if ((thread.SchedFlags & ThreadSchedState.LowMask) == ThreadSchedState.Paused)
                     {
                         thread.SignaledObj   = syncObj;
-                        thread.ObjSyncResult = 0;
+                        thread.ObjSyncResult = KernelResult.Success;
 
                         thread.Reschedule(ThreadSchedState.Running);
                     }
diff --git a/Ryujinx.HLE/HOS/Kernel/KThread.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
similarity index 97%
rename from Ryujinx.HLE/HOS/Kernel/KThread.cs
rename to Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
index 846b41aa..3ad64024 100644
--- a/Ryujinx.HLE/HOS/Kernel/KThread.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
@@ -1,12 +1,12 @@
 using ChocolArm64;
 using ChocolArm64.Memory;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Process;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 
-using static Ryujinx.HLE.HOS.ErrorCode;
-
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Threading
 {
     class KThread : KSynchronizationObject, IKFutureSchedulerObject
     {
@@ -20,11 +20,11 @@ namespace Ryujinx.HLE.HOS.Kernel
 
         public KSynchronizationObject SignaledObj { get; set; }
 
-        public long CondVarAddress { get; set; }
+        public ulong CondVarAddress { get; set; }
 
         private ulong _entrypoint;
 
-        public long MutexAddress { get; set; }
+        public ulong MutexAddress { get; set; }
 
         public KProcess Owner { get; private set; }
 
@@ -48,7 +48,7 @@ namespace Ryujinx.HLE.HOS.Kernel
 
         private ThreadSchedState _forcePauseFlags;
 
-        public int ObjSyncResult { get; set; }
+        public KernelResult ObjSyncResult { get; set; }
 
         public int DynamicPriority { get; set; }
         public int CurrentCore     { get; set; }
@@ -113,7 +113,7 @@ namespace Ryujinx.HLE.HOS.Kernel
             DynamicPriority = priority;
             BasePriority    = priority;
 
-            ObjSyncResult = 0x7201;
+            ObjSyncResult = KernelResult.ThreadNotStarted;
 
             _entrypoint = entrypoint;
 
@@ -274,7 +274,7 @@ namespace Ryujinx.HLE.HOS.Kernel
             System.CriticalSection.Leave();
         }
 
-        public long Sleep(long timeout)
+        public KernelResult Sleep(long timeout)
         {
             System.CriticalSection.Enter();
 
@@ -282,7 +282,7 @@ namespace Ryujinx.HLE.HOS.Kernel
             {
                 System.CriticalSection.Leave();
 
-                return MakeError(ErrorModule.Kernel, KernelErr.ThreadTerminating);
+                return KernelResult.ThreadTerminating;
             }
 
             SetNewSchedFlags(ThreadSchedState.Paused);
@@ -468,9 +468,9 @@ namespace Ryujinx.HLE.HOS.Kernel
             System.CriticalSection.Leave();
         }
 
-        public long SetActivity(bool pause)
+        public KernelResult SetActivity(bool pause)
         {
-            long result = 0;
+            KernelResult result = KernelResult.Success;
 
             System.CriticalSection.Enter();
 
@@ -480,7 +480,7 @@ namespace Ryujinx.HLE.HOS.Kernel
             {
                 System.CriticalSection.Leave();
 
-                return MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
+                return KernelResult.InvalidState;
             }
 
             System.CriticalSection.Enter();
@@ -498,7 +498,7 @@ namespace Ryujinx.HLE.HOS.Kernel
                     }
                     else
                     {
-                        result = MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
+                        result = KernelResult.InvalidState;
                     }
                 }
                 else
@@ -521,7 +521,7 @@ namespace Ryujinx.HLE.HOS.Kernel
                     }
                     else
                     {
-                        result = MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
+                        result = KernelResult.InvalidState;
                     }
                 }
             }
@@ -553,7 +553,7 @@ namespace Ryujinx.HLE.HOS.Kernel
             else
             {
                 SignaledObj   = null;
-                ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Cancelled);
+                ObjSyncResult = KernelResult.Cancelled;
 
                 SetNewSchedFlags(ThreadSchedState.Running);
 
@@ -716,7 +716,7 @@ namespace Ryujinx.HLE.HOS.Kernel
             UpdatePriorityInheritance();
         }
 
-        public KThread RelinquishMutex(long mutexAddress, out int count)
+        public KThread RelinquishMutex(ulong mutexAddress, out int count)
         {
             count = 0;
 
@@ -1017,7 +1017,7 @@ namespace Ryujinx.HLE.HOS.Kernel
             {
                 thread.MutexOwner             = null;
                 thread._preferredCoreOverride = 0;
-                thread.ObjSyncResult          = 0xfa01;
+                thread.ObjSyncResult          = KernelResult.InvalidState;
 
                 thread.ReleaseAndResume();
             }
diff --git a/Ryujinx.HLE/HOS/Kernel/KWritableEvent.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KWritableEvent.cs
similarity index 82%
rename from Ryujinx.HLE/HOS/Kernel/KWritableEvent.cs
rename to Ryujinx.HLE/HOS/Kernel/Threading/KWritableEvent.cs
index 4d56a92d..c9b2f40d 100644
--- a/Ryujinx.HLE/HOS/Kernel/KWritableEvent.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Threading/KWritableEvent.cs
@@ -1,4 +1,6 @@
-namespace Ryujinx.HLE.HOS.Kernel
+using Ryujinx.HLE.HOS.Kernel.Common;
+
+namespace Ryujinx.HLE.HOS.Kernel.Threading
 {
     class KWritableEvent
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/SignalType.cs b/Ryujinx.HLE/HOS/Kernel/Threading/SignalType.cs
similarity index 77%
rename from Ryujinx.HLE/HOS/Kernel/SignalType.cs
rename to Ryujinx.HLE/HOS/Kernel/Threading/SignalType.cs
index 05803151..e72b719b 100644
--- a/Ryujinx.HLE/HOS/Kernel/SignalType.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Threading/SignalType.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Threading
 {
     enum SignalType
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/ThreadSchedState.cs b/Ryujinx.HLE/HOS/Kernel/Threading/ThreadSchedState.cs
similarity index 90%
rename from Ryujinx.HLE/HOS/Kernel/ThreadSchedState.cs
rename to Ryujinx.HLE/HOS/Kernel/Threading/ThreadSchedState.cs
index 37e5908a..c9eaa6b3 100644
--- a/Ryujinx.HLE/HOS/Kernel/ThreadSchedState.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Threading/ThreadSchedState.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Threading
 {
     enum ThreadSchedState : ushort
     {
diff --git a/Ryujinx.HLE/HOS/Kernel/ThreadType.cs b/Ryujinx.HLE/HOS/Kernel/Threading/ThreadType.cs
similarity index 69%
rename from Ryujinx.HLE/HOS/Kernel/ThreadType.cs
rename to Ryujinx.HLE/HOS/Kernel/Threading/ThreadType.cs
index 0fe83423..0b44b57f 100644
--- a/Ryujinx.HLE/HOS/Kernel/ThreadType.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Threading/ThreadType.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.HLE.HOS.Kernel
+namespace Ryujinx.HLE.HOS.Kernel.Threading
 {
     enum ThreadType
     {
diff --git a/Ryujinx.HLE/HOS/ProgramLoader.cs b/Ryujinx.HLE/HOS/ProgramLoader.cs
index 00fc6b93..bb09db6e 100644
--- a/Ryujinx.HLE/HOS/ProgramLoader.cs
+++ b/Ryujinx.HLE/HOS/ProgramLoader.cs
@@ -1,7 +1,9 @@
 using ChocolArm64.Memory;
 using Ryujinx.Common;
 using Ryujinx.Common.Logging;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Memory;
+using Ryujinx.HLE.HOS.Kernel.Process;
 using Ryujinx.HLE.Loaders.Executables;
 using Ryujinx.HLE.Loaders.Npdm;
 
diff --git a/Ryujinx.HLE/HOS/ServiceCtx.cs b/Ryujinx.HLE/HOS/ServiceCtx.cs
index f55e4546..005d16f3 100644
--- a/Ryujinx.HLE/HOS/ServiceCtx.cs
+++ b/Ryujinx.HLE/HOS/ServiceCtx.cs
@@ -1,6 +1,7 @@
 using ChocolArm64.Memory;
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Ipc;
+using Ryujinx.HLE.HOS.Kernel.Process;
 using System.IO;
 
 namespace Ryujinx.HLE.HOS
diff --git a/Ryujinx.HLE/HOS/Services/Am/ICommonStateGetter.cs b/Ryujinx.HLE/HOS/Services/Am/ICommonStateGetter.cs
index 8ec42152..f143db2c 100644
--- a/Ryujinx.HLE/HOS/Services/Am/ICommonStateGetter.cs
+++ b/Ryujinx.HLE/HOS/Services/Am/ICommonStateGetter.cs
@@ -1,6 +1,7 @@
 using Ryujinx.Common.Logging;
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using System;
 using System.Collections.Generic;
 
diff --git a/Ryujinx.HLE/HOS/Services/Am/IHomeMenuFunctions.cs b/Ryujinx.HLE/HOS/Services/Am/IHomeMenuFunctions.cs
index db116f33..fdcd923d 100644
--- a/Ryujinx.HLE/HOS/Services/Am/IHomeMenuFunctions.cs
+++ b/Ryujinx.HLE/HOS/Services/Am/IHomeMenuFunctions.cs
@@ -1,6 +1,7 @@
 using Ryujinx.Common.Logging;
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using System;
 using System.Collections.Generic;
 
diff --git a/Ryujinx.HLE/HOS/Services/Am/ILibraryAppletAccessor.cs b/Ryujinx.HLE/HOS/Services/Am/ILibraryAppletAccessor.cs
index 7c4aa16c..faf522e4 100644
--- a/Ryujinx.HLE/HOS/Services/Am/ILibraryAppletAccessor.cs
+++ b/Ryujinx.HLE/HOS/Services/Am/ILibraryAppletAccessor.cs
@@ -1,6 +1,7 @@
 using Ryujinx.Common.Logging;
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using System;
 using System.Collections.Generic;
 
diff --git a/Ryujinx.HLE/HOS/Services/Am/ISelfController.cs b/Ryujinx.HLE/HOS/Services/Am/ISelfController.cs
index dc922037..e30e8d0d 100644
--- a/Ryujinx.HLE/HOS/Services/Am/ISelfController.cs
+++ b/Ryujinx.HLE/HOS/Services/Am/ISelfController.cs
@@ -1,6 +1,7 @@
 using Ryujinx.Common.Logging;
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using System;
 using System.Collections.Generic;
 
diff --git a/Ryujinx.HLE/HOS/Services/Aud/AudioOut/IAudioOut.cs b/Ryujinx.HLE/HOS/Services/Aud/AudioOut/IAudioOut.cs
index 93bda210..5270a041 100644
--- a/Ryujinx.HLE/HOS/Services/Aud/AudioOut/IAudioOut.cs
+++ b/Ryujinx.HLE/HOS/Services/Aud/AudioOut/IAudioOut.cs
@@ -1,7 +1,8 @@
 using ChocolArm64.Memory;
 using Ryujinx.Audio;
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using System;
 using System.Collections.Generic;
 
diff --git a/Ryujinx.HLE/HOS/Services/Aud/AudioRenderer/IAudioRenderer.cs b/Ryujinx.HLE/HOS/Services/Aud/AudioRenderer/IAudioRenderer.cs
index 0ad193ca..bc069436 100644
--- a/Ryujinx.HLE/HOS/Services/Aud/AudioRenderer/IAudioRenderer.cs
+++ b/Ryujinx.HLE/HOS/Services/Aud/AudioRenderer/IAudioRenderer.cs
@@ -3,7 +3,8 @@ using Ryujinx.Audio;
 using Ryujinx.Audio.Adpcm;
 using Ryujinx.Common.Logging;
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using Ryujinx.HLE.Utilities;
 using System;
 using System.Collections.Generic;
diff --git a/Ryujinx.HLE/HOS/Services/Aud/IAudioDevice.cs b/Ryujinx.HLE/HOS/Services/Aud/IAudioDevice.cs
index 585d7e43..0d68fe13 100644
--- a/Ryujinx.HLE/HOS/Services/Aud/IAudioDevice.cs
+++ b/Ryujinx.HLE/HOS/Services/Aud/IAudioDevice.cs
@@ -1,6 +1,7 @@
 using Ryujinx.Common.Logging;
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using Ryujinx.HLE.HOS.SystemState;
 using System;
 using System.Collections.Generic;
diff --git a/Ryujinx.HLE/HOS/Services/Aud/IAudioOutManager.cs b/Ryujinx.HLE/HOS/Services/Aud/IAudioOutManager.cs
index 4b1440a0..a276c96e 100644
--- a/Ryujinx.HLE/HOS/Services/Aud/IAudioOutManager.cs
+++ b/Ryujinx.HLE/HOS/Services/Aud/IAudioOutManager.cs
@@ -2,7 +2,7 @@ using ChocolArm64.Memory;
 using Ryujinx.Audio;
 using Ryujinx.Common.Logging;
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using Ryujinx.HLE.HOS.Services.Aud.AudioOut;
 using System.Collections.Generic;
 using System.Text;
diff --git a/Ryujinx.HLE/HOS/Services/Hid/IAppletResource.cs b/Ryujinx.HLE/HOS/Services/Hid/IAppletResource.cs
index e82b824e..c92252d8 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/IAppletResource.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/IAppletResource.cs
@@ -1,5 +1,6 @@
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Memory;
 using System;
 using System.Collections.Generic;
 
diff --git a/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs b/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs
index 4e14943b..cc75e99b 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs
@@ -1,6 +1,7 @@
 using Ryujinx.Common.Logging;
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using Ryujinx.HLE.Input;
 using System;
 using System.Collections.Generic;
@@ -1216,7 +1217,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
             long appletResourceUserId = context.RequestData.ReadInt64();
 
             Logger.PrintStub(LogClass.ServiceHid, $"Stubbed. AppletResourceUserId: {appletResourceUserId}");
-            
+
             return 0;
         }
 
diff --git a/Ryujinx.HLE/HOS/Services/IpcService.cs b/Ryujinx.HLE/HOS/Services/IpcService.cs
index ec43430e..8d2036ea 100644
--- a/Ryujinx.HLE/HOS/Services/IpcService.cs
+++ b/Ryujinx.HLE/HOS/Services/IpcService.cs
@@ -1,6 +1,7 @@
 using Ryujinx.Common.Logging;
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Ipc;
 using System;
 using System.Collections.Generic;
 using System.IO;
diff --git a/Ryujinx.HLE/HOS/Services/Ldr/IRoInterface.cs b/Ryujinx.HLE/HOS/Services/Ldr/IRoInterface.cs
index 1ee30a6c..202e6df5 100644
--- a/Ryujinx.HLE/HOS/Services/Ldr/IRoInterface.cs
+++ b/Ryujinx.HLE/HOS/Services/Ldr/IRoInterface.cs
@@ -1,7 +1,9 @@
 using ChocolArm64.Memory;
 using Ryujinx.Common;
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Memory;
+using Ryujinx.HLE.HOS.Kernel.Process;
 using Ryujinx.HLE.Loaders.Executables;
 using Ryujinx.HLE.Utilities;
 using System.Collections.Generic;
diff --git a/Ryujinx.HLE/HOS/Services/Nfp/IUser.cs b/Ryujinx.HLE/HOS/Services/Nfp/IUser.cs
index 9e19e77f..42ef4829 100644
--- a/Ryujinx.HLE/HOS/Services/Nfp/IUser.cs
+++ b/Ryujinx.HLE/HOS/Services/Nfp/IUser.cs
@@ -1,6 +1,7 @@
 using Ryujinx.Common.Logging;
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using Ryujinx.HLE.Input;
 using System;
 using System.Collections.Generic;
diff --git a/Ryujinx.HLE/HOS/Services/Nifm/IRequest.cs b/Ryujinx.HLE/HOS/Services/Nifm/IRequest.cs
index 52adce9e..d2c646be 100644
--- a/Ryujinx.HLE/HOS/Services/Nifm/IRequest.cs
+++ b/Ryujinx.HLE/HOS/Services/Nifm/IRequest.cs
@@ -1,6 +1,7 @@
 using Ryujinx.Common.Logging;
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using System;
 using System.Collections.Generic;
 
diff --git a/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs b/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs
index 1ed97dde..3a00f514 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs
@@ -1,7 +1,9 @@
 using ChocolArm64.Memory;
 using Ryujinx.Common.Logging;
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Process;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using Ryujinx.HLE.HOS.Services.Nv.NvGpuAS;
 using Ryujinx.HLE.HOS.Services.Nv.NvGpuGpu;
 using Ryujinx.HLE.HOS.Services.Nv.NvHostChannel;
diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvGpuAS/NvGpuASIoctl.cs b/Ryujinx.HLE/HOS/Services/Nv/NvGpuAS/NvGpuASIoctl.cs
index 8e128a0d..2a5f1b18 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/NvGpuAS/NvGpuASIoctl.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/NvGpuAS/NvGpuASIoctl.cs
@@ -1,7 +1,7 @@
 using ChocolArm64.Memory;
 using Ryujinx.Common.Logging;
 using Ryujinx.Graphics.Memory;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Process;
 using Ryujinx.HLE.HOS.Services.Nv.NvMap;
 using System;
 using System.Collections.Concurrent;
diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvHostChannel/NvHostChannelIoctl.cs b/Ryujinx.HLE/HOS/Services/Nv/NvHostChannel/NvHostChannelIoctl.cs
index a3b55309..a6681441 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/NvHostChannel/NvHostChannelIoctl.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/NvHostChannel/NvHostChannelIoctl.cs
@@ -1,7 +1,7 @@
 using ChocolArm64.Memory;
 using Ryujinx.Common.Logging;
 using Ryujinx.Graphics.Memory;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Process;
 using Ryujinx.HLE.HOS.Services.Nv.NvGpuAS;
 using Ryujinx.HLE.HOS.Services.Nv.NvMap;
 using System;
diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvHostCtrl/NvHostCtrlIoctl.cs b/Ryujinx.HLE/HOS/Services/Nv/NvHostCtrl/NvHostCtrlIoctl.cs
index f13f7a68..ddef456c 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/NvHostCtrl/NvHostCtrlIoctl.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/NvHostCtrl/NvHostCtrlIoctl.cs
@@ -1,6 +1,6 @@
 using ChocolArm64.Memory;
 using Ryujinx.Common.Logging;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Process;
 using System;
 using System.Collections.Concurrent;
 using System.Text;
diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvMap/NvMapIoctl.cs b/Ryujinx.HLE/HOS/Services/Nv/NvMap/NvMapIoctl.cs
index 75a76b91..b1ae8307 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/NvMap/NvMapIoctl.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/NvMap/NvMapIoctl.cs
@@ -1,7 +1,7 @@
 using ChocolArm64.Memory;
 using Ryujinx.Common.Logging;
 using Ryujinx.Graphics.Memory;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Process;
 using Ryujinx.HLE.Utilities;
 using System.Collections.Concurrent;
 
diff --git a/Ryujinx.HLE/HOS/Services/Pl/ISharedFontManager.cs b/Ryujinx.HLE/HOS/Services/Pl/ISharedFontManager.cs
index c555c504..1bdff31a 100644
--- a/Ryujinx.HLE/HOS/Services/Pl/ISharedFontManager.cs
+++ b/Ryujinx.HLE/HOS/Services/Pl/ISharedFontManager.cs
@@ -1,6 +1,6 @@
 using Ryujinx.HLE.HOS.Font;
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
 using System;
 using System.Collections.Generic;
 
diff --git a/Ryujinx.HLE/HOS/Services/Psm/IPsmSession.cs b/Ryujinx.HLE/HOS/Services/Psm/IPsmSession.cs
index 4763f2d5..0c304b41 100644
--- a/Ryujinx.HLE/HOS/Services/Psm/IPsmSession.cs
+++ b/Ryujinx.HLE/HOS/Services/Psm/IPsmSession.cs
@@ -1,6 +1,7 @@
 using Ryujinx.Common.Logging;
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using System.Collections.Generic;
 
 namespace Ryujinx.HLE.HOS.Services.Psm
diff --git a/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs b/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs
index 2bfafd95..df551a41 100644
--- a/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs
+++ b/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs
@@ -1,5 +1,6 @@
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Ipc;
 using System;
 using System.Collections.Generic;
 
diff --git a/Ryujinx.HLE/HOS/Services/Vi/IApplicationDisplayService.cs b/Ryujinx.HLE/HOS/Services/Vi/IApplicationDisplayService.cs
index 63e542d2..0b5705b9 100644
--- a/Ryujinx.HLE/HOS/Services/Vi/IApplicationDisplayService.cs
+++ b/Ryujinx.HLE/HOS/Services/Vi/IApplicationDisplayService.cs
@@ -1,6 +1,6 @@
 using ChocolArm64.Memory;
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
 using System.Collections.Generic;
 using System;
 using System.IO;
diff --git a/Ryujinx.HLE/HOS/Services/Vi/IHOSBinderDriver.cs b/Ryujinx.HLE/HOS/Services/Vi/IHOSBinderDriver.cs
index 7ca3053d..adcedf4e 100644
--- a/Ryujinx.HLE/HOS/Services/Vi/IHOSBinderDriver.cs
+++ b/Ryujinx.HLE/HOS/Services/Vi/IHOSBinderDriver.cs
@@ -1,6 +1,7 @@
 using Ryujinx.Graphics.Gal;
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using Ryujinx.HLE.HOS.Services.Android;
 using System;
 using System.Collections.Generic;
diff --git a/Ryujinx.HLE/HOS/Services/Vi/NvFlinger.cs b/Ryujinx.HLE/HOS/Services/Vi/NvFlinger.cs
index 1b57b331..cce1b2b9 100644
--- a/Ryujinx.HLE/HOS/Services/Vi/NvFlinger.cs
+++ b/Ryujinx.HLE/HOS/Services/Vi/NvFlinger.cs
@@ -1,7 +1,7 @@
 using Ryujinx.Common.Logging;
 using Ryujinx.Graphics.Gal;
 using Ryujinx.Graphics.Memory;
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using Ryujinx.HLE.HOS.Services.Nv.NvGpuAS;
 using Ryujinx.HLE.HOS.Services.Nv.NvMap;
 using System;
diff --git a/Ryujinx.HLE/HOS/SystemState/AppletStateMgr.cs b/Ryujinx.HLE/HOS/SystemState/AppletStateMgr.cs
index f46a7c30..1fd27505 100644
--- a/Ryujinx.HLE/HOS/SystemState/AppletStateMgr.cs
+++ b/Ryujinx.HLE/HOS/SystemState/AppletStateMgr.cs
@@ -1,4 +1,4 @@
-using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Threading;
 using Ryujinx.HLE.HOS.Services.Am;
 using System.Collections.Concurrent;