mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-06-08 20:11:39 +12:00
Added the rest of the kernel resource functions
This commit is contained in:
parent
a89c850189
commit
0fbc5f210f
8 changed files with 206 additions and 30 deletions
|
@ -7,7 +7,8 @@ void Kernel::serviceSVC(u32 svc) {
|
|||
case 0x21: createAddressArbiter(); break;
|
||||
case 0x38: getResourceLimit(); break;
|
||||
case 0x39: getResourceLimitLimitValues(); break;
|
||||
default: Helpers::panic("Unimplemented svc: %x @ %08X", svc, regs[15]); break;
|
||||
case 0x3A: getResourceLimitCurrentValues(); break;
|
||||
default: Helpers::panic("Unimplemented svc: %X @ %08X", svc, regs[15]); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,31 +57,6 @@ void Kernel::createAddressArbiter() {
|
|||
regs[0] = SVCResult::Success;
|
||||
}
|
||||
|
||||
// Result GetResourceLimit(Handle* resourceLimit, Handle process)
|
||||
// out: r0 -> result
|
||||
void Kernel::getResourceLimit() {
|
||||
const auto handlePointer = regs[0];
|
||||
const auto pid = regs[1];
|
||||
const auto process = getProcessFromPID(pid);
|
||||
|
||||
if (process == nullptr) [[unlikely]] {
|
||||
regs[0] = SVCResult::BadHandle;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto processData = static_cast<ProcessData*>(process->data);
|
||||
|
||||
printf("GetResourceLimit (Handle pointer = %08X, process: %s)\n", handlePointer, getProcessName(pid).c_str());
|
||||
mem.write32(handlePointer, processData->limits.handle);
|
||||
regs[0] = SVCResult::Success;
|
||||
// Is the handle meant to be output through both r1 and memory? Libctru breaks otherwise.
|
||||
regs[1] = processData->limits.handle;
|
||||
}
|
||||
|
||||
void Kernel::getResourceLimitLimitValues() {
|
||||
Helpers::panic("Trying to getResourceLimitLimitValues from resourceLimit with handle %08X\n", regs[1]);
|
||||
}
|
||||
|
||||
std::string Kernel::getProcessName(u32 pid) {
|
||||
if (pid == KernelHandles::CurrentProcess) {
|
||||
return "current";
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
#include "resource_limits.hpp"
|
||||
#include "kernel.hpp"
|
||||
|
||||
// Result GetResourceLimit(Handle* resourceLimit, Handle process)
|
||||
// out: r0 -> result, r1 -> handle
|
||||
void Kernel::getResourceLimit() {
|
||||
const auto handlePointer = regs[0];
|
||||
const auto pid = regs[1];
|
||||
const auto process = getProcessFromPID(pid);
|
||||
|
||||
if (process == nullptr) [[unlikely]] {
|
||||
regs[0] = SVCResult::BadHandle;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto processData = static_cast<ProcessData*>(process->data);
|
||||
|
||||
printf("GetResourceLimit (handle pointer = %08X, process: %s)\n", handlePointer, getProcessName(pid).c_str());
|
||||
mem.write32(handlePointer, processData->limits.handle);
|
||||
regs[0] = SVCResult::Success;
|
||||
// Is the handle meant to be output through both r1 and memory? Libctru breaks otherwise.
|
||||
regs[1] = processData->limits.handle;
|
||||
}
|
||||
|
||||
// Result GetResourceLimitLimitValues(s64* values, Handle resourceLimit, LimitableResource* names, s32 nameCount)
|
||||
void Kernel::getResourceLimitLimitValues() {
|
||||
u32 values = regs[0]; // Pointer to values (The resource limits get output here)
|
||||
const Handle resourceLimit = regs[1];
|
||||
u32 names = regs[2]; // Pointer to resources that we should return
|
||||
u32 count = regs[3]; // Number of resources
|
||||
|
||||
const KernelObject* limit = getObject(resourceLimit, KernelObjectType::ResourceLimit);
|
||||
if (limit == nullptr) [[unlikely]] {
|
||||
regs[0] = SVCResult::BadHandle;
|
||||
return;
|
||||
}
|
||||
|
||||
printf("GetResourceLimitLimitValues(values = %08X, handle = %X, names = %08X, count = %d)\n", values, resourceLimit, names, count);
|
||||
// printf("[Warning] We do not currently support any resource maximum aside from the application ones");
|
||||
while (count != 0) {
|
||||
const u32 name = mem.read32(names);
|
||||
u32 max = getMaxForResource(limit, name);
|
||||
mem.write64(values, u64(max));
|
||||
|
||||
// Increment pointers and decrement count
|
||||
values += sizeof(u64);
|
||||
names += sizeof(u32);
|
||||
count--;
|
||||
}
|
||||
|
||||
regs[0] = SVCResult::Success;
|
||||
}
|
||||
|
||||
// Result GetResourceLimitCurrentValues(s64* values, Handle resourceLimit, LimitableResource* names, s32 nameCount)
|
||||
void Kernel::getResourceLimitCurrentValues() {
|
||||
u32 values = regs[0]; // Pointer to values (The resource limits get output here)
|
||||
const Handle resourceLimit = regs[1];
|
||||
u32 names = regs[2]; // Pointer to resources that we should return
|
||||
u32 count = regs[3]; // Number of resources
|
||||
|
||||
const KernelObject* limit = getObject(resourceLimit, KernelObjectType::ResourceLimit);
|
||||
if (limit == nullptr) [[unlikely]] {
|
||||
regs[0] = SVCResult::BadHandle;
|
||||
return;
|
||||
}
|
||||
|
||||
printf("GetResourceLimitCurrentValues(values = %08X, handle = %X, names = %08X, count = %d)\n", values, resourceLimit, names, count);
|
||||
while (count != 0) {
|
||||
const u32 name = mem.read32(names);
|
||||
// TODO: Unsure if this is supposed to be s32 or u32. Shouldn't matter as the kernel can't create so many resources
|
||||
s32 value = getCurrentResourceValue(limit, name);
|
||||
mem.write64(values, u64(value));
|
||||
|
||||
// Increment pointers and decrement count
|
||||
values += sizeof(u64);
|
||||
names += sizeof(u32);
|
||||
count--;
|
||||
}
|
||||
|
||||
regs[0] = SVCResult::Success;
|
||||
}
|
||||
|
||||
s32 Kernel::getCurrentResourceValue(const KernelObject* limit, u32 resourceName) {
|
||||
const auto data = static_cast<ResourceLimits*>(limit->data);
|
||||
switch (resourceName) {
|
||||
case ResourceType::Commit: return data->currentCommit;
|
||||
default: Helpers::panic("Attempted to get current value of unknown kernel resource: %d\n", resourceName);
|
||||
}
|
||||
}
|
||||
|
||||
u32 Kernel::getMaxForResource(const KernelObject* limit, u32 resourceName) {
|
||||
switch (resourceName) {
|
||||
case ResourceType::Commit: return appResourceLimits.maxCommit;
|
||||
default: Helpers::panic("Attempted to get the max of unknown kernel resource: %d\n", resourceName);
|
||||
}
|
||||
}
|
|
@ -60,6 +60,12 @@ u32 Memory::read32(u32 vaddr) {
|
|||
}
|
||||
}
|
||||
|
||||
u64 Memory::read64(u32 vaddr) {
|
||||
u64 bottom = u64(read32(vaddr));
|
||||
u64 top = u64(read32(vaddr + 4));
|
||||
return (top << 32) | bottom;
|
||||
}
|
||||
|
||||
void Memory::write8(u32 vaddr, u8 value) {
|
||||
const u32 page = vaddr >> pageShift;
|
||||
const u32 offset = vaddr & pageMask;
|
||||
|
@ -89,6 +95,11 @@ void Memory::write32(u32 vaddr, u32 value) {
|
|||
}
|
||||
}
|
||||
|
||||
void Memory::write64(u32 vaddr, u64 value) {
|
||||
write32(vaddr, u32(value));
|
||||
write32(vaddr + 4, u32(value >> 32));
|
||||
}
|
||||
|
||||
void* Memory::getReadPointer(u32 address) {
|
||||
const u32 page = address >> pageShift;
|
||||
const u32 offset = address & pageMask;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue