From 5d6bf24a9df7c5c486c3a1c8a2f5a6d22b8a01fd Mon Sep 17 00:00:00 2001 From: wheremyfoodat Date: Tue, 21 Mar 2023 02:32:47 +0200 Subject: [PATCH] [Kernel] Add memory mirroring function & throw warning on mprotect --- include/memory.hpp | 4 ++++ src/core/PICA/gpu.cpp | 5 +++++ src/core/kernel/memory_management.cpp | 8 ++++++++ src/core/memory.cpp | 18 ++++++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/include/memory.hpp b/include/memory.hpp index ddc2da35..c10e0649 100644 --- a/include/memory.hpp +++ b/include/memory.hpp @@ -223,6 +223,10 @@ public: // Returns a pointer to the FCRAM block used for the memory if allocation succeeded u8* mapSharedMemory(Handle handle, u32 vaddr, u32 myPerms, u32 otherPerms); + // Mirrors the page mapping for "size" bytes starting from sourceAddress, to "size" bytes in destAddress + // All of the above must be page-aligned. + void mirrorMapping(u32 destAddress, u32 sourceAddress, u32 size); + // Backup of the game's CXI partition info, if any std::optional loadedCXI = std::nullopt; // File handle for reading the loaded ncch diff --git a/src/core/PICA/gpu.cpp b/src/core/PICA/gpu.cpp index 9266c28c..5b817888 100644 --- a/src/core/PICA/gpu.cpp +++ b/src/core/PICA/gpu.cpp @@ -196,6 +196,7 @@ void GPU::drawArrays() { //printf("(x, y, z, w) = (%f, %f, %f, %f)\n", (double)vertices[i].position.x(), (double)vertices[i].position.y(), (double)vertices[i].position.z(), (double)vertices[i].position.w()); //printf("(r, g, b, a) = (%f, %f, %f, %f)\n", (double)vertices[i].colour.r(), (double)vertices[i].colour.g(), (double)vertices[i].colour.b(), (double)vertices[i].colour.a()); + //printf("(u, v ) = (%f, %f)\n", vertices[i].UVs.u(), vertices[i].UVs.v()); } // The fourth type is meant to be "Geometry primitive". TODO: Find out what that is @@ -221,6 +222,10 @@ Vertex GPU::getImmediateModeVertex() { std::memcpy(&v.colour, &shaderUnit.vs.outputs[1], sizeof(vec4f)); std::memcpy(&v.UVs, &shaderUnit.vs.outputs[2], 2 * sizeof(f24)); + printf("(x, y, z, w) = (%f, %f, %f, %f)\n", (double)v.position.x(), (double)v.position.y(), (double)v.position.z(), (double)v.position.w()); + printf("(r, g, b, a) = (%f, %f, %f, %f)\n", (double)v.colour.r(), (double)v.colour.g(), (double)v.colour.b(), (double)v.colour.a()); + printf("(u, v ) = (%f, %f)\n", v.UVs.u(), v.UVs.v()); + return v; } void GPU::fireDMA(u32 dest, u32 source, u32 size) { diff --git a/src/core/kernel/memory_management.cpp b/src/core/kernel/memory_management.cpp index 3c171231..18aa93a6 100644 --- a/src/core/kernel/memory_management.cpp +++ b/src/core/kernel/memory_management.cpp @@ -79,6 +79,14 @@ void Kernel::controlMemory() { break; } + case Operation::Map: + mem.mirrorMapping(addr0, addr1, size); + break; + + case Operation::Protect: + Helpers::warn("Ignoring mprotect! Hope nothing goes wrong but if the game accesses invalid memory or crashes then we prolly need to implement this\n"); + break; + default: Helpers::panic("ControlMemory: unknown operation %X\n", operation); } diff --git a/src/core/memory.cpp b/src/core/memory.cpp index e89344e7..65e3f9e2 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -392,6 +392,24 @@ u8* Memory::mapSharedMemory(Handle handle, u32 vaddr, u32 myPerms, u32 otherPerm return nullptr; } +void Memory::mirrorMapping(u32 destAddress, u32 sourceAddress, u32 size) { + // Should theoretically be unreachable, only here for safety purposes + assert(isAligned(destAddress) && isAligned(sourceAddress) && isAligned(size)); + + const u32 pageCount = size / pageSize; // How many pages we need to mirror + for (u32 i = 0; i < pageCount; i++) { + // Redo the shift here to "properly" handle wrapping around the address space instead of reading OoB + const u32 sourcePage = sourceAddress / pageSize; + const u32 destPage = destAddress / pageSize; + + readTable[destPage] = readTable[sourcePage]; + writeTable[destPage] = writeTable[sourcePage]; + + sourceAddress += pageSize; + destAddress += pageSize; + } +} + // Get the number of ms since Jan 1 1900 u64 Memory::timeSince3DSEpoch() { using namespace std::chrono;