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 addTicks(u64 ticks) { env.AddTicks(ticks); }
void clearCache() { jit->ClearCache(); } void clearCache() { jit->ClearCache(); }
void clearCacheRange(u32 start, u32 size) { jit->InvalidateCacheRange(start, size); }
void runFrame(); void runFrame();
}; };

View file

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

View file

@ -69,6 +69,10 @@ void Kernel::serviceSVC(u32 svc) {
case 0x3A: getResourceLimitCurrentValues(); break; case 0x3A: getResourceLimitCurrentValues(); break;
case 0x3B: getThreadContext(); break; case 0x3B: getThreadContext(); break;
case 0x3D: outputDebugString(); 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; 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::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 { namespace SystemInfoType {
enum : u32 { enum : u32 {

View file

@ -22,6 +22,7 @@ namespace CROHeader {
NameOffset = 0x084, NameOffset = 0x084,
NextCRO = 0x088, NextCRO = 0x088,
PrevCRO = 0x08C, PrevCRO = 0x08C,
FixedSize = 0x98,
OnUnresolved = 0x0AC, OnUnresolved = 0x0AC,
CodeOffset = 0x0B0, CodeOffset = 0x0B0,
DataOffset = 0x0B8, DataOffset = 0x0B8,
@ -167,6 +168,10 @@ public:
return mem.read32(croPointer + CROHeader::PrevCRO); return mem.read32(croPointer + CROHeader::PrevCRO);
} }
u32 getFixedSize() {
return mem.read32(croPointer + CROHeader::FixedSize);
}
void setNextCRO(u32 nextCRO) { void setNextCRO(u32 nextCRO) {
mem.write32(croPointer + CROHeader::NextCRO, nextCRO); mem.write32(croPointer + CROHeader::NextCRO, nextCRO);
} }
@ -1248,8 +1253,7 @@ void LDRService::initialize(u32 messagePointer) {
Helpers::panic("Failed to rebase CRS"); Helpers::panic("Failed to rebase CRS");
} }
kernel.clearInstructionCache(); kernel.clearInstructionCacheRange(mapVaddr, size);
loadedCRS = mapVaddr; loadedCRS = mapVaddr;
mem.write32(messagePointer, IPC::responseHeader(0x1, 1, 0)); mem.write32(messagePointer, IPC::responseHeader(0x1, 1, 0));
@ -1278,8 +1282,6 @@ void LDRService::linkCRO(u32 messagePointer) {
Helpers::panic("Failed to link CRO"); Helpers::panic("Failed to link CRO");
} }
kernel.clearInstructionCache();
mem.write32(messagePointer, IPC::responseHeader(0x6, 1, 0)); mem.write32(messagePointer, IPC::responseHeader(0x6, 1, 0));
mem.write32(messagePointer + 4, Result::Success); mem.write32(messagePointer + 4, Result::Success);
} }
@ -1346,8 +1348,7 @@ void LDRService::loadCRO(u32 messagePointer, bool isNew) {
// TODO: add fixing // TODO: add fixing
cro.fix(fixLevel); cro.fix(fixLevel);
kernel.clearInstructionCacheRange(mapVaddr, size);
kernel.clearInstructionCache();
if (isNew) { if (isNew) {
mem.write32(messagePointer, IPC::responseHeader(0x9, 2, 0)); mem.write32(messagePointer, IPC::responseHeader(0x9, 2, 0));
@ -1377,7 +1378,6 @@ void LDRService::unloadCRO(u32 messagePointer) {
} }
CRO cro(mem, mapVaddr, true); CRO cro(mem, mapVaddr, true);
cro.unregisterCRO(loadedCRS); cro.unregisterCRO(loadedCRS);
if (!cro.unlink(loadedCRS)) { if (!cro.unlink(loadedCRS)) {
@ -1388,8 +1388,7 @@ void LDRService::unloadCRO(u32 messagePointer) {
Helpers::panic("Failed to unrebase CRO"); Helpers::panic("Failed to unrebase CRO");
} }
kernel.clearInstructionCache(); kernel.clearInstructionCacheRange(mapVaddr, cro.getFixedSize());
mem.write32(messagePointer, IPC::responseHeader(0x5, 1, 0)); mem.write32(messagePointer, IPC::responseHeader(0x5, 1, 0));
mem.write32(messagePointer + 4, Result::Success); mem.write32(messagePointer + 4, Result::Success);
} }