diff --git a/Core/HLE/HLEHelperThread.cpp b/Core/HLE/HLEHelperThread.cpp index 939a910c46..71b8bbc701 100644 --- a/Core/HLE/HLEHelperThread.cpp +++ b/Core/HLE/HLEHelperThread.cpp @@ -24,6 +24,7 @@ #include "Core/HLE/KernelWaitHelpers.h" #include "Core/HLE/sceKernelThread.h" #include "Core/HLE/sceKernelMemory.h" +#include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPSCodeUtils.h" HLEHelperThread::HLEHelperThread(const char *threadName, const u32 instructions[], u32 instrCount, u32 prio, int stacksize) { @@ -36,6 +37,8 @@ HLEHelperThread::HLEHelperThread(const char *threadName, const u32 instructions[ // Just to simplify things, we add the return here. Memory::WriteUnchecked_U32(MIPS_MAKE_JR_RA(), entry_ + instrBytes + 0); Memory::WriteUnchecked_U32(MIPS_MAKE_NOP(), entry_ + instrBytes + 4); + // The memory may have held another helper's code, already compiled. + currentMIPS->InvalidateICacheRangeDeferred(entry_, totalBytes); Create(threadName, prio, stacksize); } @@ -46,6 +49,7 @@ HLEHelperThread::HLEHelperThread(const char *threadName, const char *module, con _dbg_assert_(Memory::IsValid4AlignedAddress(entry_)); // after AllocEntry. Memory::WriteUnchecked_U32(MIPS_MAKE_JR_RA(), entry_ + 0); Memory::WriteUnchecked_U32(MIPS_MAKE_SYSCALL(module, func), entry_ + 4); + currentMIPS->InvalidateICacheRangeDeferred(entry_, bytes); Create(threadName, prio, stacksize); } diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 3b6883d972..403311b718 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -2808,6 +2808,8 @@ int __KernelStartModule(SceUID moduleId, u32 argsize, u32 argAddr, u32 returnVal Memory::WriteUnchecked_U32(MIPS_MAKE_LW(MIPS_REG_RA, MIPS_REG_SP, 8), tramp + 0x24); Memory::WriteUnchecked_U32(MIPS_MAKE_J(entryAddr), tramp + 0x28); Memory::WriteUnchecked_U32(MIPS_MAKE_ADDIU(MIPS_REG_SP, MIPS_REG_SP, 16), tramp + 0x2C); + // Thread stacks get reused, so an older trampoline may already be compiled here. + currentMIPS->InvalidateICacheRangeDeferred(tramp, 0x30); NotifyMemInfo(MemBlockFlags::WRITE, tramp, 0x30, "ModuleStartTrampoline"); startThread->context.pc = tramp; startThread->nt.entrypoint = tramp; diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 22d94cb22d..5bd4a67f7f 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -788,6 +788,8 @@ static void __KernelWriteFakeSysCall(u32 nid, u32 *ptr, u32 &pos) { *ptr = pos; pos += 8; WriteHLESyscall("FakeSysCalls", nid, *ptr); + // The memory may have held code that's already compiled. + currentMIPS->InvalidateICacheRangeDeferred(*ptr, 8); } u32 HLEMipsCallReturnAddress() { diff --git a/UI/ImDebugger/ImMemView.cpp b/UI/ImDebugger/ImMemView.cpp index 85da5f27ab..d2c317ec9f 100644 --- a/UI/ImDebugger/ImMemView.cpp +++ b/UI/ImDebugger/ImMemView.cpp @@ -13,6 +13,7 @@ #include "Common/File/FileUtil.h" #include "Core/Config.h" #include "Core/MemMap.h" +#include "Core/MIPS/MIPS.h" #include "Core/Reporting.h" #include "Core/RetroAchievements.h" #include "Common/System/Display.h" @@ -354,6 +355,7 @@ void ImMemView::EditMemory(int newNibble) { out = (og & 0x0F) | (newNibble << 4); } Memory::WriteUnchecked_U8((u8)out, curAddress_); + currentMIPS->InvalidateICacheRangeDeferred(curAddress_ & ~3, 4); ScrollCursor(1, GotoMode::RESET); } @@ -365,8 +367,10 @@ void ImMemView::CopyToByteClipboard() { } void ImMemView::PasteFromByteClipboard() { - if (editableMemory_) + if (editableMemory_) { Memory::MemcpyUnchecked(curAddress_, byteClipboard_.data(), (u32)byteClipboard_.size()); + currentMIPS->InvalidateICacheRangeDeferred(curAddress_, (u32)byteClipboard_.size()); + } } void ImMemView::toggleEditableMemory(bool toggle) { @@ -388,6 +392,7 @@ void ImMemView::onChar(int c) { if (asciiSelected_) { Memory::WriteUnchecked_U8((u8)c, curAddress_); + currentMIPS->InvalidateICacheRangeDeferred(curAddress_ & ~3, 4); ScrollCursor(1, GotoMode::RESET); } else { c = tolower(c); @@ -403,6 +408,7 @@ void ImMemView::onChar(int c) { oldValue &= ~(0xF << shiftAmount); u8 newValue = oldValue | (inputValue << shiftAmount); Memory::WriteUnchecked_U8(newValue, curAddress_); + currentMIPS->InvalidateICacheRangeDeferred(curAddress_ & ~3, 4); ScrollCursor(1, GotoMode::RESET); } } diff --git a/Windows/Debugger/CtrlMemView.cpp b/Windows/Debugger/CtrlMemView.cpp index 4d0a7807ff..8ff58677d9 100644 --- a/Windows/Debugger/CtrlMemView.cpp +++ b/Windows/Debugger/CtrlMemView.cpp @@ -8,6 +8,7 @@ #include "Core/Core.h" #include "Core/System.h" #include "Core/MemMap.h" +#include "Core/MIPS/MIPS.h" #include "Core/Reporting.h" #include "Core/RetroAchievements.h" #include "Windows/W32Util/ContextMenu.h" @@ -439,7 +440,10 @@ void CtrlMemView::onChar(WPARAM wParam, LPARAM lParam) { // Route the actual memory write to the CPU thread instead of poking at it directly from this // GUI thread - see Core_RunOnCPUThread() in Core.h. No need to force the core to pause first. if (asciiSelected_) { - Core_RunOnCPUThread([&] { Memory::WriteUnchecked_U8((u8)wParam, curAddress_); }); + Core_RunOnCPUThread([&] { + Memory::WriteUnchecked_U8((u8)wParam, curAddress_); + currentMIPS->InvalidateICacheRangeDeferred(curAddress_ & ~3, 4); + }); ScrollCursor(1, GotoMode::RESET); } else { wParam = tolower(wParam); @@ -456,6 +460,7 @@ void CtrlMemView::onChar(WPARAM wParam, LPARAM lParam) { oldValue &= ~(0xF << shiftAmount); u8 newValue = oldValue | (inputValue << shiftAmount); Memory::WriteUnchecked_U8(newValue, curAddress_); + currentMIPS->InvalidateICacheRangeDeferred(curAddress_ & ~3, 4); }); ScrollCursor(1, GotoMode::RESET); }