diff --git a/CONFIG.md b/CONFIG.md
index 09fa13b7b2..764eb528da 100644
--- a/CONFIG.md
+++ b/CONFIG.md
@@ -26,6 +26,10 @@
 
   Enable the Fatal Logging (Enabled in Debug recommanded).
 
+- `Logging_Enable_Ipc` *(bool)*
+
+  Enable the Ipc Message Logging.
+
 - `Logging_Enable_LogFile` *(bool)*
 
   Enable writing the logging inside a Ryujinx.log file.
diff --git a/Ryujinx.Core/Config.cs b/Ryujinx.Core/Config.cs
index b97e80b89f..7db49319c9 100644
--- a/Ryujinx.Core/Config.cs
+++ b/Ryujinx.Core/Config.cs
@@ -8,12 +8,13 @@ namespace Ryujinx.Core
 {
     public static class Config
     {
-        public static bool LoggingEnableInfo { get; private set; }
-        public static bool LoggingEnableTrace { get; private set; }
-        public static bool LoggingEnableDebug { get; private set; }
-        public static bool LoggingEnableWarn { get; private set; }
-        public static bool LoggingEnableError { get; private set; }
-        public static bool LoggingEnableFatal { get; private set; }
+        public static bool LoggingEnableInfo    { get; private set; }
+        public static bool LoggingEnableTrace   { get; private set; }
+        public static bool LoggingEnableDebug   { get; private set; }
+        public static bool LoggingEnableWarn    { get; private set; }
+        public static bool LoggingEnableError   { get; private set; }
+        public static bool LoggingEnableFatal   { get; private set; }
+        public static bool LoggingEnableIpc     { get; private set; }
         public static bool LoggingEnableLogFile { get; private set; }
 
         public static JoyCon FakeJoyCon { get; private set; }
@@ -30,6 +31,7 @@ namespace Ryujinx.Core
             LoggingEnableWarn    = Convert.ToBoolean(Parser.Value("Logging_Enable_Warn"));
             LoggingEnableError   = Convert.ToBoolean(Parser.Value("Logging_Enable_Error"));
             LoggingEnableFatal   = Convert.ToBoolean(Parser.Value("Logging_Enable_Fatal"));
+            LoggingEnableIpc     = Convert.ToBoolean(Parser.Value("Logging_Enable_Ipc"));
             LoggingEnableLogFile = Convert.ToBoolean(Parser.Value("Logging_Enable_LogFile"));
 
             FakeJoyCon = new JoyCon
diff --git a/Ryujinx.Core/Logging.cs b/Ryujinx.Core/Logging.cs
index e14e5587a1..b14f266539 100644
--- a/Ryujinx.Core/Logging.cs
+++ b/Ryujinx.Core/Logging.cs
@@ -1,6 +1,8 @@
-using System;
+using Ryujinx.Core.OsHle.Ipc;
+using System;
 using System.Diagnostics;
 using System.IO;
+using System.Text;
 
 namespace Ryujinx.Core
 {
@@ -9,13 +11,14 @@ namespace Ryujinx.Core
         private static Stopwatch ExecutionTime = new Stopwatch();
         private const string LogFileName = "Ryujinx.log";
 
-        public static bool EnableInfo = Config.LoggingEnableInfo;
-        public static bool EnableTrace = Config.LoggingEnableTrace;
-        public static bool EnableDebug = Config.LoggingEnableDebug;
-        public static bool EnableWarn = Config.LoggingEnableWarn;
-        public static bool EnableError = Config.LoggingEnableError;
-        public static bool EnableFatal = Config.LoggingEnableFatal;
-        public static bool EnableLogFile = Config.LoggingEnableLogFile;
+        private static bool EnableInfo    = Config.LoggingEnableInfo;
+        private static bool EnableTrace   = Config.LoggingEnableTrace;
+        private static bool EnableDebug   = Config.LoggingEnableDebug;
+        private static bool EnableWarn    = Config.LoggingEnableWarn;
+        private static bool EnableError   = Config.LoggingEnableError;
+        private static bool EnableFatal   = Config.LoggingEnableFatal;
+        private static bool EnableIpc     = Config.LoggingEnableIpc;
+        private static bool EnableLogFile = Config.LoggingEnableLogFile;
 
         static Logging()
         {
@@ -128,5 +131,79 @@ namespace Ryujinx.Core
                 LogFile(Text);
             }
         }
+
+        public static void Ipc(byte[] Data, long CmdPtr, bool Domain)
+        {
+            if (EnableIpc)
+            {
+                Console.ForegroundColor = ConsoleColor.Cyan;
+                Console.WriteLine(IpcLog.Message(Data, CmdPtr, Domain));
+                Console.ResetColor();
+            }
+        }
+
+        //https://www.codeproject.com/Articles/36747/Quick-and-Dirty-HexDump-of-a-Byte-Array
+        public static string HexDump(byte[] bytes, int bytesPerLine = 16)
+        {
+            if (bytes == null) return "<null>";
+            int bytesLength = bytes.Length;
+
+            char[] HexChars = "0123456789ABCDEF".ToCharArray();
+
+            int firstHexColumn =
+                  8                   // 8 characters for the address
+                + 3;                  // 3 spaces
+
+            int firstCharColumn = firstHexColumn
+                + bytesPerLine * 3       // - 2 digit for the hexadecimal value and 1 space
+                + (bytesPerLine - 1) / 8 // - 1 extra space every 8 characters from the 9th
+                + 2;                  // 2 spaces 
+
+            int lineLength = firstCharColumn
+                + bytesPerLine           // - characters to show the ascii value
+                + Environment.NewLine.Length; // Carriage return and line feed (should normally be 2)
+
+            char[] line = (new String(' ', lineLength - Environment.NewLine.Length) + Environment.NewLine).ToCharArray();
+            int expectedLines = (bytesLength + bytesPerLine - 1) / bytesPerLine;
+            StringBuilder result = new StringBuilder(expectedLines * lineLength);
+
+            for (int i = 0; i < bytesLength; i += bytesPerLine)
+            {
+                line[0] = HexChars[(i >> 28) & 0xF];
+                line[1] = HexChars[(i >> 24) & 0xF];
+                line[2] = HexChars[(i >> 20) & 0xF];
+                line[3] = HexChars[(i >> 16) & 0xF];
+                line[4] = HexChars[(i >> 12) & 0xF];
+                line[5] = HexChars[(i >> 8) & 0xF];
+                line[6] = HexChars[(i >> 4) & 0xF];
+                line[7] = HexChars[(i >> 0) & 0xF];
+
+                int hexColumn = firstHexColumn;
+                int charColumn = firstCharColumn;
+
+                for (int j = 0; j < bytesPerLine; j++)
+                {
+                    if (j > 0 && (j & 7) == 0) hexColumn++;
+                    if (i + j >= bytesLength)
+                    {
+                        line[hexColumn] = ' ';
+                        line[hexColumn + 1] = ' ';
+                        line[charColumn] = ' ';
+                    }
+                    else
+                    {
+                        byte b = bytes[i + j];
+                        line[hexColumn] = HexChars[(b >> 4) & 0xF];
+                        line[hexColumn + 1] = HexChars[b & 0xF];
+                        line[charColumn] = (b < 32 ? '·' : (char)b);
+                    }
+                    hexColumn += 3;
+                    charColumn++;
+                }
+
+                result.Append(line);
+            }
+            return result.ToString();
+        }
     }
 }
diff --git a/Ryujinx.Core/OsHle/Handles/HThread.cs b/Ryujinx.Core/OsHle/Handles/HThread.cs
index 8bb276fa83..c631cedc6c 100644
--- a/Ryujinx.Core/OsHle/Handles/HThread.cs
+++ b/Ryujinx.Core/OsHle/Handles/HThread.cs
@@ -7,7 +7,7 @@ namespace Ryujinx.Core.OsHle.Handles
         public AThread Thread { get; private set; }
 
         public int ProcessorId { get; private set; }
-        public int Priority    { get; private set; }
+        public int Priority    { get; set; }
 
         public int ThreadId => Thread.ThreadId;
 
diff --git a/Ryujinx.Core/OsHle/Ipc/IpcLog.cs b/Ryujinx.Core/OsHle/Ipc/IpcLog.cs
new file mode 100644
index 0000000000..dfec7ccfd4
--- /dev/null
+++ b/Ryujinx.Core/OsHle/Ipc/IpcLog.cs
@@ -0,0 +1,179 @@
+using System;
+using System.IO;
+
+namespace Ryujinx.Core.OsHle.Ipc
+{
+    public static class IpcLog
+    {
+        public static string Message(byte[] Data, long CmdPtr, bool Domain)
+        {
+            string IpcMessage = "";
+
+            using (MemoryStream MS = new MemoryStream(Data))
+            {
+                BinaryReader Reader = new BinaryReader(MS);
+
+                int Word0 = Reader.ReadInt32();
+                int Word1 = Reader.ReadInt32();
+
+                int Type = (Word0 & 0xffff);
+
+                int PtrBuffCount = (Word0 >> 16) & 0xf;
+                int SendBuffCount = (Word0 >> 20) & 0xf;
+                int RecvBuffCount = (Word0 >> 24) & 0xf;
+                int XchgBuffCount = (Word0 >> 28) & 0xf;
+
+                int RawDataSize = (Word1 >> 0) & 0x3ff;
+                int RecvListFlags = (Word1 >> 10) & 0xf;
+                bool HndDescEnable = ((Word1 >> 31) & 0x1) != 0;
+
+                IpcMessage += Environment.NewLine + $" {Logging.GetExecutionTime()} | IpcMessage >" + Environment.NewLine +
+                              $"   Type: {Enum.GetName(typeof(IpcMessageType), Type)}" + Environment.NewLine +
+
+                              $"   PtrBuffCount: {PtrBuffCount.ToString()}" + Environment.NewLine +
+                              $"   SendBuffCount: {SendBuffCount.ToString()}" + Environment.NewLine +
+                              $"   RecvBuffCount: {RecvBuffCount.ToString()}" + Environment.NewLine +
+                              $"   XchgBuffCount: {XchgBuffCount.ToString()}" + Environment.NewLine +
+
+                              $"   RawDataSize: {RawDataSize.ToString()}" + Environment.NewLine +
+                              $"   RecvListFlags: {RecvListFlags.ToString()}" + Environment.NewLine +
+                              $"   HndDescEnable: {HndDescEnable.ToString()}" + Environment.NewLine;
+
+                if (HndDescEnable)
+                {
+                    int Word = Reader.ReadInt32();
+
+                    bool HasPId = (Word & 1) != 0;
+
+                    int[] ToCopy = new int[(Word >> 1) & 0xf];
+                    int[] ToMove = new int[(Word >> 5) & 0xf];
+
+                    long PId = HasPId ? Reader.ReadInt64() : 0;
+
+                    for (int Index = 0; Index < ToCopy.Length; Index++)
+                    {
+                        ToCopy[Index] = Reader.ReadInt32();
+                    }
+
+                    for (int Index = 0; Index < ToMove.Length; Index++)
+                    {
+                        ToMove[Index] = Reader.ReadInt32();
+                    }
+
+                    IpcMessage += Environment.NewLine + "    HndDesc:" + Environment.NewLine +
+                                  $"      PId: {PId.ToString()}" + Environment.NewLine +
+                                  $"      ToCopy.Length: {ToCopy.Length.ToString()}" + Environment.NewLine +
+                                  $"      ToMove.Length: {ToMove.Length.ToString()}" + Environment.NewLine;
+                }
+
+                for (int Index = 0; Index < PtrBuffCount; Index++)
+                {
+                    long IpcPtrBuffDescWord0 = Reader.ReadUInt32();
+                    long IpcPtrBuffDescWord1 = Reader.ReadUInt32();
+
+                    long Position = IpcPtrBuffDescWord1;
+                    Position |= (IpcPtrBuffDescWord0 << 20) & 0x0f00000000;
+                    Position |= (IpcPtrBuffDescWord0 << 30) & 0x7000000000;
+
+                    int IpcPtrBuffDescIndex = ((int)IpcPtrBuffDescWord0 >> 0) & 0x03f;
+                    IpcPtrBuffDescIndex |= ((int)IpcPtrBuffDescWord0 >> 3) & 0x1c0;
+
+                    short Size = (short)(IpcPtrBuffDescWord0 >> 16);
+
+                    IpcMessage += Environment.NewLine + $"    PtrBuff[{Index}]:" + Environment.NewLine +
+                                  $"      Position: {Position.ToString()}" + Environment.NewLine +
+                                  $"      IpcPtrBuffDescIndex: {IpcPtrBuffDescIndex.ToString()}" + Environment.NewLine +
+                                  $"      Size: {Size.ToString()}" + Environment.NewLine;
+                }
+
+                ReadIpcBuffValues(Reader, SendBuffCount, IpcMessage, "SendBuff");
+                ReadIpcBuffValues(Reader, RecvBuffCount, IpcMessage, "RecvBuff");
+                ReadIpcBuffValues(Reader, XchgBuffCount, IpcMessage, "XchgBuff");
+
+                RawDataSize *= 4;
+
+                long RecvListPos = Reader.BaseStream.Position + RawDataSize;
+                long Pad0 = 0;
+
+                if ((Reader.BaseStream.Position + CmdPtr & 0xf) != 0)
+                {
+                    Pad0 = 0x10 - (Reader.BaseStream.Position + CmdPtr & 0xf);
+                }
+
+                Reader.BaseStream.Seek(Pad0, SeekOrigin.Current);
+
+                int RecvListCount = RecvListFlags - 2;
+
+                if (RecvListCount == 0)
+                {
+                    RecvListCount = 1;
+                }
+                else if (RecvListCount < 0)
+                {
+                    RecvListCount = 0;
+                }
+
+                if (Domain && (IpcMessageType)Type == IpcMessageType.Request)
+                {
+                    int DomWord0 = Reader.ReadInt32();
+
+                    int DomCmd = (DomWord0 & 0xff);
+
+                    RawDataSize = (DomWord0 >> 16) & 0xffff;
+
+                    int DomObjId = Reader.ReadInt32();
+
+                    Reader.ReadInt64(); //Padding
+
+                    IpcMessage += Environment.NewLine + $"    Domain:" + Environment.NewLine +
+                                  $"      DomCmd: {Enum.GetName(typeof(IpcDomCmd), DomCmd)}" + Environment.NewLine +
+                                  $"      DomObjId: {DomObjId.ToString()}" + Environment.NewLine;
+                }
+
+                byte[] RawData = Reader.ReadBytes(RawDataSize);
+
+                IpcMessage += Environment.NewLine + $"    RawData:" + Environment.NewLine + Logging.HexDump(RawData);
+
+                Reader.BaseStream.Seek(RecvListPos, SeekOrigin.Begin);
+
+                for (int Index = 0; Index < RecvListCount; Index++)
+                {
+                    long RecvListBuffValue = Reader.ReadInt64();
+                    long RecvListBuffPosition = RecvListBuffValue & 0xffffffffffff;
+                    long RecvListBuffSize = (short)(RecvListBuffValue >> 48);
+
+                    IpcMessage += Environment.NewLine + $"    RecvList[{Index}]:" + Environment.NewLine +
+                                  $"      Value: {RecvListBuffValue.ToString()}" + Environment.NewLine +
+                                  $"      Position: {RecvListBuffPosition.ToString()}" + Environment.NewLine +
+                                  $"      Size: {RecvListBuffSize.ToString()}" + Environment.NewLine;
+                }
+            }
+
+            return IpcMessage;
+        }
+
+        private static void ReadIpcBuffValues(BinaryReader Reader, int Count, string IpcMessage, string BufferName)
+        {
+            for (int Index = 0; Index < Count; Index++)
+            {
+                long Word0 = Reader.ReadUInt32();
+                long Word1 = Reader.ReadUInt32();
+                long Word2 = Reader.ReadUInt32();
+
+                long Position = Word1;
+                Position |= (Word2 << 4) & 0x0f00000000;
+                Position |= (Word2 << 34) & 0x7000000000;
+
+                long Size = Word0;
+                Size |= (Word2 << 8) & 0xf00000000;
+
+                int Flags = (int)Word2 & 3;
+
+                IpcMessage += Environment.NewLine + $"    {BufferName}[{Index}]:" + Environment.NewLine +
+                              $"      Position: {Position.ToString()}" + Environment.NewLine +
+                              $"      Flags: {Flags.ToString()}" + Environment.NewLine +
+                              $"      Size: {Size.ToString()}" + Environment.NewLine;
+            }
+        }
+    }
+}
diff --git a/Ryujinx.Core/OsHle/Ipc/IpcMessage.cs b/Ryujinx.Core/OsHle/Ipc/IpcMessage.cs
index 447f3f9a67..cc26df1082 100644
--- a/Ryujinx.Core/OsHle/Ipc/IpcMessage.cs
+++ b/Ryujinx.Core/OsHle/Ipc/IpcMessage.cs
@@ -41,6 +41,8 @@ namespace Ryujinx.Core.OsHle.Ipc
 
         public IpcMessage(byte[] Data, long CmdPtr, bool Domain) : this()
         {
+            Logging.Ipc(Data, CmdPtr, Domain);
+
             using (MemoryStream MS = new MemoryStream(Data))
             {
                 BinaryReader Reader = new BinaryReader(MS);
diff --git a/Ryujinx.Core/OsHle/IpcServices/ErrorModule.cs b/Ryujinx.Core/OsHle/IpcServices/ErrorModule.cs
deleted file mode 100644
index 0d15db60a6..0000000000
--- a/Ryujinx.Core/OsHle/IpcServices/ErrorModule.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Ryujinx.Core.OsHle.IpcServices
-{
-    enum ErrorModule
-    {
-        Fs = 2,
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Core/OsHle/IpcServices/Acc/IManagerForApplication.cs b/Ryujinx.Core/OsHle/Services/Acc/IManagerForApplication.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Acc/IManagerForApplication.cs
rename to Ryujinx.Core/OsHle/Services/Acc/IManagerForApplication.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Acc/IProfile.cs b/Ryujinx.Core/OsHle/Services/Acc/IProfile.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Acc/IProfile.cs
rename to Ryujinx.Core/OsHle/Services/Acc/IProfile.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Acc/ServiceAcc.cs b/Ryujinx.Core/OsHle/Services/Acc/ServiceAcc.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Acc/ServiceAcc.cs
rename to Ryujinx.Core/OsHle/Services/Acc/ServiceAcc.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Am/IApplicationFunctions.cs b/Ryujinx.Core/OsHle/Services/Am/IApplicationFunctions.cs
similarity index 85%
rename from Ryujinx.Core/OsHle/IpcServices/Am/IApplicationFunctions.cs
rename to Ryujinx.Core/OsHle/Services/Am/IApplicationFunctions.cs
index 30020c1d80..6c5beeb3e7 100644
--- a/Ryujinx.Core/OsHle/IpcServices/Am/IApplicationFunctions.cs
+++ b/Ryujinx.Core/OsHle/Services/Am/IApplicationFunctions.cs
@@ -1,4 +1,5 @@
 using Ryujinx.Core.OsHle.Ipc;
+using System;
 using System.Collections.Generic;
 using System.IO;
 
@@ -19,6 +20,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Am
                 {  1, PopLaunchParameter },
                 { 20, EnsureSaveData     },
                 { 21, GetDesiredLanguage },
+                { 22, SetTerminateResult },
                 { 40, NotifyRunning      }
             };
         }
@@ -52,6 +54,18 @@ namespace Ryujinx.Core.OsHle.IpcServices.Am
             return 0;
         }
 
+        public long SetTerminateResult(ServiceCtx Context)
+        {
+            int ErrorCode = Context.RequestData.ReadInt32();
+
+            int Module = ErrorCode & 0xFF;
+            int Description = (ErrorCode >> 9) & 0xFFF;
+
+            Logging.Info($"({(ErrorModule)Module}){2000 + Module}-{Description}");
+
+            return 0;
+        }
+
         public long NotifyRunning(ServiceCtx Context)
         {
             Context.ResponseData.Write(1);
diff --git a/Ryujinx.Core/OsHle/IpcServices/Am/IApplicationProxy.cs b/Ryujinx.Core/OsHle/Services/Am/IApplicationProxy.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Am/IApplicationProxy.cs
rename to Ryujinx.Core/OsHle/Services/Am/IApplicationProxy.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Am/IAudioController.cs b/Ryujinx.Core/OsHle/Services/Am/IAudioController.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Am/IAudioController.cs
rename to Ryujinx.Core/OsHle/Services/Am/IAudioController.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Am/ICommonStateGetter.cs b/Ryujinx.Core/OsHle/Services/Am/ICommonStateGetter.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Am/ICommonStateGetter.cs
rename to Ryujinx.Core/OsHle/Services/Am/ICommonStateGetter.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Am/IDebugFunctions.cs b/Ryujinx.Core/OsHle/Services/Am/IDebugFunctions.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Am/IDebugFunctions.cs
rename to Ryujinx.Core/OsHle/Services/Am/IDebugFunctions.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Am/IDisplayController.cs b/Ryujinx.Core/OsHle/Services/Am/IDisplayController.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Am/IDisplayController.cs
rename to Ryujinx.Core/OsHle/Services/Am/IDisplayController.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Am/ILibraryAppletCreator.cs b/Ryujinx.Core/OsHle/Services/Am/ILibraryAppletCreator.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Am/ILibraryAppletCreator.cs
rename to Ryujinx.Core/OsHle/Services/Am/ILibraryAppletCreator.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Am/ISelfController.cs b/Ryujinx.Core/OsHle/Services/Am/ISelfController.cs
similarity index 82%
rename from Ryujinx.Core/OsHle/IpcServices/Am/ISelfController.cs
rename to Ryujinx.Core/OsHle/Services/Am/ISelfController.cs
index 90ddd54b8e..403e4072d3 100644
--- a/Ryujinx.Core/OsHle/IpcServices/Am/ISelfController.cs
+++ b/Ryujinx.Core/OsHle/Services/Am/ISelfController.cs
@@ -13,14 +13,21 @@ namespace Ryujinx.Core.OsHle.IpcServices.Am
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
+                { 1,  Exit                                  },
                 { 10, SetScreenShotPermission               },
                 { 11, SetOperationModeChangedNotification   },
                 { 12, SetPerformanceModeChangedNotification },
                 { 13, SetFocusHandlingMode                  },
+                { 14, SetRestartMessageEnabled              },
                 { 16, SetOutOfFocusSuspendingEnabled        }
             };
         }
 
+        public long Exit(ServiceCtx Context)
+        {
+            return 0;
+        }
+
         public long SetScreenShotPermission(ServiceCtx Context)
         {
             bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
@@ -51,6 +58,13 @@ namespace Ryujinx.Core.OsHle.IpcServices.Am
             return 0;
         }
 
+        public long SetRestartMessageEnabled(ServiceCtx Context)
+        {
+            bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
+
+            return 0;
+        }
+
         public long SetOutOfFocusSuspendingEnabled(ServiceCtx Context)
         {
             bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
diff --git a/Ryujinx.Core/OsHle/IpcServices/Am/IStorage.cs b/Ryujinx.Core/OsHle/Services/Am/IStorage.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Am/IStorage.cs
rename to Ryujinx.Core/OsHle/Services/Am/IStorage.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Am/IStorageAccessor.cs b/Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Am/IStorageAccessor.cs
rename to Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Am/IWindowController.cs b/Ryujinx.Core/OsHle/Services/Am/IWindowController.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Am/IWindowController.cs
rename to Ryujinx.Core/OsHle/Services/Am/IWindowController.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Am/ServiceAppletOE.cs b/Ryujinx.Core/OsHle/Services/Am/ServiceAppletOE.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Am/ServiceAppletOE.cs
rename to Ryujinx.Core/OsHle/Services/Am/ServiceAppletOE.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Apm/ISession.cs b/Ryujinx.Core/OsHle/Services/Apm/ISession.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Apm/ISession.cs
rename to Ryujinx.Core/OsHle/Services/Apm/ISession.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Apm/ServiceApm.cs b/Ryujinx.Core/OsHle/Services/Apm/ServiceApm.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Apm/ServiceApm.cs
rename to Ryujinx.Core/OsHle/Services/Apm/ServiceApm.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Aud/IAudioOut.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Aud/IAudioOut.cs
rename to Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Aud/IAudioRenderer.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioRenderer.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Aud/IAudioRenderer.cs
rename to Ryujinx.Core/OsHle/Services/Aud/IAudioRenderer.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Aud/ServiceAudOut.cs b/Ryujinx.Core/OsHle/Services/Aud/ServiceAudOut.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Aud/ServiceAudOut.cs
rename to Ryujinx.Core/OsHle/Services/Aud/ServiceAudOut.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Aud/ServiceAudRen.cs b/Ryujinx.Core/OsHle/Services/Aud/ServiceAudRen.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Aud/ServiceAudRen.cs
rename to Ryujinx.Core/OsHle/Services/Aud/ServiceAudRen.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/ErrorCode.cs b/Ryujinx.Core/OsHle/Services/ErrorCode.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/ErrorCode.cs
rename to Ryujinx.Core/OsHle/Services/ErrorCode.cs
diff --git a/Ryujinx.Core/OsHle/Services/ErrorModule.cs b/Ryujinx.Core/OsHle/Services/ErrorModule.cs
new file mode 100644
index 0000000000..78af6195db
--- /dev/null
+++ b/Ryujinx.Core/OsHle/Services/ErrorModule.cs
@@ -0,0 +1,63 @@
+namespace Ryujinx.Core.OsHle.IpcServices
+{
+    enum ErrorModule
+    {
+        Kernel                = 1,
+        Fs                    = 2,
+        Nvidia_TransferMemory = 3,
+        Ncm                   = 5,
+        Dd                    = 6,
+        Lr                    = 8,
+        Loader                = 9,
+        IPC_Command_Interface = 10,
+        IPC                   = 11,
+        Pm                    = 15,
+        Ns                    = 16,
+        Htc                   = 18,
+        Sm                    = 21,
+        RO_Userland           = 22,
+        SdMmc                 = 24,
+        Spl                   = 26,
+        Ethc                  = 100,
+        I2C                   = 101,
+        Settings              = 105,
+        Nifm                  = 110,
+        Display               = 114,
+        Ntc                   = 116,
+        Fdm                   = 117,
+        Pcie                  = 120,
+        Friends               = 121,
+        SSL                   = 123,
+        Account               = 124,
+        Mii                   = 126,
+        Am                    = 128,
+        Play_Report           = 129,
+        Pcv                   = 133,
+        Omm                   = 134,
+        Nim                   = 137,
+        Psc                   = 138,
+        Usb                   = 140,
+        Nsd                   = 141,
+        Btm                   = 143,
+        Erpt                  = 147,
+        Apm                   = 148,
+        Audio                 = 153,
+        Npns                  = 154,
+        Arp                   = 157,
+        Boot                  = 158,
+        Nfc                   = 161,
+        Userland_Assert       = 162,
+        Userland_Crash        = 168,
+        Hid                   = 203,
+        Capture               = 206,
+        Libnx                 = 345,
+        Homebrew_ABI          = 346,
+        Homebrew_Loader       = 347,
+        libnx_Nvidia_Errors   = 348,
+        Tc                    = 651,
+        General_Web_Applet    = 800,
+        Wifi_Web_Auth_Applet  = 809,
+        Whitelisted_Applet    = 810,
+        ShopN                 = 811
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Core/OsHle/IpcServices/Friend/IFriendService.cs b/Ryujinx.Core/OsHle/Services/Friend/IFriendService.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Friend/IFriendService.cs
rename to Ryujinx.Core/OsHle/Services/Friend/IFriendService.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Friend/ServiceFriend.cs b/Ryujinx.Core/OsHle/Services/Friend/ServiceFriend.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Friend/ServiceFriend.cs
rename to Ryujinx.Core/OsHle/Services/Friend/ServiceFriend.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/FspSrv/FsErr.cs b/Ryujinx.Core/OsHle/Services/FspSrv/FsErr.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/FspSrv/FsErr.cs
rename to Ryujinx.Core/OsHle/Services/FspSrv/FsErr.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/FspSrv/IDirectory.cs b/Ryujinx.Core/OsHle/Services/FspSrv/IDirectory.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/FspSrv/IDirectory.cs
rename to Ryujinx.Core/OsHle/Services/FspSrv/IDirectory.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/FspSrv/IFile.cs b/Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/FspSrv/IFile.cs
rename to Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/FspSrv/IFileSystem.cs b/Ryujinx.Core/OsHle/Services/FspSrv/IFileSystem.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/FspSrv/IFileSystem.cs
rename to Ryujinx.Core/OsHle/Services/FspSrv/IFileSystem.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/FspSrv/IStorage.cs b/Ryujinx.Core/OsHle/Services/FspSrv/IStorage.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/FspSrv/IStorage.cs
rename to Ryujinx.Core/OsHle/Services/FspSrv/IStorage.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/FspSrv/ServiceFspSrv.cs b/Ryujinx.Core/OsHle/Services/FspSrv/ServiceFspSrv.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/FspSrv/ServiceFspSrv.cs
rename to Ryujinx.Core/OsHle/Services/FspSrv/ServiceFspSrv.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Hid/IActiveVibrationDeviceList.cs b/Ryujinx.Core/OsHle/Services/Hid/IActiveVibrationDeviceList.cs
similarity index 63%
rename from Ryujinx.Core/OsHle/IpcServices/Hid/IActiveVibrationDeviceList.cs
rename to Ryujinx.Core/OsHle/Services/Hid/IActiveVibrationDeviceList.cs
index 020e8e7e63..f6596f4296 100644
--- a/Ryujinx.Core/OsHle/IpcServices/Hid/IActiveVibrationDeviceList.cs
+++ b/Ryujinx.Core/OsHle/Services/Hid/IActiveVibrationDeviceList.cs
@@ -11,7 +11,17 @@ namespace Ryujinx.Core.OsHle.IpcServices.Hid
 
         public IActiveApplicationDeviceList()
         {
-            m_Commands = new Dictionary<int, ServiceProcessRequest>() { };
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                { 0, ActivateVibrationDevice }
+            };
+        }
+
+        public long ActivateVibrationDevice(ServiceCtx Context)
+        {
+            int VibrationDeviceHandle = Context.RequestData.ReadInt32();
+
+            return 0;
         }
     }
 }
\ No newline at end of file
diff --git a/Ryujinx.Core/OsHle/IpcServices/Hid/IAppletResource.cs b/Ryujinx.Core/OsHle/Services/Hid/IAppletResource.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Hid/IAppletResource.cs
rename to Ryujinx.Core/OsHle/Services/Hid/IAppletResource.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Hid/ServiceHid.cs b/Ryujinx.Core/OsHle/Services/Hid/ServiceHid.cs
similarity index 89%
rename from Ryujinx.Core/OsHle/IpcServices/Hid/ServiceHid.cs
rename to Ryujinx.Core/OsHle/Services/Hid/ServiceHid.cs
index 5cca9319e2..b0e5f44e27 100644
--- a/Ryujinx.Core/OsHle/IpcServices/Hid/ServiceHid.cs
+++ b/Ryujinx.Core/OsHle/Services/Hid/ServiceHid.cs
@@ -24,6 +24,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Hid
                 { 103, ActivateNpad                    },
                 { 120, SetNpadJoyHoldType              },
                 { 121, GetNpadJoyHoldType              },
+                { 200, GetVibrationDeviceInfo          },
                 { 203, CreateActiveVibrationDeviceList },
             };
         }
@@ -88,6 +89,15 @@ namespace Ryujinx.Core.OsHle.IpcServices.Hid
             return 0;
         }
 
+        public long GetVibrationDeviceInfo(ServiceCtx Context)
+        {
+            int VibrationDeviceHandle = Context.RequestData.ReadInt32();
+
+            Context.ResponseData.Write(0L); //VibrationDeviceInfoForIpc
+
+            return 0;
+        }
+
         public long CreateActiveVibrationDeviceList(ServiceCtx Context)
         {
             MakeObject(Context, new IActiveApplicationDeviceList());
diff --git a/Ryujinx.Core/OsHle/IpcServices/IIpcService.cs b/Ryujinx.Core/OsHle/Services/IIpcService.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/IIpcService.cs
rename to Ryujinx.Core/OsHle/Services/IIpcService.cs
diff --git a/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs b/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs
new file mode 100644
index 0000000000..5ee097b6f9
--- /dev/null
+++ b/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs
@@ -0,0 +1,143 @@
+using ChocolArm64.Memory;
+using Ryujinx.Core.OsHle.Ipc;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace Ryujinx.Core.OsHle.IpcServices.Lm
+{
+    class ILogger : IIpcService
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public ILogger()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                { 0, Log }
+            };
+        }
+
+        enum Flags
+        {
+            Padding,
+            IsHead,
+            IsTail
+        }
+
+        enum Severity
+        {
+            Trace,
+            Info,
+            Warning,
+            Error,
+            Critical
+        }
+
+        enum Field
+        {
+            Padding,
+            Skip,
+            Message,
+            Line,
+            Filename,
+            Function,
+            Module,
+            Thread
+        }
+
+        public long Log(ServiceCtx Context)
+        {
+            long BufferPosition = Context.Request.PtrBuff[0].Position;
+            long BufferLen      = Context.Request.PtrBuff[0].Size;
+
+            byte[] LogBuffer = AMemoryHelper.ReadBytes(Context.Memory, BufferPosition, (int)BufferLen);
+
+            MemoryStream LogMessage = new MemoryStream(LogBuffer);
+            BinaryReader bReader = new BinaryReader(LogMessage);
+
+            //Header reading.
+            long Pid       = bReader.ReadInt64();
+            long ThreadCxt = bReader.ReadInt64();
+            int Infos      = bReader.ReadInt32();
+            int PayloadLen = bReader.ReadInt32();
+
+            int iFlags     = Infos & 0xFFFF;
+            int iSeverity  = (Infos >> 17) & 0x7F;
+            int iVerbosity = (Infos >> 25) & 0x7F;
+
+            //ToDo: For now we don't care about Head or Tail Log.
+            bool IsHeadLog = Convert.ToBoolean(iFlags & (int)Flags.IsHead);
+            bool IsTailLog = Convert.ToBoolean(iFlags & (int)Flags.IsTail);
+
+            string LogString = "nn::diag::detail::LogImpl()" + Environment.NewLine + Environment.NewLine +
+                               "Header:" + Environment.NewLine +
+                               $"   Pid: {Pid}" + Environment.NewLine +
+                               $"   ThreadContext: {ThreadCxt}" + Environment.NewLine +
+                               $"   Flags: {IsHeadLog}/{IsTailLog}" + Environment.NewLine +
+                               $"   Severity: {Enum.GetName(typeof(Severity), iSeverity)}" + Environment.NewLine +
+                               $"   Verbosity: {iVerbosity}";
+
+            LogString += Environment.NewLine + Environment.NewLine + "Message:" + Environment.NewLine;
+
+            string StrMessage = "", StrLine = "", StrFilename = "", StrFunction = "",
+                   StrModule = "", StrThread = "";
+
+            do
+            {
+                byte FieldType = bReader.ReadByte();
+                byte FieldSize = bReader.ReadByte();
+
+                if ((Field)FieldType != Field.Skip || FieldSize != 0)
+                {
+                    byte[] Message = bReader.ReadBytes(FieldSize);
+                    switch ((Field)FieldType)
+                    {
+                        case Field.Message:
+                            StrMessage = Encoding.UTF8.GetString(Message);
+                            break;
+
+                        case Field.Line:
+                            StrLine = BitConverter.ToInt32(Message, 0).ToString();
+                            break;
+
+                        case Field.Filename:
+                            StrFilename = Encoding.UTF8.GetString(Message);
+                            break;
+
+                        case Field.Function:
+                            StrFunction = Encoding.UTF8.GetString(Message);
+                            break;
+
+                        case Field.Module:
+                            StrModule = Encoding.UTF8.GetString(Message);
+                            break;
+
+                        case Field.Thread:
+                            StrThread = Encoding.UTF8.GetString(Message);
+                            break;
+                    }
+                }
+                
+            }
+            while (LogMessage.Position != PayloadLen + 0x18); // 0x18 - Size of Header LogMessage.
+
+            LogString += StrModule + " > " + StrThread + ": " + StrFilename + "@" + StrFunction + "(" + StrLine + ") '" + StrMessage + "'" + Environment.NewLine;
+
+            switch((Severity)iSeverity)
+            {
+                case Severity.Trace:    Logging.Trace(LogString); break;
+                case Severity.Info:     Logging.Info(LogString);  break;
+                case Severity.Warning:  Logging.Warn(LogString);  break;
+                case Severity.Error:    Logging.Error(LogString); break;
+                case Severity.Critical: Logging.Fatal(LogString); break;
+            }
+
+            return 0;
+        }
+    }
+}
+ 
\ No newline at end of file
diff --git a/Ryujinx.Core/OsHle/IpcServices/Lm/ServiceLm.cs b/Ryujinx.Core/OsHle/Services/Lm/ServiceLm.cs
similarity index 85%
rename from Ryujinx.Core/OsHle/IpcServices/Lm/ServiceLm.cs
rename to Ryujinx.Core/OsHle/Services/Lm/ServiceLm.cs
index e665253c15..ca3fe35e83 100644
--- a/Ryujinx.Core/OsHle/IpcServices/Lm/ServiceLm.cs
+++ b/Ryujinx.Core/OsHle/Services/Lm/ServiceLm.cs
@@ -1,6 +1,8 @@
 using Ryujinx.Core.OsHle.Ipc;
 using System.Collections.Generic;
 
+using static Ryujinx.Core.OsHle.IpcServices.ObjHelper;
+
 namespace Ryujinx.Core.OsHle.IpcServices.Lm
 {
     class ServiceLm : IIpcService
@@ -21,6 +23,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Lm
         {
             Context.Session.Initialize();
 
+            MakeObject(Context, new ILogger());
+
             return 0;
         }
     }
diff --git a/Ryujinx.Core/OsHle/IpcServices/Time/ITimeZoneService.cs b/Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs
similarity index 71%
rename from Ryujinx.Core/OsHle/IpcServices/Time/ITimeZoneService.cs
rename to Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs
index 9875fa2fcf..720baa6ec2 100644
--- a/Ryujinx.Core/OsHle/IpcServices/Time/ITimeZoneService.cs
+++ b/Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs
@@ -1,19 +1,19 @@
 using Ryujinx.Core.OsHle.Ipc;
 using System.Collections.Generic;
 
-namespace Ryujinx.Core.OsHle.IpcServices.Time
+namespace Ryujinx.Core.OsHle.IpcServices.Ns
 {
-    class ITimeZoneService : IIpcService
+    class ServiceNs : IIpcService
     {
         private Dictionary<int, ServiceProcessRequest> m_Commands;
 
         public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
 
-        public ITimeZoneService()
+        public ServiceNs()
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
-                //...
+                //{ 1, Function }
             };
         }
     }
diff --git a/Ryujinx.Core/OsHle/IpcServices/NvServices/ServiceNvDrv.cs b/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/NvServices/ServiceNvDrv.cs
rename to Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/ObjHelper.cs b/Ryujinx.Core/OsHle/Services/ObjHelper.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/ObjHelper.cs
rename to Ryujinx.Core/OsHle/Services/ObjHelper.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Pctl/IParentalControlService.cs b/Ryujinx.Core/OsHle/Services/Pctl/IParentalControlService.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Pctl/IParentalControlService.cs
rename to Ryujinx.Core/OsHle/Services/Pctl/IParentalControlService.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Pctl/ServicePctl.cs b/Ryujinx.Core/OsHle/Services/Pctl/ServicePctl.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Pctl/ServicePctl.cs
rename to Ryujinx.Core/OsHle/Services/Pctl/ServicePctl.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Pl/ServicePl.cs b/Ryujinx.Core/OsHle/Services/Pl/ServicePl.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Pl/ServicePl.cs
rename to Ryujinx.Core/OsHle/Services/Pl/ServicePl.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/ServiceFactory.cs b/Ryujinx.Core/OsHle/Services/ServiceFactory.cs
similarity index 90%
rename from Ryujinx.Core/OsHle/IpcServices/ServiceFactory.cs
rename to Ryujinx.Core/OsHle/Services/ServiceFactory.cs
index e9613050f7..54fa38ab78 100644
--- a/Ryujinx.Core/OsHle/IpcServices/ServiceFactory.cs
+++ b/Ryujinx.Core/OsHle/Services/ServiceFactory.cs
@@ -6,6 +6,7 @@ using Ryujinx.Core.OsHle.IpcServices.Friend;
 using Ryujinx.Core.OsHle.IpcServices.FspSrv;
 using Ryujinx.Core.OsHle.IpcServices.Hid;
 using Ryujinx.Core.OsHle.IpcServices.Lm;
+using Ryujinx.Core.OsHle.IpcServices.Ns;
 using Ryujinx.Core.OsHle.IpcServices.NvServices;
 using Ryujinx.Core.OsHle.IpcServices.Pctl;
 using Ryujinx.Core.OsHle.IpcServices.Pl;
@@ -24,6 +25,7 @@ namespace Ryujinx.Core.OsHle.IpcServices
             switch (Name)
             {
                 case "acc:u0":   return new ServiceAcc();
+                case "aoc:u":    return new ServiceNs();
                 case "apm":      return new ServiceApm();
                 case "apm:p":    return new ServiceApm();
                 case "appletOE": return new ServiceAppletOE();
@@ -42,6 +44,8 @@ namespace Ryujinx.Core.OsHle.IpcServices
                 case "time:s":   return new ServiceTime();
                 case "time:u":   return new ServiceTime();
                 case "vi:m":     return new ServiceVi();
+                case "vi:s":     return new ServiceVi();
+                case "vi:u":     return new ServiceVi();
             }
 
             throw new NotImplementedException(Name);
diff --git a/Ryujinx.Core/OsHle/IpcServices/Set/ServiceSet.cs b/Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Set/ServiceSet.cs
rename to Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Sm/ServiceSm.cs b/Ryujinx.Core/OsHle/Services/Sm/ServiceSm.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Sm/ServiceSm.cs
rename to Ryujinx.Core/OsHle/Services/Sm/ServiceSm.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Time/ISteadyClock.cs b/Ryujinx.Core/OsHle/Services/Time/ISteadyClock.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Time/ISteadyClock.cs
rename to Ryujinx.Core/OsHle/Services/Time/ISteadyClock.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Time/ISystemClock.cs b/Ryujinx.Core/OsHle/Services/Time/ISystemClock.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Time/ISystemClock.cs
rename to Ryujinx.Core/OsHle/Services/Time/ISystemClock.cs
diff --git a/Ryujinx.Core/OsHle/Services/Time/ITimeZoneService.cs b/Ryujinx.Core/OsHle/Services/Time/ITimeZoneService.cs
new file mode 100644
index 0000000000..d220824c56
--- /dev/null
+++ b/Ryujinx.Core/OsHle/Services/Time/ITimeZoneService.cs
@@ -0,0 +1,69 @@
+using Ryujinx.Core.OsHle.Ipc;
+using System;
+using System.Collections.Generic;
+
+namespace Ryujinx.Core.OsHle.IpcServices.Time
+{
+    class ITimeZoneService : IIpcService
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        private static DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Local);
+
+        public ITimeZoneService()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                { 101,  ToCalendarTimeWithMyRule }
+            };
+        }
+
+        //(nn::time::PosixTime)-> (nn::time::CalendarTime, nn::time::sf::CalendarAdditionalInfo)
+        public long ToCalendarTimeWithMyRule(ServiceCtx Context)
+        {
+            long PosixTime = Context.RequestData.ReadInt64();
+
+            Epoch = Epoch.AddSeconds(PosixTime).ToLocalTime();
+
+            /*
+                struct CalendarTime {
+                    u16_le year;
+                    u8 month; // Starts at 1
+                    u8 day;   // Starts at 1
+                    u8 hour;
+                    u8 minute;
+                    u8 second;
+                    INSERT_PADDING_BYTES(1);
+                };
+            */
+            Context.ResponseData.Write((short)Epoch.Year);
+            Context.ResponseData.Write((byte)Epoch.Month);
+            Context.ResponseData.Write((byte)Epoch.Day);
+            Context.ResponseData.Write((byte)Epoch.Hour);
+            Context.ResponseData.Write((byte)Epoch.Minute);
+            Context.ResponseData.Write((byte)Epoch.Second);
+            Context.ResponseData.Write((byte)0);
+
+            /* Thanks to TuxSH
+                struct CalendarAdditionalInfo {
+	                u32 tm_wday; //day of week [0,6] (Sunday = 0)
+	                s32 tm_yday; //day of year [0,365]
+	                struct timezone {
+		                char[8] tz_name;
+		                bool isDaylightSavingTime;
+		                s32 utcOffsetSeconds;
+	                };
+                };
+            */
+            Context.ResponseData.Write((int)Epoch.DayOfWeek);
+            Context.ResponseData.Write(Epoch.DayOfYear);
+            Context.ResponseData.Write(new byte[8]);
+            Context.ResponseData.Write(Convert.ToByte(Epoch.IsDaylightSavingTime()));
+            Context.ResponseData.Write(0);
+
+            return 0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Core/OsHle/IpcServices/Time/ServiceTime.cs b/Ryujinx.Core/OsHle/Services/Time/ServiceTime.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Time/ServiceTime.cs
rename to Ryujinx.Core/OsHle/Services/Time/ServiceTime.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Time/SystemClockType.cs b/Ryujinx.Core/OsHle/Services/Time/SystemClockType.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Time/SystemClockType.cs
rename to Ryujinx.Core/OsHle/Services/Time/SystemClockType.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Android/GbpBuffer.cs b/Ryujinx.Core/OsHle/Services/Vi/GbpBuffer.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Android/GbpBuffer.cs
rename to Ryujinx.Core/OsHle/Services/Vi/GbpBuffer.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Vi/IApplicationDisplayService.cs b/Ryujinx.Core/OsHle/Services/Vi/IApplicationDisplayService.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Vi/IApplicationDisplayService.cs
rename to Ryujinx.Core/OsHle/Services/Vi/IApplicationDisplayService.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Vi/IHOSBinderDriver.cs b/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Vi/IHOSBinderDriver.cs
rename to Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Vi/IManagerDisplayService.cs b/Ryujinx.Core/OsHle/Services/Vi/IManagerDisplayService.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Vi/IManagerDisplayService.cs
rename to Ryujinx.Core/OsHle/Services/Vi/IManagerDisplayService.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Vi/ISystemDisplayService.cs b/Ryujinx.Core/OsHle/Services/Vi/ISystemDisplayService.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Vi/ISystemDisplayService.cs
rename to Ryujinx.Core/OsHle/Services/Vi/ISystemDisplayService.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Android/NvFlinger.cs b/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Android/NvFlinger.cs
rename to Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Android/Parcel.cs b/Ryujinx.Core/OsHle/Services/Vi/Parcel.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Android/Parcel.cs
rename to Ryujinx.Core/OsHle/Services/Vi/Parcel.cs
diff --git a/Ryujinx.Core/OsHle/IpcServices/Vi/ServiceVi.cs b/Ryujinx.Core/OsHle/Services/Vi/ServiceVi.cs
similarity index 100%
rename from Ryujinx.Core/OsHle/IpcServices/Vi/ServiceVi.cs
rename to Ryujinx.Core/OsHle/Services/Vi/ServiceVi.cs
diff --git a/Ryujinx.Core/OsHle/Svc/SvcHandler.cs b/Ryujinx.Core/OsHle/Svc/SvcHandler.cs
index 60af1e11d7..c5b6da04b6 100644
--- a/Ryujinx.Core/OsHle/Svc/SvcHandler.cs
+++ b/Ryujinx.Core/OsHle/Svc/SvcHandler.cs
@@ -30,6 +30,8 @@ namespace Ryujinx.Core.OsHle.Svc
                 { 0x09, SvcStartThread                   },
                 { 0x0b, SvcSleepThread                   },
                 { 0x0c, SvcGetThreadPriority             },
+                { 0x0d, SvcSetThreadPriority             },
+                { 0x0f, SvcSetThreadCoreMask             },
                 { 0x13, SvcMapSharedMemory               },
                 { 0x14, SvcUnmapSharedMemory             },
                 { 0x15, SvcCreateTransferMemory          },
@@ -44,6 +46,7 @@ namespace Ryujinx.Core.OsHle.Svc
                 { 0x1f, SvcConnectToNamedPort            },
                 { 0x21, SvcSendSyncRequest               },
                 { 0x22, SvcSendSyncRequestWithUserBuffer },
+                { 0x25, SvcGetThreadId                   },
                 { 0x26, SvcBreak                         },
                 { 0x27, SvcOutputDebugString             },
                 { 0x29, SvcGetInfo                       }
diff --git a/Ryujinx.Core/OsHle/Svc/SvcThread.cs b/Ryujinx.Core/OsHle/Svc/SvcThread.cs
index a635edb15c..cc0f980be3 100644
--- a/Ryujinx.Core/OsHle/Svc/SvcThread.cs
+++ b/Ryujinx.Core/OsHle/Svc/SvcThread.cs
@@ -81,5 +81,44 @@ namespace Ryujinx.Core.OsHle.Svc
 
             //TODO: Error codes.
         }
+
+        private void SvcSetThreadPriority(AThreadState ThreadState)
+        {
+            int Handle = (int)ThreadState.X1;
+            int Prio = (int)ThreadState.X0;
+
+            HThread Thread = Ns.Os.Handles.GetData<HThread>(Handle);
+
+            if (Thread != null)
+            {
+                Thread.Priority = Prio;
+
+                ThreadState.X0 = (int)SvcResult.Success;
+            }
+
+            //TODO: Error codes.
+        }
+
+        private void SvcSetThreadCoreMask(AThreadState ThreadState)
+        {
+            ThreadState.X0 = (int)SvcResult.Success;
+
+            //TODO: Error codes.
+        }
+
+        private void SvcGetThreadId(AThreadState ThreadState)
+        {
+            int Handle = (int)ThreadState.X0;
+
+            HThread Thread = Ns.Os.Handles.GetData<HThread>(Handle);
+
+            if (Thread != null)
+            {
+                ThreadState.X1 = (ulong)Thread.ThreadId;
+                ThreadState.X0 = (int)SvcResult.Success;
+            }
+
+            //TODO: Error codes.
+        }
     }
 }
\ No newline at end of file
diff --git a/Ryujinx/Ryujinx.conf b/Ryujinx/Ryujinx.conf
index 7b9af87acf..e8effac1d0 100644
--- a/Ryujinx/Ryujinx.conf
+++ b/Ryujinx/Ryujinx.conf
@@ -16,6 +16,9 @@ Logging_Enable_Error = true
 #Enabled print fatal logs
 Logging_Enable_Fatal = true
 
+#Enabled print Ipc logs
+Logging_Enable_Ipc = false
+
 #Saved logs into Ryujinx.log
 Logging_Enable_LogFile = false