mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-06-08 20:11:39 +12:00
[Kernel] Hopefully implement the QueryMemory svc remotely correctly
This commit is contained in:
parent
6bb2bd67df
commit
45c016d12e
7 changed files with 92 additions and 3 deletions
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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?
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue