diff --git a/include/cpu_dynarmic.hpp b/include/cpu_dynarmic.hpp index 43f31d30..24358533 100644 --- a/include/cpu_dynarmic.hpp +++ b/include/cpu_dynarmic.hpp @@ -181,5 +181,7 @@ class CPU { void addTicks(u64 ticks) { env.AddTicks(ticks); } void clearCache() { jit->ClearCache(); } + void clearCacheRange(u32 start, u32 size) { jit->InvalidateCacheRange(start, size); } + void runFrame(); }; \ No newline at end of file diff --git a/include/kernel/kernel.hpp b/include/kernel/kernel.hpp index abc508ac..da5298a4 100644 --- a/include/kernel/kernel.hpp +++ b/include/kernel/kernel.hpp @@ -250,4 +250,5 @@ public: void sendGPUInterrupt(GPUInterrupt type) { serviceManager.sendGPUInterrupt(type); } void clearInstructionCache(); + void clearInstructionCacheRange(u32 start, u32 size); }; \ No newline at end of file diff --git a/src/core/kernel/kernel.cpp b/src/core/kernel/kernel.cpp index d4229b55..fe7bd301 100644 --- a/src/core/kernel/kernel.cpp +++ b/src/core/kernel/kernel.cpp @@ -298,6 +298,7 @@ void Kernel::duplicateHandle() { } void Kernel::clearInstructionCache() { cpu.clearCache(); } +void Kernel::clearInstructionCacheRange(u32 start, u32 size) { cpu.clearCacheRange(start, size); } namespace SystemInfoType { enum : u32 { diff --git a/src/core/services/ldr_ro.cpp b/src/core/services/ldr_ro.cpp index a6114729..48621986 100644 --- a/src/core/services/ldr_ro.cpp +++ b/src/core/services/ldr_ro.cpp @@ -22,6 +22,7 @@ namespace CROHeader { NameOffset = 0x084, NextCRO = 0x088, PrevCRO = 0x08C, + FixedSize = 0x98, OnUnresolved = 0x0AC, CodeOffset = 0x0B0, DataOffset = 0x0B8, @@ -167,6 +168,10 @@ public: return mem.read32(croPointer + CROHeader::PrevCRO); } + u32 getFixedSize() { + return mem.read32(croPointer + CROHeader::FixedSize); + } + void setNextCRO(u32 nextCRO) { mem.write32(croPointer + CROHeader::NextCRO, nextCRO); } @@ -1248,8 +1253,7 @@ void LDRService::initialize(u32 messagePointer) { Helpers::panic("Failed to rebase CRS"); } - kernel.clearInstructionCache(); - + kernel.clearInstructionCacheRange(mapVaddr, size); loadedCRS = mapVaddr; mem.write32(messagePointer, IPC::responseHeader(0x1, 1, 0)); @@ -1278,8 +1282,6 @@ void LDRService::linkCRO(u32 messagePointer) { Helpers::panic("Failed to link CRO"); } - kernel.clearInstructionCache(); - mem.write32(messagePointer, IPC::responseHeader(0x6, 1, 0)); mem.write32(messagePointer + 4, Result::Success); } @@ -1346,8 +1348,7 @@ void LDRService::loadCRO(u32 messagePointer, bool isNew) { // TODO: add fixing cro.fix(fixLevel); - - kernel.clearInstructionCache(); + kernel.clearInstructionCacheRange(mapVaddr, size); if (isNew) { mem.write32(messagePointer, IPC::responseHeader(0x9, 2, 0)); @@ -1377,7 +1378,6 @@ void LDRService::unloadCRO(u32 messagePointer) { } CRO cro(mem, mapVaddr, true); - cro.unregisterCRO(loadedCRS); if (!cro.unlink(loadedCRS)) { @@ -1388,8 +1388,7 @@ void LDRService::unloadCRO(u32 messagePointer) { Helpers::panic("Failed to unrebase CRO"); } - kernel.clearInstructionCache(); - + kernel.clearInstructionCacheRange(mapVaddr, cro.getFixedSize()); mem.write32(messagePointer, IPC::responseHeader(0x5, 1, 0)); mem.write32(messagePointer + 4, Result::Success); } \ No newline at end of file