Merge pull request #707 from wheremyfoodat/icache

Add Luma icache SVCs and don't flush entire code cache when loading/unloading CROs
This commit is contained in:
wheremyfoodat 2025-01-03 19:38:13 +02:00 committed by GitHub
commit 40404ba7ba
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 34 additions and 9 deletions

View file

@ -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();
};

View file

@ -175,6 +175,8 @@ public:
void svcSignalEvent();
void svcSetTimer();
void svcSleepThread();
void svcInvalidateInstructionCacheRange();
void svcInvalidateEntireInstructionCache();
void connectToPort();
void outputDebugString();
void waitSynchronization1();
@ -250,4 +252,5 @@ public:
void sendGPUInterrupt(GPUInterrupt type) { serviceManager.sendGPUInterrupt(type); }
void clearInstructionCache();
void clearInstructionCacheRange(u32 start, u32 size);
};

View file

@ -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;
}
@ -298,6 +302,23 @@ 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];
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;
}
namespace SystemInfoType {
enum : u32 {

View file

@ -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);
}