[Kernel] CreateThread stub

This commit is contained in:
wheremyfoodat 2022-09-19 16:29:50 +03:00
parent 765b51696e
commit 1c4348248d
8 changed files with 58 additions and 7 deletions

View file

@ -6,6 +6,7 @@ void Kernel::serviceSVC(u32 svc) {
switch (svc) {
case 0x01: controlMemory(); break;
case 0x02: queryMemory(); break;
case 0x08: createThread(); break;
case 0x17: createEvent(); break;
case 0x1F: mapMemoryBlock(); break;
case 0x21: createAddressArbiter(); break;
@ -57,6 +58,7 @@ void Kernel::deleteObjectData(KernelObject& object) {
void Kernel::reset() {
handleCounter = 0;
threadCount = 0;
for (auto& object : objects) {
deleteObjectData(object);
@ -68,6 +70,9 @@ void Kernel::reset() {
// Allocate handle #0 to a dummy object and make a main process object
makeObject(KernelObjectType::Dummy);
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);
// Create global service manager port
makePort("srv:");

View file

@ -0,0 +1,33 @@
#include "kernel.hpp"
#include "resource_limits.hpp"
// Internal OS function to spawn a thread
Handle Kernel::makeThread(u32 entrypoint, u32 initialSP, u32 priority, u32 id) {
if (threadCount >= appResourceLimits.maxThreads) {
Helpers::panic("Overflowed the number of threads");
}
threadCount++;
// TODO: Actually create the thread
return makeObject(KernelObjectType::Thread);
}
// Result CreateThread(s32 priority, ThreadFunc entrypoint, u32 arg, u32 stacktop, s32 threadPriority, s32 processorID)
void Kernel::createThread() {
u32 priority = regs[0];
u32 entrypoint = regs[1];
u32 initialSP = regs[3] & ~7; // SP is force-aligned to 8 bytes
u32 id = regs[4];
printf("CreateThread(entry = %08X, stacktop = %08X, priority = %X, processor ID = %d)\n", entrypoint,
initialSP, priority, id);
if (!(priority <= 0x3F)) [[unlikely]] {
Helpers::panic("Created thread with bad priority value %X", priority);
regs[0] = SVCResult::BadThreadPriority;
return;
}
regs[0] = SVCResult::Success;
regs[1] = makeThread(entrypoint, initialSP, priority, id);
}

View file

@ -58,9 +58,9 @@ void GPUService::registerInterruptRelayQueue(u32 messagePointer) {
printf("GSP::GPU::RegisterInterruptRelayQueue (flags = %X, event handle = %X)\n", flags, eventHandle);
mem.write32(messagePointer + 4, Result::SuccessRegisterIRQ);
mem.write32(messagePointer + 8, 79797979); // TODO: GSP module thread index
mem.write32(messagePointer + 8, 0); // TODO: GSP module thread index
mem.write32(messagePointer + 12, 0); // Translation descriptor
mem.write32(messagePointer + 16, KernelHandles::GSPSharedMemHandle); // TODO: GSP shared memory handle
mem.write32(messagePointer + 16, KernelHandles::GSPSharedMemHandle);
}
void GPUService::writeHwRegs(u32 messagePointer) {

View file

@ -5,6 +5,8 @@ void Emulator::reset() {
cpu.reset();
kernel.reset();
// Reloading r13 and r15 needs to happen after everything has been reset
// Otherwise resetting the kernel or cpu might nuke them
cpu.setReg(13, VirtualAddrs::StackTop); // Set initial SP
if (romType == ROMType::ELF) { // Reload ELF if we're using one
loadELF(loadedROM);

View file

@ -7,7 +7,7 @@ int main (int argc, char *argv[]) {
Helpers::panic("Failed to initialize OpenGL");
}
auto elfPath = std::filesystem::current_path() / (argc > 1 ? argv[1] : "sm64.elf");
auto elfPath = std::filesystem::current_path() / (argc > 1 ? argv[1] : "SimplerTri.elf");
if (!emu.loadELF(elfPath)) {
Helpers::panic("Failed to load ELF file: %s", elfPath.c_str());
}