Re-added buffer check on lookup core

This commit is contained in:
zilmar 2012-09-25 08:07:51 +10:00
parent b372675796
commit 5344507496
9 changed files with 235 additions and 84 deletions

View File

@ -276,6 +276,13 @@ bool CMipsMemoryVM::ValidVaddr ( DWORD VAddr ) const
return m_TLB_ReadMap[VAddr >> 12] != 0; return m_TLB_ReadMap[VAddr >> 12] != 0;
} }
bool CMipsMemoryVM::VAddrToRealAddr ( DWORD VAddr, void * &RealAddress ) const
{
if (m_TLB_ReadMap[VAddr >> 12] == 0) { return false; }
RealAddress = (BYTE *)(m_TLB_ReadMap[VAddr >> 12] + VAddr);
return true;
}
bool CMipsMemoryVM::TranslateVaddr ( DWORD VAddr, DWORD &PAddr) const bool CMipsMemoryVM::TranslateVaddr ( DWORD VAddr, DWORD &PAddr) const
{ {
//Change the Virtual address to a Phyiscal Address //Change the Virtual address to a Phyiscal Address

View File

@ -105,6 +105,7 @@ public:
// CTransVaddr interface // CTransVaddr interface
bool TranslateVaddr ( DWORD VAddr, DWORD &PAddr) const; bool TranslateVaddr ( DWORD VAddr, DWORD &PAddr) const;
bool ValidVaddr ( DWORD VAddr ) const; bool ValidVaddr ( DWORD VAddr ) const;
bool VAddrToRealAddr ( DWORD VAddr, void * &RealAddress ) const;
// Labels // Labels
LPCTSTR LabelName ( DWORD Address ) const; LPCTSTR LabelName ( DWORD Address ) const;

View File

@ -1,6 +1,7 @@
class CTransVaddr class CTransVaddr
{ {
public: public:
virtual bool TranslateVaddr ( DWORD VAddr, DWORD &PAddr) const = 0; virtual bool TranslateVaddr ( DWORD VAddr, DWORD &PAddr) const = 0;
virtual bool ValidVaddr ( DWORD VAddr ) const = 0; virtual bool ValidVaddr ( DWORD VAddr ) const = 0;
virtual bool VAddrToRealAddr ( DWORD VAddr, void * &RealAddress ) const = 0;
}; };

View File

@ -10,6 +10,15 @@ CCodeBlock::CCodeBlock(DWORD VAddrEnter, BYTE * RecompPos, bool bDelaySlot) :
m_bDelaySlot(bDelaySlot), m_bDelaySlot(bDelaySlot),
m_Test(1) m_Test(1)
{ {
if (_TransVaddr->VAddrToRealAddr(VAddrEnter,*(reinterpret_cast<void **>(&m_MemLocation[0]))))
{
m_MemLocation[1] = m_MemLocation[0] + 1;
m_MemContents[0] = *m_MemLocation[0];
m_MemContents[1] = *m_MemLocation[1];
} else {
memset(m_MemLocation,0,sizeof(m_MemLocation));
memset(m_MemContents,0,sizeof(m_MemContents));
}
AnalyseBlock(); AnalyseBlock();
} }

View File

@ -23,6 +23,9 @@ public:
CCodeSection * ExistingSection ( DWORD Addr ) { return m_EnterSection.ExistingSection(Addr,NextTest()); } CCodeSection * ExistingSection ( DWORD Addr ) { return m_EnterSection.ExistingSection(Addr,NextTest()); }
bool SectionAccessible ( DWORD m_SectionID ) { return m_EnterSection.SectionAccessible(m_SectionID,NextTest()); } bool SectionAccessible ( DWORD m_SectionID ) { return m_EnterSection.SectionAccessible(m_SectionID,NextTest()); }
inline QWORD MemContents(int i) const { return m_MemContents[i]; }
inline QWORD * MemLocation(int i) const { return m_MemLocation[i]; }
EXIT_LIST m_ExitInfo; EXIT_LIST m_ExitInfo;
DWORD NextTest ( void ); DWORD NextTest ( void );
@ -39,4 +42,6 @@ private:
CCodeSection m_EnterSection; CCodeSection m_EnterSection;
DWORD m_Test; DWORD m_Test;
MD5Digest m_Hash; MD5Digest m_Hash;
QWORD m_MemContents[2];
QWORD * m_MemLocation[2];
}; };

View File

@ -8,5 +8,9 @@ CCompiledFunc::CCompiledFunc( const CCodeBlock & CodeBlock ) :
m_Hash(CodeBlock.Hash()), m_Hash(CodeBlock.Hash()),
m_Next(NULL) m_Next(NULL)
{ {
m_MemContents[0] = CodeBlock.MemContents(0);
m_MemContents[1] = CodeBlock.MemContents(1);
m_MemLocation[0] = CodeBlock.MemLocation(0);
m_MemLocation[1] = CodeBlock.MemLocation(1);
} }

View File

@ -17,6 +17,10 @@ public:
inline CCompiledFunc * Next ( void ) const { return m_Next; } inline CCompiledFunc * Next ( void ) const { return m_Next; }
inline void SetNext ( CCompiledFunc * Next ) { m_Next = Next; } inline void SetNext ( CCompiledFunc * Next ) { m_Next = Next; }
inline QWORD MemContents(int i) { return m_MemContents[i]; }
inline QWORD * MemLocation(int i) { return m_MemLocation[i]; }
private: private:
//Information //Information
DWORD m_EnterPC; // The Entry PC DWORD m_EnterPC; // The Entry PC
@ -30,7 +34,7 @@ private:
CCompiledFunc * m_Next; CCompiledFunc * m_Next;
//Validation //Validation
//QWORD MemContents[2], * MemLocation[2]; QWORD m_MemContents[2], * m_MemLocation[2];
}; };
typedef std::map<DWORD, CCompiledFunc *> CCompiledFuncList; typedef std::map<DWORD, CCompiledFunc *> CCompiledFuncList;

View File

@ -52,7 +52,23 @@ void CRecompiler::Run()
} }
else else
{ {
RecompilerMain_Lookup(); CInterpreterCPU::BuildCPU();
if (bUseTlb())
{
if (bSMM_ValidFunc())
{
RecompilerMain_Lookup_validate_TLB();
} else {
RecompilerMain_Lookup_TLB();
}
} else {
if (bSMM_ValidFunc())
{
RecompilerMain_Lookup_validate();
} else {
RecompilerMain_Lookup();
}
}
} }
} }
__except( _MMU->MemoryFilter( GetExceptionCode(), GetExceptionInformation()) ) __except( _MMU->MemoryFilter( GetExceptionCode(), GetExceptionInformation()) )
@ -293,92 +309,39 @@ void CRecompiler::RecompilerMain_VirtualTable_validate ( void )
void CRecompiler::RecompilerMain_Lookup( void ) void CRecompiler::RecompilerMain_Lookup( void )
{ {
DWORD PhysicalAddr; while(!m_EndEmulation)
CInterpreterCPU::BuildCPU();
if (bUseTlb())
{ {
while(!m_EndEmulation) DWORD PhysicalAddr = PROGRAM_COUNTER & 0x1FFFFFFF;
if (PhysicalAddr < RdramSize())
{ {
if (!_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr)) CCompiledFunc * info = JumpTable()[PhysicalAddr >> 2];
if (info == NULL)
{ {
_Reg->DoTLBMiss(false,PROGRAM_COUNTER); info = CompilerCode();
if (!_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr)) if (info == NULL || m_EndEmulation)
{ {
DisplayError("Failed to translate PC to a PAddr: %X\n\nEmulation stopped",PROGRAM_COUNTER); break;
m_EndEmulation = true;
} }
continue; if (bSMM_Protect())
{
_MMU->ProtectMemory(PROGRAM_COUNTER & ~0xFFF,PROGRAM_COUNTER | 0xFFF);
}
JumpTable()[PhysicalAddr >> 2] = info;
} }
if (PhysicalAddr < RdramSize()) (info->Function())();
} else {
DWORD opsExecuted = 0;
while (_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= RdramSize())
{ {
CCompiledFunc * info = JumpTable()[PhysicalAddr >> 2]; CInterpreterCPU::ExecuteOps(CountPerOp());
opsExecuted += CountPerOp();
if (info == NULL)
{
info = CompilerCode();
if (info == NULL || m_EndEmulation)
{
break;
}
if (bSMM_Protect())
{
_MMU->ProtectMemory(PROGRAM_COUNTER & ~0xFFF,PROGRAM_COUNTER | 0xFFF);
}
JumpTable()[PhysicalAddr >> 2] = info;
}
(info->Function())();
} else {
DWORD opsExecuted = 0;
while (_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= RdramSize())
{
CInterpreterCPU::ExecuteOps(CountPerOp());
opsExecuted += CountPerOp();
}
if (_SyncSystem)
{
_System->UpdateSyncCPU(_SyncSystem,opsExecuted);
_System->SyncCPU(_SyncSystem);
}
} }
}
} else { if (_SyncSystem)
while(!m_EndEmulation)
{
PhysicalAddr = PROGRAM_COUNTER & 0x1FFFFFFF;
if (PhysicalAddr < RdramSize())
{ {
CCompiledFunc * info = JumpTable()[PhysicalAddr >> 2]; _System->UpdateSyncCPU(_SyncSystem,opsExecuted);
if (info == NULL) _System->SyncCPU(_SyncSystem);
{
info = CompilerCode();
if (info == NULL || m_EndEmulation)
{
break;
}
if (bSMM_Protect())
{
_MMU->ProtectMemory(PROGRAM_COUNTER & ~0xFFF,PROGRAM_COUNTER | 0xFFF);
}
JumpTable()[PhysicalAddr >> 2] = info;
}
(info->Function())();
} else {
DWORD opsExecuted = 0;
while (_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= RdramSize())
{
CInterpreterCPU::ExecuteOps(CountPerOp());
opsExecuted += CountPerOp();
}
if (_SyncSystem)
{
_System->UpdateSyncCPU(_SyncSystem,opsExecuted);
_System->SyncCPU(_SyncSystem);
}
} }
} }
} }
@ -534,6 +497,161 @@ void CRecompiler::RecompilerMain_Lookup( void )
}*/ }*/
} }
void CRecompiler::RecompilerMain_Lookup_TLB( void )
{
DWORD PhysicalAddr;
while(!m_EndEmulation)
{
if (!_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr))
{
_Reg->DoTLBMiss(false,PROGRAM_COUNTER);
if (!_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr))
{
DisplayError("Failed to translate PC to a PAddr: %X\n\nEmulation stopped",PROGRAM_COUNTER);
m_EndEmulation = true;
}
continue;
}
if (PhysicalAddr < RdramSize())
{
CCompiledFunc * info = JumpTable()[PhysicalAddr >> 2];
if (info == NULL)
{
info = CompilerCode();
if (info == NULL || m_EndEmulation)
{
break;
}
if (bSMM_Protect())
{
_MMU->ProtectMemory(PROGRAM_COUNTER & ~0xFFF,PROGRAM_COUNTER | 0xFFF);
}
JumpTable()[PhysicalAddr >> 2] = info;
}
(info->Function())();
} else {
DWORD opsExecuted = 0;
while (_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= RdramSize())
{
CInterpreterCPU::ExecuteOps(CountPerOp());
opsExecuted += CountPerOp();
}
if (_SyncSystem)
{
_System->UpdateSyncCPU(_SyncSystem,opsExecuted);
_System->SyncCPU(_SyncSystem);
}
}
}
}
void CRecompiler::RecompilerMain_Lookup_validate( void )
{
while(!m_EndEmulation)
{
DWORD PhysicalAddr = PROGRAM_COUNTER & 0x1FFFFFFF;
if (PhysicalAddr < RdramSize())
{
CCompiledFunc * info = JumpTable()[PhysicalAddr >> 2];
if (info == NULL)
{
info = CompilerCode();
if (info == NULL || m_EndEmulation)
{
break;
}
if (bSMM_Protect())
{
_MMU->ProtectMemory(PROGRAM_COUNTER & ~0xFFF,PROGRAM_COUNTER | 0xFFF);
}
JumpTable()[PhysicalAddr >> 2] = info;
} else {
if (*(info->MemLocation(0)) != info->MemContents(0) ||
*(info->MemLocation(1)) != info->MemContents(1))
{
ClearRecompCode_Virt((info->EnterPC() - 0x1000) & ~0xFFF,0x3000,Remove_ValidateFunc);
info = NULL;
continue;
}
}
(info->Function())();
} else {
DWORD opsExecuted = 0;
while (_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= RdramSize())
{
CInterpreterCPU::ExecuteOps(CountPerOp());
opsExecuted += CountPerOp();
}
if (_SyncSystem)
{
_System->UpdateSyncCPU(_SyncSystem,opsExecuted);
_System->SyncCPU(_SyncSystem);
}
}
}
}
void CRecompiler::RecompilerMain_Lookup_validate_TLB( void )
{
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
DWORD PhysicalAddr;
while(!m_EndEmulation)
{
if (!_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr))
{
_Reg->DoTLBMiss(false,PROGRAM_COUNTER);
if (!_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr))
{
DisplayError("Failed to translate PC to a PAddr: %X\n\nEmulation stopped",PROGRAM_COUNTER);
m_EndEmulation = true;
}
continue;
}
if (PhysicalAddr < RdramSize())
{
CCompiledFunc * info = JumpTable()[PhysicalAddr >> 2];
if (info == NULL)
{
info = CompilerCode();
if (info == NULL || m_EndEmulation)
{
break;
}
if (bSMM_Protect())
{
_MMU->ProtectMemory(PROGRAM_COUNTER & ~0xFFF,PROGRAM_COUNTER | 0xFFF);
}
JumpTable()[PhysicalAddr >> 2] = info;
}
(info->Function())();
} else {
DWORD opsExecuted = 0;
while (_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= RdramSize())
{
CInterpreterCPU::ExecuteOps(CountPerOp());
opsExecuted += CountPerOp();
}
if (_SyncSystem)
{
_System->UpdateSyncCPU(_SyncSystem,opsExecuted);
_System->SyncCPU(_SyncSystem);
}
}
}
#endif
}
void CRecompiler::Reset() void CRecompiler::Reset()
{ {
ResetRecompCode(); ResetRecompCode();

View File

@ -57,9 +57,11 @@ private:
// Main loops for the different look up methods // Main loops for the different look up methods
void RecompilerMain_VirtualTable ( void ); void RecompilerMain_VirtualTable ( void );
void RecompilerMain_VirtualTable_validate ( void ); void RecompilerMain_VirtualTable_validate ( void );
void RecompilerMain_ChangeMemory ( void ); void RecompilerMain_ChangeMemory ( void );
void RecompilerMain_Lookup ( void ); void RecompilerMain_Lookup ( void );
void RecompilerMain_Lookup_TLB ( void ); void RecompilerMain_Lookup_TLB ( void );
void RecompilerMain_Lookup_validate ( void );
void RecompilerMain_Lookup_validate_TLB ( void );
void RemoveFunction (CCompiledFunc * FunInfo, bool DelaySlot, REMOVE_REASON Reason ); void RemoveFunction (CCompiledFunc * FunInfo, bool DelaySlot, REMOVE_REASON Reason );
}; };