#pragma once #include <array> #include <limits> #include <string> #include <vector> #include "kernel_types.hpp" #include "helpers.hpp" #include "memory.hpp" #include "services/service_manager.hpp" class Kernel { std::array<u32, 16>& regs; Memory& mem; // The handle number for the next kernel object to be created u32 handleCounter; std::vector<KernelObject> objects; std::vector<Handle> portHandles; u32 currentProcess; ServiceManager serviceManager; // Get pointer to the object with the specified handle KernelObject* getObject(u32 handle) { // Accessing an object that has not been created if (handle >= objects.size()) [[unlikely]] { return nullptr; } return &objects[handle]; } // Get pointer to the object with the specified handle and type KernelObject* getObject(u32 handle, KernelObjectType type) { if (handle >= objects.size() || objects[handle].type != type) [[unlikely]] { return nullptr; } return &objects[handle]; } Handle makeObject(KernelObjectType type) { if (handleCounter > KernelHandles::Max) [[unlikely]] { Helpers::panic("Hlep we somehow created enough kernel objects to overflow this thing"); } objects.push_back(KernelObject(handleCounter, type)); printf("Created %s object with handle %d\n", kernelObjectTypeToString(type), handleCounter); return handleCounter++; } Handle makeEvent(u32 resetType); Handle makeProcess(); Handle makePort(const char* name); Handle makeSession(Handle port); std::optional<Handle> getPortHandle(const char* name); void deleteObjectData(KernelObject& object); KernelObject* getProcessFromPID(Handle handle); s32 getCurrentResourceValue(const KernelObject* limit, u32 resourceName); u32 getMaxForResource(const KernelObject* limit, u32 resourceName); u32 getTLSPointer(); std::string getProcessName(u32 pid); // SVC implementations void createAddressArbiter(); void createEvent(); void controlMemory(); void getResourceLimit(); void getResourceLimitLimitValues(); void getResourceLimitCurrentValues(); void sendSyncRequest(); void svcCloseHandle(); void connectToPort(); void outputDebugString(); public: Kernel(std::array<u32, 16>& regs, Memory& mem) : regs(regs), mem(mem), handleCounter(0), serviceManager(regs, mem, currentProcess) { objects.reserve(512); // Make room for a few objects to avoid further memory allocs later portHandles.reserve(32); } void serviceSVC(u32 svc); void reset(); };