mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-06-08 20:11:39 +12:00
[Kernel] Implement err:f
This commit is contained in:
parent
88c93645e3
commit
5992a58351
7 changed files with 92 additions and 12 deletions
45
src/core/kernel/error.cpp
Normal file
45
src/core/kernel/error.cpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include "kernel.hpp"
|
||||
|
||||
namespace Commands {
|
||||
enum : u32 {
|
||||
Throw = 0x00010800
|
||||
};
|
||||
}
|
||||
|
||||
namespace FatalErrorType {
|
||||
enum : u32 {
|
||||
Generic = 0,
|
||||
Corrupted = 1,
|
||||
CardRemoved = 2,
|
||||
Exception = 3,
|
||||
ResultFailure = 4,
|
||||
Logged = 5
|
||||
};
|
||||
}
|
||||
|
||||
// Handle SendSyncRequest targetting the err:f port
|
||||
void Kernel::handleErrorSyncRequest(u32 messagePointer) {
|
||||
u32 cmd = mem.read32(messagePointer);
|
||||
switch (cmd) {
|
||||
case Commands::Throw: throwError(messagePointer); break;
|
||||
|
||||
default:
|
||||
Helpers::panic("Unimplemented err:f command %08X\n", cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Kernel::throwError(u32 messagePointer) {
|
||||
const auto type = mem.read8(messagePointer + 4); // Fatal error type
|
||||
const u32 pc = mem.read32(messagePointer + 12);
|
||||
const u32 pid = mem.read32(messagePointer + 16);
|
||||
logError("Thrown fatal error @ %08X (pid = %X, type = %d)\n", pc, pid, type);
|
||||
|
||||
// Read the error message if type == 4
|
||||
if (type == FatalErrorType::ResultFailure) {
|
||||
const auto error = mem.readString(messagePointer + 0x24, 0x60);
|
||||
logError("ERROR: %s\n", error.c_str());
|
||||
}
|
||||
|
||||
Helpers::panic("Thrown fatal error");
|
||||
}
|
|
@ -34,6 +34,7 @@ void Kernel::serviceSVC(u32 svc) {
|
|||
case 0x2B: getProcessInfo(); break;
|
||||
case 0x2D: connectToPort(); break;
|
||||
case 0x32: sendSyncRequest(); break;
|
||||
case 0x35: getProcessID(); break;
|
||||
case 0x37: getThreadID(); break;
|
||||
case 0x38: getResourceLimit(); break;
|
||||
case 0x39: getResourceLimitLimitValues(); break;
|
||||
|
@ -50,12 +51,12 @@ void Kernel::setVersion(u8 major, u8 minor) {
|
|||
mem.kernelVersion = descriptor; // The memory objects needs a copy because you can read the kernel ver from config mem
|
||||
}
|
||||
|
||||
Handle Kernel::makeProcess() {
|
||||
Handle Kernel::makeProcess(u32 id) {
|
||||
const Handle processHandle = makeObject(KernelObjectType::Process);
|
||||
const Handle resourceLimitHandle = makeObject(KernelObjectType::ResourceLimit);
|
||||
|
||||
// Allocate data
|
||||
objects[processHandle].data = new Process();
|
||||
objects[processHandle].data = new Process(id);
|
||||
const auto processData = objects[processHandle].getData<Process>();
|
||||
|
||||
// Link resource limit object with its parent process
|
||||
|
@ -99,7 +100,7 @@ void Kernel::reset() {
|
|||
|
||||
// Allocate handle #0 to a dummy object and make a main process object
|
||||
makeObject(KernelObjectType::Dummy);
|
||||
currentProcess = makeProcess();
|
||||
currentProcess = makeProcess(1); // Use ID = 1 for main process
|
||||
|
||||
// Make main thread object. We do not have to set the entrypoint and SP for it as the ROM loader does.
|
||||
// Main thread seems to have a priority of 0x30. TODO: This creates a dummy context for thread 0,
|
||||
|
@ -107,8 +108,9 @@ void Kernel::reset() {
|
|||
mainThread = makeThread(0, VirtualAddrs::StackTop, 0x30, -2, 0, ThreadStatus::Running);
|
||||
currentThreadIndex = 0;
|
||||
|
||||
// Create global service manager port
|
||||
srvHandle = makePort("srv:");
|
||||
// Create some of the OS ports
|
||||
srvHandle = makePort("srv:"); // Service manager port
|
||||
errorPortHandle = makePort("err:f"); // Error display port
|
||||
}
|
||||
|
||||
// Get pointer to thread-local storage
|
||||
|
@ -142,6 +144,20 @@ void Kernel::outputDebugString() {
|
|||
regs[0] = SVCResult::Success;
|
||||
}
|
||||
|
||||
void Kernel::getProcessID() {
|
||||
const auto pid = regs[1];
|
||||
const auto process = getProcessFromPID(pid);
|
||||
logSVC("GetProcessID(process: %s)\n", getProcessName(pid).c_str());
|
||||
|
||||
if (process == nullptr) [[unlikely]] {
|
||||
regs[0] = SVCResult::BadHandle;
|
||||
return;
|
||||
}
|
||||
|
||||
regs[0] = SVCResult::Success;
|
||||
regs[1] = process->getData<Process>()->id;
|
||||
}
|
||||
|
||||
// Result GetProcessInfo(s64* out, Handle process, ProcessInfoType type)
|
||||
void Kernel::getProcessInfo() {
|
||||
const auto pid = regs[1];
|
||||
|
|
|
@ -39,6 +39,7 @@ void Kernel::connectToPort() {
|
|||
const u32 handlePointer = regs[0];
|
||||
// Read up to max + 1 characters to see if the name is too long
|
||||
std::string port = mem.readString(regs[1], Port::maxNameLen + 1);
|
||||
logSVC("ConnectToPort(handle pointer = %X, port = \"%s\")\n", handlePointer, port.c_str());
|
||||
|
||||
if (port.size() > Port::maxNameLen) {
|
||||
Helpers::panic("ConnectToPort: Port name too long\n");
|
||||
|
@ -55,7 +56,6 @@ void Kernel::connectToPort() {
|
|||
}
|
||||
|
||||
Handle portHandle = optionalHandle.value();
|
||||
logSVC("ConnectToPort(handle pointer = %X, port = \"%s\")\n", handlePointer, port.c_str());
|
||||
|
||||
const auto portData = objects[portHandle].getData<Port>();
|
||||
if (!portData->isPublic) {
|
||||
|
@ -96,6 +96,8 @@ void Kernel::sendSyncRequest() {
|
|||
|
||||
if (portHandle == srvHandle) { // Special-case SendSyncRequest targetting the "srv: port"
|
||||
serviceManager.handleSyncRequest(messagePointer);
|
||||
} else if (portHandle == errorPortHandle) { // Special-case "err:f" for juicy logs too
|
||||
handleErrorSyncRequest(messagePointer);
|
||||
} else {
|
||||
const auto portData = objects[portHandle].getData<Port>();
|
||||
Helpers::panic("SendSyncRequest targetting port %s\n", portData->name);
|
||||
|
|
|
@ -28,8 +28,8 @@ void FSService::handleSyncRequest(u32 messagePointer) {
|
|||
}
|
||||
|
||||
void FSService::initialize(u32 messagePointer) {
|
||||
log("FS::Initialize (failure)\n");
|
||||
mem.write32(messagePointer + 4, Result::Failure);
|
||||
log("FS::Initialize\n");
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
}
|
||||
|
||||
void FSService::openArchive(u32 messagePointer) {
|
||||
|
@ -40,12 +40,17 @@ void FSService::openArchive(u32 messagePointer) {
|
|||
void FSService::openFileDirectly(u32 messagePointer) {
|
||||
const u32 archiveID = mem.read32(messagePointer + 8);
|
||||
const u32 archivePathType = mem.read32(messagePointer + 12);
|
||||
const u32 archivePathSize = mem.read32(messagePointer + 16);
|
||||
const u32 filePathType = mem.read32(messagePointer + 20);
|
||||
const u32 filePathSize = mem.read32(messagePointer + 24);
|
||||
const u32 openFlags = mem.read32(messagePointer + 28);
|
||||
const u32 attributes = mem.read32(messagePointer + 32);
|
||||
const u32 archivePathPointer = mem.read32(messagePointer + 40);
|
||||
const u32 filePathPointer = mem.read32(messagePointer + 48);
|
||||
|
||||
log("FS::OpenFileDirectly (failure)\n");
|
||||
|
||||
mem.write32(messagePointer + 4, Result::Failure);
|
||||
Helpers::panic("[FS::OpenFileDirectly] Tried to open file. Archive ID = %d\n", archiveID);
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write32(messagePointer + 12, 69);
|
||||
//Helpers::panic("[FS::OpenFileDirectly] Tried to open file. Archive ID = %d\n", archiveID);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue