From 8f4f4348209b60da317b6df7841a46ddfefcc36a Mon Sep 17 00:00:00 2001 From: zilmar Date: Thu, 16 Nov 2023 17:11:05 +1030 Subject: [PATCH] Core: Get Fast tlb to just be 32bit --- .../N64System/Interpreter/InterpreterOps.cpp | 4 +- .../N64System/Mips/MemoryVirtualMem.cpp | 29 ++++------- .../N64System/Mips/MemoryVirtualMem.h | 4 +- Source/Project64-core/N64System/Mips/TLB.cpp | 48 ++++++++++++++----- Source/Project64-core/N64System/Mips/TLB.h | 7 +-- .../UserInterface/Debugger/Debugger-TLB.cpp | 2 +- 6 files changed, 54 insertions(+), 40 deletions(-) diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp index acd87a574..ee225254d 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp @@ -94,7 +94,7 @@ void R4300iOp::ExecuteCPU() { if (!m_MMU.MemoryValue32(m_PROGRAM_COUNTER, m_Opcode.Value)) { - m_Reg.TriggerAddressException(m_PROGRAM_COUNTER, EXC_RMISS); + m_Reg.TriggerAddressException((int32_t)m_PROGRAM_COUNTER, EXC_RMISS); m_PROGRAM_COUNTER = JumpToLocation; PipelineStage = PIPELINE_STAGE_NORMAL; continue; @@ -305,7 +305,7 @@ void R4300iOp::ExecuteOps(int32_t Cycles) } else { - m_Reg.TriggerAddressException(m_PROGRAM_COUNTER, EXC_RMISS); + m_Reg.TriggerAddressException((int32_t)m_PROGRAM_COUNTER, EXC_RMISS); m_PROGRAM_COUNTER = JumpToLocation; PipelineStage = PIPELINE_STAGE_NORMAL; } diff --git a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp index 7070b5841..98c6618e8 100755 --- a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp +++ b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp @@ -647,7 +647,7 @@ bool CMipsMemoryVM::LB_VAddr32(uint32_t VAddr, uint8_t & Value) uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12]; if (BaseAddress == -1) { - m_Reg.TriggerAddressException(VAddr, EXC_RMISS); + m_Reg.TriggerAddressException((int32_t)VAddr, EXC_RMISS); return false; } return LB_PhysicalAddress(BaseAddress + VAddr, Value); @@ -658,7 +658,7 @@ bool CMipsMemoryVM::LH_VAddr32(uint32_t VAddr, uint16_t & Value) uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12]; if (BaseAddress == -1) { - m_Reg.TriggerAddressException(VAddr, EXC_RMISS); + m_Reg.TriggerAddressException((int32_t)VAddr, EXC_RMISS); return false; } return LH_PhysicalAddress(BaseAddress + VAddr, Value); @@ -669,7 +669,7 @@ bool CMipsMemoryVM::LW_VAddr32(uint32_t VAddr, uint32_t & Value) uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12]; if (BaseAddress == -1) { - m_Reg.TriggerAddressException(VAddr, EXC_RMISS); + m_Reg.TriggerAddressException((int32_t)VAddr, EXC_RMISS); return false; } return LW_PhysicalAddress(BaseAddress + VAddr, Value); @@ -680,7 +680,7 @@ bool CMipsMemoryVM::LD_VAddr32(uint32_t VAddr, uint64_t & Value) uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12]; if (BaseAddress == -1) { - m_Reg.TriggerAddressException(VAddr, EXC_RMISS); + m_Reg.TriggerAddressException((int32_t)VAddr, EXC_RMISS); return false; } return LD_PhysicalAddress(BaseAddress + VAddr, Value); @@ -821,7 +821,7 @@ bool CMipsMemoryVM::SB_VAddr32(uint32_t VAddr, uint32_t Value) uint32_t BaseAddress = m_TLB_WriteMap[VAddr >> 12]; if (BaseAddress == -1) { - m_Reg.TriggerAddressException(VAddr, EXC_WMISS); + m_Reg.TriggerAddressException((int32_t)VAddr, EXC_WMISS); return false; } return SB_PhysicalAddress(BaseAddress + VAddr, Value); @@ -832,7 +832,7 @@ bool CMipsMemoryVM::SH_VAddr32(uint32_t VAddr, uint32_t Value) uint32_t BaseAddress = m_TLB_WriteMap[VAddr >> 12]; if (BaseAddress == -1) { - m_Reg.TriggerAddressException(VAddr, EXC_WMISS); + m_Reg.TriggerAddressException((int32_t)VAddr, EXC_WMISS); return false; } return SH_PhysicalAddress(BaseAddress + VAddr, Value); @@ -843,7 +843,7 @@ bool CMipsMemoryVM::SW_VAddr32(uint32_t VAddr, uint32_t Value) uint32_t BaseAddress = m_TLB_WriteMap[VAddr >> 12]; if (BaseAddress == -1) { - m_Reg.TriggerAddressException(VAddr, EXC_WMISS); + m_Reg.TriggerAddressException((int32_t)VAddr, EXC_WMISS); return false; } return SW_PhysicalAddress(BaseAddress + VAddr, Value); @@ -854,7 +854,7 @@ bool CMipsMemoryVM::SD_VAddr32(uint32_t VAddr, uint64_t Value) uint32_t BaseAddress = m_TLB_WriteMap[VAddr >> 12]; if (BaseAddress == -1) { - m_Reg.TriggerAddressException(VAddr, EXC_WMISS); + m_Reg.TriggerAddressException((int32_t)VAddr, EXC_WMISS); return false; } return SD_PhysicalAddress(BaseAddress + VAddr, Value); @@ -1109,16 +1109,11 @@ const char * CMipsMemoryVM::LabelName(uint32_t Address) const return m_strLabelName; } -void CMipsMemoryVM::TLB_Mapped(uint64_t VAddr, uint32_t Len, uint32_t PAddr, bool bReadOnly) +void CMipsMemoryVM::TLB_Mapped(uint32_t VAddr, uint32_t Len, uint32_t PAddr, bool bReadOnly) { uint64_t VEnd = VAddr + Len; for (uint64_t Address = VAddr; Address < VEnd; Address += 0x1000) { - if ((uint64_t)((int32_t)Address) != Address) - { - break; - } - size_t Index = (size_t)(Address >> 12); if ((Address - VAddr + PAddr) < m_AllocatedRdramSize) { @@ -1136,15 +1131,11 @@ void CMipsMemoryVM::TLB_Mapped(uint64_t VAddr, uint32_t Len, uint32_t PAddr, boo } } -void CMipsMemoryVM::TLB_Unmaped(uint64_t Vaddr, uint32_t Len) +void CMipsMemoryVM::TLB_Unmaped(uint32_t Vaddr, uint32_t Len) { uint64_t End = Vaddr + Len; for (uint64_t Address = Vaddr; Address < End && Address >= Vaddr; Address += 0x1000) { - if ((uint64_t)((int32_t)Address) != Address) - { - continue; - } size_t Index = (size_t)(Address >> 12); m_MemoryReadMap[Index] = (size_t)-1; m_MemoryWriteMap[Index] = (size_t)-1; diff --git a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.h b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.h index 49f0368bd..a47f9cf4d 100644 --- a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.h +++ b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.h @@ -122,8 +122,8 @@ public: void UnProtectMemory(uint32_t StartVaddr, uint32_t EndVaddr); // Functions for TLB notification - void TLB_Mapped(uint64_t VAddr, uint32_t Len, uint32_t PAddr, bool bReadOnly); - void TLB_Unmaped(uint64_t Vaddr, uint32_t Len); + void TLB_Mapped(uint32_t VAddr, uint32_t Len, uint32_t PAddr, bool bReadOnly); + void TLB_Unmaped(uint32_t Vaddr, uint32_t Len); bool ValidVaddr(uint32_t VAddr) const; bool VAddrToPAddr(uint32_t VAddr, uint32_t & PAddr) const; diff --git a/Source/Project64-core/N64System/Mips/TLB.cpp b/Source/Project64-core/N64System/Mips/TLB.cpp index cdb7fbfc2..b61e56f04 100644 --- a/Source/Project64-core/N64System/Mips/TLB.cpp +++ b/Source/Project64-core/N64System/Mips/TLB.cpp @@ -226,12 +226,13 @@ void CTLB::SetupTLB_Entry(uint32_t Index, bool Random) TLB_Unmaped(m_FastTlb[FastIndx].VSTART, m_FastTlb[FastIndx].Length); } m_FastTlb[FastIndx].Length = (uint32_t)((m_tlb[Index].PageMask.Mask << 12) + 0xFFF); - m_FastTlb[FastIndx].VSTART = ((uint64_t)m_tlb[Index].EntryHi.R() << 62) | ((uint64_t)m_tlb[Index].EntryHi.VPN2() << 13); + m_FastTlb[FastIndx].Region = (uint8_t)m_tlb[Index].EntryHi.R(); + m_FastTlb[FastIndx].VSTART = (uint32_t)(m_tlb[Index].EntryHi.VPN2() << 13); m_FastTlb[FastIndx].VEND = m_FastTlb[FastIndx].VSTART + m_FastTlb[FastIndx].Length; m_FastTlb[FastIndx].PHYSSTART = (uint32_t)(m_tlb[Index].EntryLo0.PFN << 12); m_FastTlb[FastIndx].PHYSEND = m_FastTlb[FastIndx].PHYSSTART + m_FastTlb[FastIndx].Length; - m_FastTlb[FastIndx].VALID = m_tlb[Index].EntryLo0.V; - m_FastTlb[FastIndx].DIRTY = m_tlb[Index].EntryLo0.D; + m_FastTlb[FastIndx].VALID = m_tlb[Index].EntryLo0.V != 0; + m_FastTlb[FastIndx].DIRTY = m_tlb[Index].EntryLo0.D != 0; m_FastTlb[FastIndx].GLOBAL = m_tlb[Index].EntryLo0.GLOBAL & m_tlb[Index].EntryLo1.GLOBAL; m_FastTlb[FastIndx].ValidEntry = false; m_FastTlb[FastIndx].Random = Random; @@ -243,12 +244,13 @@ void CTLB::SetupTLB_Entry(uint32_t Index, bool Random) TLB_Unmaped(m_FastTlb[FastIndx].VSTART, m_FastTlb[FastIndx].Length); } m_FastTlb[FastIndx].Length = (uint32_t)((m_tlb[Index].PageMask.Mask << 12) + 0xFFF); - m_FastTlb[FastIndx].VSTART = ((uint64_t)m_tlb[Index].EntryHi.R() << 62 | ((uint64_t)m_tlb[Index].EntryHi.VPN2() << 13)) + (m_FastTlb[FastIndx].Length + 1); + m_FastTlb[FastIndx].Region = (uint8_t)m_tlb[Index].EntryHi.R(); + m_FastTlb[FastIndx].VSTART = (uint32_t)(m_tlb[Index].EntryHi.VPN2() << 13) + (m_FastTlb[FastIndx].Length + 1); m_FastTlb[FastIndx].VEND = m_FastTlb[FastIndx].VSTART + m_FastTlb[FastIndx].Length; m_FastTlb[FastIndx].PHYSSTART = (uint32_t)m_tlb[Index].EntryLo1.PFN << 12; m_FastTlb[FastIndx].PHYSEND = m_FastTlb[FastIndx].PHYSSTART + m_FastTlb[FastIndx].Length; - m_FastTlb[FastIndx].VALID = m_tlb[Index].EntryLo1.V; - m_FastTlb[FastIndx].DIRTY = m_tlb[Index].EntryLo1.D; + m_FastTlb[FastIndx].VALID = m_tlb[Index].EntryLo1.V != 0; + m_FastTlb[FastIndx].DIRTY = m_tlb[Index].EntryLo1.D != 0; m_FastTlb[FastIndx].GLOBAL = m_tlb[Index].EntryLo0.GLOBAL & m_tlb[Index].EntryLo1.GLOBAL; m_FastTlb[FastIndx].ValidEntry = false; m_FastTlb[FastIndx].Random = Random; @@ -263,6 +265,16 @@ void CTLB::SetupTLB_Entry(uint32_t Index, bool Random) continue; } + if ((m_FastTlb[FastIndx].VSTART & 0x80000000) == 0 && m_FastTlb[FastIndx].Region != 0) + { + continue; + } + + if ((m_FastTlb[FastIndx].VSTART & 0x80000000) != 0 && m_FastTlb[FastIndx].Region != 3) + { + continue; + } + if (m_FastTlb[FastIndx].VEND <= m_FastTlb[FastIndx].VSTART) { continue; @@ -282,10 +294,10 @@ void CTLB::SetupTLB_Entry(uint32_t Index, bool Random) } } -void CTLB::TLB_Unmaped(uint64_t VAddr, uint32_t Len) +void CTLB::TLB_Unmaped(uint32_t VAddr, uint32_t Len) { m_MMU.TLB_Unmaped(VAddr, Len); - if (m_Recomp && bSMM_TLB() && (uint64_t)((int32_t)VAddr) == VAddr) + if (m_Recomp && bSMM_TLB()) { m_Recomp->ClearRecompCode_Virt((uint32_t)VAddr, Len, CRecompiler::Remove_TLB); } @@ -302,17 +314,27 @@ bool CTLB::VAddrToPAddr(uint64_t VAddr, uint32_t & PAddr, bool & MemoryUnused) MemorySegment Segment = VAddrMemorySegment(VAddr); if (Segment == MemorySegment_Mapped) { - for (int i = 0; i < 64; i++) + for (uint32_t i = 0; i < 32; i++) { - if (m_FastTlb[i].ValidEntry == false) + if (m_tlb[i].EntryLo0.GLOBAL == 0) { continue; } - if (VAddr >= m_FastTlb[i].VSTART && VAddr < m_FastTlb[i].VEND) + if ((VAddr & 0xE000000000000000) != ((uint64_t)m_tlb[i].EntryHi.R() << 62)) { - PAddr = (uint32_t)(m_FastTlb[i].PHYSSTART + (VAddr - m_FastTlb[i].VSTART)); - return true; + continue; } + uint64_t PageMask = (m_tlb[i].PageMask.Mask << 12); + uint64_t AddressMaskHi = ~(PageMask | 0x1fff) & 0xFFFFFFFFFF; + uint64_t AddressRegion = ((uint64_t)m_tlb[i].EntryHi.VPN2() << 13); + if ((VAddr & AddressMaskHi) != AddressRegion) + { + continue; + } + uint64_t AddressSelect = ((m_tlb[i].PageMask.Mask << 12) | 0xfff) + 1; + COP0EntryLo EntryLo = (VAddr & AddressSelect) != 0 ? m_tlb[i].EntryLo1 : m_tlb[i].EntryLo0; + PAddr = (uint32_t)((EntryLo.PFN << 12) + (VAddr & (PageMask | 0x1fff))); + return true; } return false; } diff --git a/Source/Project64-core/N64System/Mips/TLB.h b/Source/Project64-core/N64System/Mips/TLB.h index 912c6b4c4..74fcf2c51 100644 --- a/Source/Project64-core/N64System/Mips/TLB.h +++ b/Source/Project64-core/N64System/Mips/TLB.h @@ -35,11 +35,12 @@ class CTLB : struct FASTTLB { - uint64_t VSTART; - uint64_t VEND; + uint32_t VSTART; + uint32_t VEND; uint32_t PHYSSTART; uint32_t PHYSEND; uint32_t Length; + uint8_t Region; bool VALID; bool DIRTY; bool GLOBAL; @@ -73,7 +74,7 @@ private: CTLB & operator=(const CTLB &); void SetupTLB_Entry(uint32_t Index, bool Random); - void TLB_Unmaped(uint64_t VAddr, uint32_t Len); + void TLB_Unmaped(uint32_t VAddr, uint32_t Len); MemorySegment VAddrMemorySegment(uint64_t VAddr); PRIVILEGE_MODE m_PrivilegeMode; diff --git a/Source/Project64/UserInterface/Debugger/Debugger-TLB.cpp b/Source/Project64/UserInterface/Debugger/Debugger-TLB.cpp index 1fc66be7d..014757a3e 100644 --- a/Source/Project64/UserInterface/Debugger/Debugger-TLB.cpp +++ b/Source/Project64/UserInterface/Debugger/Debugger-TLB.cpp @@ -265,7 +265,7 @@ void CDebugTlb::RefreshTLBWindow(void) if (FastTlb[count].ValidEntry && FastTlb[count].VALID) { - swprintf(Output, sizeof(Output), L"%llX:%llX -> %08X:%08X", FastTlb[count].VSTART, FastTlb[count].VEND, + swprintf(Output, sizeof(Output), L"%08X:%08X -> %08X:%08X", FastTlb[count].VSTART, FastTlb[count].VEND, FastTlb[count].PHYSSTART, FastTlb[count].PHYSEND); } else