Core/Memmap: Store and check which physical regions are actually mapped instead of relying on SConfig staying the same.

This commit is contained in:
Admiral H. Curtiss 2021-03-02 18:20:52 +01:00
parent 59f4164411
commit 8199825c6f

View File

@ -175,6 +175,7 @@ struct PhysicalMemoryRegion
WII_ONLY = 2, WII_ONLY = 2,
} flags; } flags;
u32 shm_position; u32 shm_position;
bool active;
}; };
struct LogicalMemoryView struct LogicalMemoryView
@ -223,31 +224,10 @@ struct LogicalMemoryView
// //
// TODO: The actual size of RAM is 24MB; the other 8MB shouldn't be backed by actual memory. // TODO: The actual size of RAM is 24MB; the other 8MB shouldn't be backed by actual memory.
// TODO: Do we want to handle the mirrors of the GC RAM? // TODO: Do we want to handle the mirrors of the GC RAM?
static std::array<PhysicalMemoryRegion, 4> physical_regions; static std::array<PhysicalMemoryRegion, 4> s_physical_regions;
static std::vector<LogicalMemoryView> logical_mapped_entries; static std::vector<LogicalMemoryView> logical_mapped_entries;
static u32 GetFlags()
{
bool wii = SConfig::GetInstance().bWii;
bool bMMU = SConfig::GetInstance().bMMU;
bool bFakeVMEM = false;
#ifndef _ARCH_32
// If MMU is turned off in GameCube mode, turn on fake VMEM hack.
// The fake VMEM hack's address space is above the memory space that we
// allocate on 32bit targets, so disable it there.
bFakeVMEM = !wii && !bMMU;
#endif
u32 flags = 0;
if (wii)
flags |= PhysicalMemoryRegion::WII_ONLY;
if (bFakeVMEM)
flags |= PhysicalMemoryRegion::FAKE_VMEM;
return flags;
}
void Init() void Init()
{ {
const auto get_mem1_size = [] { const auto get_mem1_size = [] {
@ -272,28 +252,43 @@ void Init()
s_exram_size = MathUtil::NextPowerOf2(GetExRamSizeReal()); s_exram_size = MathUtil::NextPowerOf2(GetExRamSizeReal());
s_exram_mask = GetExRamSize() - 1; s_exram_mask = GetExRamSize() - 1;
physical_regions[0] = {&m_pRAM, 0x00000000, GetRamSize(), PhysicalMemoryRegion::ALWAYS}; s_physical_regions[0] = {&m_pRAM, 0x00000000, GetRamSize(), PhysicalMemoryRegion::ALWAYS, false};
physical_regions[1] = {&m_pL1Cache, 0xE0000000, GetL1CacheSize(), PhysicalMemoryRegion::ALWAYS}; s_physical_regions[1] = {&m_pL1Cache, 0xE0000000, GetL1CacheSize(), PhysicalMemoryRegion::ALWAYS,
physical_regions[2] = {&m_pFakeVMEM, 0x7E000000, GetFakeVMemSize(), false};
PhysicalMemoryRegion::FAKE_VMEM}; s_physical_regions[2] = {&m_pFakeVMEM, 0x7E000000, GetFakeVMemSize(),
physical_regions[3] = {&m_pEXRAM, 0x10000000, GetExRamSize(), PhysicalMemoryRegion::WII_ONLY}; PhysicalMemoryRegion::FAKE_VMEM, false};
s_physical_regions[3] = {&m_pEXRAM, 0x10000000, GetExRamSize(), PhysicalMemoryRegion::WII_ONLY,
false};
const bool wii = SConfig::GetInstance().bWii;
const bool mmu = SConfig::GetInstance().bMMU;
bool fake_vmem = false;
#ifndef _ARCH_32
// If MMU is turned off in GameCube mode, turn on fake VMEM hack.
// The fake VMEM hack's address space is above the memory space that we
// allocate on 32bit targets, so disable it there.
fake_vmem = !wii && !mmu;
#endif
bool wii = SConfig::GetInstance().bWii;
u32 flags = GetFlags();
u32 mem_size = 0; u32 mem_size = 0;
for (PhysicalMemoryRegion& region : physical_regions) for (PhysicalMemoryRegion& region : s_physical_regions)
{ {
if ((flags & region.flags) != region.flags) if (!wii && (region.flags & PhysicalMemoryRegion::WII_ONLY))
continue; continue;
if (!fake_vmem && (region.flags & PhysicalMemoryRegion::FAKE_VMEM))
continue;
region.shm_position = mem_size; region.shm_position = mem_size;
region.active = true;
mem_size += region.size; mem_size += region.size;
} }
g_arena.GrabSHMSegment(mem_size); g_arena.GrabSHMSegment(mem_size);
// Create an anonymous view of the physical memory // Create an anonymous view of the physical memory
for (PhysicalMemoryRegion& region : physical_regions) for (const PhysicalMemoryRegion& region : s_physical_regions)
{ {
if ((flags & region.flags) != region.flags) if (!region.active)
continue; continue;
*region.out_pointer = (u8*)g_arena.CreateView(region.shm_position, region.size); *region.out_pointer = (u8*)g_arena.CreateView(region.shm_position, region.size);
@ -320,7 +315,6 @@ void Init()
bool InitFastmemArena() bool InitFastmemArena()
{ {
u32 flags = GetFlags();
physical_base = Common::MemArena::FindMemoryBase(); physical_base = Common::MemArena::FindMemoryBase();
if (!physical_base) if (!physical_base)
@ -329,9 +323,9 @@ bool InitFastmemArena()
return false; return false;
} }
for (PhysicalMemoryRegion& region : physical_regions) for (const PhysicalMemoryRegion& region : s_physical_regions)
{ {
if ((flags & region.flags) != region.flags) if (!region.active)
continue; continue;
u8* base = physical_base + region.physical_address; u8* base = physical_base + region.physical_address;
@ -372,7 +366,7 @@ void UpdateLogicalMemory(const PowerPC::BatTable& dbat_table)
// TODO: Merge adjacent mappings to make this faster. // TODO: Merge adjacent mappings to make this faster.
u32 logical_size = PowerPC::BAT_PAGE_SIZE; u32 logical_size = PowerPC::BAT_PAGE_SIZE;
u32 translated_address = dbat_table[i] & PowerPC::BAT_RESULT_MASK; u32 translated_address = dbat_table[i] & PowerPC::BAT_RESULT_MASK;
for (const auto& physical_region : physical_regions) for (const auto& physical_region : s_physical_regions)
{ {
u32 mapping_address = physical_region.physical_address; u32 mapping_address = physical_region.physical_address;
u32 mapping_end = mapping_address + physical_region.size; u32 mapping_end = mapping_address + physical_region.size;
@ -419,11 +413,11 @@ void Shutdown()
ShutdownFastmemArena(); ShutdownFastmemArena();
m_IsInitialized = false; m_IsInitialized = false;
u32 flags = GetFlags(); for (const PhysicalMemoryRegion& region : s_physical_regions)
for (PhysicalMemoryRegion& region : physical_regions)
{ {
if ((flags & region.flags) != region.flags) if (!region.active)
continue; continue;
g_arena.ReleaseView(*region.out_pointer, region.size); g_arena.ReleaseView(*region.out_pointer, region.size);
*region.out_pointer = nullptr; *region.out_pointer = nullptr;
} }
@ -437,10 +431,9 @@ void ShutdownFastmemArena()
if (!is_fastmem_arena_initialized) if (!is_fastmem_arena_initialized)
return; return;
u32 flags = GetFlags(); for (const PhysicalMemoryRegion& region : s_physical_regions)
for (PhysicalMemoryRegion& region : physical_regions)
{ {
if ((flags & region.flags) != region.flags) if (!region.active)
continue; continue;
u8* base = physical_base + region.physical_address; u8* base = physical_base + region.physical_address;