mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-20 04:29:13 +12:00
Merge branch 'master' into timerz
This commit is contained in:
commit
1d601e41ba
63 changed files with 871 additions and 262282 deletions
|
@ -3,8 +3,8 @@
|
|||
#include "kernel_types.hpp"
|
||||
#include "cpu.hpp"
|
||||
|
||||
Kernel::Kernel(CPU& cpu, Memory& mem, GPU& gpu)
|
||||
: cpu(cpu), regs(cpu.regs()), mem(mem), handleCounter(0), serviceManager(regs, mem, gpu, currentProcess, *this) {
|
||||
Kernel::Kernel(CPU& cpu, Memory& mem, GPU& gpu, const EmulatorConfig& config)
|
||||
: cpu(cpu), regs(cpu.regs()), mem(mem), handleCounter(0), serviceManager(regs, mem, gpu, currentProcess, *this, config) {
|
||||
objects.reserve(512); // Make room for a few objects to avoid further memory allocs later
|
||||
mutexHandles.reserve(8);
|
||||
timerHandles.reserve(8);
|
||||
|
@ -36,6 +36,8 @@ void Kernel::serviceSVC(u32 svc) {
|
|||
case 0x0A: svcSleepThread(); break;
|
||||
case 0x0B: getThreadPriority(); break;
|
||||
case 0x0C: setThreadPriority(); break;
|
||||
case 0x0F: getThreadIdealProcessor(); break;
|
||||
case 0x11: getCurrentProcessorNumber(); break;
|
||||
case 0x13: svcCreateMutex(); break;
|
||||
case 0x14: svcReleaseMutex(); break;
|
||||
case 0x15: svcCreateSemaphore(); break;
|
||||
|
@ -161,7 +163,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();
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "kernel.hpp"
|
||||
#include "services/shared_font.hpp"
|
||||
|
||||
namespace Operation {
|
||||
enum : u32 {
|
||||
|
@ -137,7 +136,7 @@ void Kernel::mapMemoryBlock() {
|
|||
break;
|
||||
|
||||
case KernelHandles::FontSharedMemHandle:
|
||||
std::memcpy(ptr, _shared_font_bin, _shared_font_len);
|
||||
mem.copySharedFont(ptr);
|
||||
break;
|
||||
|
||||
default: Helpers::panic("Mapping unknown shared memory block: %X", block);
|
||||
|
|
|
@ -109,7 +109,7 @@ void Kernel::sendSyncRequest() {
|
|||
// If we're actually communicating with a port
|
||||
const auto session = getObject(handle, KernelObjectType::Session);
|
||||
if (session == nullptr) [[unlikely]] {
|
||||
Helpers::panic("SendSyncRequest: Invalid handle");
|
||||
Helpers::warn("SendSyncRequest: Invalid handle");
|
||||
regs[0] = Result::Kernel::InvalidHandle;
|
||||
return;
|
||||
}
|
||||
|
@ -127,4 +127,4 @@ void Kernel::sendSyncRequest() {
|
|||
const auto portData = objects[portHandle].getData<Port>();
|
||||
Helpers::panic("SendSyncRequest targetting port %s\n", portData->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,6 +89,7 @@ s32 Kernel::getCurrentResourceValue(const KernelObject* limit, u32 resourceName)
|
|||
u32 Kernel::getMaxForResource(const KernelObject* limit, u32 resourceName) {
|
||||
switch (resourceName) {
|
||||
case ResourceType::Commit: return appResourceLimits.maxCommit;
|
||||
case ResourceType::Thread: return appResourceLimits.maxThreads;
|
||||
default: Helpers::panic("Attempted to get the max of unknown kernel resource: %d\n", resourceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -397,8 +397,12 @@ void Kernel::createThread() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (id < -2 || id > 3) {
|
||||
Helpers::panic("Invalid processor ID in CreateThread");
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -449,6 +453,15 @@ void Kernel::getThreadPriority() {
|
|||
}
|
||||
}
|
||||
|
||||
void Kernel::getThreadIdealProcessor() {
|
||||
const Handle handle = regs[1]; // Thread handle
|
||||
logSVC("GetThreadIdealProcessor (handle = %X)\n", handle);
|
||||
|
||||
// TODO: Not documented what this is or what it does. Citra doesn't implement it at all. Return AppCore as the ideal processor for now
|
||||
regs[0] = Result::Success;
|
||||
regs[1] = static_cast<u32>(ProcessorID::AppCore);
|
||||
}
|
||||
|
||||
void Kernel::setThreadPriority() {
|
||||
const Handle handle = regs[0];
|
||||
const u32 priority = regs[1];
|
||||
|
@ -476,6 +489,33 @@ void Kernel::setThreadPriority() {
|
|||
requireReschedule();
|
||||
}
|
||||
|
||||
void Kernel::getCurrentProcessorNumber() {
|
||||
logSVC("GetCurrentProcessorNumber()\n");
|
||||
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() {
|
||||
logSVC("ExitThread\n");
|
||||
|
||||
|
@ -630,4 +670,4 @@ bool Kernel::shouldWaitOnObject(KernelObject* object) {
|
|||
Helpers::panic("Not sure whether to wait on object (type: %s)", object->getTypeName());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue