From ffabed8c25490be0e61409cebd1615eedb223c3d Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 15 Apr 2014 23:28:03 -0400 Subject: [PATCH] restructured hle:services completely to use function lookup tables --- src/core/hle/service/apt.cpp | 204 +++++++++++++++------------------ src/core/hle/service/apt.h | 30 +---- src/core/hle/service/service.h | 28 ++++- src/core/hle/service/srv.cpp | 55 +++++++++ src/core/hle/service/srv.h | 39 +++++++ 5 files changed, 217 insertions(+), 139 deletions(-) create mode 100644 src/core/hle/service/srv.cpp create mode 100644 src/core/hle/service/srv.h diff --git a/src/core/hle/service/apt.cpp b/src/core/hle/service/apt.cpp index 288a68a865..e5c9dd873c 100644 --- a/src/core/hle/service/apt.cpp +++ b/src/core/hle/service/apt.cpp @@ -10,118 +10,104 @@ namespace APT_U { -const HLE::FunctionDef APT_U_Table[] = { - {0x00010040, NULL, "GetLockHandle"}, - {0x00020080, NULL, "Initialize"}, - {0x00030040, NULL, "Enable"}, - {0x00040040, NULL, "Finalize"}, - {0x00050040, NULL, "GetAppletManInfo"}, - {0x00060040, NULL, "GetAppletInfo"}, - {0x00070000, NULL, "GetLastSignaledAppletId"}, - {0x00080000, NULL, "CountRegisteredApplet"}, - {0x00090040, NULL, "IsRegistered"}, - {0x000A0040, NULL, "GetAttribute"}, - {0x000B0040, NULL, "InquireNotification"}, - {0x000C0104, NULL, "SendParameter"}, - {0x000D0080, NULL, "ReceiveParameter"}, - {0x000E0080, NULL, "GlanceParameter"}, - {0x000F0100, NULL, "CancelParameter"}, - {0x001000C2, NULL, "DebugFunc"}, - {0x001100C0, NULL, "MapProgramIdForDebug"}, - {0x00120040, NULL, "SetHomeMenuAppletIdForDebug"}, - {0x00130000, NULL, "GetPreparationState"}, - {0x00140040, NULL, "SetPreparationState"}, - {0x00150140, NULL, "PrepareToStartApplication"}, - {0x00160040, NULL, "PreloadLibraryApplet"}, - {0x00170040, NULL, "FinishPreloadingLibraryApplet"}, - {0x00180040, NULL, "PrepareToStartLibraryApplet"}, - {0x00190040, NULL, "PrepareToStartSystemApplet"}, - {0x001A0000, NULL, "PrepareToStartNewestHomeMenu"}, - {0x001B00C4, NULL, "StartApplication"}, - {0x001C0000, NULL, "WakeupApplication"}, - {0x001D0000, NULL, "CancelApplication"}, - {0x001E0084, NULL, "StartLibraryApplet"}, - {0x001F0084, NULL, "StartSystemApplet"}, - {0x00200044, NULL, "StartNewestHomeMenu"}, - {0x00210000, NULL, "OrderToCloseApplication"}, - {0x00220040, NULL, "PrepareToCloseApplication"}, - {0x00230040, NULL, "PrepareToJumpToApplication"}, - {0x00240044, NULL, "JumpToApplication"}, - {0x002500C0, NULL, "PrepareToCloseLibraryApplet"}, - {0x00260000, NULL, "PrepareToCloseSystemApplet"}, - {0x00270044, NULL, "CloseApplication"}, - {0x00280044, NULL, "CloseLibraryApplet"}, - {0x00290044, NULL, "CloseSystemApplet"}, - {0x002A0000, NULL, "OrderToCloseSystemApplet"}, - {0x002B0000, NULL, "PrepareToJumpToHomeMenu"}, - {0x002C0044, NULL, "JumpToHomeMenu"}, - {0x002D0000, NULL, "PrepareToLeaveHomeMenu"}, - {0x002E0044, NULL, "LeaveHomeMenu"}, - {0x002F0040, NULL, "PrepareToLeaveResidentApplet"}, - {0x00300044, NULL, "LeaveResidentApplet"}, - {0x00310100, NULL, "PrepareToDoApplicationJump"}, - {0x00320084, NULL, "DoApplicationJump"}, - {0x00330000, NULL, "GetProgramIdOnApplicationJump"}, - {0x00340084, NULL, "SendDeliverArg"}, - {0x00350080, NULL, "ReceiveDeliverArg"}, - {0x00360040, NULL, "LoadSysMenuArg"}, - {0x00370042, NULL, "StoreSysMenuArg"}, - {0x00380040, NULL, "PreloadResidentApplet"}, - {0x00390040, NULL, "PrepareToStartResidentApplet"}, - {0x003A0044, NULL, "StartResidentApplet"}, - {0x003B0040, NULL, "CancelLibraryApplet"}, - {0x003C0042, NULL, "SendDspSleep"}, - {0x003D0042, NULL, "SendDspWakeUp"}, - {0x003E0080, NULL, "ReplySleepQuery"}, - {0x003F0040, NULL, "ReplySleepNotificationComplete"}, - {0x00400042, NULL, "SendCaptureBufferInfo"}, - {0x00410040, NULL, "ReceiveCaptureBufferInfo"}, - {0x00420080, NULL, "SleepSystem"}, - {0x00430040, NULL, "NotifyToWait"}, - {0x00440000, NULL, "GetSharedFont"}, - {0x00450040, NULL, "GetWirelessRebootInfo"}, - {0x00460104, NULL, "Wrap"}, - {0x00470104, NULL, "Unwrap"}, - {0x00480100, NULL, "GetProgramInfo"}, - {0x00490180, NULL, "Reboot"}, - {0x004A0040, NULL, "GetCaptureInfo"}, - {0x004B00C2, NULL, "AppletUtility"}, - {0x004C0000, NULL, "SetFatalErrDispMode"}, - {0x004D0080, NULL, "GetAppletProgramInfo"}, - {0x004E0000, NULL, "HardwareResetAsync"}, +void Initialize() { + NOTICE_LOG(OSHLE, "APT_U::Sync - Initialize"); +} + +void GetLockHandle() { + u32* cmd_buff = (u32*)HLE::GetPointer(HLE::CMD_BUFFER_ADDR + Service::kCommandHeaderOffset); + cmd_buff[5] = 0x00000000; // TODO: This should be an actual mutex handle +} + +const HLE::FunctionDef FunctionTable[] = { + {0x00010040, GetLockHandle, "GetLockHandle"}, + {0x00020080, Initialize, "Initialize"}, + {0x00030040, NULL, "Enable"}, + {0x00040040, NULL, "Finalize"}, + {0x00050040, NULL, "GetAppletManInfo"}, + {0x00060040, NULL, "GetAppletInfo"}, + {0x00070000, NULL, "GetLastSignaledAppletId"}, + {0x00080000, NULL, "CountRegisteredApplet"}, + {0x00090040, NULL, "IsRegistered"}, + {0x000A0040, NULL, "GetAttribute"}, + {0x000B0040, NULL, "InquireNotification"}, + {0x000C0104, NULL, "SendParameter"}, + {0x000D0080, NULL, "ReceiveParameter"}, + {0x000E0080, NULL, "GlanceParameter"}, + {0x000F0100, NULL, "CancelParameter"}, + {0x001000C2, NULL, "DebugFunc"}, + {0x001100C0, NULL, "MapProgramIdForDebug"}, + {0x00120040, NULL, "SetHomeMenuAppletIdForDebug"}, + {0x00130000, NULL, "GetPreparationState"}, + {0x00140040, NULL, "SetPreparationState"}, + {0x00150140, NULL, "PrepareToStartApplication"}, + {0x00160040, NULL, "PreloadLibraryApplet"}, + {0x00170040, NULL, "FinishPreloadingLibraryApplet"}, + {0x00180040, NULL, "PrepareToStartLibraryApplet"}, + {0x00190040, NULL, "PrepareToStartSystemApplet"}, + {0x001A0000, NULL, "PrepareToStartNewestHomeMenu"}, + {0x001B00C4, NULL, "StartApplication"}, + {0x001C0000, NULL, "WakeupApplication"}, + {0x001D0000, NULL, "CancelApplication"}, + {0x001E0084, NULL, "StartLibraryApplet"}, + {0x001F0084, NULL, "StartSystemApplet"}, + {0x00200044, NULL, "StartNewestHomeMenu"}, + {0x00210000, NULL, "OrderToCloseApplication"}, + {0x00220040, NULL, "PrepareToCloseApplication"}, + {0x00230040, NULL, "PrepareToJumpToApplication"}, + {0x00240044, NULL, "JumpToApplication"}, + {0x002500C0, NULL, "PrepareToCloseLibraryApplet"}, + {0x00260000, NULL, "PrepareToCloseSystemApplet"}, + {0x00270044, NULL, "CloseApplication"}, + {0x00280044, NULL, "CloseLibraryApplet"}, + {0x00290044, NULL, "CloseSystemApplet"}, + {0x002A0000, NULL, "OrderToCloseSystemApplet"}, + {0x002B0000, NULL, "PrepareToJumpToHomeMenu"}, + {0x002C0044, NULL, "JumpToHomeMenu"}, + {0x002D0000, NULL, "PrepareToLeaveHomeMenu"}, + {0x002E0044, NULL, "LeaveHomeMenu"}, + {0x002F0040, NULL, "PrepareToLeaveResidentApplet"}, + {0x00300044, NULL, "LeaveResidentApplet"}, + {0x00310100, NULL, "PrepareToDoApplicationJump"}, + {0x00320084, NULL, "DoApplicationJump"}, + {0x00330000, NULL, "GetProgramIdOnApplicationJump"}, + {0x00340084, NULL, "SendDeliverArg"}, + {0x00350080, NULL, "ReceiveDeliverArg"}, + {0x00360040, NULL, "LoadSysMenuArg"}, + {0x00370042, NULL, "StoreSysMenuArg"}, + {0x00380040, NULL, "PreloadResidentApplet"}, + {0x00390040, NULL, "PrepareToStartResidentApplet"}, + {0x003A0044, NULL, "StartResidentApplet"}, + {0x003B0040, NULL, "CancelLibraryApplet"}, + {0x003C0042, NULL, "SendDspSleep"}, + {0x003D0042, NULL, "SendDspWakeUp"}, + {0x003E0080, NULL, "ReplySleepQuery"}, + {0x003F0040, NULL, "ReplySleepNotificationComplete"}, + {0x00400042, NULL, "SendCaptureBufferInfo"}, + {0x00410040, NULL, "ReceiveCaptureBufferInfo"}, + {0x00420080, NULL, "SleepSystem"}, + {0x00430040, NULL, "NotifyToWait"}, + {0x00440000, NULL, "GetSharedFont"}, + {0x00450040, NULL, "GetWirelessRebootInfo"}, + {0x00460104, NULL, "Wrap"}, + {0x00470104, NULL, "Unwrap"}, + {0x00480100, NULL, "GetProgramInfo"}, + {0x00490180, NULL, "Reboot"}, + {0x004A0040, NULL, "GetCaptureInfo"}, + {0x004B00C2, NULL, "AppletUtility"}, + {0x004C0000, NULL, "SetFatalErrDispMode"}, + {0x004D0080, NULL, "GetAppletProgramInfo"}, + {0x004E0000, NULL, "HardwareResetAsync"}, }; -// Returns handle to APT Mutex. Not imlemented. -Syscall::Result Interface::GetLockHandle() { - return 0x00000000; +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Interface class + +Interface::Interface() { + Register(FunctionTable, ARRAY_SIZE(FunctionTable)); } -/** - * Called when svcSendSyncRequest is called, loads command buffer and executes comand - * @return Return result of svcSendSyncRequest passed back to user app - */ -Syscall::Result Interface::Sync() { - Syscall::Result res = 0; - u32* cmd_buff = (u32*)HLE::GetPointer(HLE::CMD_BUFFER_ADDR + CMD_OFFSET); - - switch(cmd_buff[0]) { - case CMD_HEADER_INIT: - NOTICE_LOG(OSHLE, "APT_U::Sync - Initialize"); - break; - - case CMD_HEADER_GET_LOCK_HANDLE: - NOTICE_LOG(OSHLE, "APT_U::Sync - GetLockHandle"); - cmd_buff[5] = GetLockHandle(); - break; - - default: - ERROR_LOG(OSHLE, "APT_U::Sync - Unknown command 0x%08X", cmd_buff[0]); - res = -1; - break; - } - - return res; +Interface::~Interface() { } - -} +} // namespace diff --git a/src/core/hle/service/apt.h b/src/core/hle/service/apt.h index 2be5a7e15d..9f0245cc84 100644 --- a/src/core/hle/service/apt.h +++ b/src/core/hle/service/apt.h @@ -20,29 +20,9 @@ namespace APT_U { class Interface : public Service::Interface { public: - Interface() { - } + Interface(); - ~Interface() { - } - - enum { - CMD_OFFSET = 0x00000080, - - CMD_HEADER_INIT = 0x00020080, ///< Initialize service - CMD_HEADER_GET_LOCK_HANDLE = 0x00010040, ///< Get service Mutex - CMD_HEADER_ENABLE = 0x00030040, ///< Enable service - CMD_HEADER_INQUIRE_NOTIFICATION = 0x000B0040, ///< Inquire notification - CMD_HEADER_PREPARE_TO_JUMP_TO_HOME_MENU = 0x002B0000, ///< Prepare to jump to home menu - CMD_HEADER_JUMP_TO_HOME_MENU = 0x002C0044, ///< Jump to home menu - CMD_HEADER_NOTIFY_TO_WAIT = 0x00430040, ///< Notify to wait - CMD_HEADER_APPLET_UTILITY = 0x004B00C2, ///< Applet utility - CMD_HEADER_GLANCE_PARAMETER = 0x000E0080, ///< Glance parameter - CMD_HEADER_RECEIVE_PARAMETER = 0x000D0080, ///< Receive parameter - CMD_HEADER_REPLY_SLEEP_QUERY = 0x003E0080, ///< Reply sleep query - CMD_HEADER_PREPARE_TO_CLOSE_APP = 0x00220040, ///< Prepare to close application - CMD_HEADER_CLOSE_APP = 0x00270044, ///< Close application - }; + ~Interface(); /** * Gets the string port name used by CTROS for the APT service @@ -52,12 +32,6 @@ public: return "APT:U"; } - /** - * Called when svcSendSyncRequest is called, loads command buffer and executes comand - * @return Return result of svcSendSyncRequest passed back to user app - */ - Syscall::Result Sync(); - private: Syscall::Result GetLockHandle(); diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 9368a9f0f5..3b256aa3e8 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -17,7 +17,9 @@ namespace Service { -typedef s32 NativeUID; ///< Native handle for a service +typedef s32 NativeUID; ///< Native handle for a service + +static const int kCommandHeaderOffset = 0x80; ///< Offset into command buffer of header class Manager; @@ -26,6 +28,9 @@ class Interface { friend class Manager; public: + Interface() { + } + virtual ~Interface() { } @@ -49,7 +54,24 @@ public: * Called when svcSendSyncRequest is called, loads command buffer and executes comand * @return Return result of svcSendSyncRequest passed back to user app */ - virtual Syscall::Result Sync() = 0; + Syscall::Result Sync() { + u32* cmd_buff = (u32*)HLE::GetPointer(HLE::CMD_BUFFER_ADDR + kCommandHeaderOffset); + auto itr = m_functions.find(cmd_buff[0]); + + if (itr == m_functions.end()) { + ERROR_LOG(OSHLE, "Unknown/unimplemented function: port=%s, command=0x%08X!", + GetPortName().c_str(), cmd_buff[0]); + return -1; + } + if (itr->second.func == NULL) { + ERROR_LOG(OSHLE, "Unimplemented function: port=%s, name=%s!", + GetPortName().c_str(), itr->second.name.c_str()); + } + + itr->second.func(); + + return 0; // TODO: Implement return from actual function + } protected: /** @@ -64,6 +86,8 @@ protected: private: u32 m_uid; std::map m_functions; + + DISALLOW_COPY_AND_ASSIGN(Interface); }; /// Simple class to manage accessing services from ports and UID handles diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp new file mode 100644 index 0000000000..bb6c08b78f --- /dev/null +++ b/src/core/hle/service/srv.cpp @@ -0,0 +1,55 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include "core/hle/hle.h" +#include "core/hle/service/srv.h" +#include "core/hle/service/service.h" + + +namespace SRV { + +void Initialize() { + NOTICE_LOG(OSHLE, "SRV::Sync - Initialize"); +} + +void GetServiceHandle() { + Syscall::Result res = 0; + u32* cmd_buff = (u32*)HLE::GetPointer(HLE::CMD_BUFFER_ADDR + Service::kCommandHeaderOffset); + + const char* port_name = (const char*)&cmd_buff[1]; + Service::Interface* service = Service::g_manager->FetchFromPortName(port_name); + + NOTICE_LOG(OSHLE, "SRV::Sync - GetHandle - port: %s, handle: 0x%08X", port_name, + service->GetUID()); + + if (NULL != service) { + cmd_buff[3] = service->GetUID(); + } else { + ERROR_LOG(OSHLE, "Service %s does not exist", port_name); + res = -1; + } + cmd_buff[1] = res; + + //return res; +} + +const HLE::FunctionDef FunctionTable[] = { + {0x00010002, Initialize, "Initialize"}, + {0x00020000, NULL, "GetProcSemaphore"}, + {0x00030100, NULL, "RegisterService"}, + {0x000400C0, NULL, "UnregisterService"}, + {0x00050100, GetServiceHandle, "GetServiceHandle"}, +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Interface class + +Interface::Interface() { + Register(FunctionTable, ARRAY_SIZE(FunctionTable)); +} + +Interface::~Interface() { +} + +} // namespace diff --git a/src/core/hle/service/srv.h b/src/core/hle/service/srv.h new file mode 100644 index 0000000000..b4c5a0c171 --- /dev/null +++ b/src/core/hle/service/srv.h @@ -0,0 +1,39 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include "core/hle/service/service.h" + +namespace SRV { + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Interface to "SRV" service + +class Interface : public Service::Interface { + +public: + + Interface(); + + ~Interface(); + + /** + * Gets the string name used by CTROS for a service + * @return Port name of service + */ + std::string GetPortName() const { + return "srv:"; + } + + /** + * Called when svcSendSyncRequest is called, loads command buffer and executes comand + * @return Return result of svcSendSyncRequest passed back to user app + */ + Syscall::Result Sync(); + +private: + + DISALLOW_COPY_AND_ASSIGN(Interface); +}; + +} // namespace