exetrace.cc revision 3970:d54945bab95d
1/* 2 * Copyright (c) 2001-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Steve Reinhardt 29 * Lisa Hsu 30 * Nathan Binkert 31 * Steve Raasch 32 */ 33 34#include <fstream> 35#include <iomanip> 36#include <sys/ipc.h> 37#include <sys/shm.h> 38 39#include "arch/regfile.hh" 40#include "arch/utility.hh" 41#include "base/loader/symtab.hh" 42#include "config/full_system.hh" 43#include "cpu/base.hh" 44#include "cpu/exetrace.hh" 45#include "cpu/static_inst.hh" 46#include "sim/param.hh" 47#include "sim/system.hh" 48 49#if FULL_SYSTEM 50#include "arch/tlb.hh" 51#endif 52 53//XXX This is temporary 54#include "arch/isa_specific.hh" 55#include "cpu/m5legion_interface.h" 56 57using namespace std; 58using namespace TheISA; 59 60#if THE_ISA == SPARC_ISA && FULL_SYSTEM 61static int diffcount = 0; 62#endif 63 64namespace Trace { 65SharedData *shared_data = NULL; 66} 67 68//////////////////////////////////////////////////////////////////////// 69// 70// Methods for the InstRecord object 71// 72 73#if THE_ISA == SPARC_ISA 74 75inline char * genCenteredLabel(int length, char * buffer, char * label) 76{ 77 int labelLength = strlen(label); 78 assert(labelLength <= length); 79 int leftPad = (length - labelLength) / 2; 80 int rightPad = length - leftPad - labelLength; 81 char format[64]; 82 sprintf(format, "%%%ds%%s%%%ds", leftPad, rightPad); 83 sprintf(buffer, format, "", label, ""); 84 return buffer; 85} 86 87inline void printRegPair(ostream & os, char const * title, uint64_t a, uint64_t b) 88{ 89 ccprintf(os, " %16s | %#018x %s %#-018x \n", 90 title, a, (a == b) ? "|" : "X", b); 91} 92 93inline void printColumnLabels(ostream & os) 94{ 95 static char * regLabel = genCenteredLabel(16, new char[17], "Register"); 96 static char * m5Label = genCenteredLabel(18, new char[18], "M5"); 97 static char * legionLabel = genCenteredLabel(18, new char[18], "Legion"); 98 ccprintf(os, " %s | %s | %s \n", regLabel, m5Label, legionLabel); 99 ccprintf(os, "--------------------+-----------------------+-----------------------\n"); 100} 101 102inline void printSectionHeader(ostream & os, char * name) 103{ 104 char sectionString[70]; 105 genCenteredLabel(69, sectionString, name); 106 ccprintf(os, "====================================================================\n"); 107 ccprintf(os, "%69s\n", sectionString); 108 ccprintf(os, "====================================================================\n"); 109} 110 111inline void printLevelHeader(ostream & os, int level) 112{ 113 char sectionString[70]; 114 char levelName[70]; 115 sprintf(levelName, "Trap stack level %d", level); 116 genCenteredLabel(69, sectionString, levelName); 117 ccprintf(os, "====================================================================\n"); 118 ccprintf(os, "%69s\n", sectionString); 119 ccprintf(os, "====================================================================\n"); 120} 121 122#endif 123 124void 125Trace::InstRecord::dump(ostream &outs) 126{ 127 if (flags[PRINT_REG_DELTA]) 128 { 129#if THE_ISA == SPARC_ISA 130 //Don't print what happens for each micro-op, just print out 131 //once at the last op, and for regular instructions. 132 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) 133 { 134 static uint64_t regs[32] = { 135 0, 0, 0, 0, 0, 0, 0, 0, 136 0, 0, 0, 0, 0, 0, 0, 0, 137 0, 0, 0, 0, 0, 0, 0, 0, 138 0, 0, 0, 0, 0, 0, 0, 0}; 139 static uint64_t ccr = 0; 140 static uint64_t y = 0; 141 static uint64_t floats[32]; 142 uint64_t newVal; 143 static const char * prefixes[4] = {"G", "O", "L", "I"}; 144 145 outs << hex; 146 outs << "PC = " << thread->readNextPC(); 147 outs << " NPC = " << thread->readNextNPC(); 148 newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2); 149 //newVal = thread->readMiscReg(SparcISA::MISCREG_CCR); 150 if(newVal != ccr) 151 { 152 outs << " CCR = " << newVal; 153 ccr = newVal; 154 } 155 newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 1); 156 //newVal = thread->readMiscReg(SparcISA::MISCREG_Y); 157 if(newVal != y) 158 { 159 outs << " Y = " << newVal; 160 y = newVal; 161 } 162 for(int y = 0; y < 4; y++) 163 { 164 for(int x = 0; x < 8; x++) 165 { 166 int index = x + 8 * y; 167 newVal = thread->readIntReg(index); 168 if(regs[index] != newVal) 169 { 170 outs << " " << prefixes[y] << dec << x << " = " << hex << newVal; 171 regs[index] = newVal; 172 } 173 } 174 } 175 for(int y = 0; y < 32; y++) 176 { 177 newVal = thread->readFloatRegBits(2 * y, 64); 178 if(floats[y] != newVal) 179 { 180 outs << " F" << dec << (2 * y) << " = " << hex << newVal; 181 floats[y] = newVal; 182 } 183 } 184 outs << dec << endl; 185 } 186#endif 187 } 188 else if (flags[INTEL_FORMAT]) { 189#if FULL_SYSTEM 190 bool is_trace_system = (thread->getCpuPtr()->system->name() == trace_system); 191#else 192 bool is_trace_system = true; 193#endif 194 if (is_trace_system) { 195 ccprintf(outs, "%7d ) ", cycle); 196 outs << "0x" << hex << PC << ":\t"; 197 if (staticInst->isLoad()) { 198 outs << "<RD 0x" << hex << addr; 199 outs << ">"; 200 } else if (staticInst->isStore()) { 201 outs << "<WR 0x" << hex << addr; 202 outs << ">"; 203 } 204 outs << endl; 205 } 206 } else { 207 if (flags[PRINT_CYCLE]) 208 ccprintf(outs, "%7d: ", cycle); 209 210 outs << thread->getCpuPtr()->name() << " "; 211 212 if (flags[TRACE_MISSPEC]) 213 outs << (misspeculating ? "-" : "+") << " "; 214 215 if (flags[PRINT_THREAD_NUM]) 216 outs << "T" << thread->getThreadNum() << " : "; 217 218 219 std::string sym_str; 220 Addr sym_addr; 221 if (debugSymbolTable 222 && debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr) 223 && flags[PC_SYMBOL]) { 224 if (PC != sym_addr) 225 sym_str += csprintf("+%d", PC - sym_addr); 226 outs << "@" << sym_str << " : "; 227 } 228 else { 229 outs << "0x" << hex << PC << " : "; 230 } 231 232 // 233 // Print decoded instruction 234 // 235 236#if defined(__GNUC__) && (__GNUC__ < 3) 237 // There's a bug in gcc 2.x library that prevents setw() 238 // from working properly on strings 239 string mc(staticInst->disassemble(PC, debugSymbolTable)); 240 while (mc.length() < 26) 241 mc += " "; 242 outs << mc; 243#else 244 outs << setw(26) << left << staticInst->disassemble(PC, debugSymbolTable); 245#endif 246 247 outs << " : "; 248 249 if (flags[PRINT_OP_CLASS]) { 250 outs << opClassStrings[staticInst->opClass()] << " : "; 251 } 252 253 if (flags[PRINT_RESULT_DATA] && data_status != DataInvalid) { 254 outs << " D="; 255#if 0 256 if (data_status == DataDouble) 257 ccprintf(outs, "%f", data.as_double); 258 else 259 ccprintf(outs, "%#018x", data.as_int); 260#else 261 ccprintf(outs, "%#018x", data.as_int); 262#endif 263 } 264 265 if (flags[PRINT_EFF_ADDR] && addr_valid) 266 outs << " A=0x" << hex << addr; 267 268 if (flags[PRINT_INT_REGS] && regs_valid) { 269 for (int i = 0; i < TheISA::NumIntRegs;) 270 for (int j = i + 1; i <= j; i++) 271 ccprintf(outs, "r%02d = %#018x%s", i, 272 iregs->regs.readReg(i), 273 ((i == j) ? "\n" : " ")); 274 outs << "\n"; 275 } 276 277 if (flags[PRINT_FETCH_SEQ] && fetch_seq_valid) 278 outs << " FetchSeq=" << dec << fetch_seq; 279 280 if (flags[PRINT_CP_SEQ] && cp_seq_valid) 281 outs << " CPSeq=" << dec << cp_seq; 282 283 // 284 // End of line... 285 // 286 outs << endl; 287 } 288#if THE_ISA == SPARC_ISA && FULL_SYSTEM 289 // Compare 290 if (flags[LEGION_LOCKSTEP]) 291 { 292 bool compared = false; 293 bool diffPC = false; 294 bool diffCC = false; 295 bool diffInst = false; 296 bool diffRegs = false; 297 bool diffTpc = false; 298 bool diffTnpc = false; 299 bool diffTstate = false; 300 bool diffTt = false; 301 bool diffTba = false; 302 bool diffHpstate = false; 303 bool diffHtstate = false; 304 bool diffHtba = false; 305 bool diffPstate = false; 306 bool diffY = false; 307 bool diffCcr = false; 308 bool diffTl = false; 309 bool diffGl = false; 310 bool diffAsi = false; 311 bool diffPil = false; 312 bool diffCwp = false; 313 bool diffCansave = false; 314 bool diffCanrestore = false; 315 bool diffOtherwin = false; 316 bool diffCleanwin = false; 317 bool diffTlb = false; 318 Addr m5Pc, lgnPc; 319 320 321 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) { 322 while (!compared) { 323 if (shared_data->flags == OWN_M5) { 324 m5Pc = PC & TheISA::PAddrImplMask; 325 lgnPc = shared_data->pc & TheISA::PAddrImplMask; 326 if (lgnPc != m5Pc) 327 diffPC = true; 328 329 if (shared_data->cycle_count != 330 thread->getCpuPtr()->instCount()) 331 diffCC = true; 332 333 if (shared_data->instruction != 334 (SparcISA::MachInst)staticInst->machInst) { 335 diffInst = true; 336 } 337 for (int i = 0; i < TheISA::NumIntArchRegs; i++) { 338 if (thread->readIntReg(i) != shared_data->intregs[i]) { 339 diffRegs = true; 340 } 341 } 342 uint64_t oldTl = thread->readMiscReg(MISCREG_TL); 343 if (oldTl != shared_data->tl) 344 diffTl = true; 345 for (int i = 1; i <= MaxTL; i++) { 346 thread->setMiscReg(MISCREG_TL, i); 347 if (thread->readMiscReg(MISCREG_TPC) != 348 shared_data->tpc[i-1]) 349 diffTpc = true; 350 if (thread->readMiscReg(MISCREG_TNPC) != 351 shared_data->tnpc[i-1]) 352 diffTnpc = true; 353 if (thread->readMiscReg(MISCREG_TSTATE) != 354 shared_data->tstate[i-1]) 355 diffTstate = true; 356 if (thread->readMiscReg(MISCREG_TT) != 357 shared_data->tt[i-1]) 358 diffTt = true; 359 if (thread->readMiscReg(MISCREG_HTSTATE) != 360 shared_data->htstate[i-1]) 361 diffHtstate = true; 362 } 363 thread->setMiscReg(MISCREG_TL, oldTl); 364 365 if(shared_data->tba != thread->readMiscReg(MISCREG_TBA)) 366 diffTba = true; 367 //When the hpstate register is read by an instruction, 368 //legion has bit 11 set. When it's in storage, it doesn't. 369 //Since we don't directly support seperate interpretations 370 //of the registers like that, the bit is always set to 1 and 371 //we just don't compare it. It's not supposed to matter 372 //anyway. 373 if((shared_data->hpstate | (1 << 11)) != thread->readMiscReg(MISCREG_HPSTATE)) 374 diffHpstate = true; 375 if(shared_data->htba != thread->readMiscReg(MISCREG_HTBA)) 376 diffHtba = true; 377 if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE)) 378 diffPstate = true; 379 //if(shared_data->y != thread->readMiscReg(MISCREG_Y)) 380 if(shared_data->y != 381 thread->readIntReg(NumIntArchRegs + 1)) 382 diffY = true; 383 //if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR)) 384 if(shared_data->ccr != 385 thread->readIntReg(NumIntArchRegs + 2)) 386 diffCcr = true; 387 if(shared_data->gl != thread->readMiscReg(MISCREG_GL)) 388 diffGl = true; 389 if(shared_data->asi != thread->readMiscReg(MISCREG_ASI)) 390 diffAsi = true; 391 if(shared_data->pil != thread->readMiscReg(MISCREG_PIL)) 392 diffPil = true; 393 if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP)) 394 diffCwp = true; 395 //if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE)) 396 if(shared_data->cansave != 397 thread->readIntReg(NumIntArchRegs + 3)) 398 diffCansave = true; 399 //if(shared_data->canrestore != 400 // thread->readMiscReg(MISCREG_CANRESTORE)) 401 if(shared_data->canrestore != 402 thread->readMiscReg(NumIntArchRegs + 4)) 403 diffCanrestore = true; 404 //if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN)) 405 if(shared_data->otherwin != 406 thread->readIntReg(NumIntArchRegs + 5)) 407 diffOtherwin = true; 408 //if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN)) 409 if(shared_data->cleanwin != 410 thread->readMiscReg(NumIntArchRegs + 6)) 411 diffCleanwin = true; 412 413 for (int i = 0; i < 64; i++) { 414 if (shared_data->itb[i] != thread->getITBPtr()->TteRead(i)) 415 diffTlb = true; 416 if (shared_data->dtb[i] != thread->getDTBPtr()->TteRead(i)) 417 diffTlb = true; 418 } 419 420 if ((diffPC || diffCC || diffInst || diffRegs || diffTpc || 421 diffTnpc || diffTstate || diffTt || diffHpstate || 422 diffHtstate || diffHtba || diffPstate || diffY || 423 diffCcr || diffTl || diffGl || diffAsi || diffPil || 424 diffCwp || diffCansave || diffCanrestore || 425 diffOtherwin || diffCleanwin || diffTlb) 426 && !((staticInst->machInst & 0xC1F80000) == 0x81D00000) 427 && !(((staticInst->machInst & 0xC0000000) == 0xC0000000) 428 && shared_data->tl == thread->readMiscReg(MISCREG_TL) + 1) 429 ) { 430 431 outs << "Differences found between M5 and Legion:"; 432 if (diffPC) 433 outs << " [PC]"; 434 if (diffCC) 435 outs << " [CC]"; 436 if (diffInst) 437 outs << " [Instruction]"; 438 if (diffRegs) 439 outs << " [IntRegs]"; 440 if (diffTpc) 441 outs << " [Tpc]"; 442 if (diffTnpc) 443 outs << " [Tnpc]"; 444 if (diffTstate) 445 outs << " [Tstate]"; 446 if (diffTt) 447 outs << " [Tt]"; 448 if (diffHpstate) 449 outs << " [Hpstate]"; 450 if (diffHtstate) 451 outs << " [Htstate]"; 452 if (diffHtba) 453 outs << " [Htba]"; 454 if (diffPstate) 455 outs << " [Pstate]"; 456 if (diffY) 457 outs << " [Y]"; 458 if (diffCcr) 459 outs << " [Ccr]"; 460 if (diffTl) 461 outs << " [Tl]"; 462 if (diffGl) 463 outs << " [Gl]"; 464 if (diffAsi) 465 outs << " [Asi]"; 466 if (diffPil) 467 outs << " [Pil]"; 468 if (diffCwp) 469 outs << " [Cwp]"; 470 if (diffCansave) 471 outs << " [Cansave]"; 472 if (diffCanrestore) 473 outs << " [Canrestore]"; 474 if (diffOtherwin) 475 outs << " [Otherwin]"; 476 if (diffCleanwin) 477 outs << " [Cleanwin]"; 478 if (diffTlb) 479 outs << " [Tlb]"; 480 outs << endl << endl; 481 482 outs << right << setfill(' ') << setw(15) 483 << "M5 PC: " << "0x"<< setw(16) << setfill('0') 484 << hex << m5Pc << endl; 485 outs << setfill(' ') << setw(15) 486 << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex 487 << lgnPc << endl << endl; 488 489 outs << right << setfill(' ') << setw(15) 490 << "M5 CC: " << "0x"<< setw(16) << setfill('0') 491 << hex << thread->getCpuPtr()->instCount() << endl; 492 outs << setfill(' ') << setw(15) 493 << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex 494 << shared_data->cycle_count << endl << endl; 495 496 outs << setfill(' ') << setw(15) 497 << "M5 Inst: " << "0x"<< setw(8) 498 << setfill('0') << hex << staticInst->machInst 499 << staticInst->disassemble(m5Pc, debugSymbolTable) 500 << endl; 501 502 StaticInstPtr legionInst = 503 StaticInst::decode(makeExtMI(shared_data->instruction, 504 thread)); 505 outs << setfill(' ') << setw(15) 506 << " Legion Inst: " 507 << "0x" << setw(8) << setfill('0') << hex 508 << shared_data->instruction 509 << legionInst->disassemble(lgnPc, debugSymbolTable) 510 << endl << endl; 511 512 printSectionHeader(outs, "General State"); 513 printColumnLabels(outs); 514 printRegPair(outs, "HPstate", 515 thread->readMiscReg(MISCREG_HPSTATE), 516 shared_data->hpstate | (1 << 11)); 517 printRegPair(outs, "Htba", 518 thread->readMiscReg(MISCREG_HTBA), 519 shared_data->htba); 520 printRegPair(outs, "Pstate", 521 thread->readMiscReg(MISCREG_PSTATE), 522 shared_data->pstate); 523 printRegPair(outs, "Y", 524 //thread->readMiscReg(MISCREG_Y), 525 thread->readMiscReg(NumIntArchRegs + 1), 526 shared_data->y); 527 printRegPair(outs, "Ccr", 528 //thread->readMiscReg(MISCREG_CCR), 529 thread->readMiscReg(NumIntArchRegs + 2), 530 shared_data->ccr); 531 printRegPair(outs, "Tl", 532 thread->readMiscReg(MISCREG_TL), 533 shared_data->tl); 534 printRegPair(outs, "Gl", 535 thread->readMiscReg(MISCREG_GL), 536 shared_data->gl); 537 printRegPair(outs, "Asi", 538 thread->readMiscReg(MISCREG_ASI), 539 shared_data->asi); 540 printRegPair(outs, "Pil", 541 thread->readMiscReg(MISCREG_PIL), 542 shared_data->pil); 543 printRegPair(outs, "Cwp", 544 thread->readMiscReg(MISCREG_CWP), 545 shared_data->cwp); 546 printRegPair(outs, "Cansave", 547 //thread->readMiscReg(MISCREG_CANSAVE), 548 thread->readIntReg(NumIntArchRegs + 3), 549 shared_data->cansave); 550 printRegPair(outs, "Canrestore", 551 //thread->readMiscReg(MISCREG_CANRESTORE), 552 thread->readIntReg(NumIntArchRegs + 4), 553 shared_data->canrestore); 554 printRegPair(outs, "Otherwin", 555 //thread->readMiscReg(MISCREG_OTHERWIN), 556 thread->readIntReg(NumIntArchRegs + 5), 557 shared_data->otherwin); 558 printRegPair(outs, "Cleanwin", 559 //thread->readMiscReg(MISCREG_CLEANWIN), 560 thread->readIntReg(NumIntArchRegs + 6), 561 shared_data->cleanwin); 562 outs << endl; 563 for (int i = 1; i <= MaxTL; i++) { 564 printLevelHeader(outs, i); 565 printColumnLabels(outs); 566 thread->setMiscReg(MISCREG_TL, i); 567 printRegPair(outs, "Tpc", 568 thread->readMiscReg(MISCREG_TPC), 569 shared_data->tpc[i-1]); 570 printRegPair(outs, "Tnpc", 571 thread->readMiscReg(MISCREG_TNPC), 572 shared_data->tnpc[i-1]); 573 printRegPair(outs, "Tstate", 574 thread->readMiscReg(MISCREG_TSTATE), 575 shared_data->tstate[i-1]); 576 printRegPair(outs, "Tt", 577 thread->readMiscReg(MISCREG_TT), 578 shared_data->tt[i-1]); 579 printRegPair(outs, "Htstate", 580 thread->readMiscReg(MISCREG_HTSTATE), 581 shared_data->htstate[i-1]); 582 } 583 thread->setMiscReg(MISCREG_TL, oldTl); 584 outs << endl; 585 586 printSectionHeader(outs, "General Purpose Registers"); 587 static const char * regtypes[4] = {"%g", "%o", "%l", "%i"}; 588 for(int y = 0; y < 4; y++) 589 { 590 for(int x = 0; x < 8; x++) 591 { 592 char label[8]; 593 sprintf(label, "%s%d", regtypes[y], x); 594 printRegPair(outs, label, 595 thread->readIntReg(y*8+x), 596 shared_data->intregs[y*8+x]); 597 /*outs << regtypes[y] << x << " " ; 598 outs << "0x" << hex << setw(16) 599 << thread->readIntReg(y*8+x); 600 if (thread->readIntReg(y*8 + x) 601 != shared_data->intregs[y*8+x]) 602 outs << " X "; 603 else 604 outs << " | "; 605 outs << "0x" << setw(16) << hex 606 << shared_data->intregs[y*8+x] 607 << endl;*/ 608 } 609 } 610 printColumnLabels(outs); 611 char label[8]; 612 for (int x = 0; x < 64; x++) { 613 if (shared_data->itb[x] != ULL(0xFFFFFFFFFFFFFFFF) || 614 thread->getITBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) { 615 sprintf(label, "I-TLB:%02d", x); 616 printRegPair(outs, label, thread->getITBPtr()->TteRead(x), shared_data->itb[x]); 617 } 618 } 619 for (int x = 0; x < 64; x++) { 620 if (shared_data->dtb[x] != ULL(0xFFFFFFFFFFFFFFFF) || 621 thread->getDTBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) { 622 sprintf(label, "D-TLB:%02d", x); 623 printRegPair(outs, label, thread->getDTBPtr()->TteRead(x), shared_data->dtb[x]); 624 } 625 } 626 thread->getITBPtr()->dumpAll(); 627 thread->getDTBPtr()->dumpAll(); 628 629 diffcount++; 630 if (diffcount > 2) 631 fatal("Differences found between Legion and M5\n"); 632 } 633 634 compared = true; 635 shared_data->flags = OWN_LEGION; 636 } 637 } // while 638 } // if not microop 639 } 640#endif 641} 642 643 644vector<bool> Trace::InstRecord::flags(NUM_BITS); 645string Trace::InstRecord::trace_system; 646 647//////////////////////////////////////////////////////////////////////// 648// 649// Parameter space for per-cycle execution address tracing options. 650// Derive from ParamContext so we can override checkParams() function. 651// 652class ExecutionTraceParamContext : public ParamContext 653{ 654 public: 655 ExecutionTraceParamContext(const string &_iniSection) 656 : ParamContext(_iniSection) 657 { 658 } 659 660 void checkParams(); // defined at bottom of file 661}; 662 663ExecutionTraceParamContext exeTraceParams("exetrace"); 664 665Param<bool> exe_trace_spec(&exeTraceParams, "speculative", 666 "capture speculative instructions", true); 667 668Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle", 669 "print cycle number", true); 670Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass", 671 "print op class", true); 672Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread", 673 "print thread number", true); 674Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr", 675 "print effective address", true); 676Param<bool> exe_trace_print_data(&exeTraceParams, "print_data", 677 "print result data", true); 678Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs", 679 "print all integer regs", false); 680Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq", 681 "print fetch sequence number", false); 682Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq", 683 "print correct-path sequence number", false); 684Param<bool> exe_trace_print_reg_delta(&exeTraceParams, "print_reg_delta", 685 "print which registers changed to what", false); 686Param<bool> exe_trace_pc_symbol(&exeTraceParams, "pc_symbol", 687 "Use symbols for the PC if available", true); 688Param<bool> exe_trace_intel_format(&exeTraceParams, "intel_format", 689 "print trace in intel compatible format", false); 690Param<bool> exe_trace_legion_lockstep(&exeTraceParams, "legion_lockstep", 691 "Compare sim state to legion state every cycle", 692 false); 693Param<string> exe_trace_system(&exeTraceParams, "trace_system", 694 "print trace of which system (client or server)", 695 "client"); 696 697 698// 699// Helper function for ExecutionTraceParamContext::checkParams() just 700// to get us into the InstRecord namespace 701// 702void 703Trace::InstRecord::setParams() 704{ 705 flags[TRACE_MISSPEC] = exe_trace_spec; 706 707 flags[PRINT_CYCLE] = exe_trace_print_cycle; 708 flags[PRINT_OP_CLASS] = exe_trace_print_opclass; 709 flags[PRINT_THREAD_NUM] = exe_trace_print_thread; 710 flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr; 711 flags[PRINT_EFF_ADDR] = exe_trace_print_data; 712 flags[PRINT_INT_REGS] = exe_trace_print_iregs; 713 flags[PRINT_FETCH_SEQ] = exe_trace_print_fetchseq; 714 flags[PRINT_CP_SEQ] = exe_trace_print_cp_seq; 715 flags[PRINT_REG_DELTA] = exe_trace_print_reg_delta; 716 flags[PC_SYMBOL] = exe_trace_pc_symbol; 717 flags[INTEL_FORMAT] = exe_trace_intel_format; 718 flags[LEGION_LOCKSTEP] = exe_trace_legion_lockstep; 719 trace_system = exe_trace_system; 720 721 // If were going to be in lockstep with Legion 722 // Setup shared memory, and get otherwise ready 723 if (flags[LEGION_LOCKSTEP]) { 724 int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777); 725 if (shmfd < 0) 726 fatal("Couldn't get shared memory fd. Is Legion running?"); 727 728 shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND); 729 if (shared_data == (SharedData*)-1) 730 fatal("Couldn't allocate shared memory"); 731 732 if (shared_data->flags != OWN_M5) 733 fatal("Shared memory has invalid owner"); 734 735 if (shared_data->version != VERSION) 736 fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION, 737 shared_data->version); 738 739 // step legion forward one cycle so we can get register values 740 shared_data->flags = OWN_LEGION; 741 } 742} 743 744void 745ExecutionTraceParamContext::checkParams() 746{ 747 Trace::InstRecord::setParams(); 748} 749 750