Merge pull request #213 from wheremyfoodat/services

Implement the GetCurrentProcessorNumber SVC
This commit is contained in:
wheremyfoodat 2023-08-20 02:13:46 +03:00 committed by GitHub
commit 4fc94298a7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 47 additions and 5 deletions

View file

@ -61,7 +61,7 @@ class Kernel {
Handle makeProcess(u32 id); Handle makeProcess(u32 id);
Handle makePort(const char* name); Handle makePort(const char* name);
Handle makeSession(Handle port); 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); Handle makeMemoryBlock(u32 addr, u32 size, u32 myPermission, u32 otherPermission);
public: public:
@ -126,6 +126,7 @@ private:
void exitThread(); void exitThread();
void mapMemoryBlock(); void mapMemoryBlock();
void queryMemory(); void queryMemory();
void getCurrentProcessorNumber();
void getProcessID(); void getProcessID();
void getProcessInfo(); void getProcessInfo();
void getResourceLimit(); void getResourceLimit();

View file

@ -34,6 +34,16 @@ enum class ArbitrationType {
DecrementAndWaitIfLessTimeout = 4 DecrementAndWaitIfLessTimeout = 4
}; };
enum class ProcessorID : s32 {
AllCPUs = -1,
Default = -2,
AppCore = 0,
Syscore = 1,
New3DSExtra1 = 2,
New3DSExtra2 = 3
};
struct AddressArbiter {}; struct AddressArbiter {};
struct ResourceLimits { struct ResourceLimits {
@ -95,7 +105,7 @@ struct Thread {
u32 entrypoint; // Initial r15 value u32 entrypoint; // Initial r15 value
u32 priority; u32 priority;
u32 arg; u32 arg;
s32 processorID; ProcessorID processorID;
ThreadStatus status; ThreadStatus status;
Handle handle; // OS handle for this thread 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 int index; // Index of the thread. 0 for the first thread, 1 for the second, and so on

View file

@ -35,6 +35,7 @@ void Kernel::serviceSVC(u32 svc) {
case 0x0A: svcSleepThread(); break; case 0x0A: svcSleepThread(); break;
case 0x0B: getThreadPriority(); break; case 0x0B: getThreadPriority(); break;
case 0x0C: setThreadPriority(); break; case 0x0C: setThreadPriority(); break;
case 0x11: getCurrentProcessorNumber(); break;
case 0x13: svcCreateMutex(); break; case 0x13: svcCreateMutex(); break;
case 0x14: svcReleaseMutex(); break; case 0x14: svcReleaseMutex(); break;
case 0x15: svcCreateSemaphore(); 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. // 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, // 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 // 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; currentThreadIndex = 0;
setupIdleThread(); setupIdleThread();

View file

@ -106,7 +106,7 @@ void Kernel::rescheduleThreads() {
} }
// Internal OS function to spawn a thread // 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 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 if (threadCount < appResourceLimits.maxThreads) [[likely]] { // If we have not yet created over too many threads
@ -389,8 +389,12 @@ void Kernel::createThread() {
return; return;
} }
if (id < -2 || id > 3) {
Helpers::panic("Invalid processor ID in CreateThread");
}
regs[0] = Result::Success; regs[0] = Result::Success;
regs[1] = makeThread(entrypoint, initialSP, priority, id, arg, ThreadStatus::Ready); regs[1] = makeThread(entrypoint, initialSP, priority, static_cast<ProcessorID>(id), arg, ThreadStatus::Ready);
requireReschedule(); requireReschedule();
} }
@ -468,6 +472,32 @@ void Kernel::setThreadPriority() {
requireReschedule(); 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) {
// TODO: This is picked from exheader
case ProcessorID::Default:
ret = static_cast<s32>(ProcessorID::AppCore);
break;
case ProcessorID::AllCPUs:
ret = static_cast<s32>(ProcessorID::AppCore);
Helpers::warn("GetCurrentProcessorNumber on thread created to run on all CPUs...?\n");
break;
default: ret = static_cast<s32>(id); break;
}
if (ret != static_cast<s32>(ProcessorID::AppCore)) {
Helpers::warn("GetCurrentProcessorNumber: Thread not running on appcore\n");
}
regs[0] = static_cast<u32>(ret);
}
void Kernel::exitThread() { void Kernel::exitThread() {
logSVC("ExitThread\n"); logSVC("ExitThread\n");