summaryrefslogtreecommitdiff
path: root/src/core/memory.cpp
diff options
context:
space:
mode:
authorCamilleLaVey <camillelavey@citron-emu.org>2025-03-04 22:50:01 -0400
committerCamilleLaVey <camillelavey@citron-emu.org>2025-03-04 22:50:01 -0400
commitee3d858935600e23a7914620b21f45082cccf8bd (patch)
treebbc13a49f4f8a73c925024e220e454942a59d1d9 /src/core/memory.cpp
parent31694994f2c338486486efb7d8bc5e954b8a9e07 (diff)
Follow Up Of the previous commit with the update of TLB update
Diffstat (limited to 'src/core/memory.cpp')
-rw-r--r--src/core/memory.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index c598edbc2..dd6ffaf6c 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -1151,4 +1151,51 @@ bool Memory::InvalidateSeparateHeap(void* fault_address) {
#endif
}
+bool Memory::Remap(u64 guest_addr, u32 size) {
+ // Unmap the old address
+ UnmapRegion(*impl->current_page_table, guest_addr, size, false);
+
+ // Reclaim memory from unreferenced pages
+ ReclaimUnusedMemory();
+
+ // Allocate new memory
+ void* new_memory = std::malloc(size);
+ if (!new_memory) {
+ LOG_ERROR(Core_Memory, "Failed to allocate new memory for remapping address {:X}", guest_addr);
+ return false;
+ }
+
+ // Map the new memory to the guest address
+ MapMemoryRegion(*impl->current_page_table, guest_addr, size, reinterpret_cast<u64>(new_memory), Common::MemoryPermission::ReadWrite, false);
+
+ // Verify the mapping
+ if (GetPointer(guest_addr) != nullptr) {
+ LOG_INFO(Core_Memory, "Successfully remapped address {:X}", guest_addr);
+ return true;
+ } else {
+ LOG_ERROR(Core_Memory, "Failed to remap address {:X}", guest_addr);
+ std::free(new_memory);
+ return false;
+ }
+}
+
+void Memory::ReclaimUnusedMemory() {
+ std::lock_guard lock(m_tlb_mutex);
+
+ for (auto& entry : m_tlb) {
+ if (entry.valid && entry.ref_count == 0) {
+ // Unmap the memory region
+ UnmapRegion(*impl->current_page_table, entry.guest_addr, entry.size, false);
+
+ // Free the memory
+ std::free(reinterpret_cast<void*>(entry.host_addr));
+
+ // Invalidate the TLB entry
+ entry.valid = false;
+
+ LOG_INFO(Core_Memory, "Reclaimed memory for address {:X}", entry.guest_addr);
+ }
+ }
+}
+
} // namespace Core::Memory