Services: Stubs and minor changes
This commit is contained in:
		| @@ -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) \ | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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) { | ||||
| @@ -193,6 +200,37 @@ void CancelParameter(Service::Interface* self) { | ||||
|                 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) { | ||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); | ||||
|  | ||||
| @@ -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]; | ||||
|     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() { | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -15,6 +15,9 @@ namespace APT { | ||||
| enum class SignalType : u32 { | ||||
|     None              = 0x0, | ||||
|     AppJustStarted    = 0x1, | ||||
|     LibAppJustStarted = 0x2, | ||||
|     LibAppFinished    = 0x3, | ||||
|     LibAppClosed      = 0xA, | ||||
|     ReturningToApp    = 0xB, | ||||
|     ExitingApp        = 0xC, | ||||
| }; | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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?"}, | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -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() { | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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"}, | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
| @@ -607,6 +609,66 @@ static void CreateSystemSaveData(Service::Interface* self) { | ||||
|     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); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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(); | ||||
|  | ||||
| } | ||||
| } | ||||
|   | ||||
							
								
								
									
										46
									
								
								src/core/hle/service/nim_u.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/core/hle/service/nim_u.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||
							
								
								
									
										23
									
								
								src/core/hle/service/nim_u.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/core/hle/service/nim_u.h
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||
| @@ -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,12 +11,104 @@ | ||||
|  | ||||
| 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"}, | ||||
|     {0x00030000, Shutdown,                  "Shutdown"}, | ||||
|     {0x000F0404, RecvBeaconBroadcastData,   "RecvBeaconBroadcastData"}, | ||||
|     {0x00100042, nullptr,                   "SetBeaconAdditionalData"}, | ||||
|     {0x001400C0, nullptr,                   "RecvBroadcastDataFrame"}, | ||||
|     {0x001B0302, nullptr,               "Initialize"}, | ||||
|     {0x001B0302, Initialize,                "Initialize"}, | ||||
|     {0x001D0044, nullptr,                   "BeginHostingNetwork"}, | ||||
|     {0x001E0084, nullptr,                   "ConnectToNetwork"}, | ||||
|     {0x001F0006, nullptr,                   "DecryptBeaconData"}, | ||||
| @@ -25,6 +118,8 @@ const Interface::FunctionInfo FunctionTable[] = { | ||||
| // Interface class | ||||
|  | ||||
| Interface::Interface() { | ||||
|     handle_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "NWM_UDS::handle_event"); | ||||
|  | ||||
|     Register(FunctionTable); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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() { | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 purpasmart96
					purpasmart96