[Android] Fix CArmRecompilerOps::CompileReadTLBMiss

This commit is contained in:
zilmar 2016-10-06 22:59:03 +11:00
parent a278a2cde6
commit 1686e60b26
4 changed files with 92 additions and 24 deletions

View File

@ -380,11 +380,54 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
{
if ((int32_t)(MemAddress) < 0 || MemAddress > 0x1FFFFFFF)
{
ArmThumbOpcode * OpCode = (ArmThumbOpcode *)context.arm_pc;
Arm32Opcode * OpCode32 = (Arm32Opcode *)context.arm_pc;
WriteTrace(TraceExceptionHandler, TraceError, "Invalid memory adderess: %X", MemAddress);
if (bHaveDebugger())
WriteTrace(TraceExceptionHandler, TraceError, "Program Counter 0x%lx", g_Reg->m_PROGRAM_COUNTER);
for (int i = 0, n = (sizeof(g_BaseSystem->m_LastSuccessSyncPC) / sizeof(g_BaseSystem->m_LastSuccessSyncPC[0])); i < n; i++)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
WriteTrace(TraceExceptionHandler, TraceError, "m_LastSuccessSyncPC[%d] = 0x%lx", i, g_BaseSystem->m_LastSuccessSyncPC[i]);
}
WriteTrace(TraceExceptionHandler, TraceError, "MemAddress = 0x%lx", MemAddress);
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r0 = 0x%lx", context.arm_r0);
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r1 = 0x%lx", context.arm_r1);
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r2 = 0x%lx", context.arm_r2);
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r3 = 0x%lx", context.arm_r3);
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r4 = 0x%lx", context.arm_r4);
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r5 = 0x%lx", context.arm_r5);
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r6 = 0x%lx", context.arm_r6);
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r7 = 0x%lx", context.arm_r7);
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r8 = 0x%lx", context.arm_r8);
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r9 = 0x%lx", context.arm_r9);
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r10 = 0x%lx", context.arm_r10);
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_fp = 0x%lx", context.arm_fp);
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_ip = 0x%lx", context.arm_ip);
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_sp = 0x%lx", context.arm_sp);
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_lr = 0x%lx", context.arm_lr);
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_pc = 0x%lx", context.arm_pc);
uint8_t * TypePos = (uint8_t *)context.arm_pc;
WriteTrace(TraceExceptionHandler, TraceError, "TypePos: %02X %02X %02X %02X %02X %02X %02X %02X %02X",TypePos[0],TypePos[1],TypePos[2],TypePos[3],TypePos[4],TypePos[5],TypePos[6],TypePos[7],TypePos[8]);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode.Hex: %X",OpCode->Hex);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode.opcode: %X",OpCode->Reg.opcode);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode.rm: %X",OpCode->Reg.rm);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode.rn: %X",OpCode->Reg.rn);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode.rt: %X",OpCode->Reg.rt);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32.Hex: %X",OpCode32->Hex);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint16.opcode: %X",OpCode32->uint16.opcode);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint16.rm: %X",OpCode32->uint16.rm);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint16.rn: %X",OpCode32->uint16.rn);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint16.rt: %X",OpCode32->uint16.rt);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint16.imm2: %X",OpCode32->uint16.imm2);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint32.opcode: %X",OpCode32->uint32.opcode);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint32.rn: %X",OpCode32->uint32.rn);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint32.rt: %X",OpCode32->uint32.rt);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint32.opcode2: %X",OpCode32->uint32.opcode2);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint32.rm: %X",OpCode32->uint32.rm);
g_Notify->BreakPoint(__FILE__, __LINE__);
return false;
}
@ -646,16 +689,16 @@ void CMipsMemoryVM::segv_handler(int signal, siginfo_t *siginfo, void *sigcontex
WriteTrace(TraceExceptionHandler, TraceNotice, "%s: si_addr: %p",__FUNCTION__, siginfo->si_addr);
uint32_t MemAddress = (char *)siginfo->si_addr - (char *)g_MMU->Rdram();
WriteTrace(TraceExceptionHandler, TraceNotice, "MemAddress = %X",MemAddress);
WriteTrace(TraceExceptionHandler, TraceNotice, "MemAddress = %X", MemAddress);
#ifdef __i386__
for(int i = 0; i < NGREG; i++)
for (int i = 0; i < NGREG; i++)
{
WriteTrace(TraceExceptionHandler, TraceNotice, "reg[%02d] = 0x%08x", i, ucontext->uc_mcontext.gregs[i]);
}
WriteTrace(TraceExceptionHandler, TraceNotice, "REG_EIP = %X", ucontext->uc_mcontext.gregs[REG_EIP]);
uint8_t * TypePos = (uint8_t *)ucontext->uc_mcontext.gregs[REG_EIP];
WriteTrace(TraceExceptionHandler, TraceNotice, "TypePos: %02X %02X %02X %02X %02X %02X %02X %02X %02X",TypePos[0],TypePos[1],TypePos[2],TypePos[3],TypePos[4],TypePos[5],TypePos[6],TypePos[7],TypePos[8]);
WriteTrace(TraceExceptionHandler, TraceNotice, "TypePos: %02X %02X %02X %02X %02X %02X %02X %02X %02X", TypePos[0], TypePos[1], TypePos[2], TypePos[3], TypePos[4], TypePos[5], TypePos[6], TypePos[7], TypePos[8]);
X86_CONTEXT context;
context.Edi = (uint32_t*)&ucontext->uc_mcontext.gregs[REG_EDI];
@ -668,14 +711,14 @@ void CMipsMemoryVM::segv_handler(int signal, siginfo_t *siginfo, void *sigcontex
context.Esp = (uint32_t*)&ucontext->uc_mcontext.gregs[REG_ESP];
context.Ebp = (uint32_t*)&ucontext->uc_mcontext.gregs[REG_EBP];
if (FilterX86Exception(MemAddress,context))
if (FilterX86Exception(MemAddress, context))
{
WriteTrace(TraceExceptionHandler, TraceNotice, "Success!");
WriteTrace(TraceExceptionHandler, TraceNotice, "REG_EIP = %X", ucontext->uc_mcontext.gregs[REG_EIP]);
return;
}
#elif defined(__arm__)
if (FilterArmException(MemAddress,ucontext->uc_mcontext))
if (FilterArmException(MemAddress, ucontext->uc_mcontext))
{
WriteTrace(TraceExceptionHandler, TraceNotice, "Success!");
return;

View File

@ -4198,6 +4198,10 @@ void CArmRecompilerOps::SyncRegState(const CRegInfo & SyncTo)
void CArmRecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo &ExitRegSet, CExitInfo::EXIT_REASON reason)
{
m_RegWorkingSet = ExitRegSet;
for (int32_t i = 0; i < 16; i++)
{
m_RegWorkingSet.SetArmRegProtected((ArmReg)i, false);
}
m_RegWorkingSet.WriteBackRegisters();
ExitRegSet = m_RegWorkingSet;
@ -4253,6 +4257,14 @@ void CArmRecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo
CallFunction(AddressOf(&CRegisters::DoCopUnusableException), "CRegisters::DoCopUnusableException");
ExitCodeBlock();
break;
case CExitInfo::TLBReadMiss:
bDelay = m_NextInstruction == JUMP || m_NextInstruction == DELAY_SLOT;
MoveVariableToArmReg(g_TLBLoadAddress, "g_TLBLoadAddress",Arm_R2);
MoveConstToArmReg(Arm_R1, (uint32_t)bDelay, bDelay ? "true" : "false");
MoveConstToArmReg(Arm_R0, (uint32_t)g_Reg);
CallFunction(AddressOf(&CRegisters::DoTLBReadMiss), "CRegisters::DoTLBReadMiss");
ExitCodeBlock();
break;
default:
g_Notify->BreakPoint(__FILE__, __LINE__);
}
@ -4303,7 +4315,14 @@ void CArmRecompilerOps::CompileSystemCheck(uint32_t TargetPC, const CRegInfo & R
void CArmRecompilerOps::CompileReadTLBMiss(ArmReg AddressReg, ArmReg LookUpReg)
{
CPU_Message("%s: todo",__FUNCTION__);
m_RegWorkingSet.SetArmRegProtected(AddressReg, true);
m_RegWorkingSet.SetArmRegProtected(LookUpReg, true);
ArmReg TlbLoadReg = Map_Variable(CArmRegInfo::VARIABLE_TLB_LOAD_ADDRESS);
StoreArmRegToArmRegPointer(AddressReg, TlbLoadReg, 0);
CompareArmRegToConst(LookUpReg, 0);
CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, CExitInfo::TLBReadMiss, ArmBranch_Equal);
m_RegWorkingSet.SetArmRegProtected(TlbLoadReg, false);
}
CRegInfo & CArmRecompilerOps::GetRegWorkingSet(void)

View File

@ -285,11 +285,11 @@ void CArmRegInfo::Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad)
SetArmRegProtected(regHi, true);
reglo = FreeArmReg();
if (reglo < 0)
if (reglo < 0)
{
if (bHaveDebugger()) { g_Notify->DisplayError("Map_GPR_64bit\n\nOut of registers"); }
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
return;
}
SetArmRegProtected(reglo, true);
@ -303,7 +303,7 @@ void CArmRegInfo::Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad)
{
SetArmRegProtected(reglo, true);
regHi = FreeArmReg();
if (regHi < 0)
if (regHi < 0)
{
if (bHaveDebugger()) { g_Notify->DisplayError("Map_GPR_64bit\n\nOut of registers"); }
g_Notify->BreakPoint(__FILE__, __LINE__);
@ -346,16 +346,16 @@ void CArmRegInfo::Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad)
g_Notify->BreakPoint(__FILE__, __LINE__);
/*if (IsSigned(MipsRegToLoad))
{
MoveX86RegToX86Reg(GetMipsRegMapLo(MipsRegToLoad), x86Hi);
ShiftRightSignImmed(x86Hi, 31);
MoveX86RegToX86Reg(GetMipsRegMapLo(MipsRegToLoad), x86Hi);
ShiftRightSignImmed(x86Hi, 31);
}
else
{
XorX86RegToX86Reg(x86Hi, x86Hi);
XorX86RegToX86Reg(x86Hi, x86Hi);
}
if (MipsReg != MipsRegToLoad)
{
MoveX86RegToX86Reg(GetMipsRegMapLo(MipsRegToLoad), x86lo);
MoveX86RegToX86Reg(GetMipsRegMapLo(MipsRegToLoad), x86lo);
}*/
}
else if (MipsReg != MipsRegToLoad)
@ -371,18 +371,18 @@ void CArmRegInfo::Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad)
/*CPU_Message("Map_GPR_64bit 11");
if (Is32Bit(MipsRegToLoad))
{
if (IsSigned(MipsRegToLoad))
{
MoveConstToX86reg(GetMipsRegLo_S(MipsRegToLoad) >> 31, x86Hi);
}
else
{
MoveConstToX86reg(0, x86Hi);
}
if (IsSigned(MipsRegToLoad))
{
MoveConstToX86reg(GetMipsRegLo_S(MipsRegToLoad) >> 31, x86Hi);
}
else
{
MoveConstToX86reg(GetMipsRegHi(MipsRegToLoad), x86Hi);
MoveConstToX86reg(0, x86Hi);
}
}
else
{
MoveConstToX86reg(GetMipsRegHi(MipsRegToLoad), x86Hi);
}
MoveConstToX86reg(GetMipsRegLo(MipsRegToLoad), x86lo);*/
}
@ -898,6 +898,11 @@ CArmOps::ArmReg CArmRegInfo::Map_Variable(VARIABLE_MAPPED variable)
m_Variable_MappedTo[Reg] = variable;
MoveConstToArmReg(Reg, (uint32_t)(g_NextTimer), "g_NextTimer");
break;
case VARIABLE_TLB_LOAD_ADDRESS:
CPU_Message(" regcache: allocate %s as pointer to g_TLBLoadAddress", ArmRegName(Reg));
m_Variable_MappedTo[Reg] = variable;
MoveConstToArmReg(Reg, (uint32_t)(g_TLBLoadAddress), "g_TLBLoadAddress");
break;
default:
g_Notify->BreakPoint(__FILE__, __LINE__);
return Arm_Unknown;

View File

@ -38,6 +38,7 @@ public:
VARIABLE_FPR = 2,
VARIABLE_TLB_READMAP = 3,
VARIABLE_NEXT_TIMER = 4,
VARIABLE_TLB_LOAD_ADDRESS = 5,
};
CArmRegInfo();