diff --git a/Source/Core/Core/PowerPC/PowerPC.cpp b/Source/Core/Core/PowerPC/PowerPC.cpp index 172ce0c36c..68b21ab0e0 100644 --- a/Source/Core/Core/PowerPC/PowerPC.cpp +++ b/Source/Core/Core/PowerPC/PowerPC.cpp @@ -10,6 +10,7 @@ #include "Common/MathUtil.h" #include "Core/ConfigManager.h" +#include "Core/CoreTiming.h" #include "Core/HW/CPU.h" #include "Core/HW/Memmap.h" #include "Core/HW/SystemTimers.h" @@ -35,6 +36,12 @@ BreakPoints breakpoints; MemChecks memchecks; PPCDebugInterface debug_interface; +static int s_invalidate_cache_thread_safe; +static void InvalidateCacheThreadSafe(u64 userdata, s64 cyclesLate) +{ + ppcState.iCache.Invalidate(static_cast(userdata)); +} + u32 CompactCR() { u32 new_cr = 0; @@ -117,6 +124,9 @@ void Init(int cpu_core) // Changing the rounding mode has a limited effect. FPURoundMode::SetPrecisionMode(FPURoundMode::PREC_53); + s_invalidate_cache_thread_safe = + CoreTiming::RegisterEvent("invalidateEmulatedCache", InvalidateCacheThreadSafe); + memset(ppcState.sr, 0, sizeof(ppcState.sr)); ppcState.pagetable_base = 0; ppcState.pagetable_hashmask = 0; @@ -173,6 +183,15 @@ void Init(int cpu_core) breakpoints.ClearAllTemporary(); } +void ScheduleInvalidateCacheThreadSafe(u32 address) +{ + if (CPU::GetState() == CPU::State::CPU_RUNNING) + CoreTiming::ScheduleEvent(0, s_invalidate_cache_thread_safe, address, + CoreTiming::FromThread::NON_CPU); + else + PowerPC::ppcState.iCache.Invalidate(static_cast(address)); +} + void Shutdown() { InjectExternalCPUCore(nullptr); diff --git a/Source/Core/Core/PowerPC/PowerPC.h b/Source/Core/Core/PowerPC/PowerPC.h index 98d281e851..29b1b8496b 100644 --- a/Source/Core/Core/PowerPC/PowerPC.h +++ b/Source/Core/Core/PowerPC/PowerPC.h @@ -138,6 +138,7 @@ extern PPCDebugInterface debug_interface; void Init(int cpu_core); void Shutdown(); void DoState(PointerWrap& p); +void ScheduleInvalidateCacheThreadSafe(u32 address); CoreMode GetMode(); // [NOT THREADSAFE] CPU Thread or CPU::PauseAndLock or CORE_UNINITIALIZED