From 243224eed3539ac836d3d53bd631737fb7c04ed8 Mon Sep 17 00:00:00 2001 From: wheremyfoodat Date: Fri, 6 Jan 2023 00:32:02 +0200 Subject: [PATCH] More service calls implemented --- include/kernel/config_mem.hpp | 4 +++- include/memory.hpp | 11 +++++++++++ include/services/dsp.hpp | 1 + include/services/fs.hpp | 1 + include/services/gsp_gpu.hpp | 1 + include/services/service_manager.hpp | 1 + src/core/memory.cpp | 2 ++ src/core/services/dsp.cpp | 11 +++++++++++ src/core/services/fs.cpp | 8 ++++++++ src/core/services/gsp_gpu.cpp | 13 ++++++++++++- src/core/services/service_manager.cpp | 8 ++++++++ 11 files changed, 59 insertions(+), 2 deletions(-) diff --git a/include/kernel/config_mem.hpp b/include/kernel/config_mem.hpp index 397e84a2..7533c42c 100644 --- a/include/kernel/config_mem.hpp +++ b/include/kernel/config_mem.hpp @@ -10,6 +10,8 @@ namespace ConfigMem { EnvInfo = 0x1FF80014, AppMemAlloc = 0x1FF80040, Datetime0 = 0x1FF81020, - LedState3D = 0x1FF81084 + LedState3D = 0x1FF81084, + BatteryState = 0x1FF81085, + HeadphonesConnectedMaybe = 0x1FF810C0 // TODO: What is actually stored here? }; } \ No newline at end of file diff --git a/include/memory.hpp b/include/memory.hpp index a3815534..1775bf04 100644 --- a/include/memory.hpp +++ b/include/memory.hpp @@ -156,6 +156,17 @@ public: u32 getLinearHeapVaddr(); u8* getFCRAM() { return fcram; } + enum class BatteryLevel { + Empty = 0, AlmostEmpty, OneBar, TwoBars, ThreeBars, FourBars + }; + u8 getBatteryState(bool adapterConnected, bool charging, BatteryLevel batteryLevel) { + u8 value = static_cast(batteryLevel) << 2; // Bits 2:4 are the battery level from 0 to 5 + if (adapterConnected) value |= 1 << 0; // Bit 0 shows if the charger is connected + if (charging) value |= 1 << 1; // Bit 1 shows if we're charging + + return value; + } + NCCH* getCXI() { if (loadedCXI.has_value()) { return &loadedCXI.value(); diff --git a/include/services/dsp.hpp b/include/services/dsp.hpp index 0033bdc6..e32aa314 100644 --- a/include/services/dsp.hpp +++ b/include/services/dsp.hpp @@ -50,6 +50,7 @@ class DSPService { // Service functions void convertProcessAddressFromDspDram(u32 messagePointer); // Nice function name + void flushDataCache(u32 messagePointer); void getHeadphoneStatus(u32 messagePointer); void getSemaphoreHandle(u32 messagePointer); void loadComponent(u32 messagePointer); diff --git a/include/services/fs.hpp b/include/services/fs.hpp index 9e338c91..62f361ca 100644 --- a/include/services/fs.hpp +++ b/include/services/fs.hpp @@ -31,6 +31,7 @@ class FSService { void getPriority(u32 messagePointer); void initialize(u32 messagePointer); void initializeWithSdkVersion(u32 messagePointer); + void isSdmcDetected(u32 messagePointer); void openArchive(u32 messagePointer); void openFile(u32 messagePointer); void openFileDirectly(u32 messagePointer); diff --git a/include/services/gsp_gpu.hpp b/include/services/gsp_gpu.hpp index 3c974b65..789ed211 100644 --- a/include/services/gsp_gpu.hpp +++ b/include/services/gsp_gpu.hpp @@ -37,6 +37,7 @@ class GPUService { void setAxiConfigQoSMode(u32 messagePointer); void setInternalPriorities(u32 messagePointer); void setLCDForceBlack(u32 messagePointer); + void storeDataCache(u32 messagePointer); void triggerCmdReqQueue(u32 messagePointer); void writeHwRegs(u32 messagePointer); void writeHwRegsWithMask(u32 messagePointer); diff --git a/include/services/service_manager.hpp b/include/services/service_manager.hpp index 91f3b8be..6b2326d4 100644 --- a/include/services/service_manager.hpp +++ b/include/services/service_manager.hpp @@ -49,6 +49,7 @@ class ServiceManager { void getServiceHandle(u32 messagePointer); void receiveNotification(u32 messagePointer); void registerClient(u32 messagePointer); + void subscribe(u32 messagePointer); public: ServiceManager(std::array& regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel); diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 464ab1f7..d8de8584 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -74,10 +74,12 @@ u8 Memory::read8(u32 vaddr) { } else { switch (vaddr) { + case ConfigMem::BatteryState: return getBatteryState(true, true, BatteryLevel::FourBars); case ConfigMem::EnvInfo: return envInfo; case ConfigMem::KernelVersionMinor: return u8(kernelVersion & 0xff); case ConfigMem::KernelVersionMajor: return u8(kernelVersion >> 8); case ConfigMem::LedState3D: return 1; // Report the 3D LED as always off (non-zero) for now + case ConfigMem::HeadphonesConnectedMaybe: return 0; default: Helpers::panic("Unimplemented 8-bit read, addr: %08X", vaddr); } } diff --git a/src/core/services/dsp.cpp b/src/core/services/dsp.cpp index cbcf687f..9e10fc17 100644 --- a/src/core/services/dsp.cpp +++ b/src/core/services/dsp.cpp @@ -7,6 +7,7 @@ namespace DSPCommands { WriteProcessPipe = 0x000D0082, ReadPipeIfPossible = 0x001000C0, LoadComponent = 0x001100C2, + FlushDataCache = 0x00130082, RegisterInterruptEvents = 0x00150082, GetSemaphoreHandle = 0x00160000, SetSemaphoreMask = 0x00170040, @@ -30,6 +31,7 @@ void DSPService::handleSyncRequest(u32 messagePointer) { const u32 command = mem.read32(messagePointer); switch (command) { case DSPCommands::ConvertProcessAddressFromDspDram: convertProcessAddressFromDspDram(messagePointer); break; + case DSPCommands::FlushDataCache: flushDataCache(messagePointer); break; case DSPCommands::GetHeadphoneStatus: getHeadphoneStatus(messagePointer); break; case DSPCommands::GetSemaphoreHandle: getSemaphoreHandle(messagePointer); break; case DSPCommands::LoadComponent: loadComponent(messagePointer); break; @@ -133,4 +135,13 @@ void DSPService::writeProcessPipe(u32 messagePointer) { log("DSP::writeProcessPipe (channel = %d, size = %X, buffer = %08X)\n", channel, size, buffer); mem.write32(messagePointer + 4, Result::Success); +} + +void DSPService::flushDataCache(u32 messagePointer) { + u32 address = mem.read32(messagePointer + 4); + u32 size = mem.read32(messagePointer + 8); + u32 process = mem.read32(messagePointer + 16); + + log("DSP::FlushDataCache (addr = %08X, size = %08X, process = %X)\n", address, size, process); + mem.write32(messagePointer + 4, Result::Success); } \ No newline at end of file diff --git a/src/core/services/fs.cpp b/src/core/services/fs.cpp index 87f42c81..a8a4d891 100644 --- a/src/core/services/fs.cpp +++ b/src/core/services/fs.cpp @@ -8,6 +8,7 @@ namespace FSCommands { OpenFileDirectly = 0x08030204, OpenArchive = 0x080C00C2, CloseArchive = 0x080E0080, + IsSdmcDetected = 0x08170000, InitializeWithSdkVersion = 0x08610042, SetPriority = 0x08620040, GetPriority = 0x08630000 @@ -77,6 +78,7 @@ void FSService::handleSyncRequest(u32 messagePointer) { case FSCommands::GetPriority: getPriority(messagePointer); break; case FSCommands::Initialize: initialize(messagePointer); break; case FSCommands::InitializeWithSdkVersion: initializeWithSdkVersion(messagePointer); break; + case FSCommands::IsSdmcDetected: isSdmcDetected(messagePointer); break; case FSCommands::OpenArchive: openArchive(messagePointer); break; case FSCommands::OpenFile: openFile(messagePointer); break; case FSCommands::OpenFileDirectly: openFileDirectly(messagePointer); break; @@ -210,4 +212,10 @@ void FSService::setPriority(u32 messagePointer) { mem.write32(messagePointer + 4, Result::Success); priority = value; +} + +void FSService::isSdmcDetected(u32 messagePointer) { + log("FS::IsSdmcDetected\n"); + mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 8, 0); // Whether SD is detected. For now we emulate a 3DS without an SD. } \ No newline at end of file diff --git a/src/core/services/gsp_gpu.cpp b/src/core/services/gsp_gpu.cpp index 910f7aa9..684b3c4f 100644 --- a/src/core/services/gsp_gpu.cpp +++ b/src/core/services/gsp_gpu.cpp @@ -11,7 +11,8 @@ namespace ServiceCommands { FlushDataCache = 0x00080082, SetLCDForceBlack = 0x000B0040, TriggerCmdReqQueue = 0x000C0000, - SetInternalPriorities = 0x001E0080 + SetInternalPriorities = 0x001E0080, + StoreDataCache = 0x001F0082 }; } @@ -47,6 +48,7 @@ void GPUService::handleSyncRequest(u32 messagePointer) { case ServiceCommands::SetAxiConfigQoSMode: setAxiConfigQoSMode(messagePointer); break; case ServiceCommands::SetInternalPriorities: setInternalPriorities(messagePointer); break; case ServiceCommands::SetLCDForceBlack: setLCDForceBlack(messagePointer); break; + case ServiceCommands::StoreDataCache: storeDataCache(messagePointer); break; case ServiceCommands::TriggerCmdReqQueue: [[likely]] triggerCmdReqQueue(messagePointer); break; case ServiceCommands::WriteHwRegs: writeHwRegs(messagePointer); break; case ServiceCommands::WriteHwRegsWithMask: writeHwRegsWithMask(messagePointer); break; @@ -184,6 +186,15 @@ void GPUService::flushDataCache(u32 messagePointer) { mem.write32(messagePointer + 4, Result::Success); } +void GPUService::storeDataCache(u32 messagePointer) { + u32 address = mem.read32(messagePointer + 4); + u32 size = mem.read32(messagePointer + 8); + u32 processHandle = handle = mem.read32(messagePointer + 16); + log("GSP::GPU::StoreDataCache(address = %08X, size = %X, process = %X\n", address, size, processHandle); + + mem.write32(messagePointer + 4, Result::Success); +} + void GPUService::setLCDForceBlack(u32 messagePointer) { u32 flag = mem.read32(messagePointer + 4); log("GSP::GPU::SetLCDForceBlank(flag = %d)\n", flag); diff --git a/src/core/services/service_manager.cpp b/src/core/services/service_manager.cpp index f079d9c4..4dd44d58 100644 --- a/src/core/services/service_manager.cpp +++ b/src/core/services/service_manager.cpp @@ -62,6 +62,7 @@ void ServiceManager::handleSyncRequest(u32 messagePointer) { case Commands::ReceiveNotification: receiveNotification(messagePointer); break; case Commands::RegisterClient: registerClient(messagePointer); break; case Commands::GetServiceHandle: getServiceHandle(messagePointer); break; + case Commands::Subscribe: subscribe(messagePointer); break; default: Helpers::panic("Unknown \"srv:\" command: %08X", header); } } @@ -140,6 +141,13 @@ void ServiceManager::receiveNotification(u32 messagePointer) { mem.write32(messagePointer + 8, 0); // Notification ID } +void ServiceManager::subscribe(u32 messagePointer) { + u32 id = mem.read32(messagePointer + 4); + log("srv::Subscribe (id = %d) (stubbed)\n", id); + + mem.write32(messagePointer + 4, Result::Success); +} + void ServiceManager::sendCommandToService(u32 messagePointer, Handle handle) { switch (handle) { case KernelHandles::AC: ac.handleSyncRequest(messagePointer); break;