[Project64] Get TLB class to use standard types
This commit is contained in:
parent
cfdb5dc8d0
commit
898f1da74d
|
@ -12,133 +12,138 @@
|
||||||
|
|
||||||
class CDebugTlb;
|
class CDebugTlb;
|
||||||
|
|
||||||
class CTLB_CB
|
__interface CTLB_CB
|
||||||
{
|
{
|
||||||
public:
|
virtual void TLB_Mapped(uint32_t VAddr, uint32_t Len, uint32_t PAddr, bool bReadOnly) = 0;
|
||||||
virtual void TLB_Mapped(DWORD VAddr, DWORD Len, DWORD PAddr, bool bReadOnly) = 0;
|
virtual void TLB_Unmaped(uint32_t VAddr, uint32_t Len) = 0;
|
||||||
virtual void TLB_Unmaped(DWORD VAddr, DWORD Len) = 0;
|
virtual void TLB_Changed() = 0;
|
||||||
virtual void TLB_Changed() = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4201) // warning C4201: nonstandard extension used : nameless struct/union
|
||||||
|
|
||||||
class CTLB :
|
class CTLB :
|
||||||
protected CSystemRegisters
|
protected CSystemRegisters
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct TLB_ENTRY
|
struct TLB_ENTRY
|
||||||
{
|
{
|
||||||
bool EntryDefined;
|
bool EntryDefined;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
unsigned long Value;
|
uint32_t Value;
|
||||||
unsigned char A[4];
|
uint8_t A[4];
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
unsigned zero : 13;
|
unsigned zero : 13;
|
||||||
unsigned Mask : 12;
|
unsigned Mask : 12;
|
||||||
unsigned zero2 : 7;
|
unsigned zero2 : 7;
|
||||||
} ;
|
} ;
|
||||||
|
} PageMask;
|
||||||
} PageMask;
|
|
||||||
|
union
|
||||||
union
|
{
|
||||||
{
|
uint32_t Value;
|
||||||
unsigned long Value;
|
uint8_t A[4];
|
||||||
unsigned char A[4];
|
|
||||||
|
struct
|
||||||
struct
|
{
|
||||||
{
|
unsigned ASID : 8;
|
||||||
unsigned ASID : 8;
|
unsigned Zero : 4;
|
||||||
unsigned Zero : 4;
|
unsigned G : 1;
|
||||||
unsigned G : 1;
|
unsigned VPN2 : 19;
|
||||||
unsigned VPN2 : 19;
|
};
|
||||||
};
|
} EntryHi;
|
||||||
|
|
||||||
} EntryHi;
|
union
|
||||||
|
{
|
||||||
|
uint32_t Value;
|
||||||
|
uint8_t A[4];
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned GLOBAL: 1;
|
||||||
|
unsigned V : 1;
|
||||||
|
unsigned D : 1;
|
||||||
|
unsigned C : 3;
|
||||||
|
unsigned PFN : 20;
|
||||||
|
unsigned ZERO: 6;
|
||||||
|
} ;
|
||||||
|
} EntryLo0;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32_t Value;
|
||||||
|
uint8_t A[4];
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned GLOBAL: 1;
|
||||||
|
unsigned V : 1;
|
||||||
|
unsigned D : 1;
|
||||||
|
unsigned C : 3;
|
||||||
|
unsigned PFN : 20;
|
||||||
|
unsigned ZERO: 6;
|
||||||
|
} ;
|
||||||
|
} EntryLo1;
|
||||||
|
};
|
||||||
|
|
||||||
union
|
|
||||||
{
|
|
||||||
unsigned long Value;
|
|
||||||
unsigned char A[4];
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
unsigned GLOBAL: 1;
|
|
||||||
unsigned V : 1;
|
|
||||||
unsigned D : 1;
|
|
||||||
unsigned C : 3;
|
|
||||||
unsigned PFN : 20;
|
|
||||||
unsigned ZERO: 6;
|
|
||||||
} ;
|
|
||||||
|
|
||||||
} EntryLo0;
|
|
||||||
|
|
||||||
union
|
|
||||||
{
|
|
||||||
unsigned long Value;
|
|
||||||
unsigned char A[4];
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
unsigned GLOBAL: 1;
|
|
||||||
unsigned V : 1;
|
|
||||||
unsigned D : 1;
|
|
||||||
unsigned C : 3;
|
|
||||||
unsigned PFN : 20;
|
|
||||||
unsigned ZERO: 6;
|
|
||||||
} ;
|
|
||||||
|
|
||||||
} EntryLo1;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CTLB(CTLB_CB * CallBack);
|
CTLB(CTLB_CB * CallBack);
|
||||||
~CTLB();
|
~CTLB();
|
||||||
|
|
||||||
void Reset(bool InvalidateTLB);
|
void Reset(bool InvalidateTLB);
|
||||||
|
|
||||||
//Used by opcodes of the same name to manipulate the tlb (reads the registers)
|
|
||||||
void Probe();
|
|
||||||
void ReadEntry();
|
|
||||||
void WriteEntry(int index, bool Random);
|
|
||||||
|
|
||||||
//See if a VAddr has an entry to translate to a PAddr
|
//Used by opcodes of the same name to manipulate the tlb (reads the registers)
|
||||||
bool AddressDefined(DWORD VAddr);
|
void Probe();
|
||||||
|
void ReadEntry();
|
||||||
const TLB_ENTRY & TlbEntry(int Entry) const
|
void WriteEntry(int32_t index, bool Random);
|
||||||
{
|
|
||||||
return m_tlb[Entry];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PAddrToVAddr(DWORD PAddr, DWORD & VAddr, DWORD & Index);
|
//See if a VAddr has an entry to translate to a PAddr
|
||||||
|
bool AddressDefined(uint32_t VAddr);
|
||||||
|
|
||||||
void RecordDifference(CLog &LogFile, const CTLB& rTLB);
|
const TLB_ENTRY & TlbEntry(int32_t Entry) const
|
||||||
|
{
|
||||||
|
return m_tlb[Entry];
|
||||||
|
}
|
||||||
|
|
||||||
bool operator == (const CTLB& rTLB) const;
|
bool PAddrToVAddr(uint32_t PAddr, uint32_t & VAddr, uint32_t & Index);
|
||||||
bool operator != (const CTLB& rTLB) const;
|
|
||||||
|
void RecordDifference(CLog &LogFile, const CTLB& rTLB);
|
||||||
|
|
||||||
|
bool operator == (const CTLB& rTLB) const;
|
||||||
|
bool operator != (const CTLB& rTLB) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct FASTTLB
|
struct FASTTLB
|
||||||
{
|
{
|
||||||
DWORD VSTART;
|
uint32_t VSTART;
|
||||||
DWORD VEND;
|
uint32_t VEND;
|
||||||
DWORD PHYSSTART;
|
uint32_t PHYSSTART;
|
||||||
DWORD PHYSEND;
|
uint32_t PHYSEND;
|
||||||
DWORD Length;
|
uint32_t Length;
|
||||||
bool VALID;
|
bool VALID;
|
||||||
bool DIRTY;
|
bool DIRTY;
|
||||||
bool GLOBAL;
|
bool GLOBAL;
|
||||||
bool ValidEntry;
|
bool ValidEntry;
|
||||||
bool Random;
|
bool Random;
|
||||||
bool Probed;
|
bool Probed;
|
||||||
};
|
};
|
||||||
|
|
||||||
friend CDebugTlb; // enable debug window to read class
|
friend CDebugTlb; // enable debug window to read class
|
||||||
|
|
||||||
CTLB_CB * const m_CB;
|
CTLB_CB * const m_CB;
|
||||||
|
|
||||||
TLB_ENTRY m_tlb[32];
|
TLB_ENTRY m_tlb[32];
|
||||||
FASTTLB m_FastTlb[64];
|
FASTTLB m_FastTlb[64];
|
||||||
|
|
||||||
void SetupTLB_Entry(int index, bool Random);
|
void SetupTLB_Entry(int32_t index, bool Random);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CTLB(); // Disable default constructor
|
||||||
|
CTLB(const CTLB&); // Disable copy constructor
|
||||||
|
CTLB& operator=(const CTLB&); // Disable assignment
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
|
@ -10,323 +10,321 @@
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
CTLB::CTLB(CTLB_CB * CallBack ):
|
CTLB::CTLB(CTLB_CB * CallBack ):
|
||||||
m_CB(CallBack)
|
m_CB(CallBack)
|
||||||
{
|
{
|
||||||
WriteTrace(TraceTLB,__FUNCTION__ ": Start");
|
WriteTrace(TraceTLB,__FUNCTION__ ": Start");
|
||||||
memset(m_tlb,0,sizeof(m_tlb));
|
memset(m_tlb,0,sizeof(m_tlb));
|
||||||
memset(m_FastTlb,0,sizeof(m_FastTlb));
|
memset(m_FastTlb,0,sizeof(m_FastTlb));
|
||||||
Reset(true);
|
Reset(true);
|
||||||
WriteTrace(TraceTLB,__FUNCTION__ ": Done");
|
WriteTrace(TraceTLB,__FUNCTION__ ": Done");
|
||||||
}
|
}
|
||||||
|
|
||||||
CTLB::~CTLB()
|
CTLB::~CTLB()
|
||||||
{
|
{
|
||||||
WriteTrace(TraceTLB,__FUNCTION__ ": Start");
|
WriteTrace(TraceTLB,__FUNCTION__ ": Start");
|
||||||
WriteTrace(TraceTLB,__FUNCTION__ ": Done");
|
WriteTrace(TraceTLB,__FUNCTION__ ": Done");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTLB::Reset (bool InvalidateTLB)
|
void CTLB::Reset (bool InvalidateTLB)
|
||||||
{
|
{
|
||||||
DWORD count;
|
uint32_t count;
|
||||||
|
|
||||||
for (count = 0; count < 64; count++)
|
for (count = 0; count < 64; count++)
|
||||||
{
|
{
|
||||||
m_FastTlb[count].ValidEntry = false;
|
m_FastTlb[count].ValidEntry = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (InvalidateTLB)
|
if (InvalidateTLB)
|
||||||
{
|
{
|
||||||
for (count = 0; count < 32; count++)
|
for (count = 0; count < 32; count++)
|
||||||
{
|
{
|
||||||
m_tlb[count].EntryDefined = false;
|
m_tlb[count].EntryDefined = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (count = 0; count < 32; count ++)
|
for (count = 0; count < 32; count ++)
|
||||||
{
|
{
|
||||||
SetupTLB_Entry(count,false);
|
SetupTLB_Entry(count,false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CTLB::AddressDefined ( DWORD VAddr)
|
bool CTLB::AddressDefined ( uint32_t VAddr)
|
||||||
{
|
{
|
||||||
DWORD i;
|
uint32_t i;
|
||||||
|
|
||||||
if (VAddr >= 0x80000000 && VAddr <= 0xBFFFFFFF)
|
if (VAddr >= 0x80000000 && VAddr <= 0xBFFFFFFF)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 64; i++)
|
for (i = 0; i < 64; i++)
|
||||||
{
|
{
|
||||||
if (m_FastTlb[i].ValidEntry &&
|
if (m_FastTlb[i].ValidEntry &&
|
||||||
VAddr >= m_FastTlb[i].VSTART &&
|
VAddr >= m_FastTlb[i].VSTART &&
|
||||||
VAddr <= m_FastTlb[i].VEND)
|
VAddr <= m_FastTlb[i].VEND)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTLB::Probe()
|
void CTLB::Probe()
|
||||||
{
|
{
|
||||||
int Counter;
|
int Counter;
|
||||||
|
|
||||||
WriteTrace(TraceTLB,__FUNCTION__ ": Start");
|
|
||||||
g_Reg->INDEX_REGISTER |= 0x80000000;
|
|
||||||
for (Counter = 0; Counter < 32; Counter ++)
|
|
||||||
{
|
|
||||||
if (!m_tlb[Counter].EntryDefined)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD & TlbEntryHiValue = m_tlb[Counter].EntryHi.Value;
|
|
||||||
DWORD Mask = ~m_tlb[Counter].PageMask.Mask << 13;
|
|
||||||
DWORD TlbValueMasked = TlbEntryHiValue & Mask;
|
|
||||||
DWORD EntryHiMasked = g_Reg->ENTRYHI_REGISTER & Mask;
|
|
||||||
|
|
||||||
if (TlbValueMasked == EntryHiMasked)
|
WriteTrace(TraceTLB,__FUNCTION__ ": Start");
|
||||||
{
|
g_Reg->INDEX_REGISTER |= 0x80000000;
|
||||||
if ((TlbEntryHiValue & 0x100) != 0 || //Global
|
for (Counter = 0; Counter < 32; Counter ++)
|
||||||
((TlbEntryHiValue & 0xFF) == (g_Reg->ENTRYHI_REGISTER & 0xFF))) //SameAsid
|
{
|
||||||
{
|
if (!m_tlb[Counter].EntryDefined)
|
||||||
g_Reg->INDEX_REGISTER = Counter;
|
{
|
||||||
int FastIndx = Counter << 1;
|
continue;
|
||||||
m_FastTlb[FastIndx].Probed = true;
|
}
|
||||||
m_FastTlb[FastIndx + 1].Probed = true;
|
|
||||||
return;
|
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;
|
||||||
WriteTrace(TraceTLB,__FUNCTION__ ": Done");
|
|
||||||
|
if (TlbValueMasked == EntryHiMasked)
|
||||||
|
{
|
||||||
|
if ((TlbEntryHiValue & 0x100) != 0 || //Global
|
||||||
|
((TlbEntryHiValue & 0xFF) == (g_Reg->ENTRYHI_REGISTER & 0xFF))) //SameAsid
|
||||||
|
{
|
||||||
|
g_Reg->INDEX_REGISTER = Counter;
|
||||||
|
int FastIndx = Counter << 1;
|
||||||
|
m_FastTlb[FastIndx].Probed = true;
|
||||||
|
m_FastTlb[FastIndx + 1].Probed = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WriteTrace(TraceTLB,__FUNCTION__ ": Done");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTLB::ReadEntry()
|
void CTLB::ReadEntry()
|
||||||
{
|
{
|
||||||
DWORD 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 = (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;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTLB::WriteEntry (int index, bool Random)
|
void CTLB::WriteEntry (int index, bool Random)
|
||||||
{
|
{
|
||||||
int FastIndx;
|
int FastIndx;
|
||||||
|
|
||||||
WriteTraceF(TraceTLB,__FUNCTION__ ": %02d %d %08X %08X %08X %08X ",index,Random,g_Reg->PAGE_MASK_REGISTER,g_Reg->ENTRYHI_REGISTER,g_Reg->ENTRYLO0_REGISTER,g_Reg->ENTRYLO1_REGISTER);
|
WriteTraceF(TraceTLB,__FUNCTION__ ": %02d %d %08X %08X %08X %08X ",index,Random,g_Reg->PAGE_MASK_REGISTER,g_Reg->ENTRYHI_REGISTER,g_Reg->ENTRYLO0_REGISTER,g_Reg->ENTRYLO1_REGISTER);
|
||||||
|
|
||||||
//Check to see if entry is unmapping it self
|
//Check to see if entry is unmapping it self
|
||||||
if (m_tlb[index].EntryDefined)
|
if (m_tlb[index].EntryDefined)
|
||||||
{
|
{
|
||||||
FastIndx = index << 1;
|
FastIndx = index << 1;
|
||||||
if (*_PROGRAM_COUNTER >= m_FastTlb[FastIndx].VSTART &&
|
if (*_PROGRAM_COUNTER >= m_FastTlb[FastIndx].VSTART &&
|
||||||
*_PROGRAM_COUNTER < m_FastTlb[FastIndx].VEND &&
|
*_PROGRAM_COUNTER < m_FastTlb[FastIndx].VEND &&
|
||||||
m_FastTlb[FastIndx].ValidEntry && m_FastTlb[FastIndx].VALID)
|
m_FastTlb[FastIndx].ValidEntry && m_FastTlb[FastIndx].VALID)
|
||||||
{
|
{
|
||||||
WriteTraceF(TraceTLB,__FUNCTION__ ": Ignored PC: %X VAddr Start: %X VEND: %X",*_PROGRAM_COUNTER,m_FastTlb[FastIndx].VSTART,m_FastTlb[FastIndx].VEND);
|
WriteTraceF(TraceTLB,__FUNCTION__ ": Ignored PC: %X VAddr Start: %X VEND: %X",*_PROGRAM_COUNTER,m_FastTlb[FastIndx].VSTART,m_FastTlb[FastIndx].VEND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (*_PROGRAM_COUNTER >= m_FastTlb[FastIndx + 1].VSTART &&
|
if (*_PROGRAM_COUNTER >= m_FastTlb[FastIndx + 1].VSTART &&
|
||||||
*_PROGRAM_COUNTER < m_FastTlb[FastIndx + 1].VEND &&
|
*_PROGRAM_COUNTER < m_FastTlb[FastIndx + 1].VEND &&
|
||||||
m_FastTlb[FastIndx + 1].ValidEntry && m_FastTlb[FastIndx + 1].VALID)
|
m_FastTlb[FastIndx + 1].ValidEntry && m_FastTlb[FastIndx + 1].VALID)
|
||||||
{
|
{
|
||||||
WriteTraceF(TraceTLB,__FUNCTION__ ": Ignored PC: %X VAddr Start: %X VEND: %X",*_PROGRAM_COUNTER,m_FastTlb[FastIndx + 1].VSTART,m_FastTlb[FastIndx + 1].VEND);
|
WriteTraceF(TraceTLB,__FUNCTION__ ": Ignored PC: %X VAddr Start: %X VEND: %X",*_PROGRAM_COUNTER,m_FastTlb[FastIndx + 1].VSTART,m_FastTlb[FastIndx + 1].VEND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Reset old addresses
|
//Reset old addresses
|
||||||
if (m_tlb[index].EntryDefined)
|
if (m_tlb[index].EntryDefined)
|
||||||
{
|
{
|
||||||
for ( FastIndx = index << 1; FastIndx <= (index << 1) + 1; FastIndx++)
|
for ( FastIndx = index << 1; FastIndx <= (index << 1) + 1; FastIndx++)
|
||||||
{
|
{
|
||||||
if (!m_FastTlb[FastIndx].ValidEntry)
|
if (!m_FastTlb[FastIndx].ValidEntry)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!m_FastTlb[FastIndx].VALID)
|
if (!m_FastTlb[FastIndx].VALID)
|
||||||
{
|
{
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (FastIndx != (index << 1) && m_tlb[index].EntryLo1.Value == g_Reg->ENTRYLO1_REGISTER)
|
if (FastIndx != (index << 1) && m_tlb[index].EntryLo1.Value == g_Reg->ENTRYLO1_REGISTER)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_CB->TLB_Unmaped(m_FastTlb[FastIndx].VSTART,m_FastTlb[FastIndx].Length);
|
m_CB->TLB_Unmaped(m_FastTlb[FastIndx].VSTART,m_FastTlb[FastIndx].Length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//fill in m_tlb entry
|
//fill in m_tlb entry
|
||||||
m_tlb[index].PageMask.Value = g_Reg->PAGE_MASK_REGISTER;
|
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;
|
||||||
m_tlb[index].EntryLo0.Value = g_Reg->ENTRYLO0_REGISTER;
|
m_tlb[index].EntryLo0.Value = g_Reg->ENTRYLO0_REGISTER;
|
||||||
m_tlb[index].EntryLo1.Value = g_Reg->ENTRYLO1_REGISTER;
|
m_tlb[index].EntryLo1.Value = g_Reg->ENTRYLO1_REGISTER;
|
||||||
m_tlb[index].EntryDefined = true;
|
m_tlb[index].EntryDefined = true;
|
||||||
SetupTLB_Entry(index,Random);
|
SetupTLB_Entry(index,Random);
|
||||||
m_CB->TLB_Changed();
|
m_CB->TLB_Changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTLB::SetupTLB_Entry (int index, bool Random)
|
void CTLB::SetupTLB_Entry (int index, bool Random)
|
||||||
{
|
{
|
||||||
//Fix up Fast TLB entries
|
//Fix up Fast TLB entries
|
||||||
if (!m_tlb[index].EntryDefined)
|
if (!m_tlb[index].EntryDefined)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FastIndx = index << 1;
|
int FastIndx = index << 1;
|
||||||
if (m_FastTlb[FastIndx].VALID)
|
if (m_FastTlb[FastIndx].VALID)
|
||||||
{
|
{
|
||||||
m_CB->TLB_Unmaped(m_FastTlb[FastIndx].VSTART,m_FastTlb[FastIndx].Length);
|
m_CB->TLB_Unmaped(m_FastTlb[FastIndx].VSTART,m_FastTlb[FastIndx].Length);
|
||||||
}
|
}
|
||||||
m_FastTlb[FastIndx].Length = (m_tlb[index].PageMask.Mask << 12) + 0xFFF;
|
m_FastTlb[FastIndx].Length = (m_tlb[index].PageMask.Mask << 12) + 0xFFF;
|
||||||
m_FastTlb[FastIndx].VSTART=m_tlb[index].EntryHi.VPN2 << 13;
|
m_FastTlb[FastIndx].VSTART=m_tlb[index].EntryHi.VPN2 << 13;
|
||||||
m_FastTlb[FastIndx].VEND = m_FastTlb[FastIndx].VSTART + m_FastTlb[FastIndx].Length;
|
m_FastTlb[FastIndx].VEND = m_FastTlb[FastIndx].VSTART + m_FastTlb[FastIndx].Length;
|
||||||
m_FastTlb[FastIndx].PHYSSTART = m_tlb[index].EntryLo0.PFN << 12;
|
m_FastTlb[FastIndx].PHYSSTART = m_tlb[index].EntryLo0.PFN << 12;
|
||||||
m_FastTlb[FastIndx].PHYSEND = m_FastTlb[FastIndx].PHYSSTART + m_FastTlb[FastIndx].Length;
|
m_FastTlb[FastIndx].PHYSEND = m_FastTlb[FastIndx].PHYSSTART + m_FastTlb[FastIndx].Length;
|
||||||
m_FastTlb[FastIndx].VALID = m_tlb[index].EntryLo0.V;
|
m_FastTlb[FastIndx].VALID = m_tlb[index].EntryLo0.V;
|
||||||
m_FastTlb[FastIndx].DIRTY = m_tlb[index].EntryLo0.D;
|
m_FastTlb[FastIndx].DIRTY = m_tlb[index].EntryLo0.D;
|
||||||
m_FastTlb[FastIndx].GLOBAL = m_tlb[index].EntryLo0.GLOBAL & m_tlb[index].EntryLo1.GLOBAL;
|
m_FastTlb[FastIndx].GLOBAL = m_tlb[index].EntryLo0.GLOBAL & m_tlb[index].EntryLo1.GLOBAL;
|
||||||
m_FastTlb[FastIndx].ValidEntry = false;
|
m_FastTlb[FastIndx].ValidEntry = false;
|
||||||
m_FastTlb[FastIndx].Random = Random;
|
m_FastTlb[FastIndx].Random = Random;
|
||||||
m_FastTlb[FastIndx].Probed = false;
|
m_FastTlb[FastIndx].Probed = false;
|
||||||
|
|
||||||
|
FastIndx = (index << 1) + 1;
|
||||||
|
if (m_FastTlb[FastIndx].VALID)
|
||||||
|
{
|
||||||
|
m_CB->TLB_Unmaped(m_FastTlb[FastIndx].VSTART,m_FastTlb[FastIndx].Length);
|
||||||
|
}
|
||||||
|
m_FastTlb[FastIndx].Length = (m_tlb[index].PageMask.Mask << 12) + 0xFFF;
|
||||||
|
m_FastTlb[FastIndx].VSTART=(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 = 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].GLOBAL = m_tlb[index].EntryLo0.GLOBAL & m_tlb[index].EntryLo1.GLOBAL;
|
||||||
|
m_FastTlb[FastIndx].ValidEntry = false;
|
||||||
|
m_FastTlb[FastIndx].Random = Random;
|
||||||
|
m_FastTlb[FastIndx].Probed = false;
|
||||||
|
|
||||||
FastIndx = (index << 1) + 1;
|
//Test both entries to see if they are valid
|
||||||
if (m_FastTlb[FastIndx].VALID)
|
for ( FastIndx = index << 1; FastIndx <= (index << 1) + 1; FastIndx++)
|
||||||
{
|
{
|
||||||
m_CB->TLB_Unmaped(m_FastTlb[FastIndx].VSTART,m_FastTlb[FastIndx].Length);
|
if (!m_FastTlb[FastIndx].VALID)
|
||||||
}
|
{
|
||||||
m_FastTlb[FastIndx].Length = (m_tlb[index].PageMask.Mask << 12) + 0xFFF;
|
m_FastTlb[FastIndx].ValidEntry = true;
|
||||||
m_FastTlb[FastIndx].VSTART=(m_tlb[index].EntryHi.VPN2 << 13) + (m_FastTlb[FastIndx].Length + 1);
|
continue;
|
||||||
m_FastTlb[FastIndx].VEND = m_FastTlb[FastIndx].VSTART + m_FastTlb[FastIndx].Length;
|
}
|
||||||
m_FastTlb[FastIndx].PHYSSTART = 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].GLOBAL = m_tlb[index].EntryLo0.GLOBAL & m_tlb[index].EntryLo1.GLOBAL;
|
|
||||||
m_FastTlb[FastIndx].ValidEntry = false;
|
|
||||||
m_FastTlb[FastIndx].Random = Random;
|
|
||||||
m_FastTlb[FastIndx].Probed = false;
|
|
||||||
|
|
||||||
//Test both entries to see if they are valid
|
if (m_FastTlb[FastIndx].VEND <= m_FastTlb[FastIndx].VSTART)
|
||||||
for ( FastIndx = index << 1; FastIndx <= (index << 1) + 1; FastIndx++)
|
{
|
||||||
{
|
continue;
|
||||||
if (!m_FastTlb[FastIndx].VALID)
|
}
|
||||||
{
|
if (m_FastTlb[FastIndx].VSTART >= 0x80000000 && m_FastTlb[FastIndx].VEND <= 0xBFFFFFFF)
|
||||||
m_FastTlb[FastIndx].ValidEntry = true;
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (m_FastTlb[FastIndx].PHYSSTART > 0x1FFFFFFF)
|
||||||
if (m_FastTlb[FastIndx].VEND <= m_FastTlb[FastIndx].VSTART)
|
{
|
||||||
{
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
|
||||||
if (m_FastTlb[FastIndx].VSTART >= 0x80000000 && m_FastTlb[FastIndx].VEND <= 0xBFFFFFFF)
|
//MAP the new m_tlb entry for reading and writing
|
||||||
{
|
m_FastTlb[FastIndx].ValidEntry = true;
|
||||||
continue;
|
m_CB->TLB_Mapped(m_FastTlb[FastIndx].VSTART,m_FastTlb[FastIndx].Length,m_FastTlb[FastIndx].PHYSSTART, !m_FastTlb[FastIndx].DIRTY);
|
||||||
}
|
}
|
||||||
if (m_FastTlb[FastIndx].PHYSSTART > 0x1FFFFFFF)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//MAP the new m_tlb entry for reading and writing
|
|
||||||
m_FastTlb[FastIndx].ValidEntry = true;
|
|
||||||
m_CB->TLB_Mapped(m_FastTlb[FastIndx].VSTART,m_FastTlb[FastIndx].Length,m_FastTlb[FastIndx].PHYSSTART, !m_FastTlb[FastIndx].DIRTY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CTLB::PAddrToVAddr(DWORD PAddr, DWORD & VAddr, DWORD & Index )
|
bool CTLB::PAddrToVAddr(uint32_t PAddr, uint32_t & VAddr, uint32_t & Index )
|
||||||
{
|
{
|
||||||
for (int i = Index; i < 64; i++)
|
for (int i = Index; i < 64; i++)
|
||||||
{
|
{
|
||||||
if (m_FastTlb[i].ValidEntry == false)
|
if (m_FastTlb[i].ValidEntry == false)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (PAddr >= m_FastTlb[i].PHYSSTART && PAddr < m_FastTlb[i].PHYSEND)
|
if (PAddr >= m_FastTlb[i].PHYSSTART && PAddr < m_FastTlb[i].PHYSEND)
|
||||||
{
|
{
|
||||||
VAddr = m_FastTlb[i].VSTART + (PAddr - m_FastTlb[i].PHYSSTART);
|
VAddr = m_FastTlb[i].VSTART + (PAddr - m_FastTlb[i].PHYSSTART);
|
||||||
Index = i + 1;
|
Index = i + 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
return false;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTLB::RecordDifference( CLog &LogFile, const CTLB& rTLB)
|
void CTLB::RecordDifference( CLog &LogFile, const CTLB& rTLB)
|
||||||
{
|
{
|
||||||
for (int i = 0, n = sizeof(m_tlb)/sizeof(m_tlb[0]); i < n; i++)
|
for (int i = 0, n = sizeof(m_tlb)/sizeof(m_tlb[0]); i < n; i++)
|
||||||
{
|
{
|
||||||
if (m_tlb[i].EntryDefined != rTLB.m_tlb[i].EntryDefined)
|
if (m_tlb[i].EntryDefined != rTLB.m_tlb[i].EntryDefined)
|
||||||
{
|
{
|
||||||
LogFile.LogF("TLB[%d] Defined: %s %s\r\n",i,m_tlb[i].EntryDefined ? "Yes" : "No",rTLB.m_tlb[i].EntryDefined ? "Yes" : "No");
|
LogFile.LogF("TLB[%d] Defined: %s %s\r\n",i,m_tlb[i].EntryDefined ? "Yes" : "No",rTLB.m_tlb[i].EntryDefined ? "Yes" : "No");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!m_tlb[i].EntryDefined)
|
if (!m_tlb[i].EntryDefined)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (m_tlb[i].PageMask.Value != rTLB.m_tlb[i].PageMask.Value)
|
if (m_tlb[i].PageMask.Value != rTLB.m_tlb[i].PageMask.Value)
|
||||||
{
|
{
|
||||||
LogFile.LogF("TLB[%d] PageMask: %X %X\r\n",i,m_tlb[i].PageMask.Value,rTLB.m_tlb[i].PageMask.Value);
|
LogFile.LogF("TLB[%d] PageMask: %X %X\r\n",i,m_tlb[i].PageMask.Value,rTLB.m_tlb[i].PageMask.Value);
|
||||||
}
|
}
|
||||||
if (m_tlb[i].EntryHi.Value != rTLB.m_tlb[i].EntryHi.Value)
|
if (m_tlb[i].EntryHi.Value != rTLB.m_tlb[i].EntryHi.Value)
|
||||||
{
|
{
|
||||||
LogFile.LogF("TLB[%d] EntryHi: %X %X\r\n",i,m_tlb[i].EntryHi.Value,rTLB.m_tlb[i].EntryHi.Value);
|
LogFile.LogF("TLB[%d] EntryHi: %X %X\r\n",i,m_tlb[i].EntryHi.Value,rTLB.m_tlb[i].EntryHi.Value);
|
||||||
}
|
}
|
||||||
if (m_tlb[i].EntryLo0.Value != rTLB.m_tlb[i].EntryLo0.Value)
|
if (m_tlb[i].EntryLo0.Value != rTLB.m_tlb[i].EntryLo0.Value)
|
||||||
{
|
{
|
||||||
LogFile.LogF("TLB[%d] EntryLo0: %X %X\r\n",i,m_tlb[i].EntryLo0.Value,rTLB.m_tlb[i].EntryLo0.Value);
|
LogFile.LogF("TLB[%d] EntryLo0: %X %X\r\n",i,m_tlb[i].EntryLo0.Value,rTLB.m_tlb[i].EntryLo0.Value);
|
||||||
}
|
}
|
||||||
if (m_tlb[i].EntryLo1.Value != rTLB.m_tlb[i].EntryLo1.Value)
|
if (m_tlb[i].EntryLo1.Value != rTLB.m_tlb[i].EntryLo1.Value)
|
||||||
{
|
{
|
||||||
LogFile.LogF("TLB[%d] EntryLo1: %X %X\r\n",i,m_tlb[i].EntryLo1.Value,rTLB.m_tlb[i].EntryLo1.Value);
|
LogFile.LogF("TLB[%d] EntryLo1: %X %X\r\n",i,m_tlb[i].EntryLo1.Value,rTLB.m_tlb[i].EntryLo1.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CTLB::operator == (const CTLB& rTLB) const
|
bool CTLB::operator == (const CTLB& rTLB) const
|
||||||
{
|
{
|
||||||
for (int i = 0, n = sizeof(m_tlb)/sizeof(m_tlb[0]); i < n; i++)
|
for (int i = 0, n = sizeof(m_tlb)/sizeof(m_tlb[0]); i < n; i++)
|
||||||
{
|
{
|
||||||
if (m_tlb[i].EntryDefined != rTLB.m_tlb[i].EntryDefined)
|
if (m_tlb[i].EntryDefined != rTLB.m_tlb[i].EntryDefined)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!m_tlb[i].EntryDefined)
|
if (!m_tlb[i].EntryDefined)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (m_tlb[i].PageMask.Value != rTLB.m_tlb[i].PageMask.Value ||
|
if (m_tlb[i].PageMask.Value != rTLB.m_tlb[i].PageMask.Value ||
|
||||||
m_tlb[i].EntryHi.Value != rTLB.m_tlb[i].EntryHi.Value ||
|
m_tlb[i].EntryHi.Value != rTLB.m_tlb[i].EntryHi.Value ||
|
||||||
m_tlb[i].EntryLo0.Value != rTLB.m_tlb[i].EntryLo0.Value ||
|
m_tlb[i].EntryLo0.Value != rTLB.m_tlb[i].EntryLo0.Value ||
|
||||||
m_tlb[i].EntryLo1.Value != rTLB.m_tlb[i].EntryLo1.Value)
|
m_tlb[i].EntryLo1.Value != rTLB.m_tlb[i].EntryLo1.Value)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CTLB::operator != (const CTLB& rTLB) const
|
bool CTLB::operator != (const CTLB& rTLB) const
|
||||||
{
|
{
|
||||||
return !(*this == rTLB);
|
return !(*this == rTLB);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2073,12 +2073,12 @@ bool CN64System::WriteToProtectedMemory (uint32_t Address, int length)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CN64System::TLB_Mapped ( DWORD VAddr, DWORD Len, DWORD PAddr, bool bReadOnly )
|
void CN64System::TLB_Mapped ( uint32_t VAddr, uint32_t Len, uint32_t PAddr, bool bReadOnly )
|
||||||
{
|
{
|
||||||
m_MMU_VM.TLB_Mapped(VAddr,Len,PAddr,bReadOnly);
|
m_MMU_VM.TLB_Mapped(VAddr,Len,PAddr,bReadOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CN64System::TLB_Unmaped ( DWORD VAddr, DWORD Len )
|
void CN64System::TLB_Unmaped ( uint32_t VAddr, uint32_t Len )
|
||||||
{
|
{
|
||||||
m_MMU_VM.TLB_Unmaped(VAddr,Len);
|
m_MMU_VM.TLB_Unmaped(VAddr,Len);
|
||||||
if (m_Recomp && bSMM_TLB())
|
if (m_Recomp && bSMM_TLB())
|
||||||
|
|
|
@ -114,8 +114,8 @@ private:
|
||||||
virtual bool WriteToProtectedMemory(uint32_t Address, int length);
|
virtual bool WriteToProtectedMemory(uint32_t Address, int length);
|
||||||
|
|
||||||
//Functions in CTLB_CB
|
//Functions in CTLB_CB
|
||||||
void TLB_Mapped(DWORD VAddr, DWORD Len, DWORD PAddr, bool bReadOnly);
|
void TLB_Mapped(uint32_t VAddr, uint32_t Len, uint32_t PAddr, bool bReadOnly);
|
||||||
void TLB_Unmaped(DWORD VAddr, DWORD Len);
|
void TLB_Unmaped(uint32_t VAddr, uint32_t Len);
|
||||||
void TLB_Changed();
|
void TLB_Changed();
|
||||||
|
|
||||||
CPlugins * const m_Plugins; //The plugin container
|
CPlugins * const m_Plugins; //The plugin container
|
||||||
|
|
|
@ -908,7 +908,7 @@ void CRecompiler::ClearRecompCode_Phys(DWORD Address, int length, REMOVE_REASON
|
||||||
|
|
||||||
if (g_System->bUseTlb())
|
if (g_System->bUseTlb())
|
||||||
{
|
{
|
||||||
DWORD VAddr, Index = 0;
|
uint32_t VAddr, Index = 0;
|
||||||
while (g_TLB->PAddrToVAddr(Address,VAddr,Index))
|
while (g_TLB->PAddrToVAddr(Address,VAddr,Index))
|
||||||
{
|
{
|
||||||
WriteTraceF(TraceRecompiler,__FUNCTION__ ": ClearRecompCode Vaddr %X len: %d",VAddr,length);
|
WriteTraceF(TraceRecompiler,__FUNCTION__ ": ClearRecompCode Vaddr %X len: %d",VAddr,length);
|
||||||
|
|
Loading…
Reference in New Issue