diff options
Diffstat (limited to 'src/core/hle/service')
-rw-r--r-- | src/core/hle/service/apt.cpp | 116 | ||||
-rw-r--r-- | src/core/hle/service/apt.h | 41 | ||||
-rw-r--r-- | src/core/hle/service/gsp.cpp | 59 | ||||
-rw-r--r-- | src/core/hle/service/gsp.h | 35 | ||||
-rw-r--r-- | src/core/hle/service/hid.cpp | 33 | ||||
-rw-r--r-- | src/core/hle/service/hid.h | 37 | ||||
-rw-r--r-- | src/core/hle/service/service.cpp | 94 | ||||
-rw-r--r-- | src/core/hle/service/service.h | 143 | ||||
-rw-r--r-- | src/core/hle/service/srv.cpp | 58 | ||||
-rw-r--r-- | src/core/hle/service/srv.h | 40 |
10 files changed, 656 insertions, 0 deletions
diff --git a/src/core/hle/service/apt.cpp b/src/core/hle/service/apt.cpp new file mode 100644 index 000000000..4f8d7248d --- /dev/null +++ b/src/core/hle/service/apt.cpp @@ -0,0 +1,116 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + + +#include "common/log.h" + +#include "core/hle/hle.h" +#include "core/hle/service/apt.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace APT_U + +namespace APT_U { + +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"}, +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Interface class + +Interface::Interface() { + Register(FunctionTable, ARRAY_SIZE(FunctionTable)); +} + +Interface::~Interface() { +} + +} // namespace diff --git a/src/core/hle/service/apt.h b/src/core/hle/service/apt.h new file mode 100644 index 000000000..e74baac0c --- /dev/null +++ b/src/core/hle/service/apt.h @@ -0,0 +1,41 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace APT_U + +namespace APT_U { + +// Application and title launching service. These services handle signaling for home/power button as +// well. Only one session for either APT service can be open at a time, normally processes close the +// service handle immediately once finished using the service. The commands for APT:U and APT:S are +// exactly the same, however certain commands are only accessible with APT:S(NS module will call +// svcBreak when the command isn't accessible). See http://3dbrew.org/wiki/NS#APT_Services. + +/// Interface to "APT:U" service +class Interface : public Service::Interface { +public: + + Interface(); + + ~Interface(); + + /** + * Gets the string port name used by CTROS for the service + * @return Port name of service + */ + std::string GetPortName() const { + return "APT:U"; + } + +private: + + DISALLOW_COPY_AND_ASSIGN(Interface); +}; + +} // namespace diff --git a/src/core/hle/service/gsp.cpp b/src/core/hle/service/gsp.cpp new file mode 100644 index 000000000..7c80ab8b5 --- /dev/null +++ b/src/core/hle/service/gsp.cpp @@ -0,0 +1,59 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + + +#include "common/log.h" + +#include "core/hle/hle.h" +#include "core/hle/service/gsp.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace GSP_GPU + +namespace GSP_GPU { + +const HLE::FunctionDef FunctionTable[] = { + {0x00010082, NULL, "WriteHWRegs"}, + {0x00020084, NULL, "WriteHWRegsWithMask"}, + {0x00030082, NULL, "WriteHWRegRepeat"}, + {0x00040080, NULL, "ReadHWRegs"}, + {0x00050200, NULL, "SetBufferSwap"}, + {0x00060082, NULL, "SetCommandList"}, + {0x000700C2, NULL, "RequestDma"}, + {0x00080082, NULL, "FlushDataCache"}, + {0x00090082, NULL, "InvalidateDataCache"}, + {0x000A0044, NULL, "RegisterInterruptEvents"}, + {0x000B0040, NULL, "SetLcdForceBlack"}, + {0x000C0000, NULL, "TriggerCmdReqQueue"}, + {0x000D0140, NULL, "SetDisplayTransfer"}, + {0x000E0180, NULL, "SetTextureCopy"}, + {0x000F0200, NULL, "SetMemoryFill"}, + {0x00100040, NULL, "SetAxiConfigQoSMode"}, + {0x00110040, NULL, "SetPerfLogMode"}, + {0x00120000, NULL, "GetPerfLog"}, + {0x00130042, NULL, "RegisterInterruptRelayQueue"}, + {0x00140000, NULL, "UnregisterInterruptRelayQueue"}, + {0x00150002, NULL, "TryAcquireRight"}, + {0x00160042, NULL, "AcquireRight"}, + {0x00170000, NULL, "ReleaseRight"}, + {0x00180000, NULL, "ImportDisplayCaptureInfo"}, + {0x00190000, NULL, "SaveVramSysArea"}, + {0x001A0000, NULL, "RestoreVramSysArea"}, + {0x001B0000, NULL, "ResetGpuCore"}, + {0x001C0040, NULL, "SetLedForceOff"}, + {0x001D0040, NULL, "SetTestCommand"}, + {0x001E0080, NULL, "SetInternalPriorities"}, +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Interface class + +Interface::Interface() { + Register(FunctionTable, ARRAY_SIZE(FunctionTable)); +} + +Interface::~Interface() { +} + +} // namespace diff --git a/src/core/hle/service/gsp.h b/src/core/hle/service/gsp.h new file mode 100644 index 000000000..3b1846082 --- /dev/null +++ b/src/core/hle/service/gsp.h @@ -0,0 +1,35 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace GSP_GPU + +namespace GSP_GPU { + +/// Interface to "srv:" service +class Interface : public Service::Interface { +public: + + Interface(); + + ~Interface(); + + /** + * Gets the string port name used by CTROS for the service + * @return Port name of service + */ + std::string GetPortName() const { + return "gsp::Gpu"; + } + +private: + + DISALLOW_COPY_AND_ASSIGN(Interface); +}; + +} // namespace diff --git a/src/core/hle/service/hid.cpp b/src/core/hle/service/hid.cpp new file mode 100644 index 000000000..2d823dd16 --- /dev/null +++ b/src/core/hle/service/hid.cpp @@ -0,0 +1,33 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include "common/log.h" + +#include "core/hle/hle.h" +#include "core/hle/service/hid.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace HID_User + +namespace HID_User { + +const HLE::FunctionDef FunctionTable[] = { + {0x000A0000, NULL, "GetIPCHandles"}, + {0x00110000, NULL, "EnableAccelerometer"}, + {0x00130000, NULL, "EnableGyroscopeLow"}, + {0x00150000, NULL, "GetGyroscopeLowRawToDpsCoefficient"}, + {0x00160000, NULL, "GetGyroscopeLowCalibrateParam"}, +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Interface class + +Interface::Interface() { + Register(FunctionTable, ARRAY_SIZE(FunctionTable)); +} + +Interface::~Interface() { +} + +} // namespace diff --git a/src/core/hle/service/hid.h b/src/core/hle/service/hid.h new file mode 100644 index 000000000..746c1b1fc --- /dev/null +++ b/src/core/hle/service/hid.h @@ -0,0 +1,37 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace HID_User + +// This service is used for interfacing to physical user controls... perhaps "Human Interface +// Devices"? Uses include game pad controls, accelerometers, gyroscopes, etc. + +namespace HID_User { + +class Interface : public Service::Interface { +public: + + Interface(); + + ~Interface(); + + /** + * Gets the string port name used by CTROS for the service + * @return Port name of service + */ + std::string GetPortName() const { + return "hid:USER"; + } + +private: + + DISALLOW_COPY_AND_ASSIGN(Interface); +}; + +} // namespace diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp new file mode 100644 index 000000000..e6605a398 --- /dev/null +++ b/src/core/hle/service/service.cpp @@ -0,0 +1,94 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include "common/common.h" +#include "common/log.h" +#include "common/string_util.h" + +#include "core/hle/hle.h" +#include "core/hle/service/service.h" +#include "core/hle/service/apt.h" +#include "core/hle/service/gsp.h" +#include "core/hle/service/hid.h" +#include "core/hle/service/srv.h" + +namespace Service { + +Manager* g_manager = NULL; ///< Service manager + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Service Manager class + +Manager::Manager() { +} + +Manager::~Manager() { + for(Interface* service : m_services) { + DeleteService(service->GetPortName()); + } +} + +/// Add a service to the manager (does not create it though) +void Manager::AddService(Interface* service) { + int index = m_services.size(); + u32 new_uid = GetUIDFromIndex(index); + + m_services.push_back(service); + + m_port_map[service->GetPortName()] = new_uid; + service->m_uid = new_uid; +} + +/// Removes a service from the manager, also frees memory +void Manager::DeleteService(std::string port_name) { + auto service = FetchFromPortName(port_name); + + m_services.erase(m_services.begin() + GetIndexFromUID(service->m_uid)); + m_port_map.erase(port_name); + + delete service; +} + +/// Get a Service Interface from its UID +Interface* Manager::FetchFromUID(u32 uid) { + int index = GetIndexFromUID(uid); + if (index < (int)m_services.size()) { + return m_services[index]; + } + return NULL; +} + +/// Get a Service Interface from its port +Interface* Manager::FetchFromPortName(std::string port_name) { + auto itr = m_port_map.find(port_name); + if (itr == m_port_map.end()) { + return NULL; + } + return FetchFromUID(itr->second); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Module interface + +/// Initialize ServiceManager +void Init() { + g_manager = new Manager; + + g_manager->AddService(new SRV::Interface); + g_manager->AddService(new APT_U::Interface); + g_manager->AddService(new GSP_GPU::Interface); + g_manager->AddService(new HID_User::Interface); + + NOTICE_LOG(HLE, "Services initialized OK"); +} + +/// Shutdown ServiceManager +void Shutdown() { + delete g_manager; + NOTICE_LOG(HLE, "Services shutdown OK"); +} + + +} diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h new file mode 100644 index 000000000..9cbf8b6fa --- /dev/null +++ b/src/core/hle/service/service.h @@ -0,0 +1,143 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include <vector> +#include <map> +#include <string> + +#include "common/common.h" +#include "common/common_types.h" +#include "core/hle/syscall.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace Service + +namespace Service { + +typedef s32 NativeUID; ///< Native handle for a service + +static const int kMaxPortSize = 0x08; ///< Maximum size of a port name (8 characters) +static const int kCommandHeaderOffset = 0x80; ///< Offset into command buffer of header + +class Manager; + +/// Interface to a CTROS service +class Interface { + friend class Manager; +public: + + Interface() { + } + + virtual ~Interface() { + } + + /** + * Gets the UID for the serice + * @return UID of service in native format + */ + NativeUID GetUID() const { + return (NativeUID)m_uid; + } + + /** + * Gets the string name used by CTROS for a service + * @return Port name of service + */ + virtual std::string GetPortName() const { + return "[UNKNOWN SERVICE PORT]"; + } + + /** + * Called when svcSendSyncRequest is called, loads command buffer and executes comand + * @return Return result of svcSendSyncRequest passed back to user app + */ + 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()); + return -1; + } + + itr->second.func(); + + return 0; // TODO: Implement return from actual function + } + +protected: + /** + * Registers the functions in the service + */ + void Register(const HLE::FunctionDef* functions, int len) { + for (int i = 0; i < len; i++) { + m_functions[functions[i].id] = functions[i]; + } + } + +private: + u32 m_uid; + std::map<u32, HLE::FunctionDef> m_functions; + + DISALLOW_COPY_AND_ASSIGN(Interface); +}; + +/// Simple class to manage accessing services from ports and UID handles +class Manager { + +public: + Manager(); + + ~Manager(); + + /// Add a service to the manager (does not create it though) + void AddService(Interface* service); + + /// Removes a service from the manager (does not delete it though) + void DeleteService(std::string port_name); + + /// Get a Service Interface from its UID + Interface* FetchFromUID(u32 uid); + + /// Get a Service Interface from its port + Interface* FetchFromPortName(std::string port_name); + +private: + + /// Convert an index into m_services vector into a UID + static u32 GetUIDFromIndex(const int index) { + return index | 0x10000000; + } + + /// Convert a UID into an index into m_services + static int GetIndexFromUID(const u32 uid) { + return uid & 0x0FFFFFFF; + } + + std::vector<Interface*> m_services; + std::map<std::string, u32> m_port_map; + + DISALLOW_COPY_AND_ASSIGN(Manager); +}; + +/// Initialize ServiceManager +void Init(); + +/// Shutdown ServiceManager +void Shutdown(); + + +extern Manager* g_manager; ///< Service manager + + +} // namespace diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp new file mode 100644 index 000000000..579ea4a34 --- /dev/null +++ b/src/core/hle/service/srv.cpp @@ -0,0 +1,58 @@ +// 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 + +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); + + std::string port_name = std::string((const char*)&cmd_buff[1], 0, Service::kMaxPortSize); + Service::Interface* service = Service::g_manager->FetchFromPortName(port_name); + + NOTICE_LOG(OSHLE, "SRV::Sync - GetHandle - port: %s, handle: 0x%08X", port_name.c_str(), + service->GetUID()); + + if (NULL != service) { + cmd_buff[3] = service->GetUID(); + } else { + ERROR_LOG(OSHLE, "Service %s does not exist", port_name.c_str()); + 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 000000000..d9ac8fc88 --- /dev/null +++ b/src/core/hle/service/srv.h @@ -0,0 +1,40 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include "core/hle/service/service.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace SRV + +namespace SRV { + +/// Interface to "srv:" service +class Interface : public Service::Interface { + +public: + + Interface(); + + ~Interface(); + + /** + * Gets the string name used by CTROS for the 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 |