From 77389795d0f8d16f083dc87becc09552a2ced12e Mon Sep 17 00:00:00 2001 From: mitaclaw <140017135+mitaclaw@users.noreply.github.com> Date: Sun, 17 Mar 2024 20:14:20 -0700 Subject: [PATCH] PPCCache: Avoid Global System Accessor --- Source/Core/Core/PowerPC/PPCCache.cpp | 112 ++++++++++---------------- Source/Core/Core/PowerPC/PPCCache.h | 18 ++++- Source/Core/Core/PowerPC/PowerPC.cpp | 6 +- Source/Core/Core/PowerPC/PowerPC.h | 11 ++- Source/Core/Core/System.cpp | 2 +- 5 files changed, 74 insertions(+), 75 deletions(-) diff --git a/Source/Core/Core/PowerPC/PPCCache.cpp b/Source/Core/Core/PowerPC/PPCCache.cpp index 78cdbd05b201..3bdb55f12888 100644 --- a/Source/Core/Core/PowerPC/PPCCache.cpp +++ b/Source/Core/Core/PowerPC/PPCCache.cpp @@ -89,6 +89,11 @@ constexpr std::array s_way_from_plru = [] { }(); } // Anonymous namespace +Cache::Cache(Core::System& system, Memory::MemoryManager& memory) + : m_system(system), m_memory(memory) +{ +} + InstructionCache::~InstructionCache() { if (m_config_callback_id) @@ -108,19 +113,16 @@ void Cache::Reset() void InstructionCache::Reset() { Cache::Reset(); - Core::System::GetInstance().GetJitInterface().ClearSafe(); + m_system.GetJitInterface().ClearSafe(); } void Cache::Init() { - auto& system = Core::System::GetInstance(); - auto& memory = system.GetMemory(); - data.fill({}); addrs.fill({}); - lookup_table.resize(memory.GetRamSize() >> 5); - lookup_table_ex.resize(memory.GetExRamSize() >> 5); - lookup_table_vmem.resize(memory.GetFakeVMemSize() >> 5); + lookup_table.resize(m_memory.GetRamSize() >> 5); + lookup_table_ex.resize(m_memory.GetExRamSize() >> 5); + lookup_table_vmem.resize(m_memory.GetFakeVMemSize() >> 5); Reset(); } @@ -135,30 +137,24 @@ void InstructionCache::Init() void Cache::Store(u32 addr) { - auto& system = Core::System::GetInstance(); - auto& memory = system.GetMemory(); - auto [set, way] = GetCache(addr, true); if (way == 0xff) return; if (valid[set] & (1U << way) && modified[set] & (1U << way)) - memory.CopyToEmu((addr & ~0x1f), data[set][way].data(), 32); + m_memory.CopyToEmu((addr & ~0x1f), data[set][way].data(), 32); modified[set] &= ~(1U << way); } void Cache::FlushAll() { - auto& system = Core::System::GetInstance(); - auto& memory = system.GetMemory(); - for (size_t set = 0; set < CACHE_SETS; set++) { for (size_t way = 0; way < CACHE_WAYS; way++) { if (valid[set] & (1U << way) && modified[set] & (1U << way)) - memory.CopyToEmu(addrs[set][way], data[set][way].data(), 32); + m_memory.CopyToEmu(addrs[set][way], data[set][way].data(), 32); } } @@ -167,9 +163,6 @@ void Cache::FlushAll() void Cache::Invalidate(u32 addr) { - auto& system = Core::System::GetInstance(); - auto& memory = system.GetMemory(); - auto [set, way] = GetCache(addr, true); if (way == 0xff) @@ -178,11 +171,11 @@ void Cache::Invalidate(u32 addr) if (valid[set] & (1U << way)) { if (addrs[set][way] & CACHE_VMEM_BIT) - lookup_table_vmem[(addrs[set][way] & memory.GetFakeVMemMask()) >> 5] = 0xff; + lookup_table_vmem[(addrs[set][way] & m_memory.GetFakeVMemMask()) >> 5] = 0xff; else if (addrs[set][way] & CACHE_EXRAM_BIT) - lookup_table_ex[(addrs[set][way] & memory.GetExRamMask()) >> 5] = 0xff; + lookup_table_ex[(addrs[set][way] & m_memory.GetExRamMask()) >> 5] = 0xff; else - lookup_table[(addrs[set][way] & memory.GetRamMask()) >> 5] = 0xff; + lookup_table[(addrs[set][way] & m_memory.GetRamMask()) >> 5] = 0xff; valid[set] &= ~(1U << way); modified[set] &= ~(1U << way); @@ -191,9 +184,6 @@ void Cache::Invalidate(u32 addr) void Cache::Flush(u32 addr) { - auto& system = Core::System::GetInstance(); - auto& memory = system.GetMemory(); - auto [set, way] = GetCache(addr, true); if (way == 0xff) @@ -202,14 +192,14 @@ void Cache::Flush(u32 addr) if (valid[set] & (1U << way)) { if (modified[set] & (1U << way)) - memory.CopyToEmu((addr & ~0x1f), data[set][way].data(), 32); + m_memory.CopyToEmu((addr & ~0x1f), data[set][way].data(), 32); if (addrs[set][way] & CACHE_VMEM_BIT) - lookup_table_vmem[(addrs[set][way] & memory.GetFakeVMemMask()) >> 5] = 0xff; + lookup_table_vmem[(addrs[set][way] & m_memory.GetFakeVMemMask()) >> 5] = 0xff; else if (addrs[set][way] & CACHE_EXRAM_BIT) - lookup_table_ex[(addrs[set][way] & memory.GetExRamMask()) >> 5] = 0xff; + lookup_table_ex[(addrs[set][way] & m_memory.GetExRamMask()) >> 5] = 0xff; else - lookup_table[(addrs[set][way] & memory.GetRamMask()) >> 5] = 0xff; + lookup_table[(addrs[set][way] & m_memory.GetRamMask()) >> 5] = 0xff; valid[set] &= ~(1U << way); modified[set] &= ~(1U << way); @@ -223,24 +213,21 @@ void Cache::Touch(u32 addr, bool store) std::pair Cache::GetCache(u32 addr, bool locked) { - auto& system = Core::System::GetInstance(); - auto& memory = system.GetMemory(); - addr &= ~31; u32 set = (addr >> 5) & 0x7f; u32 way; if (addr & CACHE_VMEM_BIT) { - way = lookup_table_vmem[(addr & memory.GetFakeVMemMask()) >> 5]; + way = lookup_table_vmem[(addr & m_memory.GetFakeVMemMask()) >> 5]; } else if (addr & CACHE_EXRAM_BIT) { - way = lookup_table_ex[(addr & memory.GetExRamMask()) >> 5]; + way = lookup_table_ex[(addr & m_memory.GetExRamMask()) >> 5]; } else { - way = lookup_table[(addr & memory.GetRamMask()) >> 5]; + way = lookup_table[(addr & m_memory.GetRamMask()) >> 5]; } // load to the cache @@ -256,25 +243,25 @@ std::pair Cache::GetCache(u32 addr, bool locked) { // store the cache back to main memory if (modified[set] & (1 << way)) - memory.CopyToEmu(addrs[set][way], data[set][way].data(), 32); + m_memory.CopyToEmu(addrs[set][way], data[set][way].data(), 32); if (addrs[set][way] & CACHE_VMEM_BIT) - lookup_table_vmem[(addrs[set][way] & memory.GetFakeVMemMask()) >> 5] = 0xff; + lookup_table_vmem[(addrs[set][way] & m_memory.GetFakeVMemMask()) >> 5] = 0xff; else if (addrs[set][way] & CACHE_EXRAM_BIT) - lookup_table_ex[(addrs[set][way] & memory.GetExRamMask()) >> 5] = 0xff; + lookup_table_ex[(addrs[set][way] & m_memory.GetExRamMask()) >> 5] = 0xff; else - lookup_table[(addrs[set][way] & memory.GetRamMask()) >> 5] = 0xff; + lookup_table[(addrs[set][way] & m_memory.GetRamMask()) >> 5] = 0xff; } // load - memory.CopyFromEmu(data[set][way].data(), (addr & ~0x1f), 32); + m_memory.CopyFromEmu(data[set][way].data(), (addr & ~0x1f), 32); if (addr & CACHE_VMEM_BIT) - lookup_table_vmem[(addr & memory.GetFakeVMemMask()) >> 5] = way; + lookup_table_vmem[(addr & m_memory.GetFakeVMemMask()) >> 5] = way; else if (addr & CACHE_EXRAM_BIT) - lookup_table_ex[(addr & memory.GetExRamMask()) >> 5] = way; + lookup_table_ex[(addr & m_memory.GetExRamMask()) >> 5] = way; else - lookup_table[(addr & memory.GetRamMask()) >> 5] = way; + lookup_table[(addr & m_memory.GetRamMask()) >> 5] = way; addrs[set][way] = addr; valid[set] |= (1 << way); @@ -290,9 +277,6 @@ std::pair Cache::GetCache(u32 addr, bool locked) void Cache::Read(u32 addr, void* buffer, u32 len, bool locked) { - auto& system = Core::System::GetInstance(); - auto& memory = system.GetMemory(); - auto* value = static_cast(buffer); while (len > 0) @@ -309,7 +293,7 @@ void Cache::Read(u32 addr, void* buffer, u32 len, bool locked) } else { - memory.CopyFromEmu(value, addr, len_in_block); + m_memory.CopyFromEmu(value, addr, len_in_block); } addr += len_in_block; @@ -320,9 +304,6 @@ void Cache::Read(u32 addr, void* buffer, u32 len, bool locked) void Cache::Write(u32 addr, const void* buffer, u32 len, bool locked) { - auto& system = Core::System::GetInstance(); - auto& memory = system.GetMemory(); - auto* value = static_cast(buffer); while (len > 0) @@ -340,7 +321,7 @@ void Cache::Write(u32 addr, const void* buffer, u32 len, bool locked) } else { - memory.CopyToEmu(addr, value, len_in_block); + m_memory.CopyToEmu(addr, value, len_in_block); } addr += len_in_block; @@ -351,9 +332,6 @@ void Cache::Write(u32 addr, const void* buffer, u32 len, bool locked) void Cache::DoState(PointerWrap& p) { - auto& system = Core::System::GetInstance(); - auto& memory = system.GetMemory(); - if (p.IsReadMode()) { // Clear valid parts of the lookup tables (this is done instead of using fill(0xff) to avoid @@ -365,11 +343,11 @@ void Cache::DoState(PointerWrap& p) if ((valid[set] & (1 << way)) != 0) { if (addrs[set][way] & CACHE_VMEM_BIT) - lookup_table_vmem[(addrs[set][way] & memory.GetFakeVMemMask()) >> 5] = 0xff; + lookup_table_vmem[(addrs[set][way] & m_memory.GetFakeVMemMask()) >> 5] = 0xff; else if (addrs[set][way] & CACHE_EXRAM_BIT) - lookup_table_ex[(addrs[set][way] & memory.GetExRamMask()) >> 5] = 0xff; + lookup_table_ex[(addrs[set][way] & m_memory.GetExRamMask()) >> 5] = 0xff; else - lookup_table[(addrs[set][way] & memory.GetRamMask()) >> 5] = 0xff; + lookup_table[(addrs[set][way] & m_memory.GetRamMask()) >> 5] = 0xff; } } } @@ -391,11 +369,11 @@ void Cache::DoState(PointerWrap& p) if ((valid[set] & (1 << way)) != 0) { if (addrs[set][way] & CACHE_VMEM_BIT) - lookup_table_vmem[(addrs[set][way] & memory.GetFakeVMemMask()) >> 5] = way; + lookup_table_vmem[(addrs[set][way] & m_memory.GetFakeVMemMask()) >> 5] = way; else if (addrs[set][way] & CACHE_EXRAM_BIT) - lookup_table_ex[(addrs[set][way] & memory.GetExRamMask()) >> 5] = way; + lookup_table_ex[(addrs[set][way] & m_memory.GetExRamMask()) >> 5] = way; else - lookup_table[(addrs[set][way] & memory.GetRamMask()) >> 5] = way; + lookup_table[(addrs[set][way] & m_memory.GetRamMask()) >> 5] = way; } } } @@ -404,11 +382,10 @@ void Cache::DoState(PointerWrap& p) u32 InstructionCache::ReadInstruction(u32 addr) { - auto& system = Core::System::GetInstance(); - auto& ppc_state = system.GetPPCState(); + auto& ppc_state = m_system.GetPPCState(); if (!HID0(ppc_state).ICE || m_disable_icache) // instruction cache is disabled - return system.GetMemory().Read_U32(addr); + return m_memory.Read_U32(addr); u32 value; Read(addr, &value, sizeof(value), HID0(ppc_state).ILOCK); @@ -417,9 +394,6 @@ u32 InstructionCache::ReadInstruction(u32 addr) void InstructionCache::Invalidate(u32 addr) { - auto& system = Core::System::GetInstance(); - auto& memory = system.GetMemory(); - // Per the 750cl manual, section 3.4.1.5 Instruction Cache Enabling/Disabling (page 137) // and section 3.4.2.6 Instruction Cache Block Invalidate (icbi) (page 140), the icbi // instruction always invalidates, even if the instruction cache is disabled or locked, @@ -432,18 +406,18 @@ void InstructionCache::Invalidate(u32 addr) if (valid[set] & (1U << way)) { if (addrs[set][way] & CACHE_VMEM_BIT) - lookup_table_vmem[(addrs[set][way] & memory.GetFakeVMemMask()) >> 5] = 0xff; + lookup_table_vmem[(addrs[set][way] & m_memory.GetFakeVMemMask()) >> 5] = 0xff; else if (addrs[set][way] & CACHE_EXRAM_BIT) - lookup_table_ex[(addrs[set][way] & memory.GetExRamMask()) >> 5] = 0xff; + lookup_table_ex[(addrs[set][way] & m_memory.GetExRamMask()) >> 5] = 0xff; else - lookup_table[(addrs[set][way] & memory.GetRamMask()) >> 5] = 0xff; + lookup_table[(addrs[set][way] & m_memory.GetRamMask()) >> 5] = 0xff; } } valid[set] = 0; modified[set] = 0; // Also tell the JIT that the corresponding address has been invalidated - system.GetJitInterface().InvalidateICacheLine(addr); + m_system.GetJitInterface().InvalidateICacheLine(addr); } void InstructionCache::RefreshConfig() diff --git a/Source/Core/Core/PowerPC/PPCCache.h b/Source/Core/Core/PowerPC/PPCCache.h index 5d5648a71e7c..2f1842d84e30 100644 --- a/Source/Core/Core/PowerPC/PPCCache.h +++ b/Source/Core/Core/PowerPC/PPCCache.h @@ -10,6 +10,14 @@ #include "Common/CommonTypes.h" #include "Common/Config/Config.h" +namespace Core +{ +class System; +} +namespace Memory +{ +class MemoryManager; +} class PointerWrap; namespace PowerPC @@ -42,6 +50,11 @@ struct Cache std::vector lookup_table_ex{}; std::vector lookup_table_vmem{}; + Core::System& m_system; + Memory::MemoryManager& m_memory; + + explicit Cache(Core::System& system, Memory::MemoryManager& memory); + void Store(u32 addr); void Invalidate(u32 addr); void Flush(u32 addr); @@ -66,7 +79,10 @@ struct InstructionCache : public Cache bool m_disable_icache = false; - InstructionCache() = default; + explicit InstructionCache(Core::System& system, Memory::MemoryManager& memory) + : Cache(system, memory) + { + } ~InstructionCache(); u32 ReadInstruction(u32 addr); void Invalidate(u32 addr); diff --git a/Source/Core/Core/PowerPC/PowerPC.cpp b/Source/Core/Core/PowerPC/PowerPC.cpp index b1d76aac4531..bf6c10458bb9 100644 --- a/Source/Core/Core/PowerPC/PowerPC.cpp +++ b/Source/Core/Core/PowerPC/PowerPC.cpp @@ -84,9 +84,9 @@ std::ostream& operator<<(std::ostream& os, CPUCore core) return os; } -PowerPCManager::PowerPCManager(Core::System& system) - : m_breakpoints(system), m_memchecks(system), m_debug_interface(system, m_symbol_db), - m_system(system) +PowerPCManager::PowerPCManager(Core::System& system, Memory::MemoryManager& memory) + : m_ppc_state(system, memory), m_breakpoints(system), m_memchecks(system), + m_debug_interface(system, m_symbol_db), m_system(system) { } diff --git a/Source/Core/Core/PowerPC/PowerPC.h b/Source/Core/Core/PowerPC/PowerPC.h index e4d00ec8843e..93e12a6c7601 100644 --- a/Source/Core/Core/PowerPC/PowerPC.h +++ b/Source/Core/Core/PowerPC/PowerPC.h @@ -28,6 +28,10 @@ namespace CoreTiming { struct EventType; } +namespace Memory +{ +class MemoryManager; +} namespace PowerPC { @@ -193,6 +197,11 @@ struct PowerPCState bool reserve; u32 reserve_address; + explicit PowerPCState(Core::System& system, Memory::MemoryManager& memory) + : iCache(system, memory), dCache(system, memory) + { + } + void UpdateCR1() { cr.SetField(1, (fpscr.FX << 3) | (fpscr.FEX << 2) | (fpscr.VX << 1) | fpscr.OX); @@ -254,7 +263,7 @@ CPUCore DefaultCPUCore(); class PowerPCManager { public: - explicit PowerPCManager(Core::System& system); + explicit PowerPCManager(Core::System& system, Memory::MemoryManager& memory); PowerPCManager(const PowerPCManager& other) = delete; PowerPCManager(PowerPCManager&& other) = delete; PowerPCManager& operator=(const PowerPCManager& other) = delete; diff --git a/Source/Core/Core/System.cpp b/Source/Core/Core/System.cpp index 695d5861fc10..8879a49ce76c 100644 --- a/Source/Core/Core/System.cpp +++ b/Source/Core/Core/System.cpp @@ -49,7 +49,7 @@ struct System::Impl : m_audio_interface(system), m_core_timing(system), m_command_processor{system}, m_cpu(system), m_dsp(system), m_dvd_interface(system), m_dvd_thread(system), m_expansion_interface(system), m_fifo{system}, m_gp_fifo(system), m_wii_ipc(system), - m_memory(system), m_pixel_engine{system}, m_power_pc(system), + m_memory(system), m_pixel_engine{system}, m_power_pc(system, m_memory), m_mmu(system, m_memory, m_power_pc), m_processor_interface(system), m_serial_interface(system), m_system_timers(system), m_video_interface(system), m_interpreter(system, m_power_pc.GetPPCState(), m_mmu, m_power_pc.GetBranchWatch(),