Core: Get CRegisters::DoAddressError, CRegisters::DoTLBReadMiss, CRegisters::DoTLBWriteMiss to use TriggerException function
This commit is contained in:
parent
ae4af8746b
commit
f559aed2ad
|
@ -239,7 +239,7 @@ CP0registers::CP0registers(uint64_t * _CP0) :
|
||||||
WIRED_REGISTER(_CP0[6]),
|
WIRED_REGISTER(_CP0[6]),
|
||||||
BAD_VADDR_REGISTER(_CP0[8]),
|
BAD_VADDR_REGISTER(_CP0[8]),
|
||||||
COUNT_REGISTER(_CP0[9]),
|
COUNT_REGISTER(_CP0[9]),
|
||||||
ENTRYHI_REGISTER(_CP0[10]),
|
ENTRYHI_REGISTER((COP0EntryHi &)_CP0[10]),
|
||||||
COMPARE_REGISTER(_CP0[11]),
|
COMPARE_REGISTER(_CP0[11]),
|
||||||
STATUS_REGISTER((COP0Status &)_CP0[12]),
|
STATUS_REGISTER((COP0Status &)_CP0[12]),
|
||||||
CAUSE_REGISTER((COP0Cause &)_CP0[13]),
|
CAUSE_REGISTER((COP0Cause &)_CP0[13]),
|
||||||
|
@ -747,33 +747,8 @@ void CRegisters::DoAddressError(uint64_t BadVaddr, bool FromRead)
|
||||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FromRead)
|
AddressException(BadVaddr);
|
||||||
{
|
TriggerException(FromRead ? EXC_RADE : EXC_WADE);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRegisters::FixFpuLocations()
|
void CRegisters::FixFpuLocations()
|
||||||
|
@ -808,74 +783,24 @@ bool CRegisters::DoIntrException()
|
||||||
|
|
||||||
void CRegisters::DoTLBReadMiss(uint64_t BadVaddr)
|
void CRegisters::DoTLBReadMiss(uint64_t BadVaddr)
|
||||||
{
|
{
|
||||||
CAUSE_REGISTER.ExceptionCode = EXC_RMISS;
|
AddressException(BadVaddr);
|
||||||
CAUSE_REGISTER.CoprocessorUnitNumber = 0;
|
TriggerException(EXC_RMISS, 0, true);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRegisters::DoTLBWriteMiss(uint64_t BadVaddr)
|
void CRegisters::DoTLBWriteMiss(uint64_t BadVaddr)
|
||||||
{
|
{
|
||||||
CAUSE_REGISTER.ExceptionCode = EXC_WMISS;
|
AddressException(BadVaddr);
|
||||||
CAUSE_REGISTER.CoprocessorUnitNumber = 0;
|
TriggerException(EXC_WMISS, 0, true);
|
||||||
BAD_VADDR_REGISTER = BadVaddr;
|
}
|
||||||
CONTEXT_REGISTER.BadVPN2 = BadVaddr >> 13;
|
|
||||||
ENTRYHI_REGISTER = (BadVaddr & 0xFFFFE000);
|
void CRegisters::AddressException(uint64_t Address)
|
||||||
if ((STATUS_REGISTER.ExceptionLevel) == 0)
|
{
|
||||||
{
|
BAD_VADDR_REGISTER = Address;
|
||||||
if (g_System->m_PipelineStage == PIPELINE_STAGE_JUMP)
|
ENTRYHI_REGISTER.VPN2 = Address >> 13;
|
||||||
{
|
ENTRYHI_REGISTER.R = Address >> 62;
|
||||||
CAUSE_REGISTER.BranchDelay = 1;
|
CONTEXT_REGISTER.BadVPN2 = Address >> 13;
|
||||||
EPC_REGISTER = (int64_t)((int32_t)m_PROGRAM_COUNTER - 4);
|
XCONTEXT_REGISTER.BadVPN2 = Address >> 13;
|
||||||
}
|
XCONTEXT_REGISTER.R = Address >> 62;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRegisters::TriggerException(uint32_t ExceptionCode, uint32_t Coprocessor, bool SpecialOffset)
|
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;
|
uint32_t ExceptionBase = 0x80000000;
|
||||||
uint16_t ExceptionOffset = 0x0180;
|
uint16_t ExceptionOffset = 0x0180;
|
||||||
if (SpecialOffset && STATUS_REGISTER.ExceptionLevel == 0)
|
if (SpecialOffset && STATUS_REGISTER.ExceptionLevel != 0)
|
||||||
{
|
{
|
||||||
switch (STATUS_REGISTER.PrivilegeMode)
|
switch (STATUS_REGISTER.PrivilegeMode)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,6 +19,20 @@
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4201) // Non-standard extension used: nameless struct/union
|
#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
|
enum PRIVILEGE_MODE : unsigned
|
||||||
{
|
{
|
||||||
PrivilegeMode_Kernel,
|
PrivilegeMode_Kernel,
|
||||||
|
@ -175,7 +189,7 @@ public:
|
||||||
uint64_t & WIRED_REGISTER;
|
uint64_t & WIRED_REGISTER;
|
||||||
uint64_t & BAD_VADDR_REGISTER;
|
uint64_t & BAD_VADDR_REGISTER;
|
||||||
uint64_t & COUNT_REGISTER;
|
uint64_t & COUNT_REGISTER;
|
||||||
uint64_t & ENTRYHI_REGISTER;
|
COP0EntryHi & ENTRYHI_REGISTER;
|
||||||
uint64_t & COMPARE_REGISTER;
|
uint64_t & COMPARE_REGISTER;
|
||||||
COP0Status & STATUS_REGISTER;
|
COP0Status & STATUS_REGISTER;
|
||||||
COP0Cause & CAUSE_REGISTER;
|
COP0Cause & CAUSE_REGISTER;
|
||||||
|
@ -458,6 +472,7 @@ public:
|
||||||
void FixFpuLocations();
|
void FixFpuLocations();
|
||||||
void Reset(bool bPostPif, CMipsMemoryVM & MMU);
|
void Reset(bool bPostPif, CMipsMemoryVM & MMU);
|
||||||
void SetAsCurrentSystem();
|
void SetAsCurrentSystem();
|
||||||
|
void AddressException(uint64_t Address);
|
||||||
void TriggerException(uint32_t ExceptionCode, uint32_t Coprocessor = 0, bool SpecialOffset = false);
|
void TriggerException(uint32_t ExceptionCode, uint32_t Coprocessor = 0, bool SpecialOffset = false);
|
||||||
|
|
||||||
uint64_t Cop0_MF(COP0Reg Reg);
|
uint64_t Cop0_MF(COP0Reg Reg);
|
||||||
|
|
|
@ -82,12 +82,12 @@ void CTLB::Probe()
|
||||||
uint32_t & TlbEntryHiValue = m_tlb[Counter].EntryHi.Value;
|
uint32_t & TlbEntryHiValue = m_tlb[Counter].EntryHi.Value;
|
||||||
uint32_t Mask = ~m_tlb[Counter].PageMask.Mask << 13;
|
uint32_t Mask = ~m_tlb[Counter].PageMask.Mask << 13;
|
||||||
uint32_t TlbValueMasked = TlbEntryHiValue & Mask;
|
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 (TlbValueMasked == EntryHiMasked)
|
||||||
{
|
{
|
||||||
if ((TlbEntryHiValue & 0x100) != 0 || // Global
|
if ((TlbEntryHiValue & 0x100) != 0 || // Global
|
||||||
((TlbEntryHiValue & 0xFF) == (g_Reg->ENTRYHI_REGISTER & 0xFF))) // SameAsid
|
((TlbEntryHiValue & 0xFF) == (g_Reg->ENTRYHI_REGISTER.Value & 0xFF))) // SameAsid
|
||||||
{
|
{
|
||||||
g_Reg->INDEX_REGISTER = Counter;
|
g_Reg->INDEX_REGISTER = Counter;
|
||||||
int FastIndx = Counter << 1;
|
int FastIndx = Counter << 1;
|
||||||
|
@ -105,7 +105,7 @@ void CTLB::ReadEntry()
|
||||||
uint32_t index = g_Reg->INDEX_REGISTER & 0x1F;
|
uint32_t index = g_Reg->INDEX_REGISTER & 0x1F;
|
||||||
|
|
||||||
g_Reg->PAGE_MASK_REGISTER = m_tlb[index].PageMask.Value;
|
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->ENTRYLO0_REGISTER = m_tlb[index].EntryLo0.Value;
|
||||||
g_Reg->ENTRYLO1_REGISTER = m_tlb[index].EntryLo1.Value;
|
g_Reg->ENTRYLO1_REGISTER = m_tlb[index].EntryLo1.Value;
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ void CTLB::WriteEntry(int index, bool Random)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (m_tlb[index].PageMask.Value == g_Reg->PAGE_MASK_REGISTER &&
|
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)
|
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
|
// Fill in m_tlb entry
|
||||||
m_tlb[index].PageMask.Value = (uint32_t)g_Reg->PAGE_MASK_REGISTER;
|
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].EntryLo0.Value = (uint32_t)g_Reg->ENTRYLO0_REGISTER;
|
||||||
m_tlb[index].EntryLo1.Value = (uint32_t)g_Reg->ENTRYLO1_REGISTER;
|
m_tlb[index].EntryLo1.Value = (uint32_t)g_Reg->ENTRYLO1_REGISTER;
|
||||||
m_tlb[index].EntryDefined = true;
|
m_tlb[index].EntryDefined = true;
|
||||||
|
|
|
@ -141,7 +141,7 @@ void CRegisterTabs::RefreshEdits()
|
||||||
m_COP0Edits[6].SetValue((uint32_t)g_Reg->WIRED_REGISTER, DisplayMode::ZeroExtend);
|
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[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[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[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[11].SetValue((uint32_t)g_Reg->STATUS_REGISTER.Value, DisplayMode::ZeroExtend);
|
||||||
m_COP0Edits[12].SetValue((uint32_t)g_Reg->CAUSE_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_6_EDIT: g_Reg->WIRED_REGISTER = value; break;
|
||||||
case IDC_COP0_7_EDIT: g_Reg->BAD_VADDR_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_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_10_EDIT: g_Reg->COMPARE_REGISTER = value; break;
|
||||||
case IDC_COP0_11_EDIT: g_Reg->STATUS_REGISTER.Value = 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;
|
case IDC_COP0_12_EDIT: g_Reg->CAUSE_REGISTER.Value = value; break;
|
||||||
|
|
Loading…
Reference in New Issue