diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index b4444c869b..2595defdf0 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -52,6 +52,7 @@ static Dynarmic::UserCallbacks GetUserCallbacks(ARMul_State* interpeter_state) { user_callbacks.MemoryWrite16 = &Memory::Write16; user_callbacks.MemoryWrite32 = &Memory::Write32; user_callbacks.MemoryWrite64 = &Memory::Write64; + user_callbacks.page_table = Memory::GetCurrentPageTablePointers(); return user_callbacks; } diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 64c388374c..65e4bba854 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -45,13 +45,11 @@ struct SpecialRegion { * requires an indexed fetch and a check for NULL. */ struct PageTable { - static const size_t NUM_ENTRIES = 1 << (32 - PAGE_BITS); - /** * Array of memory pointers backing each page. An entry can only be non-null if the * corresponding entry in the `attributes` array is of type `Memory`. */ - std::array pointers; + std::array pointers; /** * Contains MMIO handlers that back memory regions whose entries in the `attribute` array is of @@ -63,13 +61,13 @@ struct PageTable { * Array of fine grained page attributes. If it is set to any value other than `Memory`, then * the corresponding entry in `pointers` MUST be set to null. */ - std::array attributes; + std::array attributes; /** * Indicates the number of externally cached resources touching a page that should be * flushed before the memory is accessed */ - std::array cached_res_count; + std::array cached_res_count; }; /// Singular page table used for the singleton process @@ -77,6 +75,10 @@ static PageTable main_page_table; /// Currently active page table static PageTable* current_page_table = &main_page_table; +std::array* GetCurrentPageTablePointers() { + return ¤t_page_table->pointers; +} + static void MapPages(u32 base, u32 size, u8* memory, PageType type) { LOG_DEBUG(HW_Memory, "Mapping %p onto %08X-%08X", memory, base * PAGE_SIZE, (base + size) * PAGE_SIZE); @@ -84,7 +86,7 @@ static void MapPages(u32 base, u32 size, u8* memory, PageType type) { u32 end = base + size; while (base != end) { - ASSERT_MSG(base < PageTable::NUM_ENTRIES, "out of range mapping at %08X", base); + ASSERT_MSG(base < PAGE_TABLE_NUM_ENTRIES, "out of range mapping at %08X", base); // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be // null here diff --git a/src/core/memory.h b/src/core/memory.h index 8fd3080ff6..903b58a22e 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include #include "common/common_types.h" @@ -17,6 +18,7 @@ namespace Memory { const u32 PAGE_SIZE = 0x1000; const u32 PAGE_MASK = PAGE_SIZE - 1; const int PAGE_BITS = 12; +const size_t PAGE_TABLE_NUM_ENTRIES = 1 << (32 - PAGE_BITS); /// Physical memory regions as seen from the ARM11 enum : PAddr { @@ -166,4 +168,11 @@ void RasterizerFlushRegion(PAddr start, u32 size); * Flushes and invalidates any externally cached rasterizer resources touching the given region. */ void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size); + +/** + * Dynarmic has an optimization to memory accesses when the pointer to the page exists that + * can be used by setting up the current page table as a callback. This function is used to + * retrieve the current page table for that purpose. + */ +std::array* GetCurrentPageTablePointers(); }