exetrace.cc revision 3945:255fad06ea71
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; 62static bool wasMicro = false; 63#endif 64 65namespace Trace { 66SharedData *shared_data = NULL; 67} 68 69//////////////////////////////////////////////////////////////////////// 70// 71// Methods for the InstRecord object 72// 73 74#if THE_ISA == SPARC_ISA 75 76inline char * genCenteredLabel(int length, char * buffer, char * label) 77{ 78 int labelLength = strlen(label); 79 assert(labelLength <= length); 80 int leftPad = (length - labelLength) / 2; 81 int rightPad = length - leftPad - labelLength; 82 char format[64]; 83 sprintf(format, "%%%ds%%s%%%ds", leftPad, rightPad); 84 sprintf(buffer, format, "", label, ""); 85 return buffer; 86} 87 88inline void printRegPair(ostream & os, char const * title, uint64_t a, uint64_t b) 89{ 90 ccprintf(os, " %16s | %#018x %s %#-018x \n", 91 title, a, (a == b) ? "|" : "X", b); 92} 93 94inline void printColumnLabels(ostream & os) 95{ 96 static char * regLabel = genCenteredLabel(16, new char[17], "Register"); 97 static char * m5Label = genCenteredLabel(18, new char[18], "M5"); 98 static char * legionLabel = genCenteredLabel(18, new char[18], "Legion"); 99 ccprintf(os, " %s | %s | %s \n", regLabel, m5Label, legionLabel); 100 ccprintf(os, "--------------------+-----------------------+-----------------------\n"); 101} 102 103inline void printSectionHeader(ostream & os, char * name) 104{ 105 char sectionString[70]; 106 genCenteredLabel(69, sectionString, name); 107 ccprintf(os, "====================================================================\n"); 108 ccprintf(os, "%69s\n", sectionString); 109 ccprintf(os, "====================================================================\n"); 110} 111 112inline void printLevelHeader(ostream & os, int level) 113{ 114 char sectionString[70]; 115 char levelName[70]; 116 sprintf(levelName, "Trap stack level %d", level); 117 genCenteredLabel(69, sectionString, levelName); 118 ccprintf(os, "====================================================================\n"); 119 ccprintf(os, "%69s\n", sectionString); 120 ccprintf(os, "====================================================================\n"); 121} 122 123#endif 124 125void 126Trace::InstRecord::dump(ostream &outs) 127{ 128 DPRINTF(Sparc, "Instruction: %#X\n", staticInst->machInst); 129 if (flags[PRINT_REG_DELTA]) 130 { 131#if THE_ISA == SPARC_ISA 132 //Don't print what happens for each micro-op, just print out 133 //once at the last op, and for regular instructions. 134 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) 135 { 136 static uint64_t regs[32] = { 137 0, 0, 0, 0, 0, 0, 0, 0, 138 0, 0, 0, 0, 0, 0, 0, 0, 139 0, 0, 0, 0, 0, 0, 0, 0, 140 0, 0, 0, 0, 0, 0, 0, 0}; 141 static uint64_t ccr = 0; 142 static uint64_t y = 0; 143 static uint64_t floats[32]; 144 uint64_t newVal; 145 static const char * prefixes[4] = {"G", "O", "L", "I"}; 146 147 outs << hex; 148 outs << "PC = " << thread->readNextPC(); 149 outs << " NPC = " << thread->readNextNPC(); 150 newVal = thread->readMiscReg(SparcISA::MISCREG_CCR); 151 if(newVal != ccr) 152 { 153 outs << " CCR = " << newVal; 154 ccr = newVal; 155 } 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 diffIntRegs = false; 297 bool diffFpRegs = false; 298 bool diffTpc = false; 299 bool diffTnpc = false; 300 bool diffTstate = false; 301 bool diffTt = false; 302 bool diffTba = false; 303 bool diffHpstate = false; 304 bool diffHtstate = false; 305 bool diffHtba = false; 306 bool diffPstate = false; 307 bool diffY = false; 308 bool diffCcr = false; 309 bool diffTl = false; 310 bool diffGl = false; 311 bool diffAsi = false; 312 bool diffPil = false; 313 bool diffCwp = false; 314 bool diffCansave = false; 315 bool diffCanrestore = false; 316 bool diffOtherwin = false; 317 bool diffCleanwin = false; 318 bool diffTlb = false; 319 Addr m5Pc, lgnPc; 320 321 // We took a trap on a micro-op... 322 if (wasMicro && !staticInst->isMicroOp()) 323 { 324 // let's skip comparing this cycle 325 while (!compared) 326 if (shared_data->flags == OWN_M5) { 327 shared_data->flags = OWN_LEGION; 328 compared = true; 329 } 330 compared = false; 331 wasMicro = false; 332 } 333 334 if (staticInst->isLastMicroOp()) 335 wasMicro = false; 336 else if (staticInst->isMicroOp()) 337 wasMicro = true; 338 339 340 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) { 341 while (!compared) { 342 if (shared_data->flags == OWN_M5) { 343 m5Pc = PC & TheISA::PAddrImplMask; 344 if (bits(shared_data->pstate,3,3)) { 345 m5Pc &= mask(32); 346 } 347 lgnPc = shared_data->pc & TheISA::PAddrImplMask; 348 if (lgnPc != m5Pc) 349 diffPC = true; 350 351 if (shared_data->cycle_count != 352 thread->getCpuPtr()->instCount()) 353 diffCC = true; 354 355 if (shared_data->instruction != 356 (SparcISA::MachInst)staticInst->machInst) { 357 diffInst = true; 358 } 359 for (int i = 0; i < TheISA::NumIntArchRegs; i++) { 360 if (thread->readIntReg(i) != shared_data->intregs[i]) { 361 diffIntRegs = true; 362 } 363 } 364 for (int i = 0; i < TheISA::NumFloatRegs/2; i++) { 365 if (thread->readFloatRegBits(i*2,FloatRegFile::DoubleWidth) != shared_data->fpregs[i]) { 366 diffFpRegs = true; 367 } 368 } 369 uint64_t oldTl = thread->readMiscReg(MISCREG_TL); 370 if (oldTl != shared_data->tl) 371 diffTl = true; 372 for (int i = 1; i <= MaxTL; i++) { 373 thread->setMiscReg(MISCREG_TL, i); 374 if (thread->readMiscReg(MISCREG_TPC) != 375 shared_data->tpc[i-1]) 376 diffTpc = true; 377 if (thread->readMiscReg(MISCREG_TNPC) != 378 shared_data->tnpc[i-1]) 379 diffTnpc = true; 380 if (thread->readMiscReg(MISCREG_TSTATE) != 381 shared_data->tstate[i-1]) 382 diffTstate = true; 383 if (thread->readMiscReg(MISCREG_TT) != 384 shared_data->tt[i-1]) 385 diffTt = true; 386 if (thread->readMiscReg(MISCREG_HTSTATE) != 387 shared_data->htstate[i-1]) 388 diffHtstate = true; 389 } 390 thread->setMiscReg(MISCREG_TL, oldTl); 391 392 if(shared_data->tba != thread->readMiscReg(MISCREG_TBA)) 393 diffTba = true; 394 //When the hpstate register is read by an instruction, 395 //legion has bit 11 set. When it's in storage, it doesn't. 396 //Since we don't directly support seperate interpretations 397 //of the registers like that, the bit is always set to 1 and 398 //we just don't compare it. It's not supposed to matter 399 //anyway. 400 if((shared_data->hpstate | (1 << 11)) != thread->readMiscReg(MISCREG_HPSTATE)) 401 diffHpstate = true; 402 if(shared_data->htba != thread->readMiscReg(MISCREG_HTBA)) 403 diffHtba = true; 404 if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE)) 405 diffPstate = true; 406 if(shared_data->y != thread->readMiscReg(MISCREG_Y)) 407 diffY = true; 408 if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR)) 409 diffCcr = true; 410 if(shared_data->gl != thread->readMiscReg(MISCREG_GL)) 411 diffGl = true; 412 if(shared_data->asi != thread->readMiscReg(MISCREG_ASI)) 413 diffAsi = true; 414 if(shared_data->pil != thread->readMiscReg(MISCREG_PIL)) 415 diffPil = true; 416 if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP)) 417 diffCwp = true; 418 if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE)) 419 diffCansave = true; 420 if(shared_data->canrestore != 421 thread->readMiscReg(MISCREG_CANRESTORE)) 422 diffCanrestore = true; 423 if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN)) 424 diffOtherwin = true; 425 if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN)) 426 diffCleanwin = true; 427 428 for (int i = 0; i < 64; i++) { 429 if (shared_data->itb[i] != thread->getITBPtr()->TteRead(i)) 430 diffTlb = true; 431 if (shared_data->dtb[i] != thread->getDTBPtr()->TteRead(i)) 432 diffTlb = true; 433 } 434 435 if ((diffPC || diffCC || diffInst || diffIntRegs || 436 diffFpRegs || diffTpc || diffTnpc || diffTstate || 437 diffTt || diffHpstate || diffHtstate || diffHtba || 438 diffPstate || diffY || diffCcr || diffTl || diffGl || 439 diffAsi || diffPil || diffCwp || diffCansave || 440 diffCanrestore || diffOtherwin || diffCleanwin || diffTlb) 441 && !((staticInst->machInst & 0xC1F80000) == 0x81D00000) 442 && !(((staticInst->machInst & 0xC0000000) == 0xC0000000) 443 && shared_data->tl == thread->readMiscReg(MISCREG_TL) + 1) 444 ) { 445 446 outs << "Differences found between M5 and Legion:"; 447 if (diffPC) 448 outs << " [PC]"; 449 if (diffCC) 450 outs << " [CC]"; 451 if (diffInst) 452 outs << " [Instruction]"; 453 if (diffIntRegs) 454 outs << " [IntRegs]"; 455 if (diffFpRegs) 456 outs << " [FpRegs]"; 457 if (diffTpc) 458 outs << " [Tpc]"; 459 if (diffTnpc) 460 outs << " [Tnpc]"; 461 if (diffTstate) 462 outs << " [Tstate]"; 463 if (diffTt) 464 outs << " [Tt]"; 465 if (diffHpstate) 466 outs << " [Hpstate]"; 467 if (diffHtstate) 468 outs << " [Htstate]"; 469 if (diffHtba) 470 outs << " [Htba]"; 471 if (diffPstate) 472 outs << " [Pstate]"; 473 if (diffY) 474 outs << " [Y]"; 475 if (diffCcr) 476 outs << " [Ccr]"; 477 if (diffTl) 478 outs << " [Tl]"; 479 if (diffGl) 480 outs << " [Gl]"; 481 if (diffAsi) 482 outs << " [Asi]"; 483 if (diffPil) 484 outs << " [Pil]"; 485 if (diffCwp) 486 outs << " [Cwp]"; 487 if (diffCansave) 488 outs << " [Cansave]"; 489 if (diffCanrestore) 490 outs << " [Canrestore]"; 491 if (diffOtherwin) 492 outs << " [Otherwin]"; 493 if (diffCleanwin) 494 outs << " [Cleanwin]"; 495 if (diffTlb) 496 outs << " [Tlb]"; 497 outs << endl << endl; 498 499 outs << right << setfill(' ') << setw(15) 500 << "M5 PC: " << "0x"<< setw(16) << setfill('0') 501 << hex << m5Pc << endl; 502 outs << setfill(' ') << setw(15) 503 << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex 504 << lgnPc << endl << endl; 505 506 outs << right << setfill(' ') << setw(15) 507 << "M5 CC: " << "0x"<< setw(16) << setfill('0') 508 << hex << thread->getCpuPtr()->instCount() << endl; 509 outs << setfill(' ') << setw(15) 510 << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex 511 << shared_data->cycle_count << endl << endl; 512 513 outs << setfill(' ') << setw(15) 514 << "M5 Inst: " << "0x"<< setw(8) 515 << setfill('0') << hex << staticInst->machInst 516 << staticInst->disassemble(m5Pc, debugSymbolTable) 517 << endl; 518 519 StaticInstPtr legionInst = 520 StaticInst::decode(makeExtMI(shared_data->instruction, 521 thread)); 522 outs << setfill(' ') << setw(15) 523 << " Legion Inst: " 524 << "0x" << setw(8) << setfill('0') << hex 525 << shared_data->instruction 526 << legionInst->disassemble(lgnPc, debugSymbolTable) 527 << endl << endl; 528 529 printSectionHeader(outs, "General State"); 530 printColumnLabels(outs); 531 printRegPair(outs, "HPstate", 532 thread->readMiscReg(MISCREG_HPSTATE), 533 shared_data->hpstate | (1 << 11)); 534 printRegPair(outs, "Htba", 535 thread->readMiscReg(MISCREG_HTBA), 536 shared_data->htba); 537 printRegPair(outs, "Pstate", 538 thread->readMiscReg(MISCREG_PSTATE), 539 shared_data->pstate); 540 printRegPair(outs, "Y", 541 thread->readMiscReg(MISCREG_Y), 542 shared_data->y); 543 printRegPair(outs, "Ccr", 544 thread->readMiscReg(MISCREG_CCR), 545 shared_data->ccr); 546 printRegPair(outs, "Tl", 547 thread->readMiscReg(MISCREG_TL), 548 shared_data->tl); 549 printRegPair(outs, "Gl", 550 thread->readMiscReg(MISCREG_GL), 551 shared_data->gl); 552 printRegPair(outs, "Asi", 553 thread->readMiscReg(MISCREG_ASI), 554 shared_data->asi); 555 printRegPair(outs, "Pil", 556 thread->readMiscReg(MISCREG_PIL), 557 shared_data->pil); 558 printRegPair(outs, "Cwp", 559 thread->readMiscReg(MISCREG_CWP), 560 shared_data->cwp); 561 printRegPair(outs, "Cansave", 562 thread->readMiscReg(MISCREG_CANSAVE), 563 shared_data->cansave); 564 printRegPair(outs, "Canrestore", 565 thread->readMiscReg(MISCREG_CANRESTORE), 566 shared_data->canrestore); 567 printRegPair(outs, "Otherwin", 568 thread->readMiscReg(MISCREG_OTHERWIN), 569 shared_data->otherwin); 570 printRegPair(outs, "Cleanwin", 571 thread->readMiscReg(MISCREG_CLEANWIN), 572 shared_data->cleanwin); 573 outs << endl; 574 for (int i = 1; i <= MaxTL; i++) { 575 printLevelHeader(outs, i); 576 printColumnLabels(outs); 577 thread->setMiscReg(MISCREG_TL, i); 578 printRegPair(outs, "Tpc", 579 thread->readMiscReg(MISCREG_TPC), 580 shared_data->tpc[i-1]); 581 printRegPair(outs, "Tnpc", 582 thread->readMiscReg(MISCREG_TNPC), 583 shared_data->tnpc[i-1]); 584 printRegPair(outs, "Tstate", 585 thread->readMiscReg(MISCREG_TSTATE), 586 shared_data->tstate[i-1]); 587 printRegPair(outs, "Tt", 588 thread->readMiscReg(MISCREG_TT), 589 shared_data->tt[i-1]); 590 printRegPair(outs, "Htstate", 591 thread->readMiscReg(MISCREG_HTSTATE), 592 shared_data->htstate[i-1]); 593 } 594 thread->setMiscReg(MISCREG_TL, oldTl); 595 outs << endl; 596 597 printSectionHeader(outs, "General Purpose Registers"); 598 static const char * regtypes[4] = {"%g", "%o", "%l", "%i"}; 599 for(int y = 0; y < 4; y++) { 600 for(int x = 0; x < 8; x++) { 601 char label[8]; 602 sprintf(label, "%s%d", regtypes[y], x); 603 printRegPair(outs, label, 604 thread->readIntReg(y*8+x), 605 shared_data->intregs[y*8+x]); 606 } 607 } 608 if (diffFpRegs) { 609 for (int x = 0; x < 32; x++) { 610 char label[8]; 611 sprintf(label, "%%f%d", x); 612 printRegPair(outs, label, 613 thread->readFloatRegBits(x,FloatRegFile::DoubleWidth), 614 shared_data->fpregs[x]); 615 } 616 } 617 if (diffTlb) { 618 printColumnLabels(outs); 619 char label[8]; 620 for (int x = 0; x < 64; x++) { 621 if (shared_data->itb[x] != ULL(0xFFFFFFFFFFFFFFFF) || 622 thread->getITBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) { 623 sprintf(label, "I-TLB:%02d", x); 624 printRegPair(outs, label, thread->getITBPtr()->TteRead(x), 625 shared_data->itb[x]); 626 } 627 } 628 for (int x = 0; x < 64; x++) { 629 if (shared_data->dtb[x] != ULL(0xFFFFFFFFFFFFFFFF) || 630 thread->getDTBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) { 631 sprintf(label, "D-TLB:%02d", x); 632 printRegPair(outs, label, thread->getDTBPtr()->TteRead(x), 633 shared_data->dtb[x]); 634 } 635 } 636 thread->getITBPtr()->dumpAll(); 637 thread->getDTBPtr()->dumpAll(); 638 } 639 640 diffcount++; 641 if (diffcount > 2) 642 fatal("Differences found between Legion and M5\n"); 643 } else 644 diffcount = 0; 645 646 compared = true; 647 shared_data->flags = OWN_LEGION; 648 } 649 } // while 650 } // if not microop 651 } 652#endif 653} 654 655 656vector<bool> Trace::InstRecord::flags(NUM_BITS); 657string Trace::InstRecord::trace_system; 658 659//////////////////////////////////////////////////////////////////////// 660// 661// Parameter space for per-cycle execution address tracing options. 662// Derive from ParamContext so we can override checkParams() function. 663// 664class ExecutionTraceParamContext : public ParamContext 665{ 666 public: 667 ExecutionTraceParamContext(const string &_iniSection) 668 : ParamContext(_iniSection) 669 { 670 } 671 672 void checkParams(); // defined at bottom of file 673}; 674 675ExecutionTraceParamContext exeTraceParams("exetrace"); 676 677Param<bool> exe_trace_spec(&exeTraceParams, "speculative", 678 "capture speculative instructions", true); 679 680Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle", 681 "print cycle number", true); 682Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass", 683 "print op class", true); 684Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread", 685 "print thread number", true); 686Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr", 687 "print effective address", true); 688Param<bool> exe_trace_print_data(&exeTraceParams, "print_data", 689 "print result data", true); 690Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs", 691 "print all integer regs", false); 692Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq", 693 "print fetch sequence number", false); 694Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq", 695 "print correct-path sequence number", false); 696Param<bool> exe_trace_print_reg_delta(&exeTraceParams, "print_reg_delta", 697 "print which registers changed to what", false); 698Param<bool> exe_trace_pc_symbol(&exeTraceParams, "pc_symbol", 699 "Use symbols for the PC if available", true); 700Param<bool> exe_trace_intel_format(&exeTraceParams, "intel_format", 701 "print trace in intel compatible format", false); 702Param<bool> exe_trace_legion_lockstep(&exeTraceParams, "legion_lockstep", 703 "Compare sim state to legion state every cycle", 704 false); 705Param<string> exe_trace_system(&exeTraceParams, "trace_system", 706 "print trace of which system (client or server)", 707 "client"); 708 709 710// 711// Helper function for ExecutionTraceParamContext::checkParams() just 712// to get us into the InstRecord namespace 713// 714void 715Trace::InstRecord::setParams() 716{ 717 flags[TRACE_MISSPEC] = exe_trace_spec; 718 719 flags[PRINT_CYCLE] = exe_trace_print_cycle; 720 flags[PRINT_OP_CLASS] = exe_trace_print_opclass; 721 flags[PRINT_THREAD_NUM] = exe_trace_print_thread; 722 flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr; 723 flags[PRINT_EFF_ADDR] = exe_trace_print_data; 724 flags[PRINT_INT_REGS] = exe_trace_print_iregs; 725 flags[PRINT_FETCH_SEQ] = exe_trace_print_fetchseq; 726 flags[PRINT_CP_SEQ] = exe_trace_print_cp_seq; 727 flags[PRINT_REG_DELTA] = exe_trace_print_reg_delta; 728 flags[PC_SYMBOL] = exe_trace_pc_symbol; 729 flags[INTEL_FORMAT] = exe_trace_intel_format; 730 flags[LEGION_LOCKSTEP] = exe_trace_legion_lockstep; 731 trace_system = exe_trace_system; 732 733 // If were going to be in lockstep with Legion 734 // Setup shared memory, and get otherwise ready 735 if (flags[LEGION_LOCKSTEP]) { 736 int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777); 737 if (shmfd < 0) 738 fatal("Couldn't get shared memory fd. Is Legion running?"); 739 740 shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND); 741 if (shared_data == (SharedData*)-1) 742 fatal("Couldn't allocate shared memory"); 743 744 if (shared_data->flags != OWN_M5) 745 fatal("Shared memory has invalid owner"); 746 747 if (shared_data->version != VERSION) 748 fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION, 749 shared_data->version); 750 751 // step legion forward one cycle so we can get register values 752 shared_data->flags = OWN_LEGION; 753 } 754} 755 756void 757ExecutionTraceParamContext::checkParams() 758{ 759 Trace::InstRecord::setParams(); 760} 761 762