From f73c3708a5b3113f52636fc1921b3a84acca678c Mon Sep 17 00:00:00 2001 From: zilmar Date: Thu, 5 Oct 2023 14:45:17 +1030 Subject: [PATCH] Core: Fix up tlb Probe and call EXC_MOD when tlb is not dirty --- .../N64System/Mips/Register.cpp | 7 ++- Source/Project64-core/N64System/Mips/TLB.cpp | 52 ++++++++++--------- Source/Project64-core/N64System/Mips/TLB.h | 2 +- Source/Project64-core/N64System/N64System.cpp | 4 +- 4 files changed, 37 insertions(+), 28 deletions(-) diff --git a/Source/Project64-core/N64System/Mips/Register.cpp b/Source/Project64-core/N64System/Mips/Register.cpp index eadf949e0..f7bba36dc 100644 --- a/Source/Project64-core/N64System/Mips/Register.cpp +++ b/Source/Project64-core/N64System/Mips/Register.cpp @@ -788,7 +788,12 @@ void CRegisters::TriggerAddressException(uint64_t Address, uint32_t ExceptionCod bool SpecialOffset = false; if (ExceptionCode == EXC_RMISS || ExceptionCode == EXC_WMISS) { - SpecialOffset = !m_TLB.AddressDefined(Address); + bool Dirty; + SpecialOffset = !m_TLB.AddressDefined(Address, Dirty); + if (!Dirty) + { + ExceptionCode = EXC_MOD; + } } BAD_VADDR_REGISTER = Address; diff --git a/Source/Project64-core/N64System/Mips/TLB.cpp b/Source/Project64-core/N64System/Mips/TLB.cpp index e7843eb25..11ccd11e5 100644 --- a/Source/Project64-core/N64System/Mips/TLB.cpp +++ b/Source/Project64-core/N64System/Mips/TLB.cpp @@ -53,21 +53,26 @@ void CTLB::Reset(bool InvalidateTLB) COP0StatusChanged(); } -bool CTLB::AddressDefined(uint64_t VAddr) +bool CTLB::AddressDefined(uint64_t VAddr, bool & Dirty) { - if (VAddr >= 0x80000000 && VAddr <= 0xBFFFFFFF) + Dirty = true; + MemorySegment Segment = VAddrMemorySegment(VAddr); + if (Segment == MemorySegment_Mapped) { - return true; - } - - for (uint32_t i = 0; i < 64; i++) - { - if (m_FastTlb[i].ValidEntry && - VAddr >= m_FastTlb[i].VSTART && - VAddr <= m_FastTlb[i].VEND) + for (uint32_t i = 0; i < 64; i++) { + if (!m_FastTlb[i].GLOBAL || !m_FastTlb[i].ValidEntry || VAddr < m_FastTlb[i].VSTART || VAddr > m_FastTlb[i].VEND + 1) + { + continue; + } + if (!m_FastTlb[i].VALID) + { + return true; + } + Dirty = m_FastTlb[i].DIRTY; return true; } + return false; } return false; } @@ -88,23 +93,22 @@ void CTLB::Probe() continue; } - uint64_t & TlbEntryHiValue = m_tlb[i].EntryHi.Value; - uint32_t Mask = (uint32_t)(~m_tlb[i].PageMask.Mask << 13); - uint32_t TlbValueMasked = TlbEntryHiValue & Mask; - uint32_t EntryHiMasked = m_Reg.ENTRYHI_REGISTER.Value & Mask; + const COP0EntryHi & TlbEntryHiValue = m_tlb[i].EntryHi; + uint64_t Mask = ~m_tlb[i].PageMask.Mask << 13; + uint64_t TlbValueMasked = TlbEntryHiValue.Value & Mask; + uint64_t EntryHiMasked = m_Reg.ENTRYHI_REGISTER.Value & Mask; - if (TlbValueMasked == EntryHiMasked) + if (TlbValueMasked != EntryHiMasked || + TlbEntryHiValue.R != m_Reg.ENTRYHI_REGISTER.R || + (m_tlb[i].EntryLo0.GLOBAL == 0 || m_tlb[i].EntryLo1.GLOBAL == 0) && TlbEntryHiValue.ASID != m_Reg.ENTRYHI_REGISTER.ASID) { - if ((TlbEntryHiValue & 0x100) != 0 || // Global - ((TlbEntryHiValue & 0xFF) == (m_Reg.ENTRYHI_REGISTER.Value & 0xFF))) // SameAsid - { - m_Reg.INDEX_REGISTER = i; - uint32_t FastIndx = i << 1; - m_FastTlb[FastIndx].Probed = true; - m_FastTlb[FastIndx + 1].Probed = true; - return; - } + continue; } + m_Reg.INDEX_REGISTER = i; + uint32_t FastIndx = i << 1; + m_FastTlb[FastIndx].Probed = true; + m_FastTlb[FastIndx + 1].Probed = true; + break; } WriteTrace(TraceTLB, TraceDebug, "Done"); } diff --git a/Source/Project64-core/N64System/Mips/TLB.h b/Source/Project64-core/N64System/Mips/TLB.h index 0af20b635..b2c6f1006 100644 --- a/Source/Project64-core/N64System/Mips/TLB.h +++ b/Source/Project64-core/N64System/Mips/TLB.h @@ -58,7 +58,7 @@ public: void ReadEntry(); void WriteEntry(uint32_t Index, bool Random); void COP0StatusChanged(void); - bool AddressDefined(uint64_t VAddr); + bool AddressDefined(uint64_t VAddr, bool & Dirty); TLB_ENTRY & TlbEntry(int32_t Entry); bool VAddrToPAddr(uint64_t VAddr, uint32_t & PAddr, bool & MemoryUnused); diff --git a/Source/Project64-core/N64System/N64System.cpp b/Source/Project64-core/N64System/N64System.cpp index 85c927d9d..ccb64cd3c 100644 --- a/Source/Project64-core/N64System/N64System.cpp +++ b/Source/Project64-core/N64System/N64System.cpp @@ -2028,13 +2028,13 @@ bool CN64System::LoadState(const char * FileName) LoadedZipFile = true; continue; } - if (LoadedZipFile && Value == SaveID_1 && port == UNZ_OK) + if (LoadedZipFile && SaveID == SaveID_1 && port == UNZ_OK) { // Extra info v1 // System timers info m_SystemTimer.LoadData(file); } - if (LoadedZipFile && Value == SaveID_2 && port == UNZ_OK) + if (LoadedZipFile && SaveID == SaveID_2 && port == UNZ_OK) { // Extra info v2 (Project64 2.4) // Disk interface info