From f559aed2ad28b97489dab85ab90a52a804d78d2c Mon Sep 17 00:00:00 2001 From: zilmar Date: Thu, 14 Sep 2023 16:23:26 +0930 Subject: [PATCH] Core: Get CRegisters::DoAddressError, CRegisters::DoTLBReadMiss, CRegisters::DoTLBWriteMiss to use TriggerException function --- .../N64System/Mips/Register.cpp | 111 +++--------------- .../Project64-core/N64System/Mips/Register.h | 17 ++- Source/Project64-core/N64System/Mips/TLB.cpp | 12 +- .../Debugger/Debugger-RegisterTabs.cpp | 4 +- 4 files changed, 42 insertions(+), 102 deletions(-) diff --git a/Source/Project64-core/N64System/Mips/Register.cpp b/Source/Project64-core/N64System/Mips/Register.cpp index c07d5b2a53..1a5a512335 100644 --- a/Source/Project64-core/N64System/Mips/Register.cpp +++ b/Source/Project64-core/N64System/Mips/Register.cpp @@ -239,7 +239,7 @@ CP0registers::CP0registers(uint64_t * _CP0) : WIRED_REGISTER(_CP0[6]), BAD_VADDR_REGISTER(_CP0[8]), COUNT_REGISTER(_CP0[9]), - ENTRYHI_REGISTER(_CP0[10]), + ENTRYHI_REGISTER((COP0EntryHi &)_CP0[10]), COMPARE_REGISTER(_CP0[11]), STATUS_REGISTER((COP0Status &)_CP0[12]), CAUSE_REGISTER((COP0Cause &)_CP0[13]), @@ -747,33 +747,8 @@ void CRegisters::DoAddressError(uint64_t BadVaddr, bool FromRead) g_Notify->BreakPoint(__FILE__, __LINE__); } - if (FromRead) - { - CAUSE_REGISTER.ExceptionCode = EXC_RADE; - } - else - { - CAUSE_REGISTER.ExceptionCode = EXC_WADE; - } - CAUSE_REGISTER.CoprocessorUnitNumber = 0; - BAD_VADDR_REGISTER = BadVaddr; - CONTEXT_REGISTER.BadVPN2 = BadVaddr >> 13; - XCONTEXT_REGISTER.BadVPN2 = BadVaddr >> 13; - XCONTEXT_REGISTER.R = BadVaddr >> 61; - - if (m_System.m_PipelineStage == PIPELINE_STAGE_JUMP) - { - CAUSE_REGISTER.BranchDelay = 1; - EPC_REGISTER = (int32_t)(m_PROGRAM_COUNTER - 4); - } - else - { - CAUSE_REGISTER.BranchDelay = 0; - EPC_REGISTER = (int32_t)m_PROGRAM_COUNTER; - } - STATUS_REGISTER.ExceptionLevel = 1; - m_System.m_JumpToLocation = 0x80000180; - m_System.m_PipelineStage = PIPELINE_STAGE_JUMP; + AddressException(BadVaddr); + TriggerException(FromRead ? EXC_RADE : EXC_WADE); } void CRegisters::FixFpuLocations() @@ -808,74 +783,24 @@ bool CRegisters::DoIntrException() void CRegisters::DoTLBReadMiss(uint64_t BadVaddr) { - CAUSE_REGISTER.ExceptionCode = EXC_RMISS; - CAUSE_REGISTER.CoprocessorUnitNumber = 0; - BAD_VADDR_REGISTER = BadVaddr; - CONTEXT_REGISTER.BadVPN2 = BadVaddr >> 13; - ENTRYHI_REGISTER = (BadVaddr & 0xFFFFE000); - if ((STATUS_REGISTER.ExceptionLevel) == 0) - { - if (m_System.m_PipelineStage == PIPELINE_STAGE_JUMP) - { - CAUSE_REGISTER.BranchDelay = 1; - EPC_REGISTER = (int64_t)((int32_t)m_PROGRAM_COUNTER - 4); - } - else - { - CAUSE_REGISTER.BranchDelay = 0; - EPC_REGISTER = (int64_t)((int32_t)m_PROGRAM_COUNTER); - } - if (g_TLB->AddressDefined((uint32_t)BadVaddr)) - { - m_System.m_JumpToLocation = 0x80000180; - } - else - { - m_System.m_JumpToLocation = 0x80000000; - } - STATUS_REGISTER.ExceptionLevel = 1; - } - else - { - m_System.m_JumpToLocation = 0x80000180; - } - m_System.m_PipelineStage = PIPELINE_STAGE_JUMP; + AddressException(BadVaddr); + TriggerException(EXC_RMISS, 0, true); } void CRegisters::DoTLBWriteMiss(uint64_t BadVaddr) { - CAUSE_REGISTER.ExceptionCode = EXC_WMISS; - CAUSE_REGISTER.CoprocessorUnitNumber = 0; - BAD_VADDR_REGISTER = BadVaddr; - CONTEXT_REGISTER.BadVPN2 = BadVaddr >> 13; - ENTRYHI_REGISTER = (BadVaddr & 0xFFFFE000); - if ((STATUS_REGISTER.ExceptionLevel) == 0) - { - if (g_System->m_PipelineStage == PIPELINE_STAGE_JUMP) - { - CAUSE_REGISTER.BranchDelay = 1; - EPC_REGISTER = (int64_t)((int32_t)m_PROGRAM_COUNTER - 4); - } - else - { - CAUSE_REGISTER.BranchDelay = 0; - EPC_REGISTER = (int64_t)((int32_t)m_PROGRAM_COUNTER); - } - if (g_TLB->AddressDefined((uint32_t)BadVaddr)) - { - m_System.m_JumpToLocation = 0x80000180; - } - else - { - m_System.m_JumpToLocation = 0x80000000; - } - STATUS_REGISTER.ExceptionLevel = 1; - } - else - { - m_System.m_JumpToLocation = 0x80000180; - } - m_System.m_PipelineStage = PIPELINE_STAGE_JUMP; + AddressException(BadVaddr); + TriggerException(EXC_WMISS, 0, true); +} + +void CRegisters::AddressException(uint64_t Address) +{ + BAD_VADDR_REGISTER = Address; + ENTRYHI_REGISTER.VPN2 = Address >> 13; + ENTRYHI_REGISTER.R = Address >> 62; + CONTEXT_REGISTER.BadVPN2 = Address >> 13; + XCONTEXT_REGISTER.BadVPN2 = Address >> 13; + XCONTEXT_REGISTER.R = Address >> 62; } void CRegisters::TriggerException(uint32_t ExceptionCode, uint32_t Coprocessor, bool SpecialOffset) @@ -894,7 +819,7 @@ void CRegisters::TriggerException(uint32_t ExceptionCode, uint32_t Coprocessor, uint32_t ExceptionBase = 0x80000000; uint16_t ExceptionOffset = 0x0180; - if (SpecialOffset && STATUS_REGISTER.ExceptionLevel == 0) + if (SpecialOffset && STATUS_REGISTER.ExceptionLevel != 0) { switch (STATUS_REGISTER.PrivilegeMode) { diff --git a/Source/Project64-core/N64System/Mips/Register.h b/Source/Project64-core/N64System/Mips/Register.h index a507ae2950..7d8c323c9a 100644 --- a/Source/Project64-core/N64System/Mips/Register.h +++ b/Source/Project64-core/N64System/Mips/Register.h @@ -19,6 +19,20 @@ #pragma warning(push) #pragma warning(disable : 4201) // Non-standard extension used: nameless struct/union +union COP0EntryHi +{ + uint64_t Value; + + struct + { + uint64_t ASID : 8; + uint64_t : 5; + uint64_t VPN2 : 31; + uint64_t FILL : 18; + uint64_t R : 2; + }; +}; + enum PRIVILEGE_MODE : unsigned { PrivilegeMode_Kernel, @@ -175,7 +189,7 @@ class CP0registers uint64_t & WIRED_REGISTER; uint64_t & BAD_VADDR_REGISTER; uint64_t & COUNT_REGISTER; - uint64_t & ENTRYHI_REGISTER; + COP0EntryHi & ENTRYHI_REGISTER; uint64_t & COMPARE_REGISTER; COP0Status & STATUS_REGISTER; COP0Cause & CAUSE_REGISTER; @@ -458,6 +472,7 @@ class CRegisters : void FixFpuLocations(); void Reset(bool bPostPif, CMipsMemoryVM & MMU); void SetAsCurrentSystem(); + void AddressException(uint64_t Address); void TriggerException(uint32_t ExceptionCode, uint32_t Coprocessor = 0, bool SpecialOffset = false); uint64_t Cop0_MF(COP0Reg Reg); diff --git a/Source/Project64-core/N64System/Mips/TLB.cpp b/Source/Project64-core/N64System/Mips/TLB.cpp index 0899fd450d..009ca63414 100644 --- a/Source/Project64-core/N64System/Mips/TLB.cpp +++ b/Source/Project64-core/N64System/Mips/TLB.cpp @@ -82,12 +82,12 @@ void CTLB::Probe() uint32_t & TlbEntryHiValue = m_tlb[Counter].EntryHi.Value; uint32_t Mask = ~m_tlb[Counter].PageMask.Mask << 13; uint32_t TlbValueMasked = TlbEntryHiValue & Mask; - uint32_t EntryHiMasked = g_Reg->ENTRYHI_REGISTER & Mask; + uint32_t EntryHiMasked = g_Reg->ENTRYHI_REGISTER.Value & Mask; if (TlbValueMasked == EntryHiMasked) { - if ((TlbEntryHiValue & 0x100) != 0 || // Global - ((TlbEntryHiValue & 0xFF) == (g_Reg->ENTRYHI_REGISTER & 0xFF))) // SameAsid + if ((TlbEntryHiValue & 0x100) != 0 || // Global + ((TlbEntryHiValue & 0xFF) == (g_Reg->ENTRYHI_REGISTER.Value & 0xFF))) // SameAsid { g_Reg->INDEX_REGISTER = Counter; int FastIndx = Counter << 1; @@ -105,7 +105,7 @@ void CTLB::ReadEntry() uint32_t index = g_Reg->INDEX_REGISTER & 0x1F; g_Reg->PAGE_MASK_REGISTER = m_tlb[index].PageMask.Value; - g_Reg->ENTRYHI_REGISTER = (m_tlb[index].EntryHi.Value & ~m_tlb[index].PageMask.Value); + g_Reg->ENTRYHI_REGISTER.Value = (m_tlb[index].EntryHi.Value & ~m_tlb[index].PageMask.Value); g_Reg->ENTRYLO0_REGISTER = m_tlb[index].EntryLo0.Value; g_Reg->ENTRYLO1_REGISTER = m_tlb[index].EntryLo1.Value; } @@ -150,7 +150,7 @@ void CTLB::WriteEntry(int index, bool Random) continue; } if (m_tlb[index].PageMask.Value == g_Reg->PAGE_MASK_REGISTER && - m_tlb[index].EntryHi.Value == g_Reg->ENTRYHI_REGISTER) + m_tlb[index].EntryHi.Value == g_Reg->ENTRYHI_REGISTER.Value) { if (FastIndx == (index << 1) && m_tlb[index].EntryLo0.Value == g_Reg->ENTRYLO0_REGISTER) { @@ -167,7 +167,7 @@ void CTLB::WriteEntry(int index, bool Random) // Fill in m_tlb entry m_tlb[index].PageMask.Value = (uint32_t)g_Reg->PAGE_MASK_REGISTER; - m_tlb[index].EntryHi.Value = (uint32_t)g_Reg->ENTRYHI_REGISTER; + m_tlb[index].EntryHi.Value = (uint32_t)g_Reg->ENTRYHI_REGISTER.Value; m_tlb[index].EntryLo0.Value = (uint32_t)g_Reg->ENTRYLO0_REGISTER; m_tlb[index].EntryLo1.Value = (uint32_t)g_Reg->ENTRYLO1_REGISTER; m_tlb[index].EntryDefined = true; diff --git a/Source/Project64/UserInterface/Debugger/Debugger-RegisterTabs.cpp b/Source/Project64/UserInterface/Debugger/Debugger-RegisterTabs.cpp index 6d76e8f5f4..9befde2c1e 100644 --- a/Source/Project64/UserInterface/Debugger/Debugger-RegisterTabs.cpp +++ b/Source/Project64/UserInterface/Debugger/Debugger-RegisterTabs.cpp @@ -141,7 +141,7 @@ void CRegisterTabs::RefreshEdits() m_COP0Edits[6].SetValue((uint32_t)g_Reg->WIRED_REGISTER, DisplayMode::ZeroExtend); m_COP0Edits[7].SetValue((uint32_t)g_Reg->BAD_VADDR_REGISTER, DisplayMode::ZeroExtend); m_COP0Edits[8].SetValue((uint32_t)g_Reg->COUNT_REGISTER, DisplayMode::ZeroExtend); - m_COP0Edits[9].SetValue((uint32_t)g_Reg->ENTRYHI_REGISTER, DisplayMode::ZeroExtend); + m_COP0Edits[9].SetValue((uint32_t)g_Reg->ENTRYHI_REGISTER.Value, DisplayMode::ZeroExtend); m_COP0Edits[10].SetValue((uint32_t)g_Reg->COMPARE_REGISTER, DisplayMode::ZeroExtend); m_COP0Edits[11].SetValue((uint32_t)g_Reg->STATUS_REGISTER.Value, DisplayMode::ZeroExtend); m_COP0Edits[12].SetValue((uint32_t)g_Reg->CAUSE_REGISTER.Value, DisplayMode::ZeroExtend); @@ -320,7 +320,7 @@ void CRegisterTabs::RegisterChanged(HWND hDlg, TAB_ID srcTabId, WPARAM wParam) case IDC_COP0_6_EDIT: g_Reg->WIRED_REGISTER = value; break; case IDC_COP0_7_EDIT: g_Reg->BAD_VADDR_REGISTER = value; break; case IDC_COP0_8_EDIT: g_Reg->COUNT_REGISTER = value; break; - case IDC_COP0_9_EDIT: g_Reg->ENTRYHI_REGISTER = value; break; + case IDC_COP0_9_EDIT: g_Reg->ENTRYHI_REGISTER.Value = value; break; case IDC_COP0_10_EDIT: g_Reg->COMPARE_REGISTER = value; break; case IDC_COP0_11_EDIT: g_Reg->STATUS_REGISTER.Value = value; break; case IDC_COP0_12_EDIT: g_Reg->CAUSE_REGISTER.Value = value; break;