From f43b030ba3ed7fc5f34cdea21458b9b6303dc6f4 Mon Sep 17 00:00:00 2001 From: Nomi Date: Tue, 26 Sep 2023 02:10:34 +0200 Subject: [PATCH] Stub new AM commands --- include/services/am.hpp | 5 +++ src/core/services/am.cpp | 70 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/include/services/am.hpp b/include/services/am.hpp index 672909ff..ace6ab6f 100644 --- a/include/services/am.hpp +++ b/include/services/am.hpp @@ -11,9 +11,14 @@ class AMService { MAKE_LOG_FUNCTION(log, amLogger) // Service commands + void checkContentRights(u32 messagePointer); void getDLCTitleInfo(u32 messagePointer); void getPatchTitleInfo(u32 messagePointer); + void getProgramInfos(u32 messagePointer); + void getProgramList(u32 messagePointer); + void getTicketList(u32 messagePointer); void listTitleInfo(u32 messagePointer); + void needsCleanup(u32 messagePointer); public: AMService(Memory& mem) : mem(mem) {} diff --git a/src/core/services/am.cpp b/src/core/services/am.cpp index 32e6a0b3..5dadbfdf 100644 --- a/src/core/services/am.cpp +++ b/src/core/services/am.cpp @@ -3,6 +3,11 @@ namespace AMCommands { enum : u32 { + GetProgramList = 0x00020082, + GetProgramInfos = 0x00030084, + GetTicketList = 0x00090082, + NeedsCleanup = 0x00130040, + CheckContentRights = 0x002500C0, GetDLCTitleInfo = 0x10050084, ListTitleInfo = 0x10070102, GetPatchTitleInfo = 0x100D0084, @@ -14,9 +19,14 @@ void AMService::reset() {} void AMService::handleSyncRequest(u32 messagePointer) { const u32 command = mem.read32(messagePointer); switch (command) { + case AMCommands::CheckContentRights: checkContentRights(messagePointer); break; case AMCommands::GetPatchTitleInfo: getPatchTitleInfo(messagePointer); break; case AMCommands::GetDLCTitleInfo: getDLCTitleInfo(messagePointer); break; + case AMCommands::GetProgramInfos: getProgramInfos(messagePointer); break; + case AMCommands::GetProgramList: getProgramList(messagePointer); break; + case AMCommands::GetTicketList: getTicketList(messagePointer); break; case AMCommands::ListTitleInfo: listTitleInfo(messagePointer); break; + case AMCommands::NeedsCleanup: needsCleanup(messagePointer); break; default: Helpers::panic("AM service requested. Command: %08X\n", command); } } @@ -56,4 +66,64 @@ void AMService::getPatchTitleInfo(u32 messagePointer) { mem.write32(messagePointer, IPC::responseHeader(0x100D, 1, 4)); mem.write32(messagePointer + 4, Result::FailurePlaceholder); +} + +void AMService::needsCleanup(u32 messagePointer) { + const u32 mediaType = mem.read32(messagePointer + 4); + log("AM::NeedsCleanup (media type = %X)\n", mediaType); + + mem.write32(messagePointer, IPC::responseHeader(0x13, 2, 0)); + mem.write32(messagePointer + 4, Result::Success); + mem.write8(messagePointer + 8, 0); // Doesn't need cleanup +} + +void AMService::getProgramInfos(u32 messagePointer) { + const u8 mediaType = mem.read8(messagePointer + 4); + const u32 titleCount = mem.read32(messagePointer + 8); + const u32 titleIDs = mem.read32(messagePointer + 16); + const u32 titleInfos = mem.read32(messagePointer + 24); + log("AM::GetProgramInfos (media type = %X, title count = %X, title IDs pointer = %X, title infos pointer = %X) (Stubbed)\n", mediaType, titleCount, titleIDs, titleInfos); + + mem.write32(messagePointer, IPC::responseHeader(0x3, 1, 4)); + mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 8, IPC::pointerHeader(0, sizeof(u64) * titleCount, IPC::BufferType::Send)); + mem.write32(messagePointer + 12, 0xC0DEC0DE); + mem.write32(messagePointer + 16, IPC::pointerHeader(1, sizeof(u32) * titleCount, IPC::BufferType::Receive)); + mem.write32(messagePointer + 20, titleInfos); +} + +void AMService::getProgramList(u32 messagePointer) { + const u32 titleCount = mem.read32(messagePointer + 4); + const u8 mediaType = mem.read8(messagePointer + 8); + const u32 titleIDs = mem.read32(messagePointer + 16); + log("AM::GetProgramList (title count = %X, media type = %X, title ID pointer = %X) (stubbed)\n", titleCount, mediaType, titleIDs); + + mem.write32(messagePointer, IPC::responseHeader(0x2, 2, 2)); + mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 8, 0); // No title IDs read? + mem.write32(messagePointer + 12, IPC::pointerHeader(0, sizeof(u64) * 0, IPC::BufferType::Receive)); + mem.write32(messagePointer + 16, titleIDs); +} + +void AMService::getTicketList(u32 messagePointer) { + const u32 ticketCount = mem.read32(messagePointer + 4); + const u32 numSkips = mem.read32(messagePointer + 8); + const u32 titleIDs = mem.read32(messagePointer + 16); + log("AM::GetTicketList (ticket count = %X, skipped tickets = %X, title ID pointer = %X) (stubbed)\n", ticketCount, numSkips, titleIDs); + + mem.write32(messagePointer, IPC::responseHeader(0x9, 2, 2)); + mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 8, 0); // No tickets read? + mem.write32(messagePointer + 12, IPC::pointerHeader(0, sizeof(u64) * 0, IPC::BufferType::Receive)); + mem.write32(messagePointer + 16, titleIDs); +} + +void AMService::checkContentRights(u32 messagePointer) { + const u64 titleID = mem.read64(messagePointer + 4); + const u16 contentIndex = mem.read16(messagePointer + 12); + log("AM::CheckContentRights (title ID = %llX, content index = %X) (stubbed)\n", titleID, contentIndex); + + mem.write32(messagePointer, IPC::responseHeader(0x25, 2, 0)); + mem.write32(messagePointer + 4, Result::Success); + mem.write8(messagePointer + 8, 1); // Has content rights } \ No newline at end of file