From ad07c70772ee78abc774a1bc5b8c5674dcbddb3b Mon Sep 17 00:00:00 2001 From: wheremyfoodat Date: Mon, 19 Sep 2022 22:19:36 +0300 Subject: [PATCH] [Kernel] Cleaning up --- CMakeLists.txt | 1 + include/kernel/kernel.hpp | 2 ++ include/kernel/kernel_types.hpp | 17 ++++++++++------- src/core/kernel/address_arbiter.cpp | 0 src/core/kernel/events.cpp | 3 --- src/core/kernel/kernel.cpp | 5 +++-- src/core/kernel/memory_management.cpp | 10 +--------- src/core/kernel/ports.cpp | 16 +++------------- src/core/kernel/resource_limits.cpp | 4 +--- 9 files changed, 21 insertions(+), 37 deletions(-) create mode 100644 src/core/kernel/address_arbiter.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 73a5b94e..d1e8348d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,7 @@ set(SOURCE_FILES src/main.cpp src/emulator.cpp src/core/CPU/cpu_dynarmic.cpp src set(KERNEL_SOURCE_FILES src/core/kernel/kernel.cpp src/core/kernel/resource_limits.cpp src/core/kernel/memory_management.cpp src/core/kernel/ports.cpp src/core/kernel/events.cpp src/core/kernel/threads.cpp + src/core/kernel/address_arbiter.cpp ) set(SERVICE_SOURCE_FILES src/core/services/service_manager.cpp src/core/services/apt.cpp src/core/services/hid.cpp src/core/services/fs.cpp src/core/services/gsp_gpu.cpp src/core/services/gsp_lcd.cpp diff --git a/include/kernel/kernel.hpp b/include/kernel/kernel.hpp index fdd9c719..bdd48b09 100644 --- a/include/kernel/kernel.hpp +++ b/include/kernel/kernel.hpp @@ -19,6 +19,8 @@ class Kernel { Handle currentProcess; Handle currentThread; + Handle mainThread; + Handle srvHandle; // Handle for the special service manager port "srv:" u32 threadCount; ServiceManager serviceManager; diff --git a/include/kernel/kernel_types.hpp b/include/kernel/kernel_types.hpp index e1503b5d..3add4b04 100644 --- a/include/kernel/kernel_types.hpp +++ b/include/kernel/kernel_types.hpp @@ -17,7 +17,7 @@ namespace SVCResult { } enum class KernelObjectType : u8 { - Event, Port, Process, ResourceLimit, Session, Thread, Dummy + AddressArbiter, Event, Port, Process, ResourceLimit, Session, Thread, Dummy }; enum class ResourceLimitCategory : int { @@ -47,6 +47,10 @@ enum ResetType { RESET_PULSE = 2, // Only meaningful for timers: same as ONESHOT but it will periodically signal the timer instead of just once. }; +struct AddressArbiter { + +}; + struct ResourceLimits { Handle handle; @@ -62,25 +66,24 @@ struct EventData { ResetType resetType = RESET_ONESHOT; }; -enum class PortType { - Generic, - ServiceManager // For the service manager port "srv:" -}; - struct PortData { static constexpr u32 maxNameLen = 11; char name[maxNameLen + 1] = {}; bool isPublic = false; // Setting name=NULL creates a private port not accessible from svcConnectToPort. - PortType type = PortType::Generic; }; struct SessionData { Handle portHandle; // The port this session is subscribed to }; +struct Thread { + +}; + static const char* kernelObjectTypeToString(KernelObjectType t) { switch (t) { + case KernelObjectType::AddressArbiter: return "address arbiter"; case KernelObjectType::Event: return "event"; case KernelObjectType::Port: return "port"; case KernelObjectType::Process: return "process"; diff --git a/src/core/kernel/address_arbiter.cpp b/src/core/kernel/address_arbiter.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/core/kernel/events.cpp b/src/core/kernel/events.cpp index 46ae4a2b..44b0ae94 100644 --- a/src/core/kernel/events.cpp +++ b/src/core/kernel/events.cpp @@ -20,8 +20,6 @@ Handle Kernel::makeEvent(ResetType resetType) { } // Result CreateEvent(Handle* event, ResetType resetType) -// TODO: Just like getResourceLimit this seems to output the handle in r1 even though 3dbrew doesn't mention this -// Should the handle be written both in memory and r1, or just r1? void Kernel::createEvent() { const u32 outPointer = regs[0]; const u32 resetType = regs[1]; @@ -34,5 +32,4 @@ void Kernel::createEvent() { Handle handle = makeEvent(static_cast(resetType)); regs[0] = SVCResult::Success; regs[1] = handle; - mem.write32(outPointer, handle); } \ No newline at end of file diff --git a/src/core/kernel/kernel.cpp b/src/core/kernel/kernel.cpp index b831da6b..f9b2d390 100644 --- a/src/core/kernel/kernel.cpp +++ b/src/core/kernel/kernel.cpp @@ -72,10 +72,11 @@ void Kernel::reset() { currentProcess = makeProcess(); // 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 - currentThread = makeThread(0, 0, 0x30, 0); + mainThread = makeThread(0, 0, 0x30, 0); + currentThread = mainThread; // Create global service manager port - makePort("srv:"); + srvHandle = makePort("srv:"); } // Get pointer to thread-local storage diff --git a/src/core/kernel/memory_management.cpp b/src/core/kernel/memory_management.cpp index 0489b993..c6787441 100644 --- a/src/core/kernel/memory_management.cpp +++ b/src/core/kernel/memory_management.cpp @@ -76,7 +76,7 @@ void Kernel::queryMemory() { const u32 pageInfo = regs[1]; const u32 addr = regs[2]; - if (addr & 0xfff) { + if (!isAligned(addr)) [[unlikely]] { Helpers::panic("QueryMemory: Address not page aligned\n"); } @@ -89,14 +89,6 @@ void Kernel::queryMemory() { regs[3] = info.perms; regs[4] = info.state; regs[5] = 0; // page flags - - /* - mem.write32(memInfo, info.baseAddr); // Set memInfo->baseVaddr - mem.write32(memInfo + 4, info.size); // Set memInfo->size - mem.write32(memInfo + 8, info.perms); // Set memInfo->perms - mem.write32(memInfo + 12, info.state); // Set memInfo->state - mem.write32(pageInfo, 0); // Set pageInfo->flags to 0 - */ } // Result MapMemoryBlock(Handle memblock, u32 addr, MemoryPermission myPermissions, MemoryPermission otherPermission) diff --git a/src/core/kernel/ports.cpp b/src/core/kernel/ports.cpp index 9f5bea3f..ead1362b 100644 --- a/src/core/kernel/ports.cpp +++ b/src/core/kernel/ports.cpp @@ -12,14 +12,6 @@ Handle Kernel::makePort(const char* name) { // If the name is empty (ie the first char is the null terminator) then the port is private data->isPublic = name[0] != '\0'; - // Check if this a special port (Like the service manager port) or not, and cache its type - if (std::strncmp(name, "srv:", PortData::maxNameLen) == 0) { - data->type = PortType::ServiceManager; - } else { - data->type = PortType::Generic; - Helpers::panic("Created generic port %s\n", name); - } - // printf("Created %s port \"%s\" with handle %d\n", data->isPublic ? "public" : "private", data->name, ret); return ret; } @@ -37,7 +29,6 @@ Handle Kernel::makeSession(Handle portHandle) { // Link session with its parent port sessionData->portHandle = portHandle; - return ret; } @@ -85,7 +76,6 @@ void Kernel::connectToPort() { // TODO: Actually create session Handle sessionHandle = makeSession(portHandle); - // TODO: Should the result be written back to [r0]? regs[0] = SVCResult::Success; regs[1] = sessionHandle; } @@ -113,12 +103,12 @@ void Kernel::sendSyncRequest() { } const auto sessionData = static_cast(session->data); - const auto port = objects[sessionData->portHandle]; // Get parent port object - const auto portData = static_cast(port.data); + const Handle portHandle = sessionData->portHandle; - if (portData->type == PortType::ServiceManager) { // Special-case SendSyncRequest targetting "srv:" + if (portHandle == srvHandle) { // Special-case SendSyncRequest targetting the "srv: port" serviceManager.handleSyncRequest(messagePointer); } else { + const auto portData = static_cast(objects[portHandle].data); Helpers::panic("SendSyncRequest targetting port %s\n", portData->name); } diff --git a/src/core/kernel/resource_limits.cpp b/src/core/kernel/resource_limits.cpp index 9a8a0c3b..30f0d695 100644 --- a/src/core/kernel/resource_limits.cpp +++ b/src/core/kernel/resource_limits.cpp @@ -7,6 +7,7 @@ void Kernel::getResourceLimit() { const auto handlePointer = regs[0]; const auto pid = regs[1]; const auto process = getProcessFromPID(pid); + printf("GetResourceLimit (handle pointer = %08X, process: %s)\n", handlePointer, getProcessName(pid).c_str()); if (process == nullptr) [[unlikely]] { regs[0] = SVCResult::BadHandle; @@ -15,10 +16,7 @@ void Kernel::getResourceLimit() { const auto processData = static_cast(process->data); - printf("GetResourceLimit (handle pointer = %08X, process: %s)\n", handlePointer, getProcessName(pid).c_str()); - mem.write32(handlePointer, processData->limits.handle); regs[0] = SVCResult::Success; - // Is the handle meant to be output through both r1 and memory? Libctru breaks otherwise. regs[1] = processData->limits.handle; }