diff --git a/src/core/kernel/memory_management.cpp b/src/core/kernel/memory_management.cpp index cc8b9313..24943c3a 100644 --- a/src/core/kernel/memory_management.cpp +++ b/src/core/kernel/memory_management.cpp @@ -89,10 +89,17 @@ void Kernel::controlMemory() { } case Operation::Map: + // Official kernel only allows Private regions to be mapped to Free regions. An Alias or Aliased region cannot be mapped again if (!mem.mapVirtualMemory(addr0, addr1, pages, r, w, false, MemoryState::Free, MemoryState::Private, MemoryState::Alias, MemoryState::Aliased)) Helpers::panic("ControlMemory: Failed to map memory"); break; + case Operation::Unmap: + // The same as a Map operation, except in reverse + if (!mem.mapVirtualMemory(addr0, addr1, pages, false, false, false, MemoryState::Alias, MemoryState::Aliased, + MemoryState::Free, MemoryState::Private)) Helpers::panic("ControlMemory: Failed to unmap memory"); + break; + case Operation::Protect: // Official kernel has an internal state bit to indicate that the region's permissions may be changed // But this should account for all cases diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 991c5437..80c2c531 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -426,6 +426,9 @@ bool Memory::allocMemoryLinear(u32& outVaddr, u32 inVaddr, s32 pages, FcramRegio u32 paddr = memList.begin()->paddr; u32 vaddr = getLinearHeapVaddr() + paddr; + auto res = testMemoryState(vaddr, pages, MemoryState::Free); + if (res.isFailure()) Helpers::panic("Unable to map linear allocation (vaddr:%08X pages:%08X)", vaddr, pages); + Operation op{ .newState = MemoryState::Continuous, .r = r, .w = w, .x = x, .changeState = true, .changePerms = true }; changeMemoryState(vaddr, pages, op); mapPhysicalMemory(vaddr, paddr, pages, r, w, x);