From 6895a1d9d6558e310bc2efc98dea53c1ec68a7d7 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Sun, 20 Aug 2023 01:51:24 +0300 Subject: [PATCH 1/3] Implement svcGetCurrentProcessorNumber --- include/kernel/kernel.hpp | 3 ++- include/kernel/kernel_types.hpp | 12 ++++++++++- src/core/kernel/kernel.cpp | 3 ++- src/core/kernel/threads.cpp | 35 +++++++++++++++++++++++++++++++-- 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/include/kernel/kernel.hpp b/include/kernel/kernel.hpp index 9fedd161..8e924c4d 100644 --- a/include/kernel/kernel.hpp +++ b/include/kernel/kernel.hpp @@ -61,7 +61,7 @@ class Kernel { Handle makeProcess(u32 id); Handle makePort(const char* name); Handle makeSession(Handle port); - Handle makeThread(u32 entrypoint, u32 initialSP, u32 priority, s32 id, u32 arg,ThreadStatus status = ThreadStatus::Dormant); + Handle makeThread(u32 entrypoint, u32 initialSP, u32 priority, ProcessorID id, u32 arg,ThreadStatus status = ThreadStatus::Dormant); Handle makeMemoryBlock(u32 addr, u32 size, u32 myPermission, u32 otherPermission); public: @@ -126,6 +126,7 @@ private: void exitThread(); void mapMemoryBlock(); void queryMemory(); + void getCurrentProcessorNumber(); void getProcessID(); void getProcessInfo(); void getResourceLimit(); diff --git a/include/kernel/kernel_types.hpp b/include/kernel/kernel_types.hpp index 56bed359..6f32bad4 100644 --- a/include/kernel/kernel_types.hpp +++ b/include/kernel/kernel_types.hpp @@ -34,6 +34,16 @@ enum class ArbitrationType { DecrementAndWaitIfLessTimeout = 4 }; +enum class ProcessorID : s32 { + AllCPUs = -1, + Default = -2, + + AppCore = 0, + Syscore = 1, + New3DSExtra1 = 2, + New3DSExtra2 = 3 +}; + struct AddressArbiter {}; struct ResourceLimits { @@ -95,7 +105,7 @@ struct Thread { u32 entrypoint; // Initial r15 value u32 priority; u32 arg; - s32 processorID; + ProcessorID processorID; ThreadStatus status; Handle handle; // OS handle for this thread int index; // Index of the thread. 0 for the first thread, 1 for the second, and so on diff --git a/src/core/kernel/kernel.cpp b/src/core/kernel/kernel.cpp index 837d20dd..677a0d5f 100644 --- a/src/core/kernel/kernel.cpp +++ b/src/core/kernel/kernel.cpp @@ -35,6 +35,7 @@ void Kernel::serviceSVC(u32 svc) { case 0x0A: svcSleepThread(); break; case 0x0B: getThreadPriority(); break; case 0x0C: setThreadPriority(); break; + case 0x11: getCurrentProcessorNumber(); break; case 0x13: svcCreateMutex(); break; case 0x14: svcReleaseMutex(); break; case 0x15: svcCreateSemaphore(); break; @@ -158,7 +159,7 @@ void Kernel::reset() { // 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, // which is thankfully not used. Maybe we should prevent this - mainThread = makeThread(0, VirtualAddrs::StackTop, 0x30, -2, 0, ThreadStatus::Running); + mainThread = makeThread(0, VirtualAddrs::StackTop, 0x30, ProcessorID::Default, 0, ThreadStatus::Running); currentThreadIndex = 0; setupIdleThread(); diff --git a/src/core/kernel/threads.cpp b/src/core/kernel/threads.cpp index 440045d3..68e02d56 100644 --- a/src/core/kernel/threads.cpp +++ b/src/core/kernel/threads.cpp @@ -106,7 +106,7 @@ void Kernel::rescheduleThreads() { } // Internal OS function to spawn a thread -Handle Kernel::makeThread(u32 entrypoint, u32 initialSP, u32 priority, s32 id, u32 arg, ThreadStatus status) { +Handle Kernel::makeThread(u32 entrypoint, u32 initialSP, u32 priority, ProcessorID id, u32 arg, ThreadStatus status) { int index; // Index of the created thread in the threads array if (threadCount < appResourceLimits.maxThreads) [[likely]] { // If we have not yet created over too many threads @@ -389,8 +389,14 @@ void Kernel::createThread() { return; } + if (id < -2 && id > 3) { + Helpers::warn("Invalid processor ID in CreateThread"); + // TODO: This should return an error + id = static_cast(ProcessorID::AppCore); + } + regs[0] = Result::Success; - regs[1] = makeThread(entrypoint, initialSP, priority, id, arg, ThreadStatus::Ready); + regs[1] = makeThread(entrypoint, initialSP, priority, static_cast(id), arg, ThreadStatus::Ready); requireReschedule(); } @@ -468,6 +474,31 @@ void Kernel::setThreadPriority() { requireReschedule(); } +void Kernel::getCurrentProcessorNumber() { + const ProcessorID id = threads[currentThreadIndex].processorID; + s32 ret; + + // Until we properly implement per-core schedulers, return whatever processor ID passed to svcCreateThread + switch (id) { + case ProcessorID::Default: + ret = static_cast(ProcessorID::AppCore); + break; + + case ProcessorID::AllCPUs: + ret = static_cast(ProcessorID::AppCore); + Helpers::warn("GetCurrentProcessorNumber on thread created to run on all CPUs...?\n"); + break; + + default: ret = static_cast(id); break; + } + + if (ret != static_cast(ProcessorID::AppCore)) { + Helpers::warn("GetCurrentProcessorNumber: Thread not running on appcore\n"); + } + + regs[0] = ret; +} + void Kernel::exitThread() { logSVC("ExitThread\n"); From 5b8bb12860ade96dbecc030d2f6a2286295fa528 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Sun, 20 Aug 2023 01:52:23 +0300 Subject: [PATCH 2/3] Make svcCreateThread panic with invalid IDs --- src/core/kernel/threads.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/kernel/threads.cpp b/src/core/kernel/threads.cpp index 68e02d56..96026365 100644 --- a/src/core/kernel/threads.cpp +++ b/src/core/kernel/threads.cpp @@ -389,10 +389,8 @@ void Kernel::createThread() { return; } - if (id < -2 && id > 3) { - Helpers::warn("Invalid processor ID in CreateThread"); - // TODO: This should return an error - id = static_cast(ProcessorID::AppCore); + if (id < -2 || id > 3) { + Helpers::panic("Invalid processor ID in CreateThread"); } regs[0] = Result::Success; From 8a435cc36b8c0ac76b47ae51fd764a5e517f3a8e Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Sun, 20 Aug 2023 01:54:45 +0300 Subject: [PATCH 3/3] Add note about default processor ID --- src/core/kernel/threads.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/kernel/threads.cpp b/src/core/kernel/threads.cpp index 96026365..2f6a27b9 100644 --- a/src/core/kernel/threads.cpp +++ b/src/core/kernel/threads.cpp @@ -478,6 +478,7 @@ void Kernel::getCurrentProcessorNumber() { // Until we properly implement per-core schedulers, return whatever processor ID passed to svcCreateThread switch (id) { + // TODO: This is picked from exheader case ProcessorID::Default: ret = static_cast(ProcessorID::AppCore); break; @@ -494,7 +495,7 @@ void Kernel::getCurrentProcessorNumber() { Helpers::warn("GetCurrentProcessorNumber: Thread not running on appcore\n"); } - regs[0] = ret; + regs[0] = static_cast(ret); } void Kernel::exitThread() {