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;
|
bool SpecialOffset = false;
|
||||||
if (ExceptionCode == EXC_RMISS || ExceptionCode == EXC_WMISS)
|
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;
|
BAD_VADDR_REGISTER = Address;
|
||||||
|
|
|
@ -53,21 +53,26 @@ void CTLB::Reset(bool InvalidateTLB)
|
||||||
COP0StatusChanged();
|
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++)
|
||||||
}
|
|
||||||
|
|
||||||
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 true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -88,23 +93,22 @@ void CTLB::Probe()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t & TlbEntryHiValue = m_tlb[i].EntryHi.Value;
|
const COP0EntryHi & TlbEntryHiValue = m_tlb[i].EntryHi;
|
||||||
uint32_t Mask = (uint32_t)(~m_tlb[i].PageMask.Mask << 13);
|
uint64_t Mask = ~m_tlb[i].PageMask.Mask << 13;
|
||||||
uint32_t TlbValueMasked = TlbEntryHiValue & Mask;
|
uint64_t TlbValueMasked = TlbEntryHiValue.Value & Mask;
|
||||||
uint32_t EntryHiMasked = m_Reg.ENTRYHI_REGISTER.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
|
continue;
|
||||||
((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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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");
|
WriteTrace(TraceTLB, TraceDebug, "Done");
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ public:
|
||||||
void ReadEntry();
|
void ReadEntry();
|
||||||
void WriteEntry(uint32_t Index, bool Random);
|
void WriteEntry(uint32_t Index, bool Random);
|
||||||
void COP0StatusChanged(void);
|
void COP0StatusChanged(void);
|
||||||
bool AddressDefined(uint64_t VAddr);
|
bool AddressDefined(uint64_t VAddr, bool & Dirty);
|
||||||
TLB_ENTRY & TlbEntry(int32_t Entry);
|
TLB_ENTRY & TlbEntry(int32_t Entry);
|
||||||
|
|
||||||
bool VAddrToPAddr(uint64_t VAddr, uint32_t & PAddr, bool & MemoryUnused);
|
bool VAddrToPAddr(uint64_t VAddr, uint32_t & PAddr, bool & MemoryUnused);
|
||||||
|
|
|
@ -2028,13 +2028,13 @@ bool CN64System::LoadState(const char * FileName)
|
||||||
LoadedZipFile = true;
|
LoadedZipFile = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (LoadedZipFile && Value == SaveID_1 && port == UNZ_OK)
|
if (LoadedZipFile && SaveID == SaveID_1 && port == UNZ_OK)
|
||||||
{
|
{
|
||||||
// Extra info v1
|
// Extra info v1
|
||||||
// System timers info
|
// System timers info
|
||||||
m_SystemTimer.LoadData(file);
|
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)
|
// Extra info v2 (Project64 2.4)
|
||||||
// Disk interface info
|
// Disk interface info
|
||||||
|
|
Loading…
Reference in New Issue