From 198c0ddc72d59f8e288c1074ee0bb1169f706cac Mon Sep 17 00:00:00 2001
From: purpasmart96 <kanzoconfigz@hotmail.com>
Date: Sat, 7 Mar 2015 17:54:16 -0800
Subject: [PATCH] Services: Stubs and minor changes

---
 src/common/logging/backend.cpp      |   2 +
 src/common/logging/log.h            |   2 +
 src/core/CMakeLists.txt             |   2 +
 src/core/hle/service/apt/apt.cpp    |  74 ++++++++++++++-----
 src/core/hle/service/apt/apt.h      |  49 ++++++++++--
 src/core/hle/service/apt/apt_a.cpp  |   6 +-
 src/core/hle/service/cfg/cfg.cpp    |   4 +-
 src/core/hle/service/cfg/cfg.h      |   4 +-
 src/core/hle/service/dsp_dsp.cpp    |  31 +++++++-
 src/core/hle/service/fs/fs_user.cpp |  80 ++++++++++++++++++--
 src/core/hle/service/gsp_gpu.cpp    |   3 +
 src/core/hle/service/hid/hid.cpp    |   6 +-
 src/core/hle/service/hid/hid.h      |   6 +-
 src/core/hle/service/nim_u.cpp      |  46 ++++++++++++
 src/core/hle/service/nim_u.h        |  23 ++++++
 src/core/hle/service/nwm_uds.cpp    | 111 ++++++++++++++++++++++++++--
 src/core/hle/service/ptm/ptm.cpp    |   4 +-
 src/core/hle/service/ptm/ptm.h      |   4 +-
 src/core/hle/service/service.cpp    |  18 +++--
 src/core/hw/gpu.cpp                 |   2 +-
 20 files changed, 409 insertions(+), 68 deletions(-)
 create mode 100644 src/core/hle/service/nim_u.cpp
 create mode 100644 src/core/hle/service/nim_u.h

diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 649640e72..7d3534a43 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -39,6 +39,8 @@ static std::shared_ptr<Logger> global_logger;
         SUB(Service, AC) \
         SUB(Service, PTM) \
         SUB(Service, LDR) \
+        SUB(Service, NIM) \
+        SUB(Service, NWM) \
         SUB(Service, CFG) \
         SUB(Service, DSP) \
         SUB(Service, HID) \
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index 83d64145b..123641cb4 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -59,6 +59,8 @@ enum class Class : ClassType {
     Service_AC,                 ///< The AC (WiFi status) service
     Service_PTM,                ///< The PTM (Power status & misc.) service
     Service_LDR,                ///< The LDR (3ds dll loader) service
+    Service_NIM,                ///< The NIM (Network interface manager) service
+    Service_NWM,                ///< The NWM (Network manager) service
     Service_CFG,                ///< The CFG (Configuration) service
     Service_DSP,                ///< The DSP (DSP control) service
     Service_HID,                ///< The HID (User input) service
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 33e5be3a4..bdf4b6212 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -69,6 +69,7 @@ set(SRCS
             hle/service/news_s.cpp
             hle/service/news_u.cpp
             hle/service/nim_aoc.cpp
+            hle/service/nim_u.cpp
             hle/service/ns_s.cpp
             hle/service/nwm_uds.cpp
             hle/service/pm_app.cpp
@@ -177,6 +178,7 @@ set(HEADERS
             hle/service/news_s.h
             hle/service/news_u.h
             hle/service/nim_aoc.h
+            hle/service/nim_u.h
             hle/service/ns_s.h
             hle/service/nwm_uds.h
             hle/service/pm_app.h
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index 5971f860b..4861d9e5f 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -28,16 +28,21 @@ namespace APT {
 static const VAddr SHARED_FONT_VADDR = 0x18000000;
 
 /// Handle to shared memory region designated to for shared system font
-static Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem;
+static Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem = nullptr;
 
-static Kernel::SharedPtr<Kernel::Mutex> lock;
-static Kernel::SharedPtr<Kernel::Event> notification_event; ///< APT notification event
-static Kernel::SharedPtr<Kernel::Event> pause_event = 0;    ///< APT pause event
+static Kernel::SharedPtr<Kernel::Mutex> lock = nullptr;
+static Kernel::SharedPtr<Kernel::Event> notification_event = nullptr; ///< APT notification event
+static Kernel::SharedPtr<Kernel::Event> pause_event = nullptr;        ///< APT pause event
 static std::vector<u8> shared_font;
 
+static u32 cpu_percent = 0; ///< CPU time available to the running application
+
 void Initialize(Service::Interface* self) {
     u32* cmd_buff = Kernel::GetCommandBuffer();
+    u32 app_id = cmd_buff[1];
+    u32 flags  = cmd_buff[2];
 
+    cmd_buff[2] = 0x04000000; // According to 3dbrew, this value should be 0x04000000
     cmd_buff[3] = Kernel::g_handle_table.Create(notification_event).MoveFrom();
     cmd_buff[4] = Kernel::g_handle_table.Create(pause_event).MoveFrom();
 
@@ -49,6 +54,8 @@ void Initialize(Service::Interface* self) {
     lock->Release();
 
     cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+
+    LOG_TRACE(Service_APT, "called app_id=0x%08X, flags=0x%08X", app_id, flags);
 }
 
 void GetSharedFont(Service::Interface* self) {
@@ -190,7 +197,38 @@ void CancelParameter(Service::Interface* self) {
     cmd_buff[2] = 1; // Set to Success
 
     LOG_WARNING(Service_APT, "(STUBBED) called flag1=0x%08X, unk=0x%08X, flag2=0x%08X, app_id=0x%08X",
-               flag1, unk, flag2, app_id);
+                flag1, unk, flag2, app_id);
+}
+
+void PrepareToStartApplication(Service::Interface* self) {
+    u32* cmd_buff = Kernel::GetCommandBuffer();
+    u32 title_info1  = cmd_buff[1];
+    u32 title_info2  = cmd_buff[2];
+    u32 title_info3  = cmd_buff[3];
+    u32 title_info4  = cmd_buff[4];
+    u32 flags        = cmd_buff[5];
+
+    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+
+    LOG_WARNING(Service_APT, "(STUBBED) called title_info1=0x%08X, title_info2=0x%08X, title_info3=0x%08X,"
+               "title_info4=0x%08X, flags=0x%08X", title_info1, title_info2, title_info3, title_info4, flags);
+}
+
+void StartApplication(Service::Interface* self) {
+    u32* cmd_buff = Kernel::GetCommandBuffer();
+    u32 buffer1_size = cmd_buff[1];
+    u32 buffer2_size = cmd_buff[2];
+    u32 flag         = cmd_buff[3];
+    u32 size1        = cmd_buff[4];
+    u32 buffer1_ptr  = cmd_buff[5];
+    u32 size2        = cmd_buff[6];
+    u32 buffer2_ptr  = cmd_buff[7];
+
+    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+
+    LOG_WARNING(Service_APT, "(STUBBED) called buffer1_size=0x%08X, buffer2_size=0x%08X, flag=0x%08X,"
+               "size1=0x%08X, buffer1_ptr=0x%08X, size2=0x%08X, buffer2_ptr=0x%08X",
+               buffer1_size, buffer2_size, flag, size1, buffer1_ptr, size2, buffer2_ptr);
 }
 
 void AppletUtility(Service::Interface* self) {
@@ -205,15 +243,15 @@ void AppletUtility(Service::Interface* self) {
 
     cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 
-    LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X, buffer1_size=0x%08x, buffer2_size=0x%08x, "
-             "buffer1_addr=0x%08x, buffer2_addr=0x%08x", unk, buffer1_size, buffer2_size,
+    LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X, buffer1_size=0x%08X, buffer2_size=0x%08X, "
+             "buffer1_addr=0x%08X, buffer2_addr=0x%08X", unk, buffer1_size, buffer2_size,
              buffer1_addr, buffer2_addr);
 }
 
 void SetAppCpuTimeLimit(Service::Interface* self) {
     u32* cmd_buff = Kernel::GetCommandBuffer();
-    u32 value = cmd_buff[1];
-    u32 percent = cmd_buff[2];
+    u32 value   = cmd_buff[1];
+    cpu_percent = cmd_buff[2];
 
     if (value != 1) {
         LOG_ERROR(Service_APT, "This value should be one, but is actually %u!", value);
@@ -221,27 +259,26 @@ void SetAppCpuTimeLimit(Service::Interface* self) {
 
     cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 
-    LOG_WARNING(Service_APT, "(STUBBED) called percent=0x%08X, value=0x%08x", percent, value);
+    LOG_WARNING(Service_APT, "(STUBBED) called cpu_percent=%u, value=%u", cpu_percent, value);
 }
 
 void GetAppCpuTimeLimit(Service::Interface* self) {
     u32* cmd_buff = Kernel::GetCommandBuffer();
     u32 value = cmd_buff[1];
 
+    ASSERT(cpu_percent != 0);
+
     if (value != 1) {
         LOG_ERROR(Service_APT, "This value should be one, but is actually %u!", value);
     }
 
-    // TODO(purpasmart96): This is incorrect, I'm pretty sure the percentage should
-    // be set by the application.
-
     cmd_buff[1] = RESULT_SUCCESS.raw; // No error
-    cmd_buff[2] = 0x80; // Set to 80%
+    cmd_buff[2] = cpu_percent;
 
-    LOG_WARNING(Service_APT, "(STUBBED) called value=0x%08x", value);
+    LOG_WARNING(Service_APT, "(STUBBED) called value=%u", value);
 }
 
-void APTInit() {
+void Init() {
     AddService(new APT_A_Interface);
     AddService(new APT_S_Interface);
     AddService(new APT_U_Interface);
@@ -271,13 +308,14 @@ void APTInit() {
     }
 
     lock = Kernel::Mutex::Create(false, "APT_U:Lock");
-    
+    cpu_percent = 0;
+
     // TODO(bunnei): Check if these are created in Initialize or on APT process startup.
     notification_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Notification");
     pause_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Pause");
 }
 
-void APTShutdown() {
+void Shutdown() {
 
 }
 
diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h
index a39adbff9..e7fa39325 100644
--- a/src/core/hle/service/apt/apt.h
+++ b/src/core/hle/service/apt/apt.h
@@ -13,10 +13,13 @@ namespace APT {
 
 /// Signals used by APT functions
 enum class SignalType : u32 {
-    None            = 0x0,
-    AppJustStarted  = 0x1,
-    ReturningToApp  = 0xB,
-    ExitingApp      = 0xC,
+    None              = 0x0,
+    AppJustStarted    = 0x1,
+    LibAppJustStarted = 0x2,
+    LibAppFinished    = 0x3,
+    LibAppClosed      = 0xA,
+    ReturningToApp    = 0xB,
+    ExitingApp        = 0xC,
 };
 
 /// App Id's used by APT functions
@@ -178,6 +181,40 @@ void GlanceParameter(Service::Interface* self);
  */
 void CancelParameter(Service::Interface* self);
 
+/**
+ * APT::PrepareToStartApplication service function. When the input title-info programID is zero,
+ * NS will load the actual program ID via AMNet:GetTitleIDList. After doing some checks with the
+ * programID, NS will then set a NS state flag to value 1, then set the programID for AppID
+ * 0x300(application) to the input program ID(or the one from GetTitleIDList). A media-type field
+ * in the NS state is also set to the input media-type value
+ * (other state fields are set at this point as well). With 8.0.0-18, NS will set an u8 NS state
+ * field to value 1 when input flags bit8 is set
+ *  Inputs:
+ *    1-4 : 0x10-byte title-info struct
+ *      4 : Flags
+ *  Outputs:
+ *      0 : Return header
+ *      1 : Result of function, 0 on success, otherwise error code
+ */
+void PrepareToStartApplication(Service::Interface* self);
+
+/**
+ * APT::StartApplication service function. Buf0 is copied to NS FIRMparams+0x0, then Buf1 is copied
+ * to the NS FIRMparams+0x480. Then the application is launched.
+ * Inputs:
+ *     1 : Buffer 0 size, max size is 0x300
+ *     2 : Buffer 1 size, max size is 0x20 (this can be zero)
+ *     3 : u8 flag
+ *     4 : (Size0<<14) | 2
+ *     5 : Buffer 0 pointer
+ *     6 : (Size1<<14) | 0x802
+ *     7 : Buffer 1 pointer
+ * Outputs:
+ *     0 : Return Header
+ *     1 : Result of function, 0 on success, otherwise error code
+*/
+void StartApplication(Service::Interface* self);
+
 /**
  * APT::AppletUtility service function
  *  Inputs:
@@ -213,10 +250,10 @@ void SetAppCpuTimeLimit(Service::Interface* self);
 void GetAppCpuTimeLimit(Service::Interface* self);
 
 /// Initialize the APT service
-void APTInit();
+void Init();
 
 /// Shutdown the APT service
-void APTShutdown();
+void Shutdown();
 
 } // namespace APT
 } // namespace Service
diff --git a/src/core/hle/service/apt/apt_a.cpp b/src/core/hle/service/apt/apt_a.cpp
index dbe5c1d87..864934245 100644
--- a/src/core/hle/service/apt/apt_a.cpp
+++ b/src/core/hle/service/apt/apt_a.cpp
@@ -12,16 +12,16 @@ namespace APT {
 const Interface::FunctionInfo FunctionTable[] = {
     {0x00010040, GetLockHandle,      "GetLockHandle?"},
     {0x00020080, Initialize,         "Initialize?"},
-    {0x00030040, nullptr,            "Enable?"},
+    {0x00030040, Enable,             "Enable?"},
     {0x00040040, nullptr,            "Finalize?"},
     {0x00050040, nullptr,            "GetAppletManInfo?"},
     {0x00060040, nullptr,            "GetAppletInfo?"},
     {0x000D0080, ReceiveParameter,   "ReceiveParameter?"},
     {0x000E0080, GlanceParameter,    "GlanceParameter?"},
     {0x003B0040, nullptr,            "CancelLibraryApplet?"},
-    {0x00430040, nullptr,            "NotifyToWait?"},
+    {0x00430040, NotifyToWait,       "NotifyToWait?"},
     {0x00440000, GetSharedFont,      "GetSharedFont?"},
-    {0x004B00C2, nullptr,            "AppletUtility?"},
+    {0x004B00C2, AppletUtility,      "AppletUtility?"},
     {0x00550040, nullptr,            "WriteInputToNsState?"},
 };
 
diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp
index 6adadb224..fe1245fe8 100644
--- a/src/core/hle/service/cfg/cfg.cpp
+++ b/src/core/hle/service/cfg/cfg.cpp
@@ -170,7 +170,7 @@ ResultCode FormatConfig() {
     return RESULT_SUCCESS;
 }
 
-void CFGInit() {
+void Init() {
     AddService(new CFG_I_Interface);
     AddService(new CFG_S_Interface);
     AddService(new CFG_U_Interface);
@@ -218,7 +218,7 @@ void CFGInit() {
     FormatConfig();
 }
 
-void CFGShutdown() {
+void Shutdown() {
 
 }
 
diff --git a/src/core/hle/service/cfg/cfg.h b/src/core/hle/service/cfg/cfg.h
index e818d7bdc..3488c40d0 100644
--- a/src/core/hle/service/cfg/cfg.h
+++ b/src/core/hle/service/cfg/cfg.h
@@ -135,10 +135,10 @@ ResultCode UpdateConfigNANDSavegame();
 ResultCode FormatConfig();
 
 /// Initialize the config service
-void CFGInit();
+void Init();
 
 /// Shutdown the config service
-void CFGShutdown();
+void Shutdown();
 
 } // namespace CFG
 } // namespace Service
diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp
index 0b3603ce1..f16f84e67 100644
--- a/src/core/hle/service/dsp_dsp.cpp
+++ b/src/core/hle/service/dsp_dsp.cpp
@@ -83,6 +83,33 @@ static void GetSemaphoreEventHandle(Service::Interface* self) {
     LOG_WARNING(Service_DSP, "(STUBBED) called");
 }
 
+/**
+ * DSP_DSP::FlushDataCache service function
+ *
+ * This Function is a no-op, We aren't emulating the CPU cache any time soon.
+ *
+ *  Inputs:
+ *      1 : Address
+ *      2 : Size
+ *      3 : Value 0, some descriptor for the KProcess Handle
+ *      4 : KProcess handle
+ *  Outputs:
+ *      1 : Result of function, 0 on success, otherwise error code
+ */
+static void FlushDataCache(Service::Interface* self) {
+    u32* cmd_buff = Kernel::GetCommandBuffer();
+    u32 address = cmd_buff[1];
+    u32 size    = cmd_buff[2];
+    u32 process = cmd_buff[4];
+
+    // TODO(purpasmart96): Verify return header on HW
+
+    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+
+    LOG_DEBUG(Service_DSP, "(STUBBED) called address=0x%08X, size=0x%08X, process=0x%08X",
+              address, size, process);
+}
+
 /**
  * DSP_DSP::RegisterInterruptEvents service function
  *  Inputs:
@@ -225,7 +252,7 @@ static void GetHeadphoneStatus(Service::Interface* self) {
     cmd_buff[1] = RESULT_SUCCESS.raw; // No error
     cmd_buff[2] = 0; // Not using headphones?
 
-    LOG_WARNING(Service_DSP, "(STUBBED) called");
+    LOG_DEBUG(Service_DSP, "(STUBBED) called");
 }
 
 const Interface::FunctionInfo FunctionTable[] = {
@@ -242,7 +269,7 @@ const Interface::FunctionInfo FunctionTable[] = {
     {0x001000C0, ReadPipeIfPossible,               "ReadPipeIfPossible"},
     {0x001100C2, LoadComponent,                    "LoadComponent"},
     {0x00120000, nullptr,                          "UnloadComponent"},
-    {0x00130082, nullptr,                          "FlushDataCache"},
+    {0x00130082, FlushDataCache,                   "FlushDataCache"},
     {0x00140082, nullptr,                          "InvalidateDCache"},
     {0x00150082, RegisterInterruptEvents,          "RegisterInterruptEvents"},
     {0x00160000, GetSemaphoreEventHandle,          "GetSemaphoreEventHandle"},
diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp
index d8d1d5547..5bc94b1b1 100644
--- a/src/core/hle/service/fs/fs_user.cpp
+++ b/src/core/hle/service/fs/fs_user.cpp
@@ -20,6 +20,8 @@ using Kernel::Session;
 namespace Service {
 namespace FS {
 
+static u32 priority = -1; ///< For SetPriority and GetPriority service functions
+
 static ArchiveHandle MakeArchiveHandle(u32 low_word, u32 high_word) {
     return (u64)low_word | ((u64)high_word << 32);
 }
@@ -215,7 +217,7 @@ static void DeleteDirectory(Service::Interface* self) {
 
     LOG_DEBUG(Service_FS, "type=%d size=%d data=%s",
               dirname_type, dirname_size, dir_path.DebugStr().c_str());
-    
+
     cmd_buff[1] = DeleteDirectoryFromArchive(archive_handle, dir_path).raw;
 }
 
@@ -424,7 +426,7 @@ static void IsSdmcWriteable(Service::Interface* self) {
     cmd_buff[1] = RESULT_SUCCESS.raw;
     // If the SD isn't enabled, it can't be writeable...else, stubbed true
     cmd_buff[2] = Settings::values.use_virtual_sd ? 1 : 0;
-    
+
     LOG_DEBUG(Service_FS, " (STUBBED)");
 }
 
@@ -511,7 +513,7 @@ static void CreateExtSaveData(Service::Interface* self) {
     MediaType media_type = static_cast<MediaType>(cmd_buff[1] & 0xFF);
     u32 save_low = cmd_buff[2];
     u32 save_high = cmd_buff[3];
-    
+
     LOG_WARNING(Service_FS, "(STUBBED) savedata_high=%08X savedata_low=%08X cmd_buff[3]=%08X "
             "cmd_buff[4]=%08X cmd_buff[5]=%08X cmd_buff[6]=%08X cmd_buff[7]=%08X cmd_buff[8]=%08X "
             "cmd_buff[9]=%08X cmd_buff[10]=%08X cmd_buff[11]=%08X", save_high, save_low,
@@ -573,7 +575,7 @@ static void DeleteSystemSaveData(Service::Interface* self) {
     u32* cmd_buff = Kernel::GetCommandBuffer();
     u32 savedata_high = cmd_buff[1];
     u32 savedata_low = cmd_buff[2];
-    
+
     cmd_buff[1] = DeleteSystemSaveData(savedata_high, savedata_low).raw;
 }
 
@@ -601,12 +603,72 @@ static void CreateSystemSaveData(Service::Interface* self) {
 
     LOG_WARNING(Service_FS, "(STUBBED) savedata_high=%08X savedata_low=%08X cmd_buff[3]=%08X "
             "cmd_buff[4]=%08X cmd_buff[5]=%08X cmd_buff[6]=%08X cmd_buff[7]=%08X cmd_buff[8]=%08X "
-            "cmd_buff[9]=%08X", savedata_high, savedata_low, cmd_buff[3], cmd_buff[4], cmd_buff[5], 
+            "cmd_buff[9]=%08X", savedata_high, savedata_low, cmd_buff[3], cmd_buff[4], cmd_buff[5],
             cmd_buff[6], cmd_buff[7], cmd_buff[8], cmd_buff[9]);
 
     cmd_buff[1] = CreateSystemSaveData(savedata_high, savedata_low).raw;
 }
 
+/**
+ * FS_User::InitializeWithSdkVersion service function.
+ *  Inputs:
+ *      0 : 0x08610042
+ *      1 : Unknown
+ *      2 : Unknown
+ *      3 : Unknown
+ *  Outputs:
+ *      1 : Result of function, 0 on success, otherwise error code
+ */
+static void InitializeWithSdkVersion(Service::Interface* self) {
+    u32* cmd_buff = Kernel::GetCommandBuffer();
+
+    u32 unk1 = cmd_buff[1];
+    u32 unk2 = cmd_buff[2];
+    u32 unk3 = cmd_buff[3];
+
+    cmd_buff[1] = RESULT_SUCCESS.raw;
+
+    LOG_WARNING(Service_FS, "(STUBBED) called unk1=0x%08X, unk2=0x%08X, unk3=0x%08X",
+                unk1, unk2, unk3);
+}
+
+/**
+ * FS_User::SetPriority service function.
+ *  Inputs:
+ *      0 : 0x08620040
+ *      1 : priority
+ *  Outputs:
+ *      1 : Result of function, 0 on success, otherwise error code
+ */
+static void SetPriority(Service::Interface* self) {
+    u32* cmd_buff = Kernel::GetCommandBuffer();
+
+    priority = cmd_buff[1];
+
+    cmd_buff[1] = RESULT_SUCCESS.raw;
+
+    LOG_DEBUG(Service_FS, "called priority=0x%08X", priority);
+}
+
+/**
+ * FS_User::GetPriority service function.
+ *  Inputs:
+ *      0 : 0x08630000
+ *  Outputs:
+ *      1 : Result of function, 0 on success, otherwise error code
+ *      2 : priority
+ */
+static void GetPriority(Service::Interface* self) {
+    u32* cmd_buff = Kernel::GetCommandBuffer();
+
+    ASSERT(priority != -1);
+
+    cmd_buff[1] = RESULT_SUCCESS.raw;
+    cmd_buff[2] = priority;
+
+    LOG_DEBUG(Service_FS, "called priority=0x%08X", priority);
+}
+
 const Interface::FunctionInfo FunctionTable[] = {
     {0x000100C6, nullptr,               "Dummy1"},
     {0x040100C4, nullptr,               "Control"},
@@ -695,15 +757,17 @@ const Interface::FunctionInfo FunctionTable[] = {
     {0x08560240, CreateSystemSaveData,  "CreateSystemSaveData"},
     {0x08570080, DeleteSystemSaveData,  "DeleteSystemSaveData"},
     {0x08580000, nullptr,               "GetMovableSedHashedKeyYRandomData"},
-    {0x08610042, nullptr,               "InitializeWithSdkVersion"},
-    {0x08620040, nullptr,               "SetPriority"},
-    {0x08630000, nullptr,               "GetPriority"},
+    {0x08610042, InitializeWithSdkVersion, "InitializeWithSdkVersion"},
+    {0x08620040, SetPriority,           "SetPriority"},
+    {0x08630000, GetPriority,           "GetPriority"},
 };
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // Interface class
 
 Interface::Interface() {
+
+    priority = -1;
     Register(FunctionTable);
 }
 
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp
index cff585698..26d3bcff6 100644
--- a/src/core/hle/service/gsp_gpu.cpp
+++ b/src/core/hle/service/gsp_gpu.cpp
@@ -265,6 +265,9 @@ static void FlushDataCache(Service::Interface* self) {
     // TODO(purpasmart96): Verify return header on HW
 
     cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+
+    LOG_DEBUG(Service_GSP, "(STUBBED) called address=0x%08X, size=0x%08X, process=0x%08X",
+              address, size, process);
 }
 
 /**
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 138603d9b..9ca5d13d4 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -45,7 +45,7 @@ static u32 next_touch_index = 0;
 //     * Set PadData.current_state.circle_left = 1 if current PadEntry.circle_pad_x <= -41
 //     * Set PadData.current_state.circle_right = 1 if current PadEntry.circle_pad_y <= -41
 
-void HIDUpdate() {
+void Update() {
     SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer().ValueOr(nullptr));
     const PadState state = VideoCore::g_emu_window->GetPadState();
 
@@ -155,7 +155,7 @@ void GetSoundVolume(Service::Interface* self) {
     LOG_WARNING(Service_HID, "(STUBBED) called");
 }
 
-void HIDInit() {
+void Init() {
     using namespace Kernel;
 
     AddService(new HID_U_Interface);
@@ -174,7 +174,7 @@ void HIDInit() {
     event_debug_pad      = Event::Create(RESETTYPE_ONESHOT, "HID:EventDebugPad");
 }
 
-void HIDShutdown() {
+void Shutdown() {
 }
 
 } // namespace HID
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 97462c7f8..897bd6764 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -200,13 +200,13 @@ void EnableGyroscopeLow(Interface* self);
 void GetSoundVolume(Interface* self);
 
 /// Checks for user input updates
-void HIDUpdate();
+void Update();
 
 /// Initialize HID service
-void HIDInit();
+void Init();
 
 /// Shutdown HID service
-void HIDShutdown();
+void Shutdown();
 
 }
 }
diff --git a/src/core/hle/service/nim_u.cpp b/src/core/hle/service/nim_u.cpp
new file mode 100644
index 000000000..a87d17ef0
--- /dev/null
+++ b/src/core/hle/service/nim_u.cpp
@@ -0,0 +1,46 @@
+// Copyright 2015 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/hle.h"
+#include "core/hle/service/nim_u.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace NIM_U
+
+namespace NIM_U {
+
+/**
+ * NIM_U::CheckSysUpdateAvailable service function
+ *  Inputs:
+ *      1 : None
+ *  Outputs:
+ *      1 : Result of function, 0 on success, otherwise error code
+ *      2 : flag, 0 = no system update available, 1 = system update available.
+ */
+static void CheckSysUpdateAvailable(Service::Interface* self) {
+    u32* cmd_buff = Kernel::GetCommandBuffer();
+
+    cmd_buff[1] = RESULT_SUCCESS.raw;
+    cmd_buff[2] = 0; // No update available
+
+    LOG_WARNING(Service_NWM, "(STUBBED) called");
+}
+
+const Interface::FunctionInfo FunctionTable[] = {
+    {0x00010000, nullptr,                  "StartSysUpdate"},
+    {0x00020000, nullptr,                  "GetUpdateDownloadProgress"},
+    {0x00040000, nullptr,                  "FinishTitlesInstall"},
+    {0x00050000, nullptr,                  "CheckForSysUpdateEvent"},
+    {0x00090000, CheckSysUpdateAvailable,  "CheckSysUpdateAvailable"},
+    {0x000A0000, nullptr,                  "GetState"},
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Interface class
+
+Interface::Interface() {
+    Register(FunctionTable);
+}
+
+} // namespace
diff --git a/src/core/hle/service/nim_u.h b/src/core/hle/service/nim_u.h
new file mode 100644
index 000000000..57a1f6acf
--- /dev/null
+++ b/src/core/hle/service/nim_u.h
@@ -0,0 +1,23 @@
+// Copyright 2015 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace NIM_U
+
+namespace NIM_U {
+
+class Interface : public Service::Interface {
+public:
+    Interface();
+
+    std::string GetPortName() const override {
+        return "nim:u";
+    }
+};
+
+} // namespace
diff --git a/src/core/hle/service/nwm_uds.cpp b/src/core/hle/service/nwm_uds.cpp
index 88be6c8d9..1cee81ab2 100644
--- a/src/core/hle/service/nwm_uds.cpp
+++ b/src/core/hle/service/nwm_uds.cpp
@@ -3,6 +3,7 @@
 // Refer to the license.txt file included.
 
 #include "core/hle/hle.h"
+#include "core/hle/kernel/event.h"
 #include "core/hle/service/nwm_uds.h"
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -10,21 +11,115 @@
 
 namespace NWM_UDS {
 
+static Kernel::SharedPtr<Kernel::Event> handle_event = nullptr;
+
+/**
+ * NWM_UDS::Shutdown service function
+ *  Inputs:
+ *      1 : None
+ *  Outputs:
+ *      0 : Return header
+ *      1 : Result of function, 0 on success, otherwise error code
+ */
+static void Shutdown(Service::Interface* self) {
+    u32* cmd_buff = Kernel::GetCommandBuffer();
+
+    // TODO(purpasmart): Verify return header on HW
+
+    cmd_buff[1] = RESULT_SUCCESS.raw;
+
+    LOG_WARNING(Service_NWM, "(STUBBED) called");
+}
+
+/**
+ * NWM_UDS::RecvBeaconBroadcastData service function
+ *  Inputs:
+ *      1 : Output buffer max size
+ *      2 : Unknown
+ *      3 : Unknown
+ *      4 : MAC address?
+ *   6-14 : Unknown, usually zero / uninitialized?
+ *     15 : WLan Comm ID
+ *     16 : This is the ID also located at offset 0xE in the CTR-generation structure.
+ *     17 : Value 0
+ *     18 : Input handle
+ *     19 : (Size<<4) | 12
+ *     20 : Output buffer ptr
+ *  Outputs:
+ *      0 : Return header
+ *      1 : Result of function, 0 on success, otherwise error code
+ */
+static void RecvBeaconBroadcastData(Service::Interface* self) {
+    u32* cmd_buff = Kernel::GetCommandBuffer();
+    u32 out_buffer_size = cmd_buff[1];
+    u32 unk1            = cmd_buff[2];
+    u32 unk2            = cmd_buff[3];
+    u32 mac_address     = cmd_buff[4];
+
+    u32 unk3            = cmd_buff[6];
+
+    u32 wlan_comm_id    = cmd_buff[15];
+    u32 ctr_gen_id      = cmd_buff[16];
+    u32 value           = cmd_buff[17];
+    u32 input_handle    = cmd_buff[18];
+    u32 new_buffer_size = cmd_buff[19];
+    u32 out_buffer_ptr  = cmd_buff[20];
+
+    cmd_buff[1] = RESULT_SUCCESS.raw;
+
+    LOG_WARNING(Service_NWM, "(STUBBED) called out_buffer_size=0x%08X, unk1=0x%08X, unk2=0x%08X,"
+                "mac_address=0x%08X, unk3=0x%08X, wlan_comm_id=0x%08X, ctr_gen_id=0x%08X,"
+                "value=%u, input_handle=0x%08X, new_buffer_size=0x%08X, out_buffer_ptr=0x%08X",
+                out_buffer_size, unk1, unk2, mac_address, unk3, wlan_comm_id, ctr_gen_id, value,
+                input_handle, new_buffer_size, out_buffer_ptr);
+}
+
+/**
+ * NWM_UDS::Initialize service function
+ *  Inputs:
+ *      1 : Unknown
+ *   2-11 : Input Structure
+ *     12 : Unknown u16
+ *     13 : Value 0
+ *     14 : Handle
+ *  Outputs:
+ *      0 : Return header
+ *      1 : Result of function, 0 on success, otherwise error code
+ *      2 : Value 0
+ *      3 : Output handle
+ */
+static void Initialize(Service::Interface* self) {
+    u32* cmd_buff = Kernel::GetCommandBuffer();
+    u32 unk1   = cmd_buff[1];
+    u32 unk2   = cmd_buff[12];
+    u32 value  = cmd_buff[13];
+    u32 handle = cmd_buff[14];
+
+    cmd_buff[1] = RESULT_SUCCESS.raw;
+    cmd_buff[2] = 0;
+    cmd_buff[3] = Kernel::g_handle_table.Create(handle_event).MoveFrom(); //TODO(purpasmart): Verify if this is a event handle
+
+    LOG_WARNING(Service_NWM, "(STUBBED) called unk1=0x%08X, unk2=0x%08X, value=%u, handle=0x%08X",
+                unk1, unk2, value, handle);
+}
+
 const Interface::FunctionInfo FunctionTable[] = {
-    {0x00030000, nullptr,               "Shutdown"},
-    {0x000F0404, nullptr,               "RecvBeaconBroadcastData"},
-    {0x00100042, nullptr,               "SetBeaconAdditionalData"},
-    {0x001400C0, nullptr,               "RecvBroadcastDataFrame"},
-    {0x001B0302, nullptr,               "Initialize"},
-    {0x001D0044, nullptr,               "BeginHostingNetwork"},
-    {0x001E0084, nullptr,               "ConnectToNetwork"},
-    {0x001F0006, nullptr,               "DecryptBeaconData"},
+    {0x00030000, Shutdown,                  "Shutdown"},
+    {0x000F0404, RecvBeaconBroadcastData,   "RecvBeaconBroadcastData"},
+    {0x00100042, nullptr,                   "SetBeaconAdditionalData"},
+    {0x001400C0, nullptr,                   "RecvBroadcastDataFrame"},
+    {0x001B0302, Initialize,                "Initialize"},
+    {0x001D0044, nullptr,                   "BeginHostingNetwork"},
+    {0x001E0084, nullptr,                   "ConnectToNetwork"},
+    {0x001F0006, nullptr,                   "DecryptBeaconData"},
 };
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // Interface class
 
 Interface::Interface() {
+    handle_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "NWM_UDS::handle_event");
+
     Register(FunctionTable);
 }
 
diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp
index 56c918d4f..57a301bec 100644
--- a/src/core/hle/service/ptm/ptm.cpp
+++ b/src/core/hle/service/ptm/ptm.cpp
@@ -38,7 +38,7 @@ ChargeLevels GetBatteryLevel() {
     return ChargeLevels::CompletelyFull; // Set to a completely full battery
 }
 
-void PTMInit() {
+void Init() {
     AddService(new PTM_Play_Interface);
     AddService(new PTM_Sysm_Interface);
     AddService(new PTM_U_Interface);
@@ -68,7 +68,7 @@ void PTMInit() {
     }
 }
 
-void PTMShutdown() {
+void Shutdown() {
 
 }
 
diff --git a/src/core/hle/service/ptm/ptm.h b/src/core/hle/service/ptm/ptm.h
index f697aae4d..3c776aa8a 100644
--- a/src/core/hle/service/ptm/ptm.h
+++ b/src/core/hle/service/ptm/ptm.h
@@ -56,10 +56,10 @@ u32 GetShellState();
 ChargeLevels GetBatteryLevel();
 
 /// Initialize the PTM service
-void PTMInit();
+void Init();
 
 /// Shutdown the PTM service
-void PTMShutdown();
+void Shutdown();
 
 } // namespace PTM
 } // namespace Service
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 91f13cd7e..eeb404659 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -32,6 +32,7 @@
 #include "core/hle/service/news_s.h"
 #include "core/hle/service/news_u.h"
 #include "core/hle/service/nim_aoc.h"
+#include "core/hle/service/nim_u.h"
 #include "core/hle/service/ns_s.h"
 #include "core/hle/service/nwm_uds.h"
 #include "core/hle/service/pm_app.h"
@@ -68,10 +69,10 @@ void Init() {
     AddNamedPort(new ERR_F::Interface);
 
     Service::FS::ArchiveInit();
-    Service::CFG::CFGInit();
-    Service::APT::APTInit();
-    Service::PTM::PTMInit();
-    Service::HID::HIDInit();
+    Service::CFG::Init();
+    Service::APT::Init();
+    Service::PTM::Init();
+    Service::HID::Init();
 
     AddService(new AC_U::Interface);
     AddService(new ACT_U::Interface);
@@ -98,6 +99,7 @@ void Init() {
     AddService(new NEWS_S::Interface);
     AddService(new NEWS_U::Interface);
     AddService(new NIM_AOC::Interface);
+    AddService(new NIM_U::Interface);
     AddService(new NS_S::Interface);
     AddService(new NWM_UDS::Interface);
     AddService(new PM_APP::Interface);
@@ -110,10 +112,10 @@ void Init() {
 
 /// Shutdown ServiceManager
 void Shutdown() {
-    Service::HID::HIDShutdown();
-    Service::PTM::PTMShutdown();
-    Service::APT::APTShutdown();
-    Service::CFG::CFGShutdown();
+    Service::HID::Shutdown();
+    Service::PTM::Shutdown();
+    Service::APT::Shutdown();
+    Service::CFG::Shutdown();
     Service::FS::ArchiveShutdown();
 
     g_srv_services.clear();
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index e6983a225..75e040b24 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -312,7 +312,7 @@ static void VBlankCallback(u64 userdata, int cycles_late) {
     DSP_DSP::SignalInterrupt();
 
     // Check for user input updates
-    Service::HID::HIDUpdate();
+    Service::HID::Update();
 
     // Reschedule recurrent event
     CoreTiming::ScheduleEvent(frame_ticks - cycles_late, vblank_event);