[Kernel] Start implementing address arbiters

This commit is contained in:
wheremyfoodat 2022-09-20 00:53:39 +03:00
parent f100601caf
commit 8bfa29568a
7 changed files with 58 additions and 13 deletions

View file

@ -21,11 +21,12 @@ class Kernel {
Handle currentThread;
Handle mainThread;
Handle srvHandle; // Handle for the special service manager port "srv:"
u32 arbiterCount;
u32 threadCount;
ServiceManager serviceManager;
// Get pointer to the object with the specified handle
KernelObject* getObject(u32 handle) {
KernelObject* getObject(Handle handle) {
// Accessing an object that has not been created
if (handle >= objects.size()) [[unlikely]] {
return nullptr;
@ -35,7 +36,7 @@ class Kernel {
}
// Get pointer to the object with the specified handle and type
KernelObject* getObject(u32 handle, KernelObjectType type) {
KernelObject* getObject(Handle handle, KernelObjectType type) {
if (handle >= objects.size() || objects[handle].type != type) [[unlikely]] {
return nullptr;
}
@ -53,6 +54,7 @@ class Kernel {
return handleCounter++;
}
Handle makeArbiter();
Handle makeEvent(ResetType resetType);
Handle makeProcess();
Handle makePort(const char* name);
@ -71,6 +73,7 @@ class Kernel {
const char* resetTypeToString(u32 type);
// SVC implementations
void arbitrateAddress();
void createAddressArbiter();
void createEvent();
void createThread();

View file

@ -88,7 +88,13 @@ struct Session {
};
struct Thread {
u32 initialSP; // Initial r13 value
u32 entrypoint; // Initial r15 value
u32 priority;
u32 processorID;
Thread(u32 initialSP, u32 entrypoint, u32 priority, u32 processorID) : initialSP(initialSP), entrypoint(entrypoint),
priority(priority), processorID(processorID) {}
};
static const char* kernelObjectTypeToString(KernelObjectType t) {

View file

@ -0,0 +1,40 @@
#include "kernel.hpp"
#include "resource_limits.hpp"
Handle Kernel::makeArbiter() {
if (arbiterCount >= appResourceLimits.maxAddressArbiters) {
Helpers::panic("Overflowed the number of address arbiters");
}
arbiterCount++;
Handle ret = makeObject(KernelObjectType::AddressArbiter);
objects[ret].data = new AddressArbiter();
return ret;
}
// Result CreateAddressArbiter(Handle* arbiter)
void Kernel::createAddressArbiter() {
regs[0] = SVCResult::Success;
regs[1] = makeArbiter();
}
// Result ArbitrateAddress(Handle arbiter, u32 addr, ArbitrationType type, s32 value, s64 nanoseconds)
void Kernel::arbitrateAddress() {
const Handle handle = regs[0];
const u32 address = regs[1];
const u32 type = regs[2];
const u32 value = regs[3];
const s64 ns = s64(u64(regs[4]) | (u64(regs[5]) << 32));
printf("ArbitrateAddress(Handle = %X, address = %08X, type = %d, value = %d, ns = %lld)\n", handle, address, type,
value, ns);
const auto arbiter = getObject(handle, KernelObjectType::AddressArbiter);
if (arbiter == nullptr) [[unlikely]] {
regs[0] = SVCResult::BadHandle;
return;
}
Helpers::panic("My balls\n");
regs[0] = SVCResult::Success;
}

View file

@ -25,7 +25,6 @@ void Kernel::createEvent() {
printf("CreateEvent(handle pointer = %08X, resetType = %s)\n", outPointer, resetTypeToString(resetType));
Handle handle = makeEvent(static_cast<ResetType>(resetType));
regs[0] = SVCResult::Success;
regs[1] = handle;
regs[1] = makeEvent(static_cast<ResetType>(resetType));
}

View file

@ -10,6 +10,7 @@ void Kernel::serviceSVC(u32 svc) {
case 0x17: createEvent(); break;
case 0x1F: mapMemoryBlock(); break;
case 0x21: createAddressArbiter(); break;
case 0x22: arbitrateAddress(); break;
case 0x23: svcCloseHandle(); break;
case 0x2D: connectToPort(); break;
case 0x32: sendSyncRequest(); break;
@ -58,6 +59,7 @@ void Kernel::deleteObjectData(KernelObject& object) {
void Kernel::reset() {
handleCounter = 0;
arbiterCount = 0;
threadCount = 0;
for (auto& object : objects) {
@ -85,12 +87,6 @@ u32 Kernel::getTLSPointer() {
return VirtualAddrs::TLSBase;
}
// Result CreateAddressArbiter(Handle* arbiter)
void Kernel::createAddressArbiter() {
printf("Stubbed call to CreateAddressArbiter. Handle address: %08X\n", regs[0]);
regs[0] = SVCResult::Success;
}
// Result CloseHandle(Handle handle)
void Kernel::svcCloseHandle() {
printf("CloseHandle(handle = %d) (Unimplemented)\n", regs[0]);

View file

@ -56,7 +56,7 @@ void Kernel::connectToPort() {
}
Handle portHandle = optionalHandle.value();
printf("ConnectToPort(handle pointer = %08X, port = \"%s\")\n", handlePointer, port.c_str());
printf("ConnectToPort(handle pointer = %X, port = \"%s\")\n", handlePointer, port.c_str());
const auto portData = objects[portHandle].getData<Port>();
if (!portData->isPublic) {

View file

@ -8,8 +8,9 @@ Handle Kernel::makeThread(u32 entrypoint, u32 initialSP, u32 priority, u32 id) {
}
threadCount++;
// TODO: Actually create the thread
return makeObject(KernelObjectType::Thread);
Handle ret = makeObject(KernelObjectType::Thread);
objects[ret].data = new Thread(initialSP, entrypoint, priority, id);
return ret;
}
// Result CreateThread(s32 priority, ThreadFunc entrypoint, u32 arg, u32 stacktop, s32 threadPriority, s32 processorID)