From d971e5f2dda43d157ccf92e020c94dd484b5b86e Mon Sep 17 00:00:00 2001 From: Ty Lamontagne Date: Fri, 27 Dec 2024 13:31:27 -0500 Subject: [PATCH] EE Cache: Fix up TLB related register fetching --- pcsx2/COP0.cpp | 66 ++++++++++++++++++++++++++++++++------------------ pcsx2/R5900.h | 3 +-- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/pcsx2/COP0.cpp b/pcsx2/COP0.cpp index fbd37682da3ff5..8f7764683a8863 100644 --- a/pcsx2/COP0.cpp +++ b/pcsx2/COP0.cpp @@ -358,6 +358,22 @@ void WriteTLB(int i) tlb[i].EntryLo0.UL = cpuRegs.CP0.n.EntryLo0; tlb[i].EntryLo1.UL = cpuRegs.CP0.n.EntryLo1; + // Setting the cache mode to reserved values is vaguely defined in the manual. + // I found that SPR is set to cached regardless. + // Non-SPR entries default to uncached on reserved cache modes. + if (tlb[i].isSPR()) + { + tlb[i].EntryLo0.C = 3; + tlb[i].EntryLo1.C = 3; + } + else + { + if (!tlb[i].EntryLo0.isValidCacheMode()) + tlb[i].EntryLo0.C = 2; + if (!tlb[i].EntryLo1.isValidCacheMode()) + tlb[i].EntryLo1.C = 2; + } + if (!tlb[i].isSPR() && ((tlb[i].EntryLo0.V && tlb[i].EntryLo0.isCached()) || (tlb[i].EntryLo1.V && tlb[i].EntryLo1.isCached()))) { const size_t idx = cachedTlbs.count; @@ -384,55 +400,57 @@ namespace COP0 { cpuRegs.CP0.n.Index, cpuRegs.CP0.n.PageMask, cpuRegs.CP0.n.EntryHi, cpuRegs.CP0.n.EntryLo0, cpuRegs.CP0.n.EntryLo1); - int i = cpuRegs.CP0.n.Index & 0x3f; + const u8 i = cpuRegs.CP0.n.Index & 0x3f; - cpuRegs.CP0.n.PageMask = tlb[i].PageMask.UL; - cpuRegs.CP0.n.EntryHi = tlb[i].EntryHi.UL & ~(tlb[i].PageMask.UL | 0x1f00); - /* - * TEST THIS?? - cpuRegs.CP0.n.EntryLo0 = (tlb[i].EntryLo0 & ~1) | ((tlb[i].EntryHi.UL >> 12) & 1); - cpuRegs.CP0.n.EntryLo1 = (tlb[i].EntryLo1 & ~1) | ((tlb[i].EntryHi.UL >> 12) & 1); - */ - cpuRegs.CP0.n.EntryLo0 = tlb[i].EntryLo0.UL; - cpuRegs.CP0.n.EntryLo1 = tlb[i].EntryLo1.UL; + if (i > 47) + { + Console.Warning("TLBR with index > 47!"); + return; + } + cpuRegs.CP0.n.PageMask = tlb[i].PageMask.Mask << 13; + cpuRegs.CP0.n.EntryHi = tlb[i].EntryHi.UL & ~((tlb[i].PageMask.Mask << 13) | 0x1f00); + cpuRegs.CP0.n.EntryLo0 = tlb[i].EntryLo0.UL & ~(0xFC000000) & ~1; + cpuRegs.CP0.n.EntryLo1 = tlb[i].EntryLo1.UL & ~(0x7C000000) & ~1; + // "If both the Global bit of EntryLo0 and EntryLo1 are set to 1, the processor ignores the ASID during TLB lookup." + // This is reflected during TLBR, where G is only set if both EntryLo0 and EntryLo1 are global. + cpuRegs.CP0.n.EntryLo0 |= (tlb[i].EntryLo0.UL & 1) & (tlb[i].EntryLo1.UL & 1); + cpuRegs.CP0.n.EntryLo1 |= (tlb[i].EntryLo0.UL & 1) & (tlb[i].EntryLo1.UL & 1); } void TLBWI() { - int j = cpuRegs.CP0.n.Index & 0x3f; + const u8 j = cpuRegs.CP0.n.Index & 0x3f; - //if (j > 48) return; + if (j > 47) + { + Console.Warning("TLBWI with index > 47!"); + return; + } COP0_LOG("COP0_TLBWI %d:%x,%x,%x,%x", cpuRegs.CP0.n.Index, cpuRegs.CP0.n.PageMask, cpuRegs.CP0.n.EntryHi, cpuRegs.CP0.n.EntryLo0, cpuRegs.CP0.n.EntryLo1); UnmapTLB(tlb[j], j); - tlb[j].PageMask.UL = cpuRegs.CP0.n.PageMask; - tlb[j].EntryHi.UL = cpuRegs.CP0.n.EntryHi; - tlb[j].EntryLo0.UL = cpuRegs.CP0.n.EntryLo0; - tlb[j].EntryLo1.UL = cpuRegs.CP0.n.EntryLo1; WriteTLB(j); } void TLBWR() { - int j = cpuRegs.CP0.n.Random & 0x3f; + const u8 j = cpuRegs.CP0.n.Random & 0x3f; - //if (j > 48) return; + if (j > 47) + { + Console.Warning("TLBWR with random > 47!"); + return; + } DevCon.Warning("COP0_TLBWR %d:%x,%x,%x,%x\n", cpuRegs.CP0.n.Random, cpuRegs.CP0.n.PageMask, cpuRegs.CP0.n.EntryHi, cpuRegs.CP0.n.EntryLo0, cpuRegs.CP0.n.EntryLo1); - //if (j > 48) return; - UnmapTLB(tlb[j], j); - tlb[j].PageMask.UL = cpuRegs.CP0.n.PageMask; - tlb[j].EntryHi.UL = cpuRegs.CP0.n.EntryHi; - tlb[j].EntryLo0.UL = cpuRegs.CP0.n.EntryLo0; - tlb[j].EntryLo1.UL = cpuRegs.CP0.n.EntryLo1; WriteTLB(j); } diff --git a/pcsx2/R5900.h b/pcsx2/R5900.h index ad0310dda6b4ef..4fdc1c808767ec 100644 --- a/pcsx2/R5900.h +++ b/pcsx2/R5900.h @@ -171,8 +171,6 @@ union PageMask_t u32 : 7; }; u32 UL; - - constexpr u32 nMask() const { return ~Mask & 0xfff; }; }; union EntryHi_t @@ -201,6 +199,7 @@ union EntryLo_t u32 UL; constexpr bool isCached() const { return C == 0x3; } + constexpr bool isValidCacheMode() const { return C == 0x2 || C == 0x3 || C == 0x7; } }; struct tlbs