From d21d7fe273f786260b170b7151ce252ce582dc8f Mon Sep 17 00:00:00 2001 From: mitaclaw <140017135+mitaclaw@users.noreply.github.com> Date: Mon, 8 Apr 2024 16:06:57 -0700 Subject: [PATCH] Curtiss' suggestion --- Source/Core/Common/x64Emitter.h | 8 ++ Source/Core/Core/GeckoCode.cpp | 4 +- Source/Core/Core/HLE/HLE.cpp | 20 ++- Source/Core/Core/HLE/HLE_Misc.cpp | 3 +- Source/Core/Core/PowerPC/GDBStub.cpp | 3 +- .../Interpreter/Interpreter_LoadStore.cpp | 4 +- .../Interpreter_SystemRegisters.cpp | 3 +- .../PowerPC/Jit64/Jit_SystemRegisters.cpp | 6 +- Source/Core/Core/PowerPC/MMU.cpp | 18 +-- Source/Core/Core/PowerPC/PPCCache.cpp | 127 +++++++++--------- Source/Core/Core/PowerPC/PPCCache.h | 47 +++---- Source/Core/Core/PowerPC/PowerPC.cpp | 28 ++-- Source/Core/Core/PowerPC/PowerPC.h | 11 +- Source/Core/Core/System.cpp | 2 +- 14 files changed, 145 insertions(+), 139 deletions(-) diff --git a/Source/Core/Common/x64Emitter.h b/Source/Core/Common/x64Emitter.h index 7a7e1a695bac..e19ef3773477 100644 --- a/Source/Core/Common/x64Emitter.h +++ b/Source/Core/Common/x64Emitter.h @@ -1082,6 +1082,14 @@ class XEmitter ABI_CallFunction(func); } + template + void ABI_CallFunctionPP(FunctionPointer func, const void* param1, const void* param2) + { + MOV(64, R(ABI_PARAM1), Imm64(reinterpret_cast(param1))); + MOV(64, R(ABI_PARAM2), Imm64(reinterpret_cast(param2))); + ABI_CallFunction(func); + } + template void ABI_CallFunctionPC(FunctionPointer func, const void* param1, u32 param2) { diff --git a/Source/Core/Core/GeckoCode.cpp b/Source/Core/Core/GeckoCode.cpp index 4ecd3b80da77..046a69cfc34d 100644 --- a/Source/Core/Core/GeckoCode.cpp +++ b/Source/Core/Core/GeckoCode.cpp @@ -208,9 +208,11 @@ static Installation InstallCodeHandlerLocked(const Core::CPUThreadGuard& guard) // Invalidate the icache and any asm codes auto& ppc_state = guard.GetSystem().GetPPCState(); + auto& memory = guard.GetSystem().GetMemory(); + auto& jit_interface = guard.GetSystem().GetJitInterface(); for (u32 j = 0; j < (INSTALLER_END_ADDRESS - INSTALLER_BASE_ADDRESS); j += 32) { - ppc_state.iCache.Invalidate(INSTALLER_BASE_ADDRESS + j); + ppc_state.iCache.Invalidate(memory, jit_interface, INSTALLER_BASE_ADDRESS + j); } return Installation::Installed; } diff --git a/Source/Core/Core/HLE/HLE.cpp b/Source/Core/Core/HLE/HLE.cpp index 94548d84efce..ff9db8fc7587 100644 --- a/Source/Core/Core/HLE/HLE.cpp +++ b/Source/Core/Core/HLE/HLE.cpp @@ -66,12 +66,14 @@ constexpr std::array os_patches{{ void Patch(Core::System& system, u32 addr, std::string_view func_name) { auto& ppc_state = system.GetPPCState(); + auto& memory = system.GetMemory(); + auto& jit_interface = system.GetJitInterface(); for (u32 i = 1; i < os_patches.size(); ++i) { if (os_patches[i].name == func_name) { s_hooked_addresses[addr] = i; - ppc_state.iCache.Invalidate(addr); + ppc_state.iCache.Invalidate(memory, jit_interface, addr); return; } } @@ -108,6 +110,8 @@ void PatchFunctions(Core::System& system) { auto& power_pc = system.GetPowerPC(); auto& ppc_state = power_pc.GetPPCState(); + auto& memory = system.GetMemory(); + auto& jit_interface = system.GetJitInterface(); auto& ppc_symbol_db = power_pc.GetSymbolDB(); // Remove all hooks that aren't fixed address hooks @@ -115,7 +119,7 @@ void PatchFunctions(Core::System& system) { if (os_patches[i->second].flags != HookFlag::Fixed) { - ppc_state.iCache.Invalidate(i->first); + ppc_state.iCache.Invalidate(memory, jit_interface, i->first); i = s_hooked_addresses.erase(i); } else @@ -135,7 +139,7 @@ void PatchFunctions(Core::System& system) for (u32 addr = symbol->address; addr < symbol->address + symbol->size; addr += 4) { s_hooked_addresses[addr] = i; - ppc_state.iCache.Invalidate(addr); + ppc_state.iCache.Invalidate(memory, jit_interface, addr); } INFO_LOG_FMT(OSHLE, "Patching {} {:08x}", os_patches[i].name, symbol->address); } @@ -234,6 +238,8 @@ u32 UnPatch(Core::System& system, std::string_view patch_name) auto& power_pc = system.GetPowerPC(); auto& ppc_state = power_pc.GetPPCState(); + auto& memory = system.GetMemory(); + auto& jit_interface = system.GetJitInterface(); if (patch->flags == HookFlag::Fixed) { @@ -245,7 +251,7 @@ u32 UnPatch(Core::System& system, std::string_view patch_name) if (i->second == patch_idx) { addr = i->first; - ppc_state.iCache.Invalidate(i->first); + ppc_state.iCache.Invalidate(memory, jit_interface, i->first); i = s_hooked_addresses.erase(i); } else @@ -263,7 +269,7 @@ u32 UnPatch(Core::System& system, std::string_view patch_name) for (u32 addr = symbol->address; addr < symbol->address + symbol->size; addr += 4) { s_hooked_addresses.erase(addr); - ppc_state.iCache.Invalidate(addr); + ppc_state.iCache.Invalidate(memory, jit_interface, addr); } return symbol->address; } @@ -274,6 +280,8 @@ u32 UnPatch(Core::System& system, std::string_view patch_name) u32 UnpatchRange(Core::System& system, u32 start_addr, u32 end_addr) { auto& ppc_state = system.GetPPCState(); + auto& memory = system.GetMemory(); + auto& jit_interface = system.GetJitInterface(); u32 count = 0; @@ -282,7 +290,7 @@ u32 UnpatchRange(Core::System& system, u32 start_addr, u32 end_addr) { INFO_LOG_FMT(OSHLE, "Unpatch HLE hooks [{:08x};{:08x}): {} at {:08x}", start_addr, end_addr, os_patches[i->second].name, i->first); - ppc_state.iCache.Invalidate(i->first); + ppc_state.iCache.Invalidate(memory, jit_interface, i->first); i = s_hooked_addresses.erase(i); count += 1; } diff --git a/Source/Core/Core/HLE/HLE_Misc.cpp b/Source/Core/Core/HLE/HLE_Misc.cpp index 91ca6513420d..423ba465dd40 100644 --- a/Source/Core/Core/HLE/HLE_Misc.cpp +++ b/Source/Core/Core/HLE/HLE_Misc.cpp @@ -36,6 +36,7 @@ void GeckoCodeHandlerICacheFlush(const Core::CPUThreadGuard& guard) { auto& system = guard.GetSystem(); auto& ppc_state = system.GetPPCState(); + auto& jit_interface = system.GetJitInterface(); // Work around the codehandler not properly invalidating the icache, but // only the first few frames. @@ -54,7 +55,7 @@ void GeckoCodeHandlerICacheFlush(const Core::CPUThreadGuard& guard) } PowerPC::MMU::HostWrite_U32(guard, gch_gameid + 1, Gecko::INSTALLER_BASE_ADDRESS); - ppc_state.iCache.Reset(); + ppc_state.iCache.Reset(jit_interface); } // Because Dolphin messes around with the CPU state instead of patching the game binary, we diff --git a/Source/Core/Core/PowerPC/GDBStub.cpp b/Source/Core/Core/PowerPC/GDBStub.cpp index a0d658eb1f4f..df87a6c75a87 100644 --- a/Source/Core/Core/PowerPC/GDBStub.cpp +++ b/Source/Core/Core/PowerPC/GDBStub.cpp @@ -1016,7 +1016,8 @@ void ProcessCommands(bool loop_until_continue) WriteMemory(guard); auto& ppc_state = system.GetPPCState(); - ppc_state.iCache.Reset(); + auto& jit_interface = system.GetJitInterface(); + ppc_state.iCache.Reset(jit_interface); Host_UpdateDisasmDialog(); break; } diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp index f046fadb98f3..a01090561e1b 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp @@ -631,7 +631,9 @@ void Interpreter::icbi(Interpreter& interpreter, UGeckoInstruction inst) // TODO: Raise DSI if translation fails (except for direct-store segments). auto& ppc_state = interpreter.m_ppc_state; const u32 address = Helper_Get_EA_X(ppc_state, inst); - ppc_state.iCache.Invalidate(address); + auto& memory = interpreter.m_system.GetMemory(); + auto& jit_interface = interpreter.m_system.GetJitInterface(); + ppc_state.iCache.Invalidate(memory, jit_interface, address); } void Interpreter::lbzux(Interpreter& interpreter, UGeckoInstruction inst) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp index 02a7d3ac6ca1..a28a96865315 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp @@ -358,7 +358,8 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst) INFO_LOG_FMT(POWERPC, "Flush Instruction Cache! ICE={}", HID0(ppc_state).ICE); // this is rather slow // most games do it only once during initialization - ppc_state.iCache.Reset(); + auto& jit_interface = interpreter.m_system.GetJitInterface(); + ppc_state.iCache.Reset(jit_interface); } } break; diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp index 67e218bb9879..31794b9ba959 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp @@ -216,9 +216,9 @@ void Jit64::UpdateFPExceptionSummary(X64Reg fpscr, X64Reg tmp1, X64Reg tmp2) OR(32, R(fpscr), R(tmp1)); } -static void DoICacheReset(PowerPC::PowerPCState& ppc_state) +static void DoICacheReset(PowerPC::PowerPCState& ppc_state, JitInterface& jit_interface) { - ppc_state.iCache.Reset(); + ppc_state.iCache.Reset(jit_interface); } void Jit64::mtspr(UGeckoInstruction inst) @@ -286,7 +286,7 @@ void Jit64::mtspr(UGeckoInstruction inst) FixupBranch dont_reset_icache = J_CC(CC_NC); BitSet32 regs = CallerSavedRegistersInUse(); ABI_PushRegistersAndAdjustStack(regs, 0); - ABI_CallFunctionP(DoICacheReset, &m_ppc_state); + ABI_CallFunctionPP(DoICacheReset, &m_ppc_state, &m_system.GetJitInterface()); ABI_PopRegistersAndAdjustStack(regs, 0); SetJumpTarget(dont_reset_icache); return; diff --git a/Source/Core/Core/PowerPC/MMU.cpp b/Source/Core/Core/PowerPC/MMU.cpp index 0291010bad43..b812195c1082 100644 --- a/Source/Core/Core/PowerPC/MMU.cpp +++ b/Source/Core/Core/PowerPC/MMU.cpp @@ -220,7 +220,7 @@ T MMU::ReadFromHardware(u32 em_address) } else { - m_ppc_state.dCache.Read(em_address, &value, sizeof(T), + m_ppc_state.dCache.Read(m_memory, em_address, &value, sizeof(T), HID0(m_ppc_state).DLOCK || flag != XCheckTLBFlag::Read); } @@ -239,7 +239,7 @@ T MMU::ReadFromHardware(u32 em_address) } else { - m_ppc_state.dCache.Read(em_address + 0x10000000, &value, sizeof(T), + m_ppc_state.dCache.Read(m_memory, em_address + 0x10000000, &value, sizeof(T), HID0(m_ppc_state).DLOCK || flag != XCheckTLBFlag::Read); } @@ -412,7 +412,7 @@ void MMU::WriteToHardware(u32 em_address, const u32 data, const u32 size) em_address &= m_memory.GetRamMask(); if (m_ppc_state.m_enable_dcache && !wi) - m_ppc_state.dCache.Write(em_address, &swapped_data, size, HID0(m_ppc_state).DLOCK); + m_ppc_state.dCache.Write(m_memory, em_address, &swapped_data, size, HID0(m_ppc_state).DLOCK); if (!m_ppc_state.m_enable_dcache || wi || flag != XCheckTLBFlag::Write) std::memcpy(&m_memory.GetRAM()[em_address], &swapped_data, size); @@ -427,7 +427,7 @@ void MMU::WriteToHardware(u32 em_address, const u32 data, const u32 size) if (m_ppc_state.m_enable_dcache && !wi) { - m_ppc_state.dCache.Write(em_address + 0x10000000, &swapped_data, size, + m_ppc_state.dCache.Write(m_memory, em_address + 0x10000000, &swapped_data, size, HID0(m_ppc_state).DLOCK); } @@ -497,7 +497,7 @@ TryReadInstResult MMU::TryReadInstruction(u32 address) } else { - hex = m_ppc_state.iCache.ReadInstruction(address); + hex = m_ppc_state.iCache.ReadInstruction(m_memory, m_ppc_state, address); } return TryReadInstResult{true, from_bat, hex, address}; } @@ -1137,7 +1137,7 @@ void MMU::StoreDCacheLine(u32 address) } if (m_ppc_state.m_enable_dcache) - m_ppc_state.dCache.Store(address); + m_ppc_state.dCache.Store(m_memory, address); } void MMU::InvalidateDCacheLine(u32 address) @@ -1159,7 +1159,7 @@ void MMU::InvalidateDCacheLine(u32 address) } if (m_ppc_state.m_enable_dcache) - m_ppc_state.dCache.Invalidate(address); + m_ppc_state.dCache.Invalidate(m_memory, address); } void MMU::FlushDCacheLine(u32 address) @@ -1183,7 +1183,7 @@ void MMU::FlushDCacheLine(u32 address) } if (m_ppc_state.m_enable_dcache) - m_ppc_state.dCache.Flush(address); + m_ppc_state.dCache.Flush(m_memory, address); } void MMU::TouchDCacheLine(u32 address, bool store) @@ -1207,7 +1207,7 @@ void MMU::TouchDCacheLine(u32 address, bool store) } if (m_ppc_state.m_enable_dcache) - m_ppc_state.dCache.Touch(address, store); + m_ppc_state.dCache.Touch(m_memory, address, store); } u32 MMU::IsOptimizableMMIOAccess(u32 address, u32 access_size) const diff --git a/Source/Core/Core/PowerPC/PPCCache.cpp b/Source/Core/Core/PowerPC/PPCCache.cpp index 3bdb55f12888..0213a47c3802 100644 --- a/Source/Core/Core/PowerPC/PPCCache.cpp +++ b/Source/Core/Core/PowerPC/PPCCache.cpp @@ -89,11 +89,6 @@ 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) @@ -110,60 +105,60 @@ void Cache::Reset() std::fill(lookup_table_vmem.begin(), lookup_table_vmem.end(), 0xFF); } -void InstructionCache::Reset() +void InstructionCache::Reset(JitInterface& jit_interface) { Cache::Reset(); - m_system.GetJitInterface().ClearSafe(); + jit_interface.ClearSafe(); } -void Cache::Init() +void Cache::Init(Memory::MemoryManager& memory) { data.fill({}); addrs.fill({}); - lookup_table.resize(m_memory.GetRamSize() >> 5); - lookup_table_ex.resize(m_memory.GetExRamSize() >> 5); - lookup_table_vmem.resize(m_memory.GetFakeVMemSize() >> 5); + lookup_table.resize(memory.GetRamSize() >> 5); + lookup_table_ex.resize(memory.GetExRamSize() >> 5); + lookup_table_vmem.resize(memory.GetFakeVMemSize() >> 5); Reset(); } -void InstructionCache::Init() +void InstructionCache::Init(Memory::MemoryManager& memory) { if (!m_config_callback_id) m_config_callback_id = Config::AddConfigChangedCallback([this] { RefreshConfig(); }); RefreshConfig(); - Cache::Init(); + Cache::Init(memory); } -void Cache::Store(u32 addr) +void Cache::Store(Memory::MemoryManager& memory, u32 addr) { - auto [set, way] = GetCache(addr, true); + auto [set, way] = GetCache(memory, addr, true); if (way == 0xff) return; if (valid[set] & (1U << way) && modified[set] & (1U << way)) - m_memory.CopyToEmu((addr & ~0x1f), data[set][way].data(), 32); + memory.CopyToEmu((addr & ~0x1f), data[set][way].data(), 32); modified[set] &= ~(1U << way); } -void Cache::FlushAll() +void Cache::FlushAll(Memory::MemoryManager& memory) { 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)) - m_memory.CopyToEmu(addrs[set][way], data[set][way].data(), 32); + memory.CopyToEmu(addrs[set][way], data[set][way].data(), 32); } } Reset(); } -void Cache::Invalidate(u32 addr) +void Cache::Invalidate(Memory::MemoryManager& memory, u32 addr) { - auto [set, way] = GetCache(addr, true); + auto [set, way] = GetCache(memory, addr, true); if (way == 0xff) return; @@ -171,20 +166,20 @@ void Cache::Invalidate(u32 addr) if (valid[set] & (1U << way)) { if (addrs[set][way] & CACHE_VMEM_BIT) - lookup_table_vmem[(addrs[set][way] & m_memory.GetFakeVMemMask()) >> 5] = 0xff; + lookup_table_vmem[(addrs[set][way] & memory.GetFakeVMemMask()) >> 5] = 0xff; else if (addrs[set][way] & CACHE_EXRAM_BIT) - lookup_table_ex[(addrs[set][way] & m_memory.GetExRamMask()) >> 5] = 0xff; + lookup_table_ex[(addrs[set][way] & memory.GetExRamMask()) >> 5] = 0xff; else - lookup_table[(addrs[set][way] & m_memory.GetRamMask()) >> 5] = 0xff; + lookup_table[(addrs[set][way] & memory.GetRamMask()) >> 5] = 0xff; valid[set] &= ~(1U << way); modified[set] &= ~(1U << way); } } -void Cache::Flush(u32 addr) +void Cache::Flush(Memory::MemoryManager& memory, u32 addr) { - auto [set, way] = GetCache(addr, true); + auto [set, way] = GetCache(memory, addr, true); if (way == 0xff) return; @@ -192,26 +187,26 @@ void Cache::Flush(u32 addr) if (valid[set] & (1U << way)) { if (modified[set] & (1U << way)) - m_memory.CopyToEmu((addr & ~0x1f), data[set][way].data(), 32); + memory.CopyToEmu((addr & ~0x1f), data[set][way].data(), 32); if (addrs[set][way] & CACHE_VMEM_BIT) - lookup_table_vmem[(addrs[set][way] & m_memory.GetFakeVMemMask()) >> 5] = 0xff; + lookup_table_vmem[(addrs[set][way] & memory.GetFakeVMemMask()) >> 5] = 0xff; else if (addrs[set][way] & CACHE_EXRAM_BIT) - lookup_table_ex[(addrs[set][way] & m_memory.GetExRamMask()) >> 5] = 0xff; + lookup_table_ex[(addrs[set][way] & memory.GetExRamMask()) >> 5] = 0xff; else - lookup_table[(addrs[set][way] & m_memory.GetRamMask()) >> 5] = 0xff; + lookup_table[(addrs[set][way] & memory.GetRamMask()) >> 5] = 0xff; valid[set] &= ~(1U << way); modified[set] &= ~(1U << way); } } -void Cache::Touch(u32 addr, bool store) +void Cache::Touch(Memory::MemoryManager& memory, u32 addr, bool store) { - GetCache(addr, false); + GetCache(memory, addr, false); } -std::pair Cache::GetCache(u32 addr, bool locked) +std::pair Cache::GetCache(Memory::MemoryManager& memory, u32 addr, bool locked) { addr &= ~31; u32 set = (addr >> 5) & 0x7f; @@ -219,15 +214,15 @@ std::pair Cache::GetCache(u32 addr, bool locked) if (addr & CACHE_VMEM_BIT) { - way = lookup_table_vmem[(addr & m_memory.GetFakeVMemMask()) >> 5]; + way = lookup_table_vmem[(addr & memory.GetFakeVMemMask()) >> 5]; } else if (addr & CACHE_EXRAM_BIT) { - way = lookup_table_ex[(addr & m_memory.GetExRamMask()) >> 5]; + way = lookup_table_ex[(addr & memory.GetExRamMask()) >> 5]; } else { - way = lookup_table[(addr & m_memory.GetRamMask()) >> 5]; + way = lookup_table[(addr & memory.GetRamMask()) >> 5]; } // load to the cache @@ -243,25 +238,25 @@ std::pair Cache::GetCache(u32 addr, bool locked) { // store the cache back to main memory if (modified[set] & (1 << way)) - m_memory.CopyToEmu(addrs[set][way], data[set][way].data(), 32); + memory.CopyToEmu(addrs[set][way], data[set][way].data(), 32); if (addrs[set][way] & CACHE_VMEM_BIT) - lookup_table_vmem[(addrs[set][way] & m_memory.GetFakeVMemMask()) >> 5] = 0xff; + lookup_table_vmem[(addrs[set][way] & memory.GetFakeVMemMask()) >> 5] = 0xff; else if (addrs[set][way] & CACHE_EXRAM_BIT) - lookup_table_ex[(addrs[set][way] & m_memory.GetExRamMask()) >> 5] = 0xff; + lookup_table_ex[(addrs[set][way] & memory.GetExRamMask()) >> 5] = 0xff; else - lookup_table[(addrs[set][way] & m_memory.GetRamMask()) >> 5] = 0xff; + lookup_table[(addrs[set][way] & memory.GetRamMask()) >> 5] = 0xff; } // load - m_memory.CopyFromEmu(data[set][way].data(), (addr & ~0x1f), 32); + memory.CopyFromEmu(data[set][way].data(), (addr & ~0x1f), 32); if (addr & CACHE_VMEM_BIT) - lookup_table_vmem[(addr & m_memory.GetFakeVMemMask()) >> 5] = way; + lookup_table_vmem[(addr & memory.GetFakeVMemMask()) >> 5] = way; else if (addr & CACHE_EXRAM_BIT) - lookup_table_ex[(addr & m_memory.GetExRamMask()) >> 5] = way; + lookup_table_ex[(addr & memory.GetExRamMask()) >> 5] = way; else - lookup_table[(addr & m_memory.GetRamMask()) >> 5] = way; + lookup_table[(addr & memory.GetRamMask()) >> 5] = way; addrs[set][way] = addr; valid[set] |= (1 << way); @@ -275,13 +270,13 @@ std::pair Cache::GetCache(u32 addr, bool locked) return {set, way}; } -void Cache::Read(u32 addr, void* buffer, u32 len, bool locked) +void Cache::Read(Memory::MemoryManager& memory, u32 addr, void* buffer, u32 len, bool locked) { auto* value = static_cast(buffer); while (len > 0) { - auto [set, way] = GetCache(addr, locked); + auto [set, way] = GetCache(memory, addr, locked); u32 offset_in_block = addr - (addr & ~31); u32 len_in_block = std::min(len, ((addr + 32) & ~31) - addr); @@ -293,7 +288,7 @@ void Cache::Read(u32 addr, void* buffer, u32 len, bool locked) } else { - m_memory.CopyFromEmu(value, addr, len_in_block); + memory.CopyFromEmu(value, addr, len_in_block); } addr += len_in_block; @@ -302,13 +297,13 @@ void Cache::Read(u32 addr, void* buffer, u32 len, bool locked) } } -void Cache::Write(u32 addr, const void* buffer, u32 len, bool locked) +void Cache::Write(Memory::MemoryManager& memory, u32 addr, const void* buffer, u32 len, bool locked) { auto* value = static_cast(buffer); while (len > 0) { - auto [set, way] = GetCache(addr, locked); + auto [set, way] = GetCache(memory, addr, locked); u32 offset_in_block = addr - (addr & ~31); u32 len_in_block = std::min(len, ((addr + 32) & ~31) - addr); @@ -321,7 +316,7 @@ void Cache::Write(u32 addr, const void* buffer, u32 len, bool locked) } else { - m_memory.CopyToEmu(addr, value, len_in_block); + memory.CopyToEmu(addr, value, len_in_block); } addr += len_in_block; @@ -330,7 +325,7 @@ void Cache::Write(u32 addr, const void* buffer, u32 len, bool locked) } } -void Cache::DoState(PointerWrap& p) +void Cache::DoState(Memory::MemoryManager& memory, PointerWrap& p) { if (p.IsReadMode()) { @@ -343,11 +338,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] & m_memory.GetFakeVMemMask()) >> 5] = 0xff; + lookup_table_vmem[(addrs[set][way] & memory.GetFakeVMemMask()) >> 5] = 0xff; else if (addrs[set][way] & CACHE_EXRAM_BIT) - lookup_table_ex[(addrs[set][way] & m_memory.GetExRamMask()) >> 5] = 0xff; + lookup_table_ex[(addrs[set][way] & memory.GetExRamMask()) >> 5] = 0xff; else - lookup_table[(addrs[set][way] & m_memory.GetRamMask()) >> 5] = 0xff; + lookup_table[(addrs[set][way] & memory.GetRamMask()) >> 5] = 0xff; } } } @@ -369,30 +364,30 @@ void Cache::DoState(PointerWrap& p) if ((valid[set] & (1 << way)) != 0) { if (addrs[set][way] & CACHE_VMEM_BIT) - lookup_table_vmem[(addrs[set][way] & m_memory.GetFakeVMemMask()) >> 5] = way; + lookup_table_vmem[(addrs[set][way] & memory.GetFakeVMemMask()) >> 5] = way; else if (addrs[set][way] & CACHE_EXRAM_BIT) - lookup_table_ex[(addrs[set][way] & m_memory.GetExRamMask()) >> 5] = way; + lookup_table_ex[(addrs[set][way] & memory.GetExRamMask()) >> 5] = way; else - lookup_table[(addrs[set][way] & m_memory.GetRamMask()) >> 5] = way; + lookup_table[(addrs[set][way] & memory.GetRamMask()) >> 5] = way; } } } } } -u32 InstructionCache::ReadInstruction(u32 addr) +u32 InstructionCache::ReadInstruction(Memory::MemoryManager& memory, + PowerPC::PowerPCState& ppc_state, u32 addr) { - auto& ppc_state = m_system.GetPPCState(); - if (!HID0(ppc_state).ICE || m_disable_icache) // instruction cache is disabled - return m_memory.Read_U32(addr); + return memory.Read_U32(addr); u32 value; - Read(addr, &value, sizeof(value), HID0(ppc_state).ILOCK); + Read(memory, addr, &value, sizeof(value), HID0(ppc_state).ILOCK); return Common::swap32(value); } -void InstructionCache::Invalidate(u32 addr) +void InstructionCache::Invalidate(Memory::MemoryManager& memory, JitInterface& jit_interface, + u32 addr) { // 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 @@ -406,18 +401,18 @@ void InstructionCache::Invalidate(u32 addr) if (valid[set] & (1U << way)) { if (addrs[set][way] & CACHE_VMEM_BIT) - lookup_table_vmem[(addrs[set][way] & m_memory.GetFakeVMemMask()) >> 5] = 0xff; + lookup_table_vmem[(addrs[set][way] & memory.GetFakeVMemMask()) >> 5] = 0xff; else if (addrs[set][way] & CACHE_EXRAM_BIT) - lookup_table_ex[(addrs[set][way] & m_memory.GetExRamMask()) >> 5] = 0xff; + lookup_table_ex[(addrs[set][way] & memory.GetExRamMask()) >> 5] = 0xff; else - lookup_table[(addrs[set][way] & m_memory.GetRamMask()) >> 5] = 0xff; + lookup_table[(addrs[set][way] & memory.GetRamMask()) >> 5] = 0xff; } } valid[set] = 0; modified[set] = 0; // Also tell the JIT that the corresponding address has been invalidated - m_system.GetJitInterface().InvalidateICacheLine(addr); + jit_interface.InvalidateICacheLine(addr); } void InstructionCache::RefreshConfig() diff --git a/Source/Core/Core/PowerPC/PPCCache.h b/Source/Core/Core/PowerPC/PPCCache.h index 2f1842d84e30..890f30825205 100644 --- a/Source/Core/Core/PowerPC/PPCCache.h +++ b/Source/Core/Core/PowerPC/PPCCache.h @@ -10,15 +10,16 @@ #include "Common/CommonTypes.h" #include "Common/Config/Config.h" -namespace Core -{ -class System; -} +class JitInterface; namespace Memory { class MemoryManager; } class PointerWrap; +namespace PowerPC +{ +struct PowerPCState; +} namespace PowerPC { @@ -50,27 +51,22 @@ 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(Memory::MemoryManager& memory, u32 addr); + void Invalidate(Memory::MemoryManager& memory, u32 addr); + void Flush(Memory::MemoryManager& memory, u32 addr); + void Touch(Memory::MemoryManager& memory, u32 addr, bool store); - void Store(u32 addr); - void Invalidate(u32 addr); - void Flush(u32 addr); - void Touch(u32 addr, bool store); + void FlushAll(Memory::MemoryManager& memory); - void FlushAll(); + std::pair GetCache(Memory::MemoryManager& memory, u32 addr, bool locked); - std::pair GetCache(u32 addr, bool locked); + void Read(Memory::MemoryManager& memory, u32 addr, void* buffer, u32 len, bool locked); + void Write(Memory::MemoryManager& memory, u32 addr, const void* buffer, u32 len, bool locked); - void Read(u32 addr, void* buffer, u32 len, bool locked); - void Write(u32 addr, const void* buffer, u32 len, bool locked); - - void Init(); + void Init(Memory::MemoryManager& memory); void Reset(); - void DoState(PointerWrap& p); + void DoState(Memory::MemoryManager& memory, PointerWrap& p); }; struct InstructionCache : public Cache @@ -79,15 +75,12 @@ struct InstructionCache : public Cache bool m_disable_icache = false; - explicit InstructionCache(Core::System& system, Memory::MemoryManager& memory) - : Cache(system, memory) - { - } + InstructionCache() = default; ~InstructionCache(); - u32 ReadInstruction(u32 addr); - void Invalidate(u32 addr); - void Init(); - void Reset(); + u32 ReadInstruction(Memory::MemoryManager& memory, PowerPC::PowerPCState& ppc_state, u32 addr); + void Invalidate(Memory::MemoryManager& memory, JitInterface& jit_interface, u32 addr); + void Init(Memory::MemoryManager& memory); + void Reset(JitInterface& jit_interface); void RefreshConfig(); }; } // namespace PowerPC diff --git a/Source/Core/Core/PowerPC/PowerPC.cpp b/Source/Core/Core/PowerPC/PowerPC.cpp index bf6c10458bb9..127eff4ddf0b 100644 --- a/Source/Core/Core/PowerPC/PowerPC.cpp +++ b/Source/Core/Core/PowerPC/PowerPC.cpp @@ -57,7 +57,8 @@ void PairedSingle::SetPS1(double value) static void InvalidateCacheThreadSafe(Core::System& system, u64 userdata, s64 cyclesLate) { - system.GetPPCState().iCache.Invalidate(static_cast(userdata)); + system.GetPPCState().iCache.Invalidate(system.GetMemory(), system.GetJitInterface(), + static_cast(userdata)); } std::istream& operator>>(std::istream& is, CPUCore& core) @@ -84,9 +85,9 @@ std::ostream& operator<<(std::ostream& os, CPUCore core) return os; } -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) +PowerPCManager::PowerPCManager(Core::System& system) + : m_breakpoints(system), m_memchecks(system), m_debug_interface(system, m_symbol_db), + m_system(system) { } @@ -125,15 +126,16 @@ void PowerPCManager::DoState(PointerWrap& p) p.Do(m_ppc_state.reserve); p.Do(m_ppc_state.reserve_address); - m_ppc_state.iCache.DoState(p); - m_ppc_state.dCache.DoState(p); + auto& memory = m_system.GetMemory(); + m_ppc_state.iCache.DoState(memory, p); + m_ppc_state.dCache.DoState(memory, p); if (p.IsReadMode()) { if (!m_ppc_state.m_enable_dcache) { INFO_LOG_FMT(POWERPC, "Flushing data cache"); - m_ppc_state.dCache.FlushAll(); + m_ppc_state.dCache.FlushAll(memory); } RoundingModeUpdated(m_ppc_state); @@ -275,7 +277,7 @@ void PowerPCManager::RefreshConfig() if (old_enable_dcache && !m_ppc_state.m_enable_dcache) { INFO_LOG_FMT(POWERPC, "Flushing data cache"); - m_ppc_state.dCache.FlushAll(); + m_ppc_state.dCache.FlushAll(m_system.GetMemory()); } } @@ -291,8 +293,9 @@ void PowerPCManager::Init(CPUCore cpu_core) Reset(); InitializeCPUCore(cpu_core); - m_ppc_state.iCache.Init(); - m_ppc_state.dCache.Init(); + auto& memory = m_system.GetMemory(); + m_ppc_state.iCache.Init(memory); + m_ppc_state.dCache.Init(memory); if (Config::Get(Config::MAIN_ENABLE_DEBUGGING)) m_breakpoints.ClearAllTemporary(); @@ -305,7 +308,7 @@ void PowerPCManager::Reset() m_ppc_state.tlb = {}; ResetRegisters(); - m_ppc_state.iCache.Reset(); + m_ppc_state.iCache.Reset(m_system.GetJitInterface()); m_ppc_state.dCache.Reset(); } @@ -320,7 +323,8 @@ void PowerPCManager::ScheduleInvalidateCacheThreadSafe(u32 address) } else { - m_ppc_state.iCache.Invalidate(static_cast(address)); + m_ppc_state.iCache.Invalidate(m_system.GetMemory(), m_system.GetJitInterface(), + static_cast(address)); } } diff --git a/Source/Core/Core/PowerPC/PowerPC.h b/Source/Core/Core/PowerPC/PowerPC.h index 93e12a6c7601..e4d00ec8843e 100644 --- a/Source/Core/Core/PowerPC/PowerPC.h +++ b/Source/Core/Core/PowerPC/PowerPC.h @@ -28,10 +28,6 @@ namespace CoreTiming { struct EventType; } -namespace Memory -{ -class MemoryManager; -} namespace PowerPC { @@ -197,11 +193,6 @@ 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); @@ -263,7 +254,7 @@ CPUCore DefaultCPUCore(); class PowerPCManager { public: - explicit PowerPCManager(Core::System& system, Memory::MemoryManager& memory); + explicit PowerPCManager(Core::System& system); 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 8879a49ce76c..695d5861fc10 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), + m_memory(system), m_pixel_engine{system}, m_power_pc(system), 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(),