Core: Fix up tlb Probe and call EXC_MOD when tlb is not dirty
This commit is contained in:
parent
e74e8f6a23
commit
f73c3708a5
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
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 ((TlbEntryHiValue & 0x100) != 0 || // Global
|
||||
((TlbEntryHiValue & 0xFF) == (m_Reg.ENTRYHI_REGISTER.Value & 0xFF))) // SameAsid
|
||||
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)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
m_Reg.INDEX_REGISTER = i;
|
||||
uint32_t FastIndx = i << 1;
|
||||
m_FastTlb[FastIndx].Probed = true;
|
||||
m_FastTlb[FastIndx + 1].Probed = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
WriteTrace(TraceTLB, TraceDebug, "Done");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue