nativetrace.cc revision 6724
12810Srdreslin@umich.edu/* 22810Srdreslin@umich.edu * Copyright (c) 2006 The Regents of The University of Michigan 32810Srdreslin@umich.edu * All rights reserved. 42810Srdreslin@umich.edu * 52810Srdreslin@umich.edu * Redistribution and use in source and binary forms, with or without 62810Srdreslin@umich.edu * modification, are permitted provided that the following conditions are 72810Srdreslin@umich.edu * met: redistributions of source code must retain the above copyright 82810Srdreslin@umich.edu * notice, this list of conditions and the following disclaimer; 92810Srdreslin@umich.edu * redistributions in binary form must reproduce the above copyright 102810Srdreslin@umich.edu * notice, this list of conditions and the following disclaimer in the 112810Srdreslin@umich.edu * documentation and/or other materials provided with the distribution; 122810Srdreslin@umich.edu * neither the name of the copyright holders nor the names of its 132810Srdreslin@umich.edu * contributors may be used to endorse or promote products derived from 142810Srdreslin@umich.edu * this software without specific prior written permission. 152810Srdreslin@umich.edu * 162810Srdreslin@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172810Srdreslin@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182810Srdreslin@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192810Srdreslin@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202810Srdreslin@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212810Srdreslin@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222810Srdreslin@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232810Srdreslin@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242810Srdreslin@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252810Srdreslin@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262810Srdreslin@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272810Srdreslin@umich.edu * 282810Srdreslin@umich.edu * Authors: Gabe Black 292810Srdreslin@umich.edu */ 302810Srdreslin@umich.edu 312810Srdreslin@umich.edu#include "arch/arm/isa_traits.hh" 322810Srdreslin@umich.edu#include "arch/arm/miscregs.hh" 332810Srdreslin@umich.edu#include "arch/arm/nativetrace.hh" 342810Srdreslin@umich.edu#include "cpu/thread_context.hh" 352810Srdreslin@umich.edu#include "params/ArmNativeTrace.hh" 362810Srdreslin@umich.edu 372810Srdreslin@umich.edunamespace Trace { 382810Srdreslin@umich.edu 392810Srdreslin@umich.edu#if TRACING_ON 402810Srdreslin@umich.edustatic const char *regNames[] = { 415338Sstever@gmail.com "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 422810Srdreslin@umich.edu "r8", "r9", "r10", "fp", "r12", "sp", "lr", "pc", 432810Srdreslin@umich.edu "cpsr" 445338Sstever@gmail.com}; 452810Srdreslin@umich.edu#endif 462810Srdreslin@umich.edu 472810Srdreslin@umich.eduvoid 482810Srdreslin@umich.eduTrace::ArmNativeTrace::ThreadState::update(NativeTrace *parent) 492810Srdreslin@umich.edu{ 502810Srdreslin@umich.edu oldState = state[current]; 512810Srdreslin@umich.edu current = (current + 1) % 2; 522810Srdreslin@umich.edu newState = state[current]; 532810Srdreslin@umich.edu 542810Srdreslin@umich.edu memcpy(newState, oldState, sizeof(state[0])); 552810Srdreslin@umich.edu 562810Srdreslin@umich.edu uint32_t diffVector; 572810Srdreslin@umich.edu parent->read(&diffVector, sizeof(diffVector)); 582810Srdreslin@umich.edu diffVector = ArmISA::gtoh(diffVector); 592810Srdreslin@umich.edu 602810Srdreslin@umich.edu int changes = 0; 612810Srdreslin@umich.edu for (int i = 0; i < STATE_NUMVALS; i++) { 622810Srdreslin@umich.edu if (diffVector & 0x1) { 632810Srdreslin@umich.edu changed[i] = true; 642810Srdreslin@umich.edu changes++; 652810Srdreslin@umich.edu } else { 662810Srdreslin@umich.edu changed[i] = false; 672810Srdreslin@umich.edu } 682810Srdreslin@umich.edu diffVector >>= 1; 692810Srdreslin@umich.edu } 702810Srdreslin@umich.edu 712810Srdreslin@umich.edu uint32_t values[changes]; 722810Srdreslin@umich.edu parent->read(values, sizeof(values)); 732810Srdreslin@umich.edu int pos = 0; 742810Srdreslin@umich.edu for (int i = 0; i < STATE_NUMVALS; i++) { 752810Srdreslin@umich.edu if (changed[i]) { 762810Srdreslin@umich.edu newState[i] = ArmISA::gtoh(values[pos++]); 772810Srdreslin@umich.edu changed[i] = (newState[i] != oldState[i]); 782810Srdreslin@umich.edu } 792810Srdreslin@umich.edu } 802810Srdreslin@umich.edu} 812810Srdreslin@umich.edu 822810Srdreslin@umich.eduvoid 832810Srdreslin@umich.eduTrace::ArmNativeTrace::ThreadState::update(ThreadContext *tc) 842810Srdreslin@umich.edu{ 852810Srdreslin@umich.edu oldState = state[current]; 862810Srdreslin@umich.edu current = (current + 1) % 2; 872810Srdreslin@umich.edu newState = state[current]; 882810Srdreslin@umich.edu 892810Srdreslin@umich.edu // Regular int regs 902810Srdreslin@umich.edu for (int i = 0; i < 15; i++) { 912810Srdreslin@umich.edu newState[i] = tc->readIntReg(i); 922810Srdreslin@umich.edu changed[i] = (oldState[i] != newState[i]); 932810Srdreslin@umich.edu } 942810Srdreslin@umich.edu 952810Srdreslin@umich.edu //R15, aliased with the PC 962810Srdreslin@umich.edu newState[STATE_PC] = tc->readNextPC(); 972810Srdreslin@umich.edu changed[STATE_PC] = (newState[STATE_PC] != oldState[STATE_PC]); 982810Srdreslin@umich.edu 992810Srdreslin@umich.edu //CPSR 1002810Srdreslin@umich.edu newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR) | 1012810Srdreslin@umich.edu tc->readIntReg(INTREG_CONDCODES); 1022810Srdreslin@umich.edu changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]); 1032810Srdreslin@umich.edu} 1042810Srdreslin@umich.edu 1052810Srdreslin@umich.eduvoid 1062810Srdreslin@umich.eduTrace::ArmNativeTrace::check(NativeTraceRecord *record) 1072810Srdreslin@umich.edu{ 1082810Srdreslin@umich.edu ThreadContext *tc = record->getThread(); 1092810Srdreslin@umich.edu // This area is read only on the target. It can't stop there to tell us 1102810Srdreslin@umich.edu // what's going on, so we should skip over anything there also. 1112810Srdreslin@umich.edu if (tc->readNextPC() > 0xffff0000) 1122810Srdreslin@umich.edu return; 1132810Srdreslin@umich.edu nState.update(this); 1142810Srdreslin@umich.edu mState.update(tc); 1152810Srdreslin@umich.edu 1162810Srdreslin@umich.edu bool errorFound = false; 1172810Srdreslin@umich.edu // Regular int regs 1182810Srdreslin@umich.edu for (int i = 0; i < STATE_NUMVALS; i++) { 1192810Srdreslin@umich.edu if (nState.changed[i] || mState.changed[i]) { 1202810Srdreslin@umich.edu const char *vergence = " "; 1212810Srdreslin@umich.edu bool oldMatch = (mState.oldState[i] == nState.oldState[i]); 1222810Srdreslin@umich.edu bool newMatch = (mState.newState[i] == nState.newState[i]); 1232810Srdreslin@umich.edu if (oldMatch && newMatch) { 1242810Srdreslin@umich.edu // The more things change, the more they stay the same. 1252810Srdreslin@umich.edu continue; 1262810Srdreslin@umich.edu } else if (oldMatch && !newMatch) { 1272810Srdreslin@umich.edu vergence = "<>"; 1282810Srdreslin@umich.edu } else if (!oldMatch && newMatch) { 1292810Srdreslin@umich.edu vergence = "><"; 1302810Srdreslin@umich.edu } 1312810Srdreslin@umich.edu errorFound = true; 1322810Srdreslin@umich.edu if (!nState.changed[i]) { 1332810Srdreslin@umich.edu DPRINTF(ExecRegDelta, "%s [%5s] "\ 1342810Srdreslin@umich.edu "Native: %#010x "\ 1352810Srdreslin@umich.edu "M5: %#010x => %#010x\n", 1362810Srdreslin@umich.edu vergence, regNames[i], 1372810Srdreslin@umich.edu nState.newState[i], 1382810Srdreslin@umich.edu mState.oldState[i], mState.newState[i]); 1392810Srdreslin@umich.edu } else if (!mState.changed[i]) { 1402810Srdreslin@umich.edu DPRINTF(ExecRegDelta, "%s [%5s] "\ 1412810Srdreslin@umich.edu "Native: %#010x => %#010x "\ 1422810Srdreslin@umich.edu "M5: %#010x \n", 1432810Srdreslin@umich.edu vergence, regNames[i], 1442810Srdreslin@umich.edu nState.oldState[i], nState.newState[i], 1452810Srdreslin@umich.edu mState.newState[i]); 1462810Srdreslin@umich.edu } else { 1472810Srdreslin@umich.edu DPRINTF(ExecRegDelta, "%s [%5s] "\ 1482810Srdreslin@umich.edu "Native: %#010x => %#010x "\ 1492810Srdreslin@umich.edu "M5: %#010x => %#010x\n", 1502810Srdreslin@umich.edu vergence, regNames[i], 1512810Srdreslin@umich.edu nState.oldState[i], nState.newState[i], 1522810Srdreslin@umich.edu mState.oldState[i], mState.newState[i]); 1532810Srdreslin@umich.edu } 1542810Srdreslin@umich.edu } 1552810Srdreslin@umich.edu } 1562810Srdreslin@umich.edu if (errorFound) { 1572810Srdreslin@umich.edu StaticInstPtr inst = record->getStaticInst(); 1582810Srdreslin@umich.edu assert(inst); 1592810Srdreslin@umich.edu bool ran = true; 1602810Srdreslin@umich.edu if (inst->isMicroop()) { 1612810Srdreslin@umich.edu ran = false; 1622810Srdreslin@umich.edu inst = record->getMacroStaticInst(); 1632810Srdreslin@umich.edu } 1642810Srdreslin@umich.edu assert(inst); 1652810Srdreslin@umich.edu record->traceInst(inst, ran); 1662810Srdreslin@umich.edu 1672810Srdreslin@umich.edu bool pcError = (mState.newState[STATE_PC] != 1683862Sstever@eecs.umich.edu nState.newState[STATE_PC]); 1693862Sstever@eecs.umich.edu if (stopOnPCError && pcError) 1702810Srdreslin@umich.edu panic("Native trace detected an error in control flow!"); 1713862Sstever@eecs.umich.edu } 1722810Srdreslin@umich.edu} 1732810Srdreslin@umich.edu 1745716Shsul@eecs.umich.edu} /* namespace Trace */ 1755716Shsul@eecs.umich.edu 1765716Shsul@eecs.umich.edu//////////////////////////////////////////////////////////////////////// 1775716Shsul@eecs.umich.edu// 1782810Srdreslin@umich.edu// ExeTracer Simulation Object 1792810Srdreslin@umich.edu// 1802810Srdreslin@umich.eduTrace::ArmNativeTrace * 1812810Srdreslin@umich.eduArmNativeTraceParams::create() 1822810Srdreslin@umich.edu{ 1832810Srdreslin@umich.edu return new Trace::ArmNativeTrace(this); 1845716Shsul@eecs.umich.edu}; 1852810Srdreslin@umich.edu