PPCCache: Avoid Global System Accessor

This commit is contained in:
mitaclaw 2024-03-17 20:14:20 -07:00
parent db0cd82326
commit cf74c0d683
12 changed files with 109 additions and 104 deletions

View File

@ -1082,6 +1082,14 @@ public:
ABI_CallFunction(func); ABI_CallFunction(func);
} }
template <typename FunctionPointer>
void ABI_CallFunctionPP(FunctionPointer func, const void* param1, const void* param2)
{
MOV(64, R(ABI_PARAM1), Imm64(reinterpret_cast<u64>(param1)));
MOV(64, R(ABI_PARAM2), Imm64(reinterpret_cast<u64>(param2)));
ABI_CallFunction(func);
}
template <typename FunctionPointer> template <typename FunctionPointer>
void ABI_CallFunctionPC(FunctionPointer func, const void* param1, u32 param2) void ABI_CallFunctionPC(FunctionPointer func, const void* param1, u32 param2)
{ {

View File

@ -208,9 +208,11 @@ static Installation InstallCodeHandlerLocked(const Core::CPUThreadGuard& guard)
// Invalidate the icache and any asm codes // Invalidate the icache and any asm codes
auto& ppc_state = guard.GetSystem().GetPPCState(); 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) 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; return Installation::Installed;
} }

View File

@ -66,12 +66,14 @@ constexpr std::array<Hook, 23> os_patches{{
void Patch(Core::System& system, u32 addr, std::string_view func_name) void Patch(Core::System& system, u32 addr, std::string_view func_name)
{ {
auto& ppc_state = system.GetPPCState(); auto& ppc_state = system.GetPPCState();
auto& memory = system.GetMemory();
auto& jit_interface = system.GetJitInterface();
for (u32 i = 1; i < os_patches.size(); ++i) for (u32 i = 1; i < os_patches.size(); ++i)
{ {
if (os_patches[i].name == func_name) if (os_patches[i].name == func_name)
{ {
s_hooked_addresses[addr] = i; s_hooked_addresses[addr] = i;
ppc_state.iCache.Invalidate(addr); ppc_state.iCache.Invalidate(memory, jit_interface, addr);
return; return;
} }
} }
@ -108,6 +110,8 @@ void PatchFunctions(Core::System& system)
{ {
auto& power_pc = system.GetPowerPC(); auto& power_pc = system.GetPowerPC();
auto& ppc_state = power_pc.GetPPCState(); auto& ppc_state = power_pc.GetPPCState();
auto& memory = system.GetMemory();
auto& jit_interface = system.GetJitInterface();
auto& ppc_symbol_db = power_pc.GetSymbolDB(); auto& ppc_symbol_db = power_pc.GetSymbolDB();
// Remove all hooks that aren't fixed address hooks // 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) 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); i = s_hooked_addresses.erase(i);
} }
else else
@ -135,7 +139,7 @@ void PatchFunctions(Core::System& system)
for (u32 addr = symbol->address; addr < symbol->address + symbol->size; addr += 4) for (u32 addr = symbol->address; addr < symbol->address + symbol->size; addr += 4)
{ {
s_hooked_addresses[addr] = i; 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); 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& power_pc = system.GetPowerPC();
auto& ppc_state = power_pc.GetPPCState(); auto& ppc_state = power_pc.GetPPCState();
auto& memory = system.GetMemory();
auto& jit_interface = system.GetJitInterface();
if (patch->flags == HookFlag::Fixed) if (patch->flags == HookFlag::Fixed)
{ {
@ -245,7 +251,7 @@ u32 UnPatch(Core::System& system, std::string_view patch_name)
if (i->second == patch_idx) if (i->second == patch_idx)
{ {
addr = i->first; addr = i->first;
ppc_state.iCache.Invalidate(i->first); ppc_state.iCache.Invalidate(memory, jit_interface, i->first);
i = s_hooked_addresses.erase(i); i = s_hooked_addresses.erase(i);
} }
else 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) for (u32 addr = symbol->address; addr < symbol->address + symbol->size; addr += 4)
{ {
s_hooked_addresses.erase(addr); s_hooked_addresses.erase(addr);
ppc_state.iCache.Invalidate(addr); ppc_state.iCache.Invalidate(memory, jit_interface, addr);
} }
return symbol->address; 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) u32 UnpatchRange(Core::System& system, u32 start_addr, u32 end_addr)
{ {
auto& ppc_state = system.GetPPCState(); auto& ppc_state = system.GetPPCState();
auto& memory = system.GetMemory();
auto& jit_interface = system.GetJitInterface();
u32 count = 0; 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, INFO_LOG_FMT(OSHLE, "Unpatch HLE hooks [{:08x};{:08x}): {} at {:08x}", start_addr, end_addr,
os_patches[i->second].name, i->first); 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); i = s_hooked_addresses.erase(i);
count += 1; count += 1;
} }

View File

@ -36,6 +36,7 @@ void GeckoCodeHandlerICacheFlush(const Core::CPUThreadGuard& guard)
{ {
auto& system = guard.GetSystem(); auto& system = guard.GetSystem();
auto& ppc_state = system.GetPPCState(); auto& ppc_state = system.GetPPCState();
auto& jit_interface = system.GetJitInterface();
// Work around the codehandler not properly invalidating the icache, but // Work around the codehandler not properly invalidating the icache, but
// only the first few frames. // 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); 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 // Because Dolphin messes around with the CPU state instead of patching the game binary, we

View File

@ -1016,7 +1016,8 @@ void ProcessCommands(bool loop_until_continue)
WriteMemory(guard); WriteMemory(guard);
auto& ppc_state = system.GetPPCState(); auto& ppc_state = system.GetPPCState();
ppc_state.iCache.Reset(); auto& jit_interface = system.GetJitInterface();
ppc_state.iCache.Reset(jit_interface);
Host_UpdateDisasmDialog(); Host_UpdateDisasmDialog();
break; break;
} }

View File

@ -631,7 +631,9 @@ void Interpreter::icbi(Interpreter& interpreter, UGeckoInstruction inst)
// TODO: Raise DSI if translation fails (except for direct-store segments). // TODO: Raise DSI if translation fails (except for direct-store segments).
auto& ppc_state = interpreter.m_ppc_state; auto& ppc_state = interpreter.m_ppc_state;
const u32 address = Helper_Get_EA_X(ppc_state, inst); 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) void Interpreter::lbzux(Interpreter& interpreter, UGeckoInstruction inst)

View File

@ -358,7 +358,8 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst)
INFO_LOG_FMT(POWERPC, "Flush Instruction Cache! ICE={}", HID0(ppc_state).ICE); INFO_LOG_FMT(POWERPC, "Flush Instruction Cache! ICE={}", HID0(ppc_state).ICE);
// this is rather slow // this is rather slow
// most games do it only once during initialization // 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; break;

View File

@ -216,9 +216,9 @@ void Jit64::UpdateFPExceptionSummary(X64Reg fpscr, X64Reg tmp1, X64Reg tmp2)
OR(32, R(fpscr), R(tmp1)); 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) void Jit64::mtspr(UGeckoInstruction inst)
@ -286,7 +286,7 @@ void Jit64::mtspr(UGeckoInstruction inst)
FixupBranch dont_reset_icache = J_CC(CC_NC); FixupBranch dont_reset_icache = J_CC(CC_NC);
BitSet32 regs = CallerSavedRegistersInUse(); BitSet32 regs = CallerSavedRegistersInUse();
ABI_PushRegistersAndAdjustStack(regs, 0); ABI_PushRegistersAndAdjustStack(regs, 0);
ABI_CallFunctionP(DoICacheReset, &m_ppc_state); ABI_CallFunctionPP(DoICacheReset, &m_ppc_state, &m_system.GetJitInterface());
ABI_PopRegistersAndAdjustStack(regs, 0); ABI_PopRegistersAndAdjustStack(regs, 0);
SetJumpTarget(dont_reset_icache); SetJumpTarget(dont_reset_icache);
return; return;

View File

@ -220,7 +220,7 @@ T MMU::ReadFromHardware(u32 em_address)
} }
else 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); HID0(m_ppc_state).DLOCK || flag != XCheckTLBFlag::Read);
} }
@ -239,7 +239,7 @@ T MMU::ReadFromHardware(u32 em_address)
} }
else 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); 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(); em_address &= m_memory.GetRamMask();
if (m_ppc_state.m_enable_dcache && !wi) 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) if (!m_ppc_state.m_enable_dcache || wi || flag != XCheckTLBFlag::Write)
std::memcpy(&m_memory.GetRAM()[em_address], &swapped_data, size); 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) 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); HID0(m_ppc_state).DLOCK);
} }
@ -497,7 +497,7 @@ TryReadInstResult MMU::TryReadInstruction(u32 address)
} }
else 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}; return TryReadInstResult{true, from_bat, hex, address};
} }
@ -1137,7 +1137,7 @@ void MMU::StoreDCacheLine(u32 address)
} }
if (m_ppc_state.m_enable_dcache) 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) void MMU::InvalidateDCacheLine(u32 address)
@ -1159,7 +1159,7 @@ void MMU::InvalidateDCacheLine(u32 address)
} }
if (m_ppc_state.m_enable_dcache) 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) void MMU::FlushDCacheLine(u32 address)
@ -1183,7 +1183,7 @@ void MMU::FlushDCacheLine(u32 address)
} }
if (m_ppc_state.m_enable_dcache) 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) 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) 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 u32 MMU::IsOptimizableMMIOAccess(u32 address, u32 access_size) const

View File

@ -105,17 +105,14 @@ void Cache::Reset()
std::fill(lookup_table_vmem.begin(), lookup_table_vmem.end(), 0xFF); std::fill(lookup_table_vmem.begin(), lookup_table_vmem.end(), 0xFF);
} }
void InstructionCache::Reset() void InstructionCache::Reset(JitInterface& jit_interface)
{ {
Cache::Reset(); Cache::Reset();
Core::System::GetInstance().GetJitInterface().ClearSafe(); jit_interface.ClearSafe();
} }
void Cache::Init() void Cache::Init(Memory::MemoryManager& memory)
{ {
auto& system = Core::System::GetInstance();
auto& memory = system.GetMemory();
data.fill({}); data.fill({});
addrs.fill({}); addrs.fill({});
lookup_table.resize(memory.GetRamSize() >> 5); lookup_table.resize(memory.GetRamSize() >> 5);
@ -124,21 +121,18 @@ void Cache::Init()
Reset(); Reset();
} }
void InstructionCache::Init() void InstructionCache::Init(Memory::MemoryManager& memory)
{ {
if (!m_config_callback_id) if (!m_config_callback_id)
m_config_callback_id = Config::AddConfigChangedCallback([this] { RefreshConfig(); }); m_config_callback_id = Config::AddConfigChangedCallback([this] { RefreshConfig(); });
RefreshConfig(); RefreshConfig();
Cache::Init(); Cache::Init(memory);
} }
void Cache::Store(u32 addr) void Cache::Store(Memory::MemoryManager& memory, u32 addr)
{ {
auto& system = Core::System::GetInstance(); auto [set, way] = GetCache(memory, addr, true);
auto& memory = system.GetMemory();
auto [set, way] = GetCache(addr, true);
if (way == 0xff) if (way == 0xff)
return; return;
@ -148,11 +142,8 @@ void Cache::Store(u32 addr)
modified[set] &= ~(1U << way); modified[set] &= ~(1U << way);
} }
void Cache::FlushAll() void Cache::FlushAll(Memory::MemoryManager& memory)
{ {
auto& system = Core::System::GetInstance();
auto& memory = system.GetMemory();
for (size_t set = 0; set < CACHE_SETS; set++) for (size_t set = 0; set < CACHE_SETS; set++)
{ {
for (size_t way = 0; way < CACHE_WAYS; way++) for (size_t way = 0; way < CACHE_WAYS; way++)
@ -165,12 +156,9 @@ void Cache::FlushAll()
Reset(); Reset();
} }
void Cache::Invalidate(u32 addr) void Cache::Invalidate(Memory::MemoryManager& memory, u32 addr)
{ {
auto& system = Core::System::GetInstance(); auto [set, way] = GetCache(memory, addr, true);
auto& memory = system.GetMemory();
auto [set, way] = GetCache(addr, true);
if (way == 0xff) if (way == 0xff)
return; return;
@ -189,12 +177,9 @@ void Cache::Invalidate(u32 addr)
} }
} }
void Cache::Flush(u32 addr) void Cache::Flush(Memory::MemoryManager& memory, u32 addr)
{ {
auto& system = Core::System::GetInstance(); auto [set, way] = GetCache(memory, addr, true);
auto& memory = system.GetMemory();
auto [set, way] = GetCache(addr, true);
if (way == 0xff) if (way == 0xff)
return; return;
@ -216,16 +201,13 @@ void Cache::Flush(u32 addr)
} }
} }
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<u32, u32> Cache::GetCache(u32 addr, bool locked) std::pair<u32, u32> Cache::GetCache(Memory::MemoryManager& memory, u32 addr, bool locked)
{ {
auto& system = Core::System::GetInstance();
auto& memory = system.GetMemory();
addr &= ~31; addr &= ~31;
u32 set = (addr >> 5) & 0x7f; u32 set = (addr >> 5) & 0x7f;
u32 way; u32 way;
@ -288,16 +270,13 @@ std::pair<u32, u32> Cache::GetCache(u32 addr, bool locked)
return {set, way}; 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& system = Core::System::GetInstance();
auto& memory = system.GetMemory();
auto* value = static_cast<u8*>(buffer); auto* value = static_cast<u8*>(buffer);
while (len > 0) while (len > 0)
{ {
auto [set, way] = GetCache(addr, locked); auto [set, way] = GetCache(memory, addr, locked);
u32 offset_in_block = addr - (addr & ~31); u32 offset_in_block = addr - (addr & ~31);
u32 len_in_block = std::min<u32>(len, ((addr + 32) & ~31) - addr); u32 len_in_block = std::min<u32>(len, ((addr + 32) & ~31) - addr);
@ -318,16 +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& system = Core::System::GetInstance();
auto& memory = system.GetMemory();
auto* value = static_cast<const u8*>(buffer); auto* value = static_cast<const u8*>(buffer);
while (len > 0) while (len > 0)
{ {
auto [set, way] = GetCache(addr, locked); auto [set, way] = GetCache(memory, addr, locked);
u32 offset_in_block = addr - (addr & ~31); u32 offset_in_block = addr - (addr & ~31);
u32 len_in_block = std::min<u32>(len, ((addr + 32) & ~31) - addr); u32 len_in_block = std::min<u32>(len, ((addr + 32) & ~31) - addr);
@ -349,11 +325,8 @@ 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)
{ {
auto& system = Core::System::GetInstance();
auto& memory = system.GetMemory();
if (p.IsReadMode()) if (p.IsReadMode())
{ {
// Clear valid parts of the lookup tables (this is done instead of using fill(0xff) to avoid // Clear valid parts of the lookup tables (this is done instead of using fill(0xff) to avoid
@ -402,24 +375,20 @@ void Cache::DoState(PointerWrap& p)
} }
} }
u32 InstructionCache::ReadInstruction(u32 addr) u32 InstructionCache::ReadInstruction(Memory::MemoryManager& memory,
PowerPC::PowerPCState& ppc_state, u32 addr)
{ {
auto& system = Core::System::GetInstance();
auto& ppc_state = system.GetPPCState();
if (!HID0(ppc_state).ICE || m_disable_icache) // instruction cache is disabled if (!HID0(ppc_state).ICE || m_disable_icache) // instruction cache is disabled
return system.GetMemory().Read_U32(addr); return memory.Read_U32(addr);
u32 value; 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); return Common::swap32(value);
} }
void InstructionCache::Invalidate(u32 addr) void InstructionCache::Invalidate(Memory::MemoryManager& memory, JitInterface& jit_interface,
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) // 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 // 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, // instruction always invalidates, even if the instruction cache is disabled or locked,
@ -443,7 +412,7 @@ void InstructionCache::Invalidate(u32 addr)
modified[set] = 0; modified[set] = 0;
// Also tell the JIT that the corresponding address has been invalidated // Also tell the JIT that the corresponding address has been invalidated
system.GetJitInterface().InvalidateICacheLine(addr); jit_interface.InvalidateICacheLine(addr);
} }
void InstructionCache::RefreshConfig() void InstructionCache::RefreshConfig()

View File

@ -10,7 +10,16 @@
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/Config/Config.h" #include "Common/Config/Config.h"
class JitInterface;
namespace Memory
{
class MemoryManager;
}
class PointerWrap; class PointerWrap;
namespace PowerPC
{
struct PowerPCState;
}
namespace PowerPC namespace PowerPC
{ {
@ -42,22 +51,22 @@ struct Cache
std::vector<u8> lookup_table_ex{}; std::vector<u8> lookup_table_ex{};
std::vector<u8> lookup_table_vmem{}; std::vector<u8> lookup_table_vmem{};
void Store(u32 addr); void Store(Memory::MemoryManager& memory, u32 addr);
void Invalidate(u32 addr); void Invalidate(Memory::MemoryManager& memory, u32 addr);
void Flush(u32 addr); void Flush(Memory::MemoryManager& memory, u32 addr);
void Touch(u32 addr, bool store); void Touch(Memory::MemoryManager& memory, u32 addr, bool store);
void FlushAll(); void FlushAll(Memory::MemoryManager& memory);
std::pair<u32, u32> GetCache(u32 addr, bool locked); std::pair<u32, u32> GetCache(Memory::MemoryManager& memory, u32 addr, bool locked);
void Read(u32 addr, void* buffer, u32 len, bool locked); void Read(Memory::MemoryManager& memory, u32 addr, void* buffer, u32 len, bool locked);
void Write(u32 addr, const void* buffer, u32 len, bool locked); void Write(Memory::MemoryManager& memory, u32 addr, const void* buffer, u32 len, bool locked);
void Init(); void Init(Memory::MemoryManager& memory);
void Reset(); void Reset();
void DoState(PointerWrap& p); void DoState(Memory::MemoryManager& memory, PointerWrap& p);
}; };
struct InstructionCache : public Cache struct InstructionCache : public Cache
@ -68,10 +77,10 @@ struct InstructionCache : public Cache
InstructionCache() = default; InstructionCache() = default;
~InstructionCache(); ~InstructionCache();
u32 ReadInstruction(u32 addr); u32 ReadInstruction(Memory::MemoryManager& memory, PowerPC::PowerPCState& ppc_state, u32 addr);
void Invalidate(u32 addr); void Invalidate(Memory::MemoryManager& memory, JitInterface& jit_interface, u32 addr);
void Init(); void Init(Memory::MemoryManager& memory);
void Reset(); void Reset(JitInterface& jit_interface);
void RefreshConfig(); void RefreshConfig();
}; };
} // namespace PowerPC } // namespace PowerPC

View File

@ -57,7 +57,8 @@ void PairedSingle::SetPS1(double value)
static void InvalidateCacheThreadSafe(Core::System& system, u64 userdata, s64 cyclesLate) static void InvalidateCacheThreadSafe(Core::System& system, u64 userdata, s64 cyclesLate)
{ {
system.GetPPCState().iCache.Invalidate(static_cast<u32>(userdata)); system.GetPPCState().iCache.Invalidate(system.GetMemory(), system.GetJitInterface(),
static_cast<u32>(userdata));
} }
std::istream& operator>>(std::istream& is, CPUCore& core) std::istream& operator>>(std::istream& is, CPUCore& core)
@ -125,15 +126,16 @@ void PowerPCManager::DoState(PointerWrap& p)
p.Do(m_ppc_state.reserve); p.Do(m_ppc_state.reserve);
p.Do(m_ppc_state.reserve_address); p.Do(m_ppc_state.reserve_address);
m_ppc_state.iCache.DoState(p); auto& memory = m_system.GetMemory();
m_ppc_state.dCache.DoState(p); m_ppc_state.iCache.DoState(memory, p);
m_ppc_state.dCache.DoState(memory, p);
if (p.IsReadMode()) if (p.IsReadMode())
{ {
if (!m_ppc_state.m_enable_dcache) if (!m_ppc_state.m_enable_dcache)
{ {
INFO_LOG_FMT(POWERPC, "Flushing data cache"); INFO_LOG_FMT(POWERPC, "Flushing data cache");
m_ppc_state.dCache.FlushAll(); m_ppc_state.dCache.FlushAll(memory);
} }
RoundingModeUpdated(m_ppc_state); RoundingModeUpdated(m_ppc_state);
@ -275,7 +277,7 @@ void PowerPCManager::RefreshConfig()
if (old_enable_dcache && !m_ppc_state.m_enable_dcache) if (old_enable_dcache && !m_ppc_state.m_enable_dcache)
{ {
INFO_LOG_FMT(POWERPC, "Flushing data cache"); 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(); Reset();
InitializeCPUCore(cpu_core); InitializeCPUCore(cpu_core);
m_ppc_state.iCache.Init(); auto& memory = m_system.GetMemory();
m_ppc_state.dCache.Init(); m_ppc_state.iCache.Init(memory);
m_ppc_state.dCache.Init(memory);
if (Config::Get(Config::MAIN_ENABLE_DEBUGGING)) if (Config::Get(Config::MAIN_ENABLE_DEBUGGING))
m_breakpoints.ClearAllTemporary(); m_breakpoints.ClearAllTemporary();
@ -305,7 +308,7 @@ void PowerPCManager::Reset()
m_ppc_state.tlb = {}; m_ppc_state.tlb = {};
ResetRegisters(); ResetRegisters();
m_ppc_state.iCache.Reset(); m_ppc_state.iCache.Reset(m_system.GetJitInterface());
m_ppc_state.dCache.Reset(); m_ppc_state.dCache.Reset();
} }
@ -320,7 +323,8 @@ void PowerPCManager::ScheduleInvalidateCacheThreadSafe(u32 address)
} }
else else
{ {
m_ppc_state.iCache.Invalidate(static_cast<u32>(address)); m_ppc_state.iCache.Invalidate(m_system.GetMemory(), m_system.GetJitInterface(),
static_cast<u32>(address));
} }
} }