diff options
Diffstat (limited to 'src/core/hle/service')
42 files changed, 883 insertions, 362 deletions
diff --git a/src/core/hle/service/am_sys.cpp b/src/core/hle/service/am_sys.cpp index b244190a2..f9e3fe4b7 100644 --- a/src/core/hle/service/am_sys.cpp +++ b/src/core/hle/service/am_sys.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/logging/log.h" + #include "core/hle/hle.h" #include "core/hle/service/am_sys.h" diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index 5971f860b..09d463dd5 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -2,7 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/common_paths.h" #include "common/file_util.h" +#include "common/logging/log.h" #include "core/hle/service/service.h" #include "core/hle/service/apt/apt.h" @@ -32,23 +34,31 @@ static Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem; 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::Event> start_event; ///< APT start event + static std::vector<u8> shared_font; +static u32 cpu_percent; ///< 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(); + cmd_buff[4] = Kernel::g_handle_table.Create(start_event).MoveFrom(); - // TODO(bunnei): Check if these events are cleared/signaled every time Initialize is called. + // TODO(bunnei): Check if these events are cleared every time Initialize is called. notification_event->Clear(); - pause_event->Signal(); // Fire start event + start_event->Clear(); ASSERT_MSG((nullptr != lock), "Cannot initialize without lock"); 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) { @@ -74,7 +84,7 @@ void NotifyToWait(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 app_id = cmd_buff[1]; // TODO(Subv): Verify this, it seems to get SWKBD and Home Menu further. - pause_event->Signal(); + start_event->Signal(); cmd_buff[1] = RESULT_SUCCESS.raw; // No error LOG_WARNING(Service_APT, "(STUBBED) app_id=%u", app_id); @@ -190,7 +200,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 +246,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 +262,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); @@ -264,21 +304,29 @@ void APTInit() { file.ReadBytes(shared_font.data(), (size_t)file.GetSize()); // Create shared font memory object - shared_font_mem = Kernel::SharedMemory::Create("APT_U:shared_font_mem"); + using Kernel::MemoryPermission; + shared_font_mem = Kernel::SharedMemory::Create(3 * 1024 * 1024, // 3MB + MemoryPermission::ReadWrite, MemoryPermission::Read, "APT_U:shared_font_mem"); } else { LOG_WARNING(Service_APT, "Unable to load shared font: %s", filepath.c_str()); shared_font_mem = nullptr; } 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"); + start_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Start"); } -void APTShutdown() { - +void Shutdown() { + shared_font.clear(); + shared_font_mem = nullptr; + lock = nullptr; + notification_event = nullptr; + start_event = nullptr; } } // namespace APT 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 @@ -179,6 +182,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: * 1 : Unknown, but clearly used for something @@ -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/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp index 3fd348651..396d1f04a 100644 --- a/src/core/hle/service/apt/apt_s.cpp +++ b/src/core/hle/service/apt/apt_s.cpp @@ -3,9 +3,6 @@ // Refer to the license.txt file included. -#include "common/common.h" -#include "common/file_util.h" - #include "core/hle/hle.h" #include "core/hle/service/apt/apt.h" #include "core/hle/service/apt/apt_s.h" diff --git a/src/core/hle/service/apt/apt_u.cpp b/src/core/hle/service/apt/apt_u.cpp index 5ab23801e..d006b5930 100644 --- a/src/core/hle/service/apt/apt_u.cpp +++ b/src/core/hle/service/apt/apt_u.cpp @@ -3,7 +3,6 @@ // Refer to the license.txt file included. -#include "common/common.h" #include "common/file_util.h" #include "core/hle/service/apt/apt.h" diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp index 6adadb224..2d26c9330 100644 --- a/src/core/hle/service/cfg/cfg.cpp +++ b/src/core/hle/service/cfg/cfg.cpp @@ -4,12 +4,16 @@ #include <algorithm> -#include "core/hle/service/fs/archive.h" -#include "core/hle/service/service.h" +#include "common/logging/log.h" +#include "common/string_util.h" + +#include "core/file_sys/file_backend.h" #include "core/hle/service/cfg/cfg.h" #include "core/hle/service/cfg/cfg_i.h" #include "core/hle/service/cfg/cfg_s.h" #include "core/hle/service/cfg/cfg_u.h" +#include "core/hle/service/fs/archive.h" +#include "core/hle/service/service.h" namespace Service { namespace CFG { @@ -53,12 +57,12 @@ ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, u8* output) { }); if (itr == std::end(config->block_entries)) { - LOG_ERROR(Service_CFG, "Config block %u with flags %u was not found", block_id, flag); + LOG_ERROR(Service_CFG, "Config block 0x%X with flags %u and size %u was not found", block_id, flag, size); return ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent); } if (itr->size != size) { - LOG_ERROR(Service_CFG, "Invalid size %u for config block %u with flags %u", size, block_id, flag); + LOG_ERROR(Service_CFG, "Invalid size %u for config block 0x%X with flags %u", size, block_id, flag); return ResultCode(ErrorDescription::InvalidSize, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent); } @@ -170,7 +174,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); @@ -207,6 +211,7 @@ void CFGInit() { // Initialize the Username block // TODO(Subv): Initialize this directly in the variable when MSVC supports char16_t string literals + memset(&CONSOLE_USERNAME_BLOCK, 0, sizeof(CONSOLE_USERNAME_BLOCK)); CONSOLE_USERNAME_BLOCK.ng_word = 0; CONSOLE_USERNAME_BLOCK.zero = 0; @@ -218,8 +223,7 @@ void CFGInit() { FormatConfig(); } -void CFGShutdown() { - +void Shutdown() { } } // namespace CFG 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/cfg/cfg_u.cpp b/src/core/hle/service/cfg/cfg_u.cpp index c8c1c5b17..221de9918 100644 --- a/src/core/hle/service/cfg/cfg_u.cpp +++ b/src/core/hle/service/cfg/cfg_u.cpp @@ -3,7 +3,9 @@ // Refer to the license.txt file included. #include "common/file_util.h" +#include "common/logging/log.h" #include "common/string_util.h" + #include "core/settings.h" #include "core/file_sys/archive_systemsavedata.h" #include "core/hle/hle.h" diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp index 0b3603ce1..fafb43a2f 100644 --- a/src/core/hle/service/dsp_dsp.cpp +++ b/src/core/hle/service/dsp_dsp.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/logging/log.h" + #include "core/hle/hle.h" #include "core/hle/kernel/event.h" #include "core/hle/service/dsp_dsp.h" @@ -11,7 +13,7 @@ namespace DSP_DSP { -static u32 read_pipe_count = 0; +static u32 read_pipe_count; static Kernel::SharedPtr<Kernel::Event> semaphore_event; static Kernel::SharedPtr<Kernel::Event> interrupt_event; @@ -40,9 +42,9 @@ static void ConvertProcessAddressFromDspDram(Service::Interface* self) { u32 addr = cmd_buff[1]; cmd_buff[1] = 0; // No error - cmd_buff[2] = (addr << 1) + (Memory::DSP_MEMORY_VADDR + 0x40000); + cmd_buff[2] = (addr << 1) + (Memory::DSP_RAM_VADDR + 0x40000); - LOG_WARNING(Service_DSP, "(STUBBED) called with address %u", addr); + LOG_WARNING(Service_DSP, "(STUBBED) called with address 0x%08X", addr); } /** @@ -60,12 +62,19 @@ static void ConvertProcessAddressFromDspDram(Service::Interface* self) { static void LoadComponent(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); + u32 size = cmd_buff[1]; + u32 unk1 = cmd_buff[2]; + u32 unk2 = cmd_buff[3]; + u32 new_size = cmd_buff[4]; + u32 buffer = cmd_buff[5]; + cmd_buff[1] = 0; // No error cmd_buff[2] = 1; // Pretend that we actually loaded the DSP firmware // TODO(bunnei): Implement real DSP firmware loading - LOG_WARNING(Service_DSP, "(STUBBED) called"); + LOG_WARNING(Service_DSP, "(STUBBED) called size=0x%X, unk1=0x%08X, unk2=0x%08X, new_size=0x%X, buffer=0x%08X", + size, unk1, unk2, new_size, buffer); } /** @@ -84,6 +93,33 @@ static void GetSemaphoreEventHandle(Service::Interface* self) { } /** + * 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%X, process=0x%08X", + address, size, process); +} + +/** * DSP_DSP::RegisterInterruptEvents service function * Inputs: * 1 : Parameter 0 (purpose unknown) @@ -95,6 +131,10 @@ static void GetSemaphoreEventHandle(Service::Interface* self) { static void RegisterInterruptEvents(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); + u32 param0 = cmd_buff[1]; + u32 param1 = cmd_buff[2]; + u32 event_handle = cmd_buff[4]; + auto evt = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]); if (evt != nullptr) { interrupt_event = evt; @@ -106,7 +146,7 @@ static void RegisterInterruptEvents(Service::Interface* self) { cmd_buff[1] = -1; } - LOG_WARNING(Service_DSP, "(STUBBED) called"); + LOG_WARNING(Service_DSP, "(STUBBED) called param0=%u, param1=%u, event_handle=0x%08X", param0, param1, event_handle); } /** @@ -147,7 +187,7 @@ static void WriteProcessPipe(Service::Interface* self) { cmd_buff[1] = RESULT_SUCCESS.raw; // No error - LOG_WARNING(Service_DSP, "(STUBBED) called number=%u, size=0x%08X, new_size=0x%08X, buffer=0x%08X", + LOG_WARNING(Service_DSP, "(STUBBED) called number=%u, size=0x%X, new_size=0x%X, buffer=0x%08X", number, size, new_size, buffer); } @@ -165,6 +205,8 @@ static void WriteProcessPipe(Service::Interface* self) { static void ReadPipeIfPossible(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); + u32 unk1 = cmd_buff[1]; + u32 unk2 = cmd_buff[2]; u32 size = cmd_buff[3] & 0xFFFF;// Lower 16 bits are size VAddr addr = cmd_buff[0x41]; @@ -190,7 +232,8 @@ static void ReadPipeIfPossible(Service::Interface* self) { cmd_buff[1] = 0; // No error cmd_buff[2] = (read_pipe_count - initial_size) * sizeof(u16); - LOG_WARNING(Service_DSP, "(STUBBED) called size=0x%08X, buffer=0x%08X", size, addr); + LOG_WARNING(Service_DSP, "(STUBBED) called unk1=0x%08X, unk2=0x%08X, size=0x%X, buffer=0x%08X", + unk1, unk2, size, addr); } /** @@ -225,7 +268,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 +285,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/err_f.cpp b/src/core/hle/service/err_f.cpp index 58c5acd1e..e8c06c1cf 100644 --- a/src/core/hle/service/err_f.cpp +++ b/src/core/hle/service/err_f.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/logging/log.h" + #include "core/hle/hle.h" #include "core/hle/service/err_f.h" diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index b0fd834c7..6d4a9c7c9 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -9,6 +9,7 @@ #include "common/common_types.h" #include "common/file_util.h" +#include "common/logging/log.h" #include "common/make_unique.h" #include "common/math_util.h" @@ -78,6 +79,11 @@ enum class DirectoryCommand : u32 { Close = 0x08020000, }; +File::File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path & path) + : path(path), priority(0), backend(std::move(backend)) {} + +File::~File() {} + ResultVal<bool> File::SyncRequest() { u32* cmd_buff = Kernel::GetCommandBuffer(); FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]); @@ -172,6 +178,11 @@ ResultVal<bool> File::SyncRequest() { return MakeResult<bool>(false); } +Directory::Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path & path) + : path(path), backend(std::move(backend)) {} + +Directory::~Directory() {} + ResultVal<bool> Directory::SyncRequest() { u32* cmd_buff = Kernel::GetCommandBuffer(); DirectoryCommand cmd = static_cast<DirectoryCommand>(cmd_buff[0]); diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index b00f0fd60..faab0cb79 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -45,31 +45,27 @@ typedef u64 ArchiveHandle; class File : public Kernel::Session { public: - File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path) - : path(path), priority(0), backend(std::move(backend)) { - } + File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path); + ~File(); std::string GetName() const override { return "Path: " + path.DebugStr(); } + ResultVal<bool> SyncRequest() override; FileSys::Path path; ///< Path of the file u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface - - ResultVal<bool> SyncRequest() override; }; class Directory : public Kernel::Session { public: - Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path) - : path(path), backend(std::move(backend)) { - } + Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path); + ~Directory(); std::string GetName() const override { return "Directory: " + path.DebugStr(); } + ResultVal<bool> SyncRequest() override; FileSys::Path path; ///< Path of the directory std::unique_ptr<FileSys::DirectoryBackend> backend; ///< File backend interface - - ResultVal<bool> SyncRequest() override; }; /** diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index d8d1d5547..0d2a426b0 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -2,10 +2,13 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/common.h" +#include "common/assert.h" +#include "common/common_types.h" #include "common/file_util.h" +#include "common/logging/log.h" #include "common/scope_exit.h" #include "common/string_util.h" + #include "core/hle/result.h" #include "core/hle/service/fs/archive.h" #include "core/hle/service/fs/fs_user.h" @@ -20,6 +23,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 +220,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 +429,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 +516,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 +578,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 +606,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 +760,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..c11c5faba 100644 --- a/src/core/hle/service/gsp_gpu.cpp +++ b/src/core/hle/service/gsp_gpu.cpp @@ -5,6 +5,7 @@ #include "common/bit_field.h" #include "core/mem_map.h" +#include "core/memory.h" #include "core/hle/kernel/event.h" #include "core/hle/kernel/shared_memory.h" #include "core/hle/result.h" @@ -30,13 +31,12 @@ namespace GSP_GPU { Kernel::SharedPtr<Kernel::Event> g_interrupt_event; /// GSP shared memoryings Kernel::SharedPtr<Kernel::SharedMemory> g_shared_memory; -/// Thread index into interrupt relay queue, 1 is arbitrary -u32 g_thread_id = 1; +/// Thread index into interrupt relay queue +u32 g_thread_id = 0; /// Gets a pointer to a thread command buffer in GSP shared memory static inline u8* GetCommandBuffer(u32 thread_id) { - ResultVal<u8*> ptr = g_shared_memory->GetPointer(0x800 + (thread_id * sizeof(CommandBuffer))); - return ptr.ValueOr(nullptr); + return g_shared_memory->GetPointer(0x800 + (thread_id * sizeof(CommandBuffer))); } static inline FrameBufferUpdate* GetFrameBufferInfo(u32 thread_id, u32 screen_index) { @@ -44,14 +44,14 @@ static inline FrameBufferUpdate* GetFrameBufferInfo(u32 thread_id, u32 screen_in // For each thread there are two FrameBufferUpdate fields u32 offset = 0x200 + (2 * thread_id + screen_index) * sizeof(FrameBufferUpdate); - ResultVal<u8*> ptr = g_shared_memory->GetPointer(offset); - return reinterpret_cast<FrameBufferUpdate*>(ptr.ValueOr(nullptr)); + u8* ptr = g_shared_memory->GetPointer(offset); + return reinterpret_cast<FrameBufferUpdate*>(ptr); } /// Gets a pointer to the interrupt relay queue for a given thread index static inline InterruptRelayQueue* GetInterruptRelayQueue(u32 thread_id) { - ResultVal<u8*> ptr = g_shared_memory->GetPointer(sizeof(InterruptRelayQueue) * thread_id); - return reinterpret_cast<InterruptRelayQueue*>(ptr.ValueOr(nullptr)); + u8* ptr = g_shared_memory->GetPointer(sizeof(InterruptRelayQueue) * thread_id); + return reinterpret_cast<InterruptRelayQueue*>(ptr); } /** @@ -204,16 +204,18 @@ static void ReadHWRegs(Service::Interface* self) { static void SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) { u32 base_address = 0x400000; + PAddr phys_address_left = Memory::VirtualToPhysicalAddress(info.address_left); + PAddr phys_address_right = Memory::VirtualToPhysicalAddress(info.address_right); if (info.active_fb == 0) { WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_left1)), 4, - &info.address_left); + &phys_address_left); WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_right1)), 4, - &info.address_right); + &phys_address_right); } else { WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_left2)), 4, - &info.address_left); + &phys_address_left); WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_right2)), 4, - &info.address_right); + &phys_address_right); } WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].stride)), 4, &info.stride); @@ -265,6 +267,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); } /** @@ -273,7 +278,7 @@ static void FlushDataCache(Service::Interface* self) { * 1 : "Flags" field, purpose is unknown * 3 : Handle to GSP synchronization event * Outputs: - * 0 : Result of function, 0 on success, otherwise error code + * 1 : Result of function, 0x2A07 on success, otherwise error code * 2 : Thread index into GSP command buffer * 4 : Handle to GSP shared memory */ @@ -283,11 +288,12 @@ static void RegisterInterruptRelayQueue(Service::Interface* self) { g_interrupt_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[3]); ASSERT_MSG((g_interrupt_event != nullptr), "handle is not valid!"); - g_shared_memory = Kernel::SharedMemory::Create("GSPSharedMem"); Handle shmem_handle = Kernel::g_handle_table.Create(g_shared_memory).MoveFrom(); - cmd_buff[1] = 0x2A07; // Value verified by 3dmoo team, purpose unknown, but needed for GSP init + // This specific code is required for a successful initialization, rather than 0 + cmd_buff[1] = ResultCode((ErrorDescription)519, ErrorModule::GX, + ErrorSummary::Success, ErrorLevel::Success).raw; cmd_buff[2] = g_thread_id++; // Thread ID cmd_buff[4] = shmem_handle; // GSP shared memory @@ -522,8 +528,12 @@ Interface::Interface() { Register(FunctionTable); g_interrupt_event = 0; - g_shared_memory = 0; - g_thread_id = 1; + + using Kernel::MemoryPermission; + g_shared_memory = Kernel::SharedMemory::Create(0x1000, MemoryPermission::ReadWrite, + MemoryPermission::ReadWrite, "GSPSharedMem"); + + g_thread_id = 0; } } // namespace diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 138603d9b..9695f7e56 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/logging/log.h" + #include "core/hle/service/service.h" #include "core/hle/service/hid/hid.h" #include "core/hle/service/hid/hid_spvr.h" @@ -20,17 +22,17 @@ namespace HID { static const int MAX_CIRCLEPAD_POS = 0x9C; ///< Max value for a circle pad position // Handle to shared memory region designated to HID_User service -static Kernel::SharedPtr<Kernel::SharedMemory> shared_mem = nullptr; +static Kernel::SharedPtr<Kernel::SharedMemory> shared_mem; // Event handles -static Kernel::SharedPtr<Kernel::Event> event_pad_or_touch_1 = nullptr; -static Kernel::SharedPtr<Kernel::Event> event_pad_or_touch_2 = nullptr; -static Kernel::SharedPtr<Kernel::Event> event_accelerometer = nullptr; -static Kernel::SharedPtr<Kernel::Event> event_gyroscope = nullptr; -static Kernel::SharedPtr<Kernel::Event> event_debug_pad = nullptr; +static Kernel::SharedPtr<Kernel::Event> event_pad_or_touch_1; +static Kernel::SharedPtr<Kernel::Event> event_pad_or_touch_2; +static Kernel::SharedPtr<Kernel::Event> event_accelerometer; +static Kernel::SharedPtr<Kernel::Event> event_gyroscope; +static Kernel::SharedPtr<Kernel::Event> event_debug_pad; -static u32 next_pad_index = 0; -static u32 next_touch_index = 0; +static u32 next_pad_index; +static u32 next_touch_index; // TODO(peachum): // Add a method for setting analog input from joystick device for the circle Pad. @@ -45,8 +47,8 @@ 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() { - SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer().ValueOr(nullptr)); +void Update() { + SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer()); const PadState state = VideoCore::g_emu_window->GetPadState(); if (mem == nullptr) { @@ -155,13 +157,15 @@ void GetSoundVolume(Service::Interface* self) { LOG_WARNING(Service_HID, "(STUBBED) called"); } -void HIDInit() { +void Init() { using namespace Kernel; AddService(new HID_U_Interface); AddService(new HID_SPVR_Interface); - shared_mem = SharedMemory::Create("HID:SharedMem"); + using Kernel::MemoryPermission; + shared_mem = SharedMemory::Create(0x1000, MemoryPermission::ReadWrite, + MemoryPermission::Read, "HID:SharedMem"); next_pad_index = 0; next_touch_index = 0; @@ -174,7 +178,13 @@ void HIDInit() { event_debug_pad = Event::Create(RESETTYPE_ONESHOT, "HID:EventDebugPad"); } -void HIDShutdown() { +void Shutdown() { + shared_mem = nullptr; + event_pad_or_touch_1 = nullptr; + event_pad_or_touch_2 = nullptr; + event_accelerometer = nullptr; + event_gyroscope = nullptr; + event_debug_pad = nullptr; } } // 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/ir/ir.cpp b/src/core/hle/service/ir/ir.cpp new file mode 100644 index 000000000..adfbb258d --- /dev/null +++ b/src/core/hle/service/ir/ir.cpp @@ -0,0 +1,52 @@ +// Copyright 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/service.h" +#include "core/hle/service/ir/ir.h" +#include "core/hle/service/ir/ir_rst.h" +#include "core/hle/service/ir/ir_u.h" +#include "core/hle/service/ir/ir_user.h" + +#include "core/hle/hle.h" +#include "core/hle/kernel/event.h" +#include "core/hle/kernel/shared_memory.h" + +namespace Service { +namespace IR { + +static Kernel::SharedPtr<Kernel::Event> handle_event; +static Kernel::SharedPtr<Kernel::SharedMemory> shared_memory; + +void GetHandles(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[1] = RESULT_SUCCESS.raw; + cmd_buff[2] = 0x4000000; + cmd_buff[3] = Kernel::g_handle_table.Create(Service::IR::shared_memory).MoveFrom(); + cmd_buff[4] = Kernel::g_handle_table.Create(Service::IR::handle_event).MoveFrom(); +} + +void Init() { + using namespace Kernel; + + AddService(new IR_RST_Interface); + AddService(new IR_U_Interface); + AddService(new IR_User_Interface); + + using Kernel::MemoryPermission; + shared_memory = SharedMemory::Create(0x1000, Kernel::MemoryPermission::ReadWrite, + Kernel::MemoryPermission::ReadWrite, "IR:SharedMemory"); + + // Create event handle(s) + handle_event = Event::Create(RESETTYPE_ONESHOT, "IR:HandleEvent"); +} + +void Shutdown() { + shared_memory = nullptr; + handle_event = nullptr; +} + +} // namespace IR + +} // namespace Service diff --git a/src/core/hle/service/ir/ir.h b/src/core/hle/service/ir/ir.h new file mode 100644 index 000000000..c16d963e7 --- /dev/null +++ b/src/core/hle/service/ir/ir.h @@ -0,0 +1,30 @@ +// Copyright 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/kernel/kernel.h" +#include "core/hle/service/service.h" + +namespace Service { +namespace IR { + +/** + * IR::GetHandles service function + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Translate header, used by the ARM11-kernel + * 3 : Shared memory handle + * 4 : Event handle + */ +void GetHandles(Interface* self); + +/// Initialize IR service +void Init(); + +/// Shutdown IR service +void Shutdown(); + +} // namespace IR +} // namespace Service diff --git a/src/core/hle/service/ir/ir_rst.cpp b/src/core/hle/service/ir/ir_rst.cpp new file mode 100644 index 000000000..96ae63420 --- /dev/null +++ b/src/core/hle/service/ir/ir_rst.cpp @@ -0,0 +1,24 @@ +// 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/ir/ir.h" +#include "core/hle/service/ir/ir_rst.h" + +namespace Service { +namespace IR { + +const Interface::FunctionInfo FunctionTable[] = { + {0x00010000, GetHandles, "GetHandles"}, + {0x00020080, nullptr, "Initialize"}, + {0x00030000, nullptr, "Shutdown"}, + {0x00090000, nullptr, "WriteToTwoFields"}, +}; + +IR_RST_Interface::IR_RST_Interface() { + Register(FunctionTable); +} + +} // namespace IR +} // namespace Service diff --git a/src/core/hle/service/ir_rst.h b/src/core/hle/service/ir/ir_rst.h index deef701c5..a492e15c9 100644 --- a/src/core/hle/service/ir_rst.h +++ b/src/core/hle/service/ir/ir_rst.h @@ -6,18 +6,17 @@ #include "core/hle/service/service.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace IR_RST +namespace Service { +namespace IR { -namespace IR_RST { - -class Interface : public Service::Interface { +class IR_RST_Interface : public Service::Interface { public: - Interface(); + IR_RST_Interface(); std::string GetPortName() const override { return "ir:rst"; } }; -} // namespace +} // namespace IR +} // namespace Service diff --git a/src/core/hle/service/ir_u.cpp b/src/core/hle/service/ir/ir_u.cpp index 608ed3c06..1b1e3078b 100644 --- a/src/core/hle/service/ir_u.cpp +++ b/src/core/hle/service/ir/ir_u.cpp @@ -3,12 +3,11 @@ // Refer to the license.txt file included. #include "core/hle/hle.h" -#include "core/hle/service/ir_u.h" +#include "core/hle/service/ir/ir.h" +#include "core/hle/service/ir/ir_u.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace IR_U - -namespace IR_U { +namespace Service { +namespace IR { const Interface::FunctionInfo FunctionTable[] = { {0x00010000, nullptr, "Initialize"}, @@ -31,11 +30,9 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00120040, nullptr, "SetSleepModeState"}, }; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Interface class - -Interface::Interface() { +IR_U_Interface::IR_U_Interface() { Register(FunctionTable); } -} // namespace +} // namespace IR +} // namespace Service diff --git a/src/core/hle/service/ir/ir_u.h b/src/core/hle/service/ir/ir_u.h new file mode 100644 index 000000000..056d2ce1a --- /dev/null +++ b/src/core/hle/service/ir/ir_u.h @@ -0,0 +1,22 @@ +// Copyright 2014 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 Service { +namespace IR { + +class IR_U_Interface : public Service::Interface { +public: + IR_U_Interface(); + + std::string GetPortName() const override { + return "ir:u"; + } +}; + +} // namespace IR +} // namespace Service diff --git a/src/core/hle/service/ir/ir_user.cpp b/src/core/hle/service/ir/ir_user.cpp new file mode 100644 index 000000000..8e3ff140f --- /dev/null +++ b/src/core/hle/service/ir/ir_user.cpp @@ -0,0 +1,34 @@ +// 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/ir/ir.h" +#include "core/hle/service/ir/ir_user.h" + +namespace Service { +namespace IR { + +const Interface::FunctionInfo FunctionTable[] = { + {0x00010182, nullptr, "InitializeIrNop"}, + {0x00020000, nullptr, "FinalizeIrNop"}, + {0x00030000, nullptr, "ClearReceiveBuffer"}, + {0x00040000, nullptr, "ClearSendBuffer"}, + {0x00060040, nullptr, "RequireConnection"}, + {0x00090000, nullptr, "Disconnect"}, + {0x000A0000, nullptr, "GetReceiveEvent"}, + {0x000B0000, nullptr, "GetSendEvent"}, + {0x000C0000, nullptr, "GetConnectionStatusEvent"}, + {0x000D0042, nullptr, "SendIrNop"}, + {0x000E0042, nullptr, "SendIrNopLarge"}, + {0x00180182, nullptr, "InitializeIrNopShared"}, + {0x00190040, nullptr, "ReleaseReceivedData"}, + {0x001A0040, nullptr, "SetOwnMachineId"}, +}; + +IR_User_Interface::IR_User_Interface() { + Register(FunctionTable); +} + +} // namespace IR +} // namespace Service diff --git a/src/core/hle/service/ir/ir_user.h b/src/core/hle/service/ir/ir_user.h new file mode 100644 index 000000000..71c932ffa --- /dev/null +++ b/src/core/hle/service/ir/ir_user.h @@ -0,0 +1,22 @@ +// 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 Service { +namespace IR { + +class IR_User_Interface : public Service::Interface { +public: + IR_User_Interface(); + + std::string GetPortName() const override { + return "ir:USER"; + } +}; + +} // namespace IR +} // namespace Service diff --git a/src/core/hle/service/ir_rst.cpp b/src/core/hle/service/ir_rst.cpp deleted file mode 100644 index 4c26c2f03..000000000 --- a/src/core/hle/service/ir_rst.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2014 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/ir_rst.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace IR_RST - -namespace IR_RST { - -const Interface::FunctionInfo FunctionTable[] = { - {0x00010000, nullptr, "GetHandles"}, - {0x00020080, nullptr, "Initialize"}, - {0x00030000, nullptr, "Shutdown"}, - {0x00090000, nullptr, "WriteToTwoFields"}, -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Interface class - -Interface::Interface() { - Register(FunctionTable); -} - -} // namespace diff --git a/src/core/hle/service/ldr_ro.cpp b/src/core/hle/service/ldr_ro.cpp index c0c4a2344..155b97f69 100644 --- a/src/core/hle/service/ldr_ro.cpp +++ b/src/core/hle/service/ldr_ro.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/logging/log.h" + #include "core/hle/hle.h" #include "core/hle/service/ldr_ro.h" diff --git a/src/core/hle/service/nim_u.cpp b/src/core/hle/service/nim_u.cpp new file mode 100644 index 000000000..5f13bd98e --- /dev/null +++ b/src/core/hle/service/nim_u.cpp @@ -0,0 +1,48 @@ +// Copyright 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/logging/log.h" + +#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/ir_u.h b/src/core/hle/service/nim_u.h index ec47a1524..57a1f6acf 100644 --- a/src/core/hle/service/ir_u.h +++ b/src/core/hle/service/nim_u.h @@ -1,4 +1,4 @@ -// Copyright 2014 Citra Emulator Project +// Copyright 2015 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -7,16 +7,16 @@ #include "core/hle/service/service.h" //////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace IR_U +// Namespace NIM_U -namespace IR_U { +namespace NIM_U { class Interface : public Service::Interface { public: Interface(); std::string GetPortName() const override { - return "ir:u"; + return "nim:u"; } }; diff --git a/src/core/hle/service/ns_s.cpp b/src/core/hle/service/ns_s.cpp index 5cf3e2039..6b3ef6ece 100644 --- a/src/core/hle/service/ns_s.cpp +++ b/src/core/hle/service/ns_s.cpp @@ -3,8 +3,6 @@ // Refer to the license.txt file included. -#include "common/common.h" - #include "core/hle/hle.h" #include "core/hle/service/ns_s.h" diff --git a/src/core/hle/service/nwm_uds.cpp b/src/core/hle/service/nwm_uds.cpp index 88be6c8d9..25b01860e 100644 --- a/src/core/hle/service/nwm_uds.cpp +++ b/src/core/hle/service/nwm_uds.cpp @@ -2,7 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/logging/log.h" + #include "core/hle/hle.h" +#include "core/hle/kernel/event.h" #include "core/hle/service/nwm_uds.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -10,21 +13,115 @@ namespace NWM_UDS { +static Kernel::SharedPtr<Kernel::Event> handle_event; + +/** + * 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/nwm_uds.h b/src/core/hle/service/nwm_uds.h index 9043f5aa7..82abdff28 100644 --- a/src/core/hle/service/nwm_uds.h +++ b/src/core/hle/service/nwm_uds.h @@ -18,7 +18,7 @@ public: Interface(); std::string GetPortName() const override { - return "nwm:UDS"; + return "nwm::UDS"; } }; diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp index 56c918d4f..2c7d49c9f 100644 --- a/src/core/hle/service/ptm/ptm.cpp +++ b/src/core/hle/service/ptm/ptm.cpp @@ -2,12 +2,15 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/service.h" +#include "common/logging/log.h" + +#include "core/file_sys/file_backend.h" #include "core/hle/service/fs/archive.h" #include "core/hle/service/ptm/ptm.h" #include "core/hle/service/ptm/ptm_play.h" #include "core/hle/service/ptm/ptm_sysm.h" #include "core/hle/service/ptm/ptm_u.h" +#include "core/hle/service/service.h" namespace Service { namespace PTM { @@ -18,31 +21,70 @@ static const GameCoin default_game_coin = { 0x4F00, 42, 0, 0, 0, 2014, 12, 29 }; /// Id of the SharedExtData archive used by the PTM process static const std::vector<u8> ptm_shared_extdata_id = {0, 0, 0, 0, 0x0B, 0, 0, 0xF0, 0, 0, 0, 0}; -static bool shell_open = true; +static bool shell_open; -static bool battery_is_charging = true; +static bool battery_is_charging; + +void GetAdapterState(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); -u32 GetAdapterState() { // TODO(purpasmart96): This function is only a stub, // it returns a valid result without implementing full functionality. - return battery_is_charging ? 1 : 0; + + cmd_buff[1] = RESULT_SUCCESS.raw; + cmd_buff[2] = battery_is_charging ? 1 : 0; + + LOG_WARNING(Service_PTM, "(STUBBED) called"); } -u32 GetShellState() { - return shell_open ? 1 : 0; +void GetShellState(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[1] = RESULT_SUCCESS.raw; + cmd_buff[2] = shell_open ? 1 : 0; +} + +void GetBatteryLevel(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + // TODO(purpasmart96): This function is only a stub, + // it returns a valid result without implementing full functionality. + + cmd_buff[1] = RESULT_SUCCESS.raw; + cmd_buff[2] = static_cast<u32>(ChargeLevels::CompletelyFull); // Set to a completely full battery + + LOG_WARNING(Service_PTM, "(STUBBED) called"); } -ChargeLevels GetBatteryLevel() { +void GetBatteryChargeState(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + // TODO(purpasmart96): This function is only a stub, // it returns a valid result without implementing full functionality. - return ChargeLevels::CompletelyFull; // Set to a completely full battery + + cmd_buff[1] = RESULT_SUCCESS.raw; + cmd_buff[2] = battery_is_charging ? 1 : 0; + + LOG_WARNING(Service_PTM, "(STUBBED) called"); } -void PTMInit() { +void IsLegacyPowerOff(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[1] = RESULT_SUCCESS.raw; + cmd_buff[2] = 0; + + LOG_WARNING(Service_PTM, "(STUBBED) called"); +} + +void Init() { AddService(new PTM_Play_Interface); AddService(new PTM_Sysm_Interface); AddService(new PTM_U_Interface); + shell_open = true; + battery_is_charging = true; + // Open the SharedExtSaveData archive 0xF000000B and create the gamecoin.dat file if it doesn't exist FileSys::Path archive_path(ptm_shared_extdata_id); auto archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path); @@ -68,7 +110,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..493e6a11f 100644 --- a/src/core/hle/service/ptm/ptm.h +++ b/src/core/hle/service/ptm/ptm.h @@ -5,6 +5,7 @@ #pragma once #include <array> +#include "core/hle/service/service.h" #include "core/hle/result.h" namespace Service { @@ -35,31 +36,54 @@ struct GameCoin { }; /** - * Returns whether the battery is charging or not. * It is unknown if GetAdapterState is the same as GetBatteryChargeState, * it is likely to just be a duplicate function of GetBatteryChargeState * that controls another part of the HW. - * @returns 1 if the battery is charging, and 0 otherwise. + * PTM::GetAdapterState service function + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Output of function, 0 = not charging, 1 = charging. */ -u32 GetAdapterState(); +void GetAdapterState(Interface* self); /** - * Returns whether the 3DS's physical shell casing is open or closed - * @returns 1 if the shell is open, and 0 if otherwise + * PTM::GetShellState service function. + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Whether the 3DS's physical shell casing is open (1) or closed (0) */ -u32 GetShellState(); +void GetShellState(Interface* self); /** - * Get the current battery's charge level. - * @returns The battery's charge level. + * PTM::GetBatteryLevel service function + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Battery level, 5 = completely full battery, 4 = mostly full battery, + * 3 = half full battery, 2 = low battery, 1 = critical battery. */ -ChargeLevels GetBatteryLevel(); +void GetBatteryLevel(Interface* self); + +/** + * PTM::GetBatteryChargeState service function + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Output of function, 0 = not charging, 1 = charging. + */ +void GetBatteryChargeState(Interface* self); + +/** + * PTM::IsLegacyPowerOff service function + * Outputs: + * 1: Result code, 0 on success, otherwise error code + * 2: Whether the system is going through a power off + */ +void IsLegacyPowerOff(Interface* self); /// 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/ptm/ptm_play.cpp b/src/core/hle/service/ptm/ptm_play.cpp index 8e8ae8558..48e68a3d8 100644 --- a/src/core/hle/service/ptm/ptm_play.cpp +++ b/src/core/hle/service/ptm/ptm_play.cpp @@ -9,10 +9,10 @@ namespace Service { namespace PTM { const Interface::FunctionInfo FunctionTable[] = { - { 0x08070082, nullptr, "GetPlayHistory" }, - { 0x08080000, nullptr, "GetPlayHistoryStart" }, - { 0x08090000, nullptr, "GetPlayHistoryLength" }, - { 0x080B0080, nullptr, "CalcPlayHistoryStart" }, + {0x08070082, nullptr, "GetPlayHistory"}, + {0x08080000, nullptr, "GetPlayHistoryStart"}, + {0x08090000, nullptr, "GetPlayHistoryLength"}, + {0x080B0080, nullptr, "CalcPlayHistoryStart"}, }; PTM_Play_Interface::PTM_Play_Interface() { diff --git a/src/core/hle/service/ptm/ptm_sysm.cpp b/src/core/hle/service/ptm/ptm_sysm.cpp index 2d841f69c..655658f3b 100644 --- a/src/core/hle/service/ptm/ptm_sysm.cpp +++ b/src/core/hle/service/ptm/ptm_sysm.cpp @@ -2,57 +2,44 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/make_unique.h" -#include "core/file_sys/archive_extsavedata.h" #include "core/hle/hle.h" +#include "core/hle/service/ptm/ptm.h" #include "core/hle/service/ptm/ptm_sysm.h" namespace Service { namespace PTM { -/** - * Returns whether the system is powering off (?) - * Outputs: - * 1: Result code, 0 on success, otherwise error code - * 2: Whether the system is going through a power off - */ -void IsLegacyPowerOff(Service::Interface* self) { - u32* cmd_buff = Kernel::GetCommandBuffer(); - cmd_buff[1] = RESULT_SUCCESS.raw; - cmd_buff[2] = 0; -} - const Interface::FunctionInfo FunctionTable[] = { - {0x040100C0, nullptr, "SetRtcAlarmEx"}, - {0x04020042, nullptr, "ReplySleepQuery"}, - {0x04030042, nullptr, "NotifySleepPreparationComplete"}, - {0x04040102, nullptr, "SetWakeupTrigger"}, - {0x04050000, nullptr, "GetAwakeReason"}, - {0x04060000, nullptr, "RequestSleep"}, - {0x040700C0, nullptr, "ShutdownAsync"}, - {0x04080000, nullptr, "Awake"}, - {0x04090080, nullptr, "RebootAsync"}, - {0x040A0000, nullptr, "CheckNew3DS"}, - {0x08010640, nullptr, "SetInfoLEDPattern"}, - {0x08020040, nullptr, "SetInfoLEDPatternHeader"}, - {0x08030000, nullptr, "GetInfoLEDStatus"}, - {0x08040040, nullptr, "SetBatteryEmptyLEDPattern"}, - {0x08050000, nullptr, "ClearStepHistory"}, - {0x080600C2, nullptr, "SetStepHistory"}, - {0x08070082, nullptr, "GetPlayHistory"}, - {0x08080000, nullptr, "GetPlayHistoryStart"}, - {0x08090000, nullptr, "GetPlayHistoryLength"}, - {0x080A0000, nullptr, "ClearPlayHistory"}, - {0x080B0080, nullptr, "CalcPlayHistoryStart"}, - {0x080C0080, nullptr, "SetUserTime"}, - {0x080D0000, nullptr, "InvalidateSystemTime"}, - {0x080E0140, nullptr, "NotifyPlayEvent"}, - {0x080F0000, IsLegacyPowerOff, "IsLegacyPowerOff"}, - {0x08100000, nullptr, "ClearLegacyPowerOff"}, - {0x08110000, nullptr, "GetShellStatus"}, - {0x08120000, nullptr, "IsShutdownByBatteryEmpty"}, - {0x08130000, nullptr, "FormatSavedata"}, - {0x08140000, nullptr, "GetLegacyJumpProhibitedFlag"} + {0x040100C0, nullptr, "SetRtcAlarmEx"}, + {0x04020042, nullptr, "ReplySleepQuery"}, + {0x04030042, nullptr, "NotifySleepPreparationComplete"}, + {0x04040102, nullptr, "SetWakeupTrigger"}, + {0x04050000, nullptr, "GetAwakeReason"}, + {0x04060000, nullptr, "RequestSleep"}, + {0x040700C0, nullptr, "ShutdownAsync"}, + {0x04080000, nullptr, "Awake"}, + {0x04090080, nullptr, "RebootAsync"}, + {0x040A0000, nullptr, "CheckNew3DS"}, + {0x08010640, nullptr, "SetInfoLEDPattern"}, + {0x08020040, nullptr, "SetInfoLEDPatternHeader"}, + {0x08030000, nullptr, "GetInfoLEDStatus"}, + {0x08040040, nullptr, "SetBatteryEmptyLEDPattern"}, + {0x08050000, nullptr, "ClearStepHistory"}, + {0x080600C2, nullptr, "SetStepHistory"}, + {0x08070082, nullptr, "GetPlayHistory"}, + {0x08080000, nullptr, "GetPlayHistoryStart"}, + {0x08090000, nullptr, "GetPlayHistoryLength"}, + {0x080A0000, nullptr, "ClearPlayHistory"}, + {0x080B0080, nullptr, "CalcPlayHistoryStart"}, + {0x080C0080, nullptr, "SetUserTime"}, + {0x080D0000, nullptr, "InvalidateSystemTime"}, + {0x080E0140, nullptr, "NotifyPlayEvent"}, + {0x080F0000, IsLegacyPowerOff, "IsLegacyPowerOff"}, + {0x08100000, nullptr, "ClearLegacyPowerOff"}, + {0x08110000, nullptr, "GetShellStatus"}, + {0x08120000, nullptr, "IsShutdownByBatteryEmpty"}, + {0x08130000, nullptr, "FormatSavedata"}, + {0x08140000, nullptr, "GetLegacyJumpProhibitedFlag"} }; PTM_Sysm_Interface::PTM_Sysm_Interface() { diff --git a/src/core/hle/service/ptm/ptm_u.cpp b/src/core/hle/service/ptm/ptm_u.cpp index 0af7c8bf6..3f5e9c7c1 100644 --- a/src/core/hle/service/ptm/ptm_u.cpp +++ b/src/core/hle/service/ptm/ptm_u.cpp @@ -2,7 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/make_unique.h" +#include "common/logging/log.h" #include "core/hle/hle.h" #include "core/hle/service/ptm/ptm.h" @@ -11,68 +11,6 @@ namespace Service { namespace PTM { -/** - * PTM_U::GetAdapterState service function - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Output of function, 0 = not charging, 1 = charging. - */ -static void GetAdapterState(Service::Interface* self) { - u32* cmd_buff = Kernel::GetCommandBuffer(); - - cmd_buff[1] = RESULT_SUCCESS.raw; - cmd_buff[2] = GetAdapterState(); - - LOG_WARNING(Service_PTM, "(STUBBED) called"); -} - -/* - * PTM_User::GetShellState service function. - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Whether the 3DS's physical shell casing is open (1) or closed (0) - */ -static void GetShellState(Service::Interface* self) { - u32* cmd_buff = Kernel::GetCommandBuffer(); - - cmd_buff[1] = RESULT_SUCCESS.raw; - cmd_buff[2] = GetShellState(); -} - -/** - * PTM_U::GetBatteryLevel service function - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Battery level, 5 = completely full battery, 4 = mostly full battery, - * 3 = half full battery, 2 = low battery, 1 = critical battery. - */ -static void GetBatteryLevel(Service::Interface* self) { - u32* cmd_buff = Kernel::GetCommandBuffer(); - - cmd_buff[1] = RESULT_SUCCESS.raw; - cmd_buff[2] = static_cast<u32>(GetBatteryLevel()); - - LOG_WARNING(Service_PTM, "(STUBBED) called"); -} - -/** - * PTM_U::GetBatteryChargeState service function - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Output of function, 0 = not charging, 1 = charging. - */ -static void GetBatteryChargeState(Service::Interface* self) { - u32* cmd_buff = Kernel::GetCommandBuffer(); - - // TODO(purpasmart96): This function is only a stub, - // it returns a valid result without implementing full functionality. - - cmd_buff[1] = RESULT_SUCCESS.raw; - cmd_buff[2] = GetAdapterState(); - - LOG_WARNING(Service_PTM, "(STUBBED) called"); -} - const Interface::FunctionInfo FunctionTable[] = { {0x00010002, nullptr, "RegisterAlarmClient"}, {0x00020080, nullptr, "SetRtcAlarm"}, diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 91f13cd7e..64185c62e 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -2,7 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/common.h" +#include "common/logging/log.h" #include "common/string_util.h" #include "core/hle/service/service.h" @@ -24,14 +24,13 @@ #include "core/hle/service/gsp_gpu.h" #include "core/hle/service/gsp_lcd.h" #include "core/hle/service/http_c.h" -#include "core/hle/service/ir_rst.h" -#include "core/hle/service/ir_u.h" #include "core/hle/service/ldr_ro.h" #include "core/hle/service/mic_u.h" #include "core/hle/service/ndm_u.h" #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" @@ -44,6 +43,7 @@ #include "core/hle/service/fs/archive.h" #include "core/hle/service/cfg/cfg.h" #include "core/hle/service/hid/hid.h" +#include "core/hle/service/ir/ir.h" #include "core/hle/service/ptm/ptm.h" namespace Service { @@ -51,6 +51,49 @@ namespace Service { std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_kernel_named_ports; std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_srv_services; +/** + * Creates a function string for logging, complete with the name (or header code, depending + * on what's passed in) the port name, and all the cmd_buff arguments. + */ +static std::string MakeFunctionString(const char* name, const char* port_name, const u32* cmd_buff) { + // Number of params == bits 0-5 + bits 6-11 + int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F); + + std::string function_string = Common::StringFromFormat("function '%s': port=%s", name, port_name); + for (int i = 1; i <= num_params; ++i) { + function_string += Common::StringFromFormat(", cmd_buff[%i]=%u", i, cmd_buff[i]); + } + return function_string; +} + +ResultVal<bool> Interface::SyncRequest() { + u32* cmd_buff = Kernel::GetCommandBuffer(); + auto itr = m_functions.find(cmd_buff[0]); + + if (itr == m_functions.end() || itr->second.func == nullptr) { + std::string function_name = (itr == m_functions.end()) ? Common::StringFromFormat("0x%08X", cmd_buff[0]) : itr->second.name; + LOG_ERROR(Service, "unknown / unimplemented %s", MakeFunctionString(function_name.c_str(), GetPortName().c_str(), cmd_buff).c_str()); + + // TODO(bunnei): Hack - ignore error + cmd_buff[1] = 0; + return MakeResult<bool>(false); + } else { + LOG_TRACE(Service, "%s", MakeFunctionString(itr->second.name, GetPortName().c_str(), cmd_buff).c_str()); + } + + itr->second.func(this); + + return MakeResult<bool>(false); // TODO: Implement return from actual function +} + +void Interface::Register(const FunctionInfo* functions, size_t n) { + m_functions.reserve(n); + for (size_t i = 0; i < n; ++i) { + // Usually this array is sorted by id already, so hint to instead at the end + m_functions.emplace_hint(m_functions.cend(), functions[i].id, functions[i]); + } +} + //////////////////////////////////////////////////////////////////////////////////////////////////// // Module interface @@ -68,10 +111,11 @@ 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(); + Service::IR::Init(); AddService(new AC_U::Interface); AddService(new ACT_U::Interface); @@ -90,14 +134,13 @@ void Init() { AddService(new GSP_GPU::Interface); AddService(new GSP_LCD::Interface); AddService(new HTTP_C::Interface); - AddService(new IR_RST::Interface); - AddService(new IR_U::Interface); AddService(new LDR_RO::Interface); AddService(new MIC_U::Interface); AddService(new NDM_U::Interface); 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 +153,11 @@ void Init() { /// Shutdown ServiceManager void Shutdown() { - Service::HID::HIDShutdown(); - Service::PTM::PTMShutdown(); - Service::APT::APTShutdown(); - Service::CFG::CFGShutdown(); + Service::IR::Shutdown(); + Service::HID::Shutdown(); + Service::PTM::Shutdown(); + Service::APT::Shutdown(); + Service::CFG::Shutdown(); Service::FS::ArchiveShutdown(); g_srv_services.clear(); diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index bfe16ebad..77bfb9ff1 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -4,20 +4,15 @@ #pragma once -#include <algorithm> #include <string> #include <unordered_map> -#include <vector> #include <boost/container/flat_map.hpp> -#include "common/common.h" -#include "common/string_util.h" -#include "core/mem_map.h" +#include "common/common_types.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/session.h" -#include "core/hle/svc.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // Namespace Service @@ -26,31 +21,11 @@ namespace Service { static const int kMaxPortSize = 8; ///< Maximum size of a port name (8 characters) -class Manager; - /// Interface to a CTROS service class Interface : public Kernel::Session { // TODO(yuriks): An "Interface" being a Kernel::Object is mostly non-sense. Interface should be // just something that encapsulates a session and acts as a helper to implement service // processes. - - friend class Manager; - - /** - * Creates a function string for logging, complete with the name (or header code, depending - * on what's passed in) the port name, and all the cmd_buff arguments. - */ - std::string MakeFunctionString(const char* name, const char* port_name, const u32* cmd_buff) { - // Number of params == bits 0-5 + bits 6-11 - int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F); - - std::string function_string = Common::StringFromFormat("function '%s': port=%s", name, port_name); - for (int i = 1; i <= num_params; ++i) { - function_string += Common::StringFromFormat(", cmd_buff[%i]=%u", i, cmd_buff[i]); - } - return function_string; - } - public: std::string GetName() const override { return GetPortName(); } @@ -70,25 +45,7 @@ public: return "[UNKNOWN SERVICE PORT]"; } - ResultVal<bool> SyncRequest() override { - u32* cmd_buff = Kernel::GetCommandBuffer(); - auto itr = m_functions.find(cmd_buff[0]); - - if (itr == m_functions.end() || itr->second.func == nullptr) { - std::string function_name = (itr == m_functions.end()) ? Common::StringFromFormat("0x%08X", cmd_buff[0]) : itr->second.name; - LOG_ERROR(Service, "unknown / unimplemented %s", MakeFunctionString(function_name.c_str(), GetPortName().c_str(), cmd_buff).c_str()); - - // TODO(bunnei): Hack - ignore error - cmd_buff[1] = 0; - return MakeResult<bool>(false); - } else { - LOG_TRACE(Service, "%s", MakeFunctionString(itr->second.name, GetPortName().c_str(), cmd_buff).c_str()); - } - - itr->second.func(this); - - return MakeResult<bool>(false); // TODO: Implement return from actual function - } + ResultVal<bool> SyncRequest() override; protected: @@ -96,14 +53,12 @@ protected: * Registers the functions in the service */ template <size_t N> - void Register(const FunctionInfo (&functions)[N]) { - m_functions.reserve(N); - for (auto& fn : functions) { - // Usually this array is sorted by id already, so hint to instead at the end - m_functions.emplace_hint(m_functions.cend(), fn.id, fn); - } + inline void Register(const FunctionInfo (&functions)[N]) { + Register(functions, N); } + void Register(const FunctionInfo* functions, size_t n); + private: boost::container::flat_map<u32, FunctionInfo> m_functions; diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp index 231ead185..39b8d65fd 100644 --- a/src/core/hle/service/soc_u.cpp +++ b/src/core/hle/service/soc_u.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/logging/log.h" #include "common/platform.h" #if EMU_PLATFORM == PLATFORM_WINDOWS diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp index cc59a03ce..6c49fa6cf 100644 --- a/src/core/hle/service/srv.cpp +++ b/src/core/hle/service/srv.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/logging/log.h" + #include "core/hle/hle.h" #include "core/hle/service/srv.h" #include "core/hle/kernel/event.h" diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp index 6607965e1..085192a07 100644 --- a/src/core/hle/service/y2r_u.cpp +++ b/src/core/hle/service/y2r_u.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/logging/log.h" + #include "core/hle/hle.h" #include "core/hle/kernel/event.h" #include "core/hle/service/y2r_u.h" @@ -11,7 +13,7 @@ namespace Y2R_U { -static Kernel::SharedPtr<Kernel::Event> completion_event = 0; +static Kernel::SharedPtr<Kernel::Event> completion_event; /** * Y2R_U::IsBusyConversion service function |
