diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/citra/citra.cpp | 27 | ||||
-rw-r--r-- | src/common/logging/log.h | 2 | ||||
-rw-r--r-- | src/core/gdbstub/gdbstub.cpp | 108 | ||||
-rw-r--r-- | src/core/hle/service/am/am.cpp | 140 | ||||
-rw-r--r-- | src/core/hle/service/am/am.h | 126 | ||||
-rw-r--r-- | src/core/hle/service/am/am_app.cpp | 16 | ||||
-rw-r--r-- | src/core/hle/service/am/am_net.cpp | 18 | ||||
-rw-r--r-- | src/core/hle/service/am/am_sys.cpp | 22 | ||||
-rw-r--r-- | src/core/hle/service/am/am_u.cpp | 18 | ||||
-rw-r--r-- | src/core/hle/service/cecd/cecd.cpp | 9 | ||||
-rw-r--r-- | src/core/hle/service/cecd/cecd.h | 18 | ||||
-rw-r--r-- | src/core/hle/service/cecd/cecd_u.cpp | 1 |
12 files changed, 425 insertions, 80 deletions
diff --git a/src/citra/citra.cpp b/src/citra/citra.cpp index b12369136..3a1fbe3f7 100644 --- a/src/citra/citra.cpp +++ b/src/citra/citra.cpp @@ -36,25 +36,43 @@ static void PrintHelp() { - std::cout << "Usage: citra <filename>" << std::endl; + std::cout << "Usage: citra [options] <filename>" << std::endl; + std::cout << "--help, -h Display this information" << std::endl; + std::cout << "--gdbport, -g number Enable gdb stub on port number" << std::endl; } /// Application entry point int main(int argc, char **argv) { + Config config; int option_index = 0; + bool use_gdbstub = Settings::values.use_gdbstub; + u32 gdb_port = static_cast<u32>(Settings::values.gdbstub_port); + char *endarg; std::string boot_filename; + static struct option long_options[] = { { "help", no_argument, 0, 'h' }, + { "gdbport", required_argument, 0, 'g' }, { 0, 0, 0, 0 } }; while (optind < argc) { - char arg = getopt_long(argc, argv, ":h", long_options, &option_index); + char arg = getopt_long(argc, argv, ":hg:", long_options, &option_index); if (arg != -1) { switch (arg) { case 'h': PrintHelp(); return 0; + case 'g': + errno = 0; + gdb_port = strtoul(optarg, &endarg, 0); + use_gdbstub = true; + if (endarg == optarg) errno = EINVAL; + if (errno != 0) { + perror("--gdbport"); + exit(1); + } + break; } } else { boot_filename = argv[optind]; @@ -73,11 +91,10 @@ int main(int argc, char **argv) { return -1; } - Config config; log_filter.ParseFilterString(Settings::values.log_filter); - GDBStub::ToggleServer(Settings::values.use_gdbstub); - GDBStub::SetServerPort(static_cast<u32>(Settings::values.gdbstub_port)); + GDBStub::ToggleServer(use_gdbstub); + GDBStub::SetServerPort(gdb_port); std::unique_ptr<EmuWindow_SDL2> emu_window = std::make_unique<EmuWindow_SDL2>(); diff --git a/src/common/logging/log.h b/src/common/logging/log.h index b8eede3b8..521362317 100644 --- a/src/common/logging/log.h +++ b/src/common/logging/log.h @@ -62,7 +62,7 @@ enum class Class : ClassType { Service_NIM, ///< The NIM (Network interface manager) service Service_NWM, ///< The NWM (Network wlan manager) service Service_CAM, ///< The CAM (Camera) service - Service_CECD, ///< The CECD service + Service_CECD, ///< The CECD (StreetPass) service Service_CFG, ///< The CFG (Configuration) service Service_DSP, ///< The DSP (DSP control) service Service_DLP, ///< The DLP (Download Play) service diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp index 3a2445241..c1a7ec5bf 100644 --- a/src/core/gdbstub/gdbstub.cpp +++ b/src/core/gdbstub/gdbstub.cpp @@ -60,6 +60,59 @@ const u32 R15_REGISTER = 15; const u32 CPSR_REGISTER = 25; const u32 FPSCR_REGISTER = 58; +// For sample XML files see the GDB source /gdb/features +// GDB also wants the l character at the start +// This XML defines what the registers are for this specific ARM device +static const char* target_xml = +R"(l<?xml version="1.0"?> +<!DOCTYPE target SYSTEM "gdb-target.dtd"> +<target version="1.0"> + <feature name="org.gnu.gdb.arm.core"> + <reg name="r0" bitsize="32"/> + <reg name="r1" bitsize="32"/> + <reg name="r2" bitsize="32"/> + <reg name="r3" bitsize="32"/> + <reg name="r4" bitsize="32"/> + <reg name="r5" bitsize="32"/> + <reg name="r6" bitsize="32"/> + <reg name="r7" bitsize="32"/> + <reg name="r8" bitsize="32"/> + <reg name="r9" bitsize="32"/> + <reg name="r10" bitsize="32"/> + <reg name="r11" bitsize="32"/> + <reg name="r12" bitsize="32"/> + <reg name="sp" bitsize="32" type="data_ptr"/> + <reg name="lr" bitsize="32"/> + <reg name="pc" bitsize="32" type="code_ptr"/> + + <!-- The CPSR is register 25, rather than register 16, because + the FPA registers historically were placed between the PC + and the CPSR in the "g" packet. --> + + <reg name="cpsr" bitsize="32" regnum="25"/> + </feature> + <feature name="org.gnu.gdb.arm.vfp"> + <reg name="d0" bitsize="64" type="float"/> + <reg name="d1" bitsize="64" type="float"/> + <reg name="d2" bitsize="64" type="float"/> + <reg name="d3" bitsize="64" type="float"/> + <reg name="d4" bitsize="64" type="float"/> + <reg name="d5" bitsize="64" type="float"/> + <reg name="d6" bitsize="64" type="float"/> + <reg name="d7" bitsize="64" type="float"/> + <reg name="d8" bitsize="64" type="float"/> + <reg name="d9" bitsize="64" type="float"/> + <reg name="d10" bitsize="64" type="float"/> + <reg name="d11" bitsize="64" type="float"/> + <reg name="d12" bitsize="64" type="float"/> + <reg name="d13" bitsize="64" type="float"/> + <reg name="d14" bitsize="64" type="float"/> + <reg name="d15" bitsize="64" type="float"/> + <reg name="fpscr" bitsize="32" type="int" group="float"/> + </feature> +</target> +)"; + namespace GDBStub { static int gdbserver_socket = -1; @@ -211,7 +264,7 @@ static u8 ReadByte() { } /// Calculate the checksum of the current command buffer. -static u8 CalculateChecksum(u8 *buffer, u32 length) { +static u8 CalculateChecksum(u8* buffer, u32 length) { return static_cast<u8>(std::accumulate(buffer, buffer + length, 0, std::plus<u8>())); } @@ -353,8 +406,15 @@ static void SendReply(const char* reply) { static void HandleQuery() { LOG_DEBUG(Debug_GDBStub, "gdb: query '%s'\n", command_buffer + 1); - if (!strcmp(reinterpret_cast<const char*>(command_buffer + 1), "TStatus")) { + const char* query = reinterpret_cast<const char*>(command_buffer + 1); + + if (strcmp(query, "TStatus") == 0 ) { SendReply("T0"); + } else if (strncmp(query, "Supported:", strlen("Supported:")) == 0) { + // PacketSize needs to be large enough for target xml + SendReply("PacketSize=800;qXfer:features:read+"); + } else if (strncmp(query, "Xfer:features:read:target.xml:", strlen("Xfer:features:read:target.xml:")) == 0) { + SendReply(target_xml); } else { SendReply(""); } @@ -491,29 +551,25 @@ static void ReadRegisters() { memset(buffer, 0, sizeof(buffer)); u8* bufptr = buffer; - for (int i = 0, reg = 0; reg <= FPSCR_REGISTER; i++, reg++) { - if (reg <= R15_REGISTER) { - IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetReg(reg)); - } else if (reg == CPSR_REGISTER) { - IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetCPSR()); - } else if (reg == CPSR_REGISTER - 1) { - // Dummy FPA register, ignore - IntToGdbHex(bufptr + i * CHAR_BIT, 0); - } else if (reg < CPSR_REGISTER) { - // Dummy FPA registers, ignore - IntToGdbHex(bufptr + i * CHAR_BIT, 0); - IntToGdbHex(bufptr + (i + 1) * CHAR_BIT, 0); - IntToGdbHex(bufptr + (i + 2) * CHAR_BIT, 0); - i += 2; - } else if (reg > CPSR_REGISTER && reg < FPSCR_REGISTER) { - IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetVFPReg(reg - CPSR_REGISTER - 1)); - IntToGdbHex(bufptr + (i + 1) * CHAR_BIT, 0); - i++; - } else if (reg == FPSCR_REGISTER) { - IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetVFPSystemReg(VFP_FPSCR)); - } + + for (int reg = 0; reg <= R15_REGISTER; reg++) { + IntToGdbHex(bufptr + reg * CHAR_BIT, Core::g_app_core->GetReg(reg)); } + bufptr += (16 * CHAR_BIT); + + IntToGdbHex(bufptr, Core::g_app_core->GetCPSR()); + + bufptr += CHAR_BIT; + + for (int reg = 0; reg <= 31; reg++) { + IntToGdbHex(bufptr + reg * CHAR_BIT, Core::g_app_core->GetVFPReg(reg)); + } + + bufptr += (32 * CHAR_BIT); + + IntToGdbHex(bufptr, Core::g_app_core->GetVFPSystemReg(VFP_FPSCR)); + SendReply(reinterpret_cast<char*>(buffer)); } @@ -885,6 +941,12 @@ void Init(u16 port) { LOG_ERROR(Debug_GDBStub, "Failed to create gdb socket"); } + // Set socket to SO_REUSEADDR so it can always bind on the same port + int reuse_enabled = 1; + if (setsockopt(tmpsock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse_enabled, sizeof(reuse_enabled)) < 0) { + LOG_ERROR(Debug_GDBStub, "Failed to set gdb socket option"); + } + const sockaddr* server_addr = reinterpret_cast<const sockaddr*>(&saddr_server); socklen_t server_addrlen = sizeof(saddr_server); if (bind(tmpsock, server_addr, server_addrlen) < 0) { diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 06be9940e..9591522e5 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <cinttypes> + #include "common/logging/log.h" #include "core/hle/service/service.h" @@ -9,30 +11,119 @@ #include "core/hle/service/am/am_app.h" #include "core/hle/service/am/am_net.h" #include "core/hle/service/am/am_sys.h" +#include "core/hle/service/am/am_u.h" namespace Service { namespace AM { -void TitleIDListGetTotal(Service::Interface* self) { +static std::array<u32, 3> am_content_count = { 0, 0, 0 }; +static std::array<u32, 3> am_titles_count = { 0, 0, 0 }; +static std::array<u32, 3> am_titles_list_count = { 0, 0, 0 }; +static u32 am_ticket_count = 0; +static u32 am_ticket_list_count = 0; + +void GetTitleCount(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); + u32 media_type = cmd_buff[1] & 0xFF; cmd_buff[1] = RESULT_SUCCESS.raw; - cmd_buff[2] = 0; + cmd_buff[2] = am_titles_count[media_type]; + LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, title_count=0x%08x", media_type, am_titles_count[media_type]); +} + +void FindContentInfos(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + u32 media_type = cmd_buff[1] & 0xFF; + u64 title_id = (static_cast<u64>(cmd_buff[3]) << 32) | cmd_buff[2]; + u32 content_ids_pointer = cmd_buff[6]; + u32 content_info_pointer = cmd_buff[8]; + + am_content_count[media_type] = cmd_buff[4]; - LOG_WARNING(Service_AM, "(STUBBED) media_type %u", media_type); + cmd_buff[1] = RESULT_SUCCESS.raw; + LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, title_id=0x%016lx, content_cound=%u, content_ids_pointer=0x%08x, content_info_pointer=0x%08x", + media_type, title_id, am_content_count[media_type], content_ids_pointer, content_info_pointer); } -void GetTitleIDList(Service::Interface* self) { +void ListContentInfos(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - u32 num_titles = cmd_buff[1]; + u32 media_type = cmd_buff[2] & 0xFF; - u32 addr = cmd_buff[4]; + u64 title_id = (static_cast<u64>(cmd_buff[4]) << 32) | cmd_buff[3]; + u32 start_index = cmd_buff[5]; + u32 content_info_pointer = cmd_buff[7]; + + am_content_count[media_type] = cmd_buff[1]; cmd_buff[1] = RESULT_SUCCESS.raw; - cmd_buff[2] = 0; + cmd_buff[2] = am_content_count[media_type]; + LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, content_count=%u, title_id=0x%016" PRIx64 ", start_index=0x%08x, content_info_pointer=0x%08X", + media_type, am_content_count[media_type], title_id, start_index, content_info_pointer); +} + +void DeleteContents(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + u32 media_type = cmd_buff[1] & 0xFF; + u64 title_id = (static_cast<u64>(cmd_buff[3]) << 32) | cmd_buff[2]; + u32 content_ids_pointer = cmd_buff[6]; - LOG_WARNING(Service_AM, "(STUBBED) Requested %u titles from media type %u. Address=0x%08X", num_titles, media_type, addr); + am_content_count[media_type] = cmd_buff[4]; + + cmd_buff[1] = RESULT_SUCCESS.raw; + LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, title_id=0x%016" PRIx64 ", content_count=%u, content_ids_pointer=0x%08x", + media_type, title_id, am_content_count[media_type], content_ids_pointer); +} + +void GetTitleList(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + u32 media_type = cmd_buff[2] & 0xFF; + u32 title_ids_output_pointer = cmd_buff[4]; + + am_titles_list_count[media_type] = cmd_buff[1]; + + cmd_buff[1] = RESULT_SUCCESS.raw; + cmd_buff[2] = am_titles_list_count[media_type]; + LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, titles_list_count=0x%08X, title_ids_output_pointer=0x%08X", + media_type, am_titles_list_count[media_type], title_ids_output_pointer); +} + +void GetTitleInfo(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + u32 media_type = cmd_buff[1] & 0xFF; + u32 title_id_list_pointer = cmd_buff[4]; + u32 title_list_pointer = cmd_buff[6]; + + am_titles_count[media_type] = cmd_buff[2]; + + cmd_buff[1] = RESULT_SUCCESS.raw; + LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, total_titles=0x%08X, title_id_list_pointer=0x%08X, title_list_pointer=0x%08X", + media_type, am_titles_count[media_type], title_id_list_pointer, title_list_pointer); +} + +void GetDataTitleInfos(Service::Interface* self) { + GetTitleInfo(self); + + LOG_WARNING(Service_AM, "(STUBBED) called"); +} + +void ListDataTitleTicketInfos(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + u64 title_id = (static_cast<u64>(cmd_buff[3]) << 32) | cmd_buff[2]; + u32 start_index = cmd_buff[4]; + u32 ticket_info_pointer = cmd_buff[6]; + + am_ticket_count = cmd_buff[1]; + + cmd_buff[1] = RESULT_SUCCESS.raw; + cmd_buff[2] = am_ticket_count; + LOG_WARNING(Service_AM, "(STUBBED) ticket_count=0x%08X, title_id=0x%016" PRIx64 ", start_index=0x%08X, ticket_info_pointer=0x%08X", + am_ticket_count, title_id, start_index, ticket_info_pointer); } void GetNumContentInfos(Service::Interface* self) { @@ -40,16 +131,47 @@ void GetNumContentInfos(Service::Interface* self) { cmd_buff[1] = RESULT_SUCCESS.raw; cmd_buff[2] = 1; // Number of content infos plus one - LOG_WARNING(Service_AM, "(STUBBED) called"); } +void DeleteTicket(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + u64 title_id = (static_cast<u64>(cmd_buff[2]) << 32) | cmd_buff[1]; + + cmd_buff[1] = RESULT_SUCCESS.raw; + LOG_WARNING(Service_AM, "(STUBBED) called title_id=0x%016" PRIx64 "",title_id); +} + +void GetTicketCount(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[1] = RESULT_SUCCESS.raw; + cmd_buff[2] = am_ticket_count; + LOG_WARNING(Service_AM, "(STUBBED) called ticket_count=0x%08x",am_ticket_count); +} + +void GetTicketList(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + u32 num_of_skip = cmd_buff[2]; + u32 ticket_list_pointer = cmd_buff[4]; + + am_ticket_list_count = cmd_buff[1]; + + cmd_buff[1] = RESULT_SUCCESS.raw; + cmd_buff[2] = am_ticket_list_count; + LOG_WARNING(Service_AM, "(STUBBED) ticket_list_count=0x%08x, num_of_skip=0x%08x, ticket_list_pointer=0x%08x", + am_ticket_list_count, num_of_skip, ticket_list_pointer); +} + void Init() { using namespace Kernel; AddService(new AM_APP_Interface); AddService(new AM_NET_Interface); AddService(new AM_SYS_Interface); + AddService(new AM_U_Interface); } void Shutdown() { diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 15e63bc7b..5676cdd5f 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -11,7 +11,7 @@ class Interface; namespace AM { /** - * AM::TitleIDListGetTotal service function + * AM::GetTitleCount service function * Gets the number of installed titles in the requested media type * Inputs: * 0 : Command header (0x00010040) @@ -20,36 +20,140 @@ namespace AM { * 1 : Result, 0 on success, otherwise error code * 2 : The number of titles in the requested media type */ -void TitleIDListGetTotal(Service::Interface* self); +void GetTitleCount(Service::Interface* self); /** - * AM::GetTitleIDList service function + * AM::FindContentInfos service function + * Inputs: + * 1 : MediaType + * 2-3 : u64, Title ID + * 4 : Content count + * 6 : Content IDs pointer + * 8 : Content Infos pointer + * Outputs: + * 1 : Result, 0 on success, otherwise error code + */ +void FindContentInfos(Service::Interface* self); + +/** + * AM::ListContentInfos service function + * Inputs: + * 1 : Content count + * 2 : MediaType + * 3-4 : u64, Title ID + * 5 : Start Index + * 7 : Content Infos pointer + * Outputs: + * 1 : Result, 0 on success, otherwise error code + * 2 : Number of content infos returned + */ +void ListContentInfos(Service::Interface* self); + +/** + * AM::DeleteContents service function + * Inputs: + * 1 : MediaType + * 2-3 : u64, Title ID + * 4 : Content count + * 6 : Content IDs pointer + * Outputs: + * 1 : Result, 0 on success, otherwise error code + */ +void DeleteContents(Service::Interface* self); + +/** + * AM::GetTitleList service function * Loads information about the desired number of titles from the desired media type into an array * Inputs: - * 0 : Command header (0x00020082) - * 1 : The maximum number of titles to load + * 1 : Title count * 2 : Media type to load the titles from - * 3 : Descriptor of the output buffer pointer - * 4 : Address of the output buffer + * 4 : Title IDs output pointer * Outputs: * 1 : Result, 0 on success, otherwise error code * 2 : The number of titles loaded from the requested media type */ -void GetTitleIDList(Service::Interface* self); +void GetTitleList(Service::Interface* self); + +/** + * AM::GetTitleInfo service function + * Inputs: + * 1 : u8 Mediatype + * 2 : Total titles + * 4 : TitleIDList pointer + * 6 : TitleList pointer + * Outputs: + * 1 : Result, 0 on success, otherwise error code + */ +void GetTitleInfo(Service::Interface* self); + +/** + * AM::GetDataTitleInfos service function + * Wrapper for AM::GetTitleInfo + * Inputs: + * 1 : u8 Mediatype + * 2 : Total titles + * 4 : TitleIDList pointer + * 6 : TitleList pointer + * Outputs: + * 1 : Result, 0 on success, otherwise error code + */ +void GetDataTitleInfos(Service::Interface* self); + +/** + * AM::ListDataTitleTicketInfos service function + * Inputs: + * 1 : Ticket count + * 2-3 : u64, Title ID + * 4 : Start Index? + * 5 : (TicketCount * 24) << 8 | 0x4 + * 6 : Ticket Infos pointer + * Outputs: + * 1 : Result, 0 on success, otherwise error code + * 2 : Number of ticket infos returned + */ +void ListDataTitleTicketInfos(Service::Interface* self); /** * AM::GetNumContentInfos service function * Inputs: * 0 : Command header (0x100100C0) - * 1 : Unknown - * 2 : Unknown - * 3 : Unknown + * 1 : MediaType + * 2-3 : u64, Title ID * Outputs: * 1 : Result, 0 on success, otherwise error code * 2 : Number of content infos plus one */ void GetNumContentInfos(Service::Interface* self); +/** + * AM::DeleteTicket service function + * Inputs: + * 1-2 : u64, Title ID + * Outputs: + * 1 : Result, 0 on success, otherwise error code + */ +void DeleteTicket(Service::Interface* self); + +/** + * AM::GetTicketCount service function + * Outputs: + * 1 : Result, 0 on success, otherwise error code + * 2 : Total titles + */ +void GetTicketCount(Service::Interface* self); + +/** + * AM::GetTicketList service function + * Inputs: + * 1 : Number of TicketList + * 2 : Number to skip + * 4 : TicketList pointer + * Outputs: + * 1 : Result, 0 on success, otherwise error code + * 2 : Total TicketList + */ +void GetTicketList(Service::Interface* self); + /// Initialize AM service void Init(); diff --git a/src/core/hle/service/am/am_app.cpp b/src/core/hle/service/am/am_app.cpp index 16c76a1eb..d27b3defd 100644 --- a/src/core/hle/service/am/am_app.cpp +++ b/src/core/hle/service/am/am_app.cpp @@ -9,14 +9,14 @@ namespace Service { namespace AM { const Interface::FunctionInfo FunctionTable[] = { - {0x100100C0, GetNumContentInfos, "GetNumContentInfos"}, - {0x10020104, nullptr, "FindContentInfos"}, - {0x10030142, nullptr, "ListContentInfos"}, - {0x10040102, nullptr, "DeleteContents"}, - {0x10050084, nullptr, "GetDataTitleInfos"}, - {0x10070102, nullptr, "ListDataTitleTicketInfos"}, - {0x100900C0, nullptr, "IsDataTitleInUse"}, - {0x100A0000, nullptr, "IsExternalTitleDatabaseInitialized"}, + {0x100100C0, GetNumContentInfos, "GetNumContentInfos"}, + {0x10020104, FindContentInfos, "FindContentInfos"}, + {0x10030142, ListContentInfos, "ListContentInfos"}, + {0x10040102, DeleteContents, "DeleteContents"}, + {0x10050084, GetDataTitleInfos, "GetDataTitleInfos"}, + {0x10070102, ListDataTitleTicketInfos, "ListDataTitleTicketInfos"}, + {0x100900C0, nullptr, "IsDataTitleInUse"}, + {0x100A0000, nullptr, "IsExternalTitleDatabaseInitialized"}, }; AM_APP_Interface::AM_APP_Interface() { diff --git a/src/core/hle/service/am/am_net.cpp b/src/core/hle/service/am/am_net.cpp index 065e04118..e75755245 100644 --- a/src/core/hle/service/am/am_net.cpp +++ b/src/core/hle/service/am/am_net.cpp @@ -9,16 +9,20 @@ namespace Service { namespace AM { const Interface::FunctionInfo FunctionTable[] = { - {0x00010040, TitleIDListGetTotal, "TitleIDListGetTotal"}, - {0x00020082, GetTitleIDList, "GetTitleIDList"}, - {0x00030084, nullptr, "ListTitles"}, + {0x00010040, GetTitleCount, "GetTitleCount"}, + {0x00020082, GetTitleList, "GetTitleList"}, + {0x00030084, GetTitleInfo, "GetTitleInfo"}, {0x000400C0, nullptr, "DeleteApplicationTitle"}, {0x000500C0, nullptr, "GetTitleProductCode"}, - {0x00080000, nullptr, "TitleIDListGetTotal3"}, - {0x00090082, nullptr, "GetTitleIDList3"}, + {0x000600C0, nullptr, "GetTitleExtDataId"}, + {0x00070080, DeleteTicket, "DeleteTicket"}, + {0x00080000, GetTicketCount, "GetTicketCount"}, + {0x00090082, GetTicketList, "GetTicketList"}, {0x000A0000, nullptr, "GetDeviceID"}, - {0x000D0084, nullptr, "ListTitles2"}, - {0x00140040, nullptr, "FinishInstallToMedia"}, + {0x000D0084, nullptr, "GetPendingTitleInfo"}, + {0x000E00C0, nullptr, "DeletePendingTitle"}, + {0x00140040, nullptr, "FinalizePendingTitles"}, + {0x00150040, nullptr, "DeleteAllPendingTitles"}, {0x00180080, nullptr, "InitializeTitleDatabase"}, {0x00190040, nullptr, "ReloadDBS"}, {0x001A00C0, nullptr, "GetDSiWareExportSize"}, diff --git a/src/core/hle/service/am/am_sys.cpp b/src/core/hle/service/am/am_sys.cpp index e38812297..8bad5e1c9 100644 --- a/src/core/hle/service/am/am_sys.cpp +++ b/src/core/hle/service/am/am_sys.cpp @@ -9,23 +9,27 @@ namespace Service { namespace AM { const Interface::FunctionInfo FunctionTable[] = { - {0x00010040, TitleIDListGetTotal, "TitleIDListGetTotal"}, - {0x00020082, GetTitleIDList, "GetTitleIDList"}, - {0x00030084, nullptr, "ListTitles"}, + {0x00010040, GetTitleCount, "GetTitleCount"}, + {0x00020082, GetTitleList, "GetTitleList"}, + {0x00030084, GetTitleInfo, "GetTitleInfo"}, {0x000400C0, nullptr, "DeleteApplicationTitle"}, {0x000500C0, nullptr, "GetTitleProductCode"}, - {0x00080000, nullptr, "TitleIDListGetTotal3"}, - {0x00090082, nullptr, "GetTitleIDList3"}, + {0x000600C0, nullptr, "GetTitleExtDataId"}, + {0x00070080, DeleteTicket, "DeleteTicket"}, + {0x00080000, GetTicketCount, "GetTicketCount"}, + {0x00090082, GetTicketList, "GetTicketList"}, {0x000A0000, nullptr, "GetDeviceID"}, - {0x000D0084, nullptr, "ListTitles2"}, - {0x00140040, nullptr, "FinishInstallToMedia"}, + {0x000D0084, nullptr, "GetPendingTitleInfo"}, + {0x000E00C0, nullptr, "DeletePendingTitle"}, + {0x00140040, nullptr, "FinalizePendingTitles"}, + {0x00150040, nullptr, "DeleteAllPendingTitles"}, {0x00180080, nullptr, "InitializeTitleDatabase"}, {0x00190040, nullptr, "ReloadDBS"}, {0x001A00C0, nullptr, "GetDSiWareExportSize"}, {0x001B0144, nullptr, "ExportDSiWare"}, {0x001C0084, nullptr, "ImportDSiWare"}, - {0x00230080, nullptr, "TitleIDListGetTotal2"}, - {0x002400C2, nullptr, "GetTitleIDList2"} + {0x00230080, nullptr, "GetPendingTitleCount"}, + {0x002400C2, nullptr, "GetPendingTitleList"} }; AM_SYS_Interface::AM_SYS_Interface() { diff --git a/src/core/hle/service/am/am_u.cpp b/src/core/hle/service/am/am_u.cpp index c0392b754..d583dd9e6 100644 --- a/src/core/hle/service/am/am_u.cpp +++ b/src/core/hle/service/am/am_u.cpp @@ -9,16 +9,20 @@ namespace Service { namespace AM { const Interface::FunctionInfo FunctionTable[] = { - {0x00010040, TitleIDListGetTotal, "TitleIDListGetTotal"}, - {0x00020082, GetTitleIDList, "GetTitleIDList"}, - {0x00030084, nullptr, "ListTitles"}, + {0x00010040, GetTitleCount, "GetTitleCount"}, + {0x00020082, GetTitleList, "GetTitleList"}, + {0x00030084, GetTitleInfo, "GetTitleInfo"}, {0x000400C0, nullptr, "DeleteApplicationTitle"}, {0x000500C0, nullptr, "GetTitleProductCode"}, - {0x00080000, nullptr, "TitleIDListGetTotal3"}, - {0x00090082, nullptr, "GetTitleIDList3"}, + {0x000600C0, nullptr, "GetTitleExtDataId"}, + {0x00070080, DeleteTicket, "DeleteTicket"}, + {0x00080000, GetTicketCount, "GetTicketCount"}, + {0x00090082, GetTicketList, "GetTicketList"}, {0x000A0000, nullptr, "GetDeviceID"}, - {0x000D0084, nullptr, "ListTitles2"}, - {0x00140040, nullptr, "FinishInstallToMedia"}, + {0x000D0084, nullptr, "GetPendingTitleInfo"}, + {0x000E00C0, nullptr, "DeletePendingTitle"}, + {0x00140040, nullptr, "FinalizePendingTitles"}, + {0x00150040, nullptr, "DeleteAllPendingTitles"}, {0x00180080, nullptr, "InitializeTitleDatabase"}, {0x00190040, nullptr, "ReloadDBS"}, {0x001A00C0, nullptr, "GetDSiWareExportSize"}, diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp index e6e36e7ec..50c03495e 100644 --- a/src/core/hle/service/cecd/cecd.cpp +++ b/src/core/hle/service/cecd/cecd.cpp @@ -16,6 +16,15 @@ namespace CECD { static Kernel::SharedPtr<Kernel::Event> cecinfo_event; static Kernel::SharedPtr<Kernel::Event> change_state_event; +void GetCecStateAbbreviated(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + cmd_buff[2] = static_cast<u32>(CecStateAbbreviated::CEC_STATE_ABBREV_IDLE); + + LOG_WARNING(Service_CECD, "(STUBBED) called"); +} + void GetCecInfoEventHandle(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); diff --git a/src/core/hle/service/cecd/cecd.h b/src/core/hle/service/cecd/cecd.h index 89a8d67bb..435611363 100644 --- a/src/core/hle/service/cecd/cecd.h +++ b/src/core/hle/service/cecd/cecd.h @@ -10,6 +10,24 @@ class Interface; namespace CECD { +enum class CecStateAbbreviated { + CEC_STATE_ABBREV_IDLE = 1, ///< Corresponds to CEC_STATE_IDLE + CEC_STATE_ABBREV_NOT_LOCAL = 2, ///< Corresponds to CEC_STATEs *FINISH*, *POST, and OVER_BOSS + CEC_STATE_ABBREV_SCANNING = 3, ///< Corresponds to CEC_STATE_SCANNING + CEC_STATE_ABBREV_WLREADY = 4, ///< Corresponds to CEC_STATE_WIRELESS_READY when some unknown bool is true + CEC_STATE_ABBREV_OTHER = 5, ///< Corresponds to CEC_STATEs besides *FINISH*, *POST, and OVER_BOSS and those listed here +}; + +/** + * GetCecStateAbbreviated service function + * Inputs: + * 0: 0x000E0000 + * Outputs: + * 1: ResultCode + * 2: CecStateAbbreviated + */ +void GetCecStateAbbreviated(Service::Interface* self); + /** * GetCecInfoEventHandle service function * Inputs: diff --git a/src/core/hle/service/cecd/cecd_u.cpp b/src/core/hle/service/cecd/cecd_u.cpp index ace1c73c0..be6d4d8f6 100644 --- a/src/core/hle/service/cecd/cecd_u.cpp +++ b/src/core/hle/service/cecd/cecd_u.cpp @@ -9,6 +9,7 @@ namespace Service { namespace CECD { static const Interface::FunctionInfo FunctionTable[] = { + {0x000E0000, GetCecStateAbbreviated, "GetCecStateAbbreviated"}, {0x000F0000, GetCecInfoEventHandle, "GetCecInfoEventHandle"}, {0x00100000, GetChangeStateEventHandle, "GetChangeStateEventHandle"}, {0x00120104, nullptr, "ReadSavedData"}, |