[Kernel] Hopefully implement the QueryMemory svc remotely correctly

This commit is contained in:
wheremyfoodat 2022-09-19 01:33:12 +03:00
parent 6bb2bd67df
commit 45c016d12e
7 changed files with 92 additions and 3 deletions

View file

@ -5,6 +5,7 @@
void Kernel::serviceSVC(u32 svc) {
switch (svc) {
case 0x01: controlMemory(); break;
case 0x02: queryMemory(); break;
case 0x17: createEvent(); break;
case 0x21: createAddressArbiter(); break;
case 0x23: svcCloseHandle(); break;

View file

@ -67,4 +67,26 @@ void Kernel::controlMemory() {
}
regs[0] = SVCResult::Success;
}
// Result QueryMemory(MemoryInfo* memInfo, PageInfo* pageInfo, u32 addr)
void Kernel::queryMemory() {
const u32 memInfo = regs[0];
const u32 pageInfo = regs[1];
const u32 addr = regs[2];
if (addr & 0xfff) {
Helpers::panic("QueryMemory: Address not page aligned\n");
}
printf("QueryMemory(mem info pointer = %08X, page info pointer = %08X, addr = %08X)\n", memInfo, pageInfo, addr);
const auto info = mem.queryMemory(addr);
regs[0] = SVCResult::Success;
mem.write32(memInfo, info.baseVaddr); // Set memInfo->baseVaddr
mem.write32(memInfo + 4, info.size); // Set memInfo->size
mem.write32(memInfo + 8, info.baseVaddr); // Set memInfo->perms
mem.write32(memInfo + 12, info.state); // Set memInfo->state
mem.write32(pageInfo, 0); // Set pageInfo->flags to 0
}

View file

@ -2,14 +2,18 @@
#include "config_mem.hpp"
#include <cassert>
using namespace KernelMemoryTypes;
Memory::Memory() {
fcram = new uint8_t[FCRAM_SIZE]();
readTable.resize(totalPageCount, 0);
writeTable.resize(totalPageCount, 0);
memoryInfo.reserve(32); // Pre-allocate some room for memory allocation info to avoid dynamic allocs
}
void Memory::reset() {
// Unallocate all memory
memoryInfo.clear();
usedFCRAMPages.reset();
usedUserMemory = 0_MB;
@ -76,13 +80,17 @@ std::optional<u32> Memory::allocateMemory(u32 vaddr, u32 paddr, u32 size, bool l
if (w) {
writeTable[virtualPage] = uintptr_t(&fcram[physPage * pageSize]);
}
// Mark FCRAM page as allocated and go on
usedFCRAMPages[physPage] = true;
virtualPage++;
physPage++;
}
// Back up the info for this allocation in our memoryInfo vector
u32 perms = (r ? PERMISSION_R : 0) | (w ? PERMISSION_W : 0) | (x ? PERMISSION_X : 0);
memoryInfo.push_back(std::move(MemoryInfo(vaddr, size, perms, KernelMemoryTypes::Reserved)));
return vaddr;
}
@ -218,4 +226,20 @@ std::string Memory::readString(u32 address, u32 maxSize) {
string.shrink_to_fit();
return string;
}
// The way I understand how the kernel's QueryMemory is supposed to work is that you give it a vaddr
// And the kernel looks up the memory allocations it's performed, finds which one it belongs in and returns its info?
// TODO: Verify this
MemoryInfo Memory::queryMemory(u32 vaddr) {
// Check each allocation
for (auto& alloc : memoryInfo) {
// Check if the memory address belongs in this allocation and return the info if so
if (vaddr >= alloc.baseVaddr && vaddr < alloc.end()) {
return alloc;
}
}
// Otherwise, if this vaddr was never allocated
return MemoryInfo(vaddr, 0, 0, KernelMemoryTypes::Free);
}

View file

@ -12,7 +12,7 @@ namespace GPUCommands {
namespace Result {
enum : u32 {
Success = 0,
SuccessRegisterIRQ = 0x2A07
SuccessRegisterIRQ = 0x2A07 // TODO: Is this a reference to the Ricoh 2A07 used in PAL NES systems?
};
}