More service calls implemented

This commit is contained in:
wheremyfoodat 2023-01-06 00:32:02 +02:00
parent 9f07286de8
commit 243224eed3
11 changed files with 59 additions and 2 deletions

View file

@ -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?
};
}

View file

@ -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<u8>(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();

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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<u32, 16>& regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel);

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -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.
}

View file

@ -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);

View file

@ -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;