From 33c3e67b31ab31f92353197b3ebf5381aa94f11b Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Fri, 3 Jan 2025 19:14:31 +0200 Subject: [PATCH 1/3] CRO: Lighter icache flushes --- include/cpu_dynarmic.hpp | 2 ++ include/kernel/kernel.hpp | 1 + src/core/kernel/kernel.cpp | 1 + src/core/services/ldr_ro.cpp | 17 ++++++++--------- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/include/cpu_dynarmic.hpp b/include/cpu_dynarmic.hpp index 43f31d308..243585336 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 abc508ac7..da5298a47 100644 --- a/include/kernel/kernel.hpp +++ b/include/kernel/kernel.hpp @@ -250,4 +250,5 @@ class Kernel { 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 d4229b55c..fe7bd3019 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 a61147299..48621986a 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 @@ class CRO { 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 From 84c358660c0b38c29b5068de7aff4f591cbca081 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Fri, 3 Jan 2025 19:21:45 +0200 Subject: [PATCH 2/3] Implement Luma icache SVCs --- include/kernel/kernel.hpp | 2 ++ src/core/kernel/kernel.cpp | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/include/kernel/kernel.hpp b/include/kernel/kernel.hpp index da5298a47..45085e152 100644 --- a/include/kernel/kernel.hpp +++ b/include/kernel/kernel.hpp @@ -175,6 +175,8 @@ class Kernel { void svcSignalEvent(); void svcSetTimer(); void svcSleepThread(); + void svcInvalidateInstructionCacheRange(); + void svcInvalidateEntireInstructionCache(); void connectToPort(); void outputDebugString(); void waitSynchronization1(); diff --git a/src/core/kernel/kernel.cpp b/src/core/kernel/kernel.cpp index fe7bd3019..8208d4acc 100644 --- a/src/core/kernel/kernel.cpp +++ b/src/core/kernel/kernel.cpp @@ -69,6 +69,10 @@ void Kernel::serviceSVC(u32 svc) { case 0x3A: getResourceLimitCurrentValues(); break; case 0x3B: getThreadContext(); break; case 0x3D: outputDebugString(); break; + + // Luma SVCs + case 0x93: svcInvalidateInstructionCacheRange(); break; + case 0x94: svcInvalidateEntireInstructionCache(); break; default: Helpers::panic("Unimplemented svc: %X @ %08X", svc, regs[15]); break; } @@ -300,6 +304,19 @@ void Kernel::duplicateHandle() { void Kernel::clearInstructionCache() { cpu.clearCache(); } void Kernel::clearInstructionCacheRange(u32 start, u32 size) { cpu.clearCacheRange(start, size); } +void Kernel::svcInvalidateInstructionCacheRange() { + const u32 start = regs[0]; + const u32 size = regs[1]; + + clearInstructionCacheRange(start, size); + regs[0] = Result::Success; +} + +void Kernel::svcInvalidateEntireInstructionCache() { + clearInstructionCache(); + regs[0] = Result::Success; +} + namespace SystemInfoType { enum : u32 { MemoryInformation = 0, From 5042594f3b156344e86acf877529720fde08cf11 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Fri, 3 Jan 2025 19:23:46 +0200 Subject: [PATCH 3/3] Add missing SVC logs --- src/core/kernel/kernel.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/kernel/kernel.cpp b/src/core/kernel/kernel.cpp index 8208d4acc..e097fab6f 100644 --- a/src/core/kernel/kernel.cpp +++ b/src/core/kernel/kernel.cpp @@ -307,12 +307,15 @@ void Kernel::clearInstructionCacheRange(u32 start, u32 size) { cpu.clearCacheRan void Kernel::svcInvalidateInstructionCacheRange() { const u32 start = regs[0]; const u32 size = regs[1]; + logSVC("svcInvalidateInstructionCacheRange(start = %08X, size = %08X)\n", start, size); clearInstructionCacheRange(start, size); regs[0] = Result::Success; } void Kernel::svcInvalidateEntireInstructionCache() { + logSVC("svcInvalidateEntireInstructionCache()\n"); + clearInstructionCache(); regs[0] = Result::Success; }