diff --git a/Core/HLE/sceDmac.cpp b/Core/HLE/sceDmac.cpp index e2615e156f..ea509746f7 100644 --- a/Core/HLE/sceDmac.cpp +++ b/Core/HLE/sceDmac.cpp @@ -50,6 +50,7 @@ static int __DmacMemcpy(u32 dst, u32 src, u32 size) { } if (!skip) { Memory::Memcpy(dst, Memory::GetPointer(src), size); + currentMIPS->InvalidateICache(dst, size); } // This number seems strangely reproducible. diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 685d732ce7..fa7a08ee21 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -799,6 +799,7 @@ static bool __IoRead(int &result, int id, u32 data_addr, int size, int &us) { u8 *data = (u8*) Memory::GetPointer(data_addr); if (f->npdrm) { result = npdrmRead(f, data, size); + currentMIPS->InvalidateICache(data_addr, size); return true; } @@ -815,6 +816,7 @@ static bool __IoRead(int &result, int id, u32 data_addr, int size, int &us) { ev.handle = f->handle; ev.buf = data; ev.bytes = size; + ev.invalidateAddr = data_addr; ioManager.ScheduleOperation(ev); return false; } else { @@ -823,6 +825,7 @@ static bool __IoRead(int &result, int id, u32 data_addr, int size, int &us) { } else { result = (int) pspFileSystem.ReadFile(f->handle, data, size, us); } + currentMIPS->InvalidateICache(data_addr, size); return true; } } else { @@ -948,6 +951,7 @@ static bool __IoWrite(int &result, int id, u32 data_addr, int size, int &us) { ev.handle = f->handle; ev.buf = (u8 *) data_ptr; ev.bytes = size; + ev.invalidateAddr = 0; ioManager.ScheduleOperation(ev); return false; } else { diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index a5fda0e8d6..7cb7ff2ec9 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -757,6 +757,9 @@ void Module::Cleanup() { Memory::Write_U32(MIPS_MAKE_BREAK(1), nm.text_addr + i); } Memory::Memset(nm.text_addr + nm.text_size, -1, nm.data_size + nm.bss_size); + + // Let's also invalidate, just to make sure it's cleared out for any future data. + currentMIPS->InvalidateICache(memoryBlockAddr, memoryBlockSize); } } @@ -959,6 +962,8 @@ static Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, bool fromT module->memoryBlockAddr = reader.GetVaddr(); module->memoryBlockSize = reader.GetTotalSize(); + currentMIPS->InvalidateICache(module->memoryBlockAddr, module->memoryBlockSize); + SectionID sceModuleInfoSection = reader.GetSectionByName(".rodata.sceModuleInfo"); PspModuleInfo *modinfo; if (sceModuleInfoSection != -1) diff --git a/Core/HW/AsyncIOManager.cpp b/Core/HW/AsyncIOManager.cpp index e4bbde36ca..5e1702668c 100644 --- a/Core/HW/AsyncIOManager.cpp +++ b/Core/HW/AsyncIOManager.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/ChunkFile.h" +#include "Core/MIPS/MIPS.h" #include "Core/Reporting.h" #include "Core/System.h" #include "Core/HW/AsyncIOManager.h" @@ -58,6 +59,10 @@ bool AsyncIOManager::PopResult(u32 handle, AsyncIOResult &result) { result = results_[handle]; results_.erase(handle); resultsPending_.erase(handle); + + if (result.invalidateAddr && result.result > 0) { + currentMIPS->InvalidateICache(result.invalidateAddr, (int)result.result); + } return true; } else { return false; @@ -111,7 +116,7 @@ u64 AsyncIOManager::ResultFinishTicks(u32 handle) { void AsyncIOManager::ProcessEvent(AsyncIOEvent ev) { switch (ev.type) { case IO_EVENT_READ: - Read(ev.handle, ev.buf, ev.bytes); + Read(ev.handle, ev.buf, ev.bytes, ev.invalidateAddr); break; case IO_EVENT_WRITE: @@ -123,10 +128,10 @@ void AsyncIOManager::ProcessEvent(AsyncIOEvent ev) { } } -void AsyncIOManager::Read(u32 handle, u8 *buf, size_t bytes) { +void AsyncIOManager::Read(u32 handle, u8 *buf, size_t bytes, u32 invalidateAddr) { int usec = 0; s64 result = pspFileSystem.ReadFile(handle, buf, bytes, usec); - EventResult(handle, AsyncIOResult(result, usec)); + EventResult(handle, AsyncIOResult(result, usec, invalidateAddr)); } void AsyncIOManager::Write(u32 handle, u8 *buf, size_t bytes) { diff --git a/Core/HW/AsyncIOManager.h b/Core/HW/AsyncIOManager.h index d73f8a44ae..a64a2a38da 100644 --- a/Core/HW/AsyncIOManager.h +++ b/Core/HW/AsyncIOManager.h @@ -37,6 +37,7 @@ struct AsyncIOEvent { u32 handle; u8 *buf; size_t bytes; + u32 invalidateAddr; operator AsyncIOEventType() const { return type; @@ -44,27 +45,33 @@ struct AsyncIOEvent { }; struct AsyncIOResult { - AsyncIOResult() : result(0), finishTicks(0) { + AsyncIOResult() : result(0), finishTicks(0), invalidateAddr(0) { } - explicit AsyncIOResult(s64 r) : result(r), finishTicks(0) { + explicit AsyncIOResult(s64 r) : result(r), finishTicks(0), invalidateAddr(0) { } - AsyncIOResult(s64 r, int usec) : result(r) { + AsyncIOResult(s64 r, int usec, u32 addr = 0) : result(r), invalidateAddr(addr) { finishTicks = CoreTiming::GetTicks() + usToCycles(usec); } void DoState(PointerWrap &p) { - auto s = p.Section("AsyncIOResult", 1); + auto s = p.Section("AsyncIOResult", 1, 2); if (!s) return; p.Do(result); p.Do(finishTicks); + if (s >= 2) { + p.Do(invalidateAddr); + } else { + invalidateAddr = 0; + } } s64 result; u64 finishTicks; + u32 invalidateAddr; }; typedef ThreadEventQueue IOThreadEventQueue; @@ -89,7 +96,7 @@ protected: } private: - void Read(u32 handle, u8 *buf, size_t bytes); + void Read(u32 handle, u8 *buf, size_t bytes, u32 invalidateAddr); void Write(u32 handle, u8 *buf, size_t bytes); void EventResult(u32 handle, AsyncIOResult result);