diff --git a/include/kernel/kernel.hpp b/include/kernel/kernel.hpp index a986271c..3726e05d 100644 --- a/include/kernel/kernel.hpp +++ b/include/kernel/kernel.hpp @@ -40,13 +40,13 @@ class Kernel { u16 kernelVersion = 0; Handle makeArbiter(); - Handle makeEvent(ResetType resetType); Handle makeProcess(u32 id); Handle makePort(const char* name); Handle makeSession(Handle port); Handle makeThread(u32 entrypoint, u32 initialSP, u32 priority, s32 id, u32 arg,ThreadStatus status = ThreadStatus::Dormant); public: + Handle makeEvent(ResetType resetType); // Needs to be public to be accessible to the APT/HID services Handle makeMutex(bool locked = false); // Needs to be public to be accessible to the APT/DSP services Handle makeSemaphore(u32 initialCount, u32 maximumCount); // Needs to be public to be accessible to the service manager port diff --git a/include/services/apt.hpp b/include/services/apt.hpp index 99a1e813..f5356058 100644 --- a/include/services/apt.hpp +++ b/include/services/apt.hpp @@ -14,6 +14,8 @@ class APTService { Kernel& kernel; std::optional lockHandle = std::nullopt; + std::optional notificationEvent = std::nullopt; + std::optional resumeEvent = std::nullopt; MAKE_LOG_FUNCTION(log, aptLogger) @@ -24,6 +26,7 @@ class APTService { void checkNew3DS(u32 messagePointer); void checkNew3DSApp(u32 messagePointer); void enable(u32 messagePointer); + void initialize(u32 messagePointer); void notifyToWait(u32 messagePointer); void receiveParameter(u32 messagePointer); void replySleepQuery(u32 messagePointer); diff --git a/src/core/services/apt.cpp b/src/core/services/apt.cpp index 8fd86eaa..6cd3ce1e 100644 --- a/src/core/services/apt.cpp +++ b/src/core/services/apt.cpp @@ -4,6 +4,7 @@ namespace APTCommands { enum : u32 { GetLockHandle = 0x00010040, + Initialize = 0x00020080, Enable = 0x00030040, ReceiveParameter = 0x000D0080, ReplySleepQuery = 0x003E0080, @@ -34,7 +35,10 @@ void APTService::reset() { // Set the default CPU time limit to 30%. Seems safe, as this is what Metroid 2 uses by default cpuTimeLimit = 30; + // Reset the handles for the various service objects lockHandle = std::nullopt; + notificationEvent = std::nullopt; + resumeEvent = std::nullopt; } void APTService::handleSyncRequest(u32 messagePointer) { @@ -44,6 +48,7 @@ void APTService::handleSyncRequest(u32 messagePointer) { case APTCommands::CheckNew3DS: checkNew3DS(messagePointer); break; case APTCommands::CheckNew3DSApp: checkNew3DSApp(messagePointer); break; case APTCommands::Enable: enable(messagePointer); break; + case APTCommands::Initialize: initialize(messagePointer); break; case APTCommands::GetApplicationCpuTimeLimit: getApplicationCpuTimeLimit(messagePointer); break; case APTCommands::GetLockHandle: getLockHandle(messagePointer); break; case APTCommands::NotifyToWait: notifyToWait(messagePointer); break; @@ -82,6 +87,18 @@ void APTService::enable(u32 messagePointer) { mem.write32(messagePointer + 4, Result::Success); } +void APTService::initialize(u32 messagePointer) { + log("APT::Initialize\n"); + + notificationEvent = kernel.makeEvent(ResetType::OneShot); + resumeEvent = kernel.makeEvent(ResetType::OneShot); + + mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 8, 0x04000000); // Translation descriptor + mem.write32(messagePointer + 12, notificationEvent.value()); // Notification Event Handle + mem.write32(messagePointer + 12, resumeEvent.value()); // Resume Event Handle +} + void APTService::getLockHandle(u32 messagePointer) { log("APT::GetLockHandle\n");