exetrace.cc revision 3972:2c65c89843c5
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->readIntReg(SparcISA::NumIntArchRegs + 2); 151 //newVal = thread->readMiscReg(SparcISA::MISCREG_CCR); 152 if(newVal != ccr) 153 { 154 outs << " CCR = " << newVal; 155 ccr = newVal; 156 } 157 newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 1); 158 //newVal = thread->readMiscReg(SparcISA::MISCREG_Y); 159 if(newVal != y) 160 { 161 outs << " Y = " << newVal; 162 y = newVal; 163 } 164 for(int y = 0; y < 4; y++) 165 { 166 for(int x = 0; x < 8; x++) 167 { 168 int index = x + 8 * y; 169 newVal = thread->readIntReg(index); 170 if(regs[index] != newVal) 171 { 172 outs << " " << prefixes[y] << dec << x << " = " << hex << newVal; 173 regs[index] = newVal; 174 } 175 } 176 } 177 for(int y = 0; y < 32; y++) 178 { 179 newVal = thread->readFloatRegBits(2 * y, 64); 180 if(floats[y] != newVal) 181 { 182 outs << " F" << dec << (2 * y) << " = " << hex << newVal; 183 floats[y] = newVal; 184 } 185 } 186 outs << dec << endl; 187 } 188#endif 189 } 190 else if (flags[INTEL_FORMAT]) { 191#if FULL_SYSTEM 192 bool is_trace_system = (thread->getCpuPtr()->system->name() == trace_system); 193#else 194 bool is_trace_system = true; 195#endif 196 if (is_trace_system) { 197 ccprintf(outs, "%7d ) ", cycle); 198 outs << "0x" << hex << PC << ":\t"; 199 if (staticInst->isLoad()) { 200 outs << "<RD 0x" << hex << addr; 201 outs << ">"; 202 } else if (staticInst->isStore()) { 203 outs << "<WR 0x" << hex << addr; 204 outs << ">"; 205 } 206 outs << endl; 207 } 208 } else { 209 if (flags[PRINT_CYCLE]) 210 ccprintf(outs, "%7d: ", cycle); 211 212 outs << thread->getCpuPtr()->name() << " "; 213 214 if (flags[TRACE_MISSPEC]) 215 outs << (misspeculating ? "-" : "+") << " "; 216 217 if (flags[PRINT_THREAD_NUM]) 218 outs << "T" << thread->getThreadNum() << " : "; 219 220 221 std::string sym_str; 222 Addr sym_addr; 223 if (debugSymbolTable 224 && debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr) 225 && flags[PC_SYMBOL]) { 226 if (PC != sym_addr) 227 sym_str += csprintf("+%d", PC - sym_addr); 228 outs << "@" << sym_str << " : "; 229 } 230 else { 231 outs << "0x" << hex << PC << " : "; 232 } 233 234 // 235 // Print decoded instruction 236 // 237 238#if defined(__GNUC__) && (__GNUC__ < 3) 239 // There's a bug in gcc 2.x library that prevents setw() 240 // from working properly on strings 241 string mc(staticInst->disassemble(PC, debugSymbolTable)); 242 while (mc.length() < 26) 243 mc += " "; 244 outs << mc; 245#else 246 outs << setw(26) << left << staticInst->disassemble(PC, debugSymbolTable); 247#endif 248 249 outs << " : "; 250 251 if (flags[PRINT_OP_CLASS]) { 252 outs << opClassStrings[staticInst->opClass()] << " : "; 253 } 254 255 if (flags[PRINT_RESULT_DATA] && data_status != DataInvalid) { 256 outs << " D="; 257#if 0 258 if (data_status == DataDouble) 259 ccprintf(outs, "%f", data.as_double); 260 else 261 ccprintf(outs, "%#018x", data.as_int); 262#else 263 ccprintf(outs, "%#018x", data.as_int); 264#endif 265 } 266 267 if (flags[PRINT_EFF_ADDR] && addr_valid) 268 outs << " A=0x" << hex << addr; 269 270 if (flags[PRINT_INT_REGS] && regs_valid) { 271 for (int i = 0; i < TheISA::NumIntRegs;) 272 for (int j = i + 1; i <= j; i++) 273 ccprintf(outs, "r%02d = %#018x%s", i, 274 iregs->regs.readReg(i), 275 ((i == j) ? "\n" : " ")); 276 outs << "\n"; 277 } 278 279 if (flags[PRINT_FETCH_SEQ] && fetch_seq_valid) 280 outs << " FetchSeq=" << dec << fetch_seq; 281 282 if (flags[PRINT_CP_SEQ] && cp_seq_valid) 283 outs << " CPSeq=" << dec << cp_seq; 284 285 // 286 // End of line... 287 // 288 outs << endl; 289 } 290#if THE_ISA == SPARC_ISA && FULL_SYSTEM 291 // Compare 292 if (flags[LEGION_LOCKSTEP]) 293 { 294 bool compared = false; 295 bool diffPC = false; 296 bool diffCC = false; 297 bool diffInst = false; 298 bool diffRegs = false; 299 bool diffTpc = false; 300 bool diffTnpc = false; 301 bool diffTstate = false; 302 bool diffTt = false; 303 bool diffTba = false; 304 bool diffHpstate = false; 305 bool diffHtstate = false; 306 bool diffHtba = false; 307 bool diffPstate = false; 308 bool diffY = false; 309 bool diffCcr = false; 310 bool diffTl = false; 311 bool diffGl = false; 312 bool diffAsi = false; 313 bool diffPil = false; 314 bool diffCwp = false; 315 bool diffCansave = false; 316 bool diffCanrestore = false; 317 bool diffOtherwin = false; 318 bool diffCleanwin = false; 319 bool diffTlb = false; 320 Addr m5Pc, lgnPc; 321 322 // We took a trap on a micro-op... 323 if (wasMicro && !staticInst->isMicroOp()) 324 { 325 // let's skip comparing this cycle 326 while (!compared) 327 if (shared_data->flags == OWN_M5) { 328 shared_data->flags = OWN_LEGION; 329 compared = true; 330 } 331 compared = false; 332 wasMicro = false; 333 } 334 335 if (staticInst->isLastMicroOp()) 336 wasMicro = false; 337 else if (staticInst->isMicroOp()) 338 wasMicro = true; 339 340 341 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) { 342 while (!compared) { 343 if (shared_data->flags == OWN_M5) { 344 m5Pc = PC & TheISA::PAddrImplMask; 345 lgnPc = shared_data->pc & TheISA::PAddrImplMask; 346 if (lgnPc != m5Pc) 347 diffPC = true; 348 349 if (shared_data->cycle_count != 350 thread->getCpuPtr()->instCount()) 351 diffCC = true; 352 353 if (shared_data->instruction != 354 (SparcISA::MachInst)staticInst->machInst) { 355 diffInst = true; 356 } 357 for (int i = 0; i < TheISA::NumIntArchRegs; i++) { 358 if (thread->readIntReg(i) != shared_data->intregs[i]) { 359 diffRegs = true; 360 } 361 } 362 uint64_t oldTl = thread->readMiscReg(MISCREG_TL); 363 if (oldTl != shared_data->tl) 364 diffTl = true; 365 for (int i = 1; i <= MaxTL; i++) { 366 thread->setMiscReg(MISCREG_TL, i); 367 if (thread->readMiscReg(MISCREG_TPC) != 368 shared_data->tpc[i-1]) 369 diffTpc = true; 370 if (thread->readMiscReg(MISCREG_TNPC) != 371 shared_data->tnpc[i-1]) 372 diffTnpc = true; 373 if (thread->readMiscReg(MISCREG_TSTATE) != 374 shared_data->tstate[i-1]) 375 diffTstate = true; 376 if (thread->readMiscReg(MISCREG_TT) != 377 shared_data->tt[i-1]) 378 diffTt = true; 379 if (thread->readMiscReg(MISCREG_HTSTATE) != 380 shared_data->htstate[i-1]) 381 diffHtstate = true; 382 } 383 thread->setMiscReg(MISCREG_TL, oldTl); 384 385 if(shared_data->tba != thread->readMiscReg(MISCREG_TBA)) 386 diffTba = true; 387 //When the hpstate register is read by an instruction, 388 //legion has bit 11 set. When it's in storage, it doesn't. 389 //Since we don't directly support seperate interpretations 390 //of the registers like that, the bit is always set to 1 and 391 //we just don't compare it. It's not supposed to matter 392 //anyway. 393 if((shared_data->hpstate | (1 << 11)) != thread->readMiscReg(MISCREG_HPSTATE)) 394 diffHpstate = true; 395 if(shared_data->htba != thread->readMiscReg(MISCREG_HTBA)) 396 diffHtba = true; 397 if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE)) 398 diffPstate = true; 399 //if(shared_data->y != thread->readMiscReg(MISCREG_Y)) 400 if(shared_data->y != 401 thread->readIntReg(NumIntArchRegs + 1)) 402 diffY = true; 403 //if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR)) 404 if(shared_data->ccr != 405 thread->readIntReg(NumIntArchRegs + 2)) 406 diffCcr = true; 407 if(shared_data->gl != thread->readMiscReg(MISCREG_GL)) 408 diffGl = true; 409 if(shared_data->asi != thread->readMiscReg(MISCREG_ASI)) 410 diffAsi = true; 411 if(shared_data->pil != thread->readMiscReg(MISCREG_PIL)) 412 diffPil = true; 413 if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP)) 414 diffCwp = true; 415 //if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE)) 416 if(shared_data->cansave != 417 thread->readIntReg(NumIntArchRegs + 3)) 418 diffCansave = true; 419 //if(shared_data->canrestore != 420 // thread->readMiscReg(MISCREG_CANRESTORE)) 421 if(shared_data->canrestore != 422 thread->readMiscReg(NumIntArchRegs + 4)) 423 diffCanrestore = true; 424 //if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN)) 425 if(shared_data->otherwin != 426 thread->readIntReg(NumIntArchRegs + 5)) 427 diffOtherwin = true; 428 //if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN)) 429 if(shared_data->cleanwin != 430 thread->readMiscReg(NumIntArchRegs + 6)) 431 diffCleanwin = true; 432 433 for (int i = 0; i < 64; i++) { 434 if (shared_data->itb[i] != thread->getITBPtr()->TteRead(i)) 435 diffTlb = true; 436 if (shared_data->dtb[i] != thread->getDTBPtr()->TteRead(i)) 437 diffTlb = true; 438 } 439 440 if ((diffPC || diffCC || diffInst || diffRegs || diffTpc || 441 diffTnpc || diffTstate || diffTt || diffHpstate || 442 diffHtstate || diffHtba || diffPstate || diffY || 443 diffCcr || diffTl || diffGl || diffAsi || diffPil || 444 diffCwp || diffCansave || diffCanrestore || 445 diffOtherwin || diffCleanwin || diffTlb) 446 && !((staticInst->machInst & 0xC1F80000) == 0x81D00000) 447 && !(((staticInst->machInst & 0xC0000000) == 0xC0000000) 448 && shared_data->tl == thread->readMiscReg(MISCREG_TL) + 1) 449 ) { 450 451 outs << "Differences found between M5 and Legion:"; 452 if (diffPC) 453 outs << " [PC]"; 454 if (diffCC) 455 outs << " [CC]"; 456 if (diffInst) 457 outs << " [Instruction]"; 458 if (diffRegs) 459 outs << " [IntRegs]"; 460 if (diffTpc) 461 outs << " [Tpc]"; 462 if (diffTnpc) 463 outs << " [Tnpc]"; 464 if (diffTstate) 465 outs << " [Tstate]"; 466 if (diffTt) 467 outs << " [Tt]"; 468 if (diffHpstate) 469 outs << " [Hpstate]"; 470 if (diffHtstate) 471 outs << " [Htstate]"; 472 if (diffHtba) 473 outs << " [Htba]"; 474 if (diffPstate) 475 outs << " [Pstate]"; 476 if (diffY) 477 outs << " [Y]"; 478 if (diffCcr) 479 outs << " [Ccr]"; 480 if (diffTl) 481 outs << " [Tl]"; 482 if (diffGl) 483 outs << " [Gl]"; 484 if (diffAsi) 485 outs << " [Asi]"; 486 if (diffPil) 487 outs << " [Pil]"; 488 if (diffCwp) 489 outs << " [Cwp]"; 490 if (diffCansave) 491 outs << " [Cansave]"; 492 if (diffCanrestore) 493 outs << " [Canrestore]"; 494 if (diffOtherwin) 495 outs << " [Otherwin]"; 496 if (diffCleanwin) 497 outs << " [Cleanwin]"; 498 if (diffTlb) 499 outs << " [Tlb]"; 500 outs << endl << endl; 501 502 outs << right << setfill(' ') << setw(15) 503 << "M5 PC: " << "0x"<< setw(16) << setfill('0') 504 << hex << m5Pc << endl; 505 outs << setfill(' ') << setw(15) 506 << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex 507 << lgnPc << endl << endl; 508 509 outs << right << setfill(' ') << setw(15) 510 << "M5 CC: " << "0x"<< setw(16) << setfill('0') 511 << hex << thread->getCpuPtr()->instCount() << endl; 512 outs << setfill(' ') << setw(15) 513 << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex 514 << shared_data->cycle_count << endl << endl; 515 516 outs << setfill(' ') << setw(15) 517 << "M5 Inst: " << "0x"<< setw(8) 518 << setfill('0') << hex << staticInst->machInst 519 << staticInst->disassemble(m5Pc, debugSymbolTable) 520 << endl; 521 522 StaticInstPtr legionInst = 523 StaticInst::decode(makeExtMI(shared_data->instruction, 524 thread)); 525 outs << setfill(' ') << setw(15) 526 << " Legion Inst: " 527 << "0x" << setw(8) << setfill('0') << hex 528 << shared_data->instruction 529 << legionInst->disassemble(lgnPc, debugSymbolTable) 530 << endl << endl; 531 532 printSectionHeader(outs, "General State"); 533 printColumnLabels(outs); 534 printRegPair(outs, "HPstate", 535 thread->readMiscReg(MISCREG_HPSTATE), 536 shared_data->hpstate | (1 << 11)); 537 printRegPair(outs, "Htba", 538 thread->readMiscReg(MISCREG_HTBA), 539 shared_data->htba); 540 printRegPair(outs, "Pstate", 541 thread->readMiscReg(MISCREG_PSTATE), 542 shared_data->pstate); 543 printRegPair(outs, "Y", 544 //thread->readMiscReg(MISCREG_Y), 545 thread->readMiscReg(NumIntArchRegs + 1), 546 shared_data->y); 547 printRegPair(outs, "Ccr", 548 //thread->readMiscReg(MISCREG_CCR), 549 thread->readMiscReg(NumIntArchRegs + 2), 550 shared_data->ccr); 551 printRegPair(outs, "Tl", 552 thread->readMiscReg(MISCREG_TL), 553 shared_data->tl); 554 printRegPair(outs, "Gl", 555 thread->readMiscReg(MISCREG_GL), 556 shared_data->gl); 557 printRegPair(outs, "Asi", 558 thread->readMiscReg(MISCREG_ASI), 559 shared_data->asi); 560 printRegPair(outs, "Pil", 561 thread->readMiscReg(MISCREG_PIL), 562 shared_data->pil); 563 printRegPair(outs, "Cwp", 564 thread->readMiscReg(MISCREG_CWP), 565 shared_data->cwp); 566 printRegPair(outs, "Cansave", 567 //thread->readMiscReg(MISCREG_CANSAVE), 568 thread->readIntReg(NumIntArchRegs + 3), 569 shared_data->cansave); 570 printRegPair(outs, "Canrestore", 571 //thread->readMiscReg(MISCREG_CANRESTORE), 572 thread->readIntReg(NumIntArchRegs + 4), 573 shared_data->canrestore); 574 printRegPair(outs, "Otherwin", 575 //thread->readMiscReg(MISCREG_OTHERWIN), 576 thread->readIntReg(NumIntArchRegs + 5), 577 shared_data->otherwin); 578 printRegPair(outs, "Cleanwin", 579 //thread->readMiscReg(MISCREG_CLEANWIN), 580 thread->readIntReg(NumIntArchRegs + 6), 581 shared_data->cleanwin); 582 outs << endl; 583 for (int i = 1; i <= MaxTL; i++) { 584 printLevelHeader(outs, i); 585 printColumnLabels(outs); 586 thread->setMiscReg(MISCREG_TL, i); 587 printRegPair(outs, "Tpc", 588 thread->readMiscReg(MISCREG_TPC), 589 shared_data->tpc[i-1]); 590 printRegPair(outs, "Tnpc", 591 thread->readMiscReg(MISCREG_TNPC), 592 shared_data->tnpc[i-1]); 593 printRegPair(outs, "Tstate", 594 thread->readMiscReg(MISCREG_TSTATE), 595 shared_data->tstate[i-1]); 596 printRegPair(outs, "Tt", 597 thread->readMiscReg(MISCREG_TT), 598 shared_data->tt[i-1]); 599 printRegPair(outs, "Htstate", 600 thread->readMiscReg(MISCREG_HTSTATE), 601 shared_data->htstate[i-1]); 602 } 603 thread->setMiscReg(MISCREG_TL, oldTl); 604 outs << endl; 605 606 printSectionHeader(outs, "General Purpose Registers"); 607 static const char * regtypes[4] = {"%g", "%o", "%l", "%i"}; 608 for(int y = 0; y < 4; y++) 609 { 610 for(int x = 0; x < 8; x++) 611 { 612 char label[8]; 613 sprintf(label, "%s%d", regtypes[y], x); 614 printRegPair(outs, label, 615 thread->readIntReg(y*8+x), 616 shared_data->intregs[y*8+x]); 617 /*outs << regtypes[y] << x << " " ; 618 outs << "0x" << hex << setw(16) 619 << thread->readIntReg(y*8+x); 620 if (thread->readIntReg(y*8 + x) 621 != shared_data->intregs[y*8+x]) 622 outs << " X "; 623 else 624 outs << " | "; 625 outs << "0x" << setw(16) << hex 626 << shared_data->intregs[y*8+x] 627 << endl;*/ 628 } 629 } 630 if (diffTlb) { 631 printColumnLabels(outs); 632 char label[8]; 633 for (int x = 0; x < 64; x++) { 634 if (shared_data->itb[x] != ULL(0xFFFFFFFFFFFFFFFF) || 635 thread->getITBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) { 636 sprintf(label, "I-TLB:%02d", x); 637 printRegPair(outs, label, thread->getITBPtr()->TteRead(x), 638 shared_data->itb[x]); 639 } 640 } 641 for (int x = 0; x < 64; x++) { 642 if (shared_data->dtb[x] != ULL(0xFFFFFFFFFFFFFFFF) || 643 thread->getDTBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) { 644 sprintf(label, "D-TLB:%02d", x); 645 printRegPair(outs, label, thread->getDTBPtr()->TteRead(x), 646 shared_data->dtb[x]); 647 } 648 } 649 thread->getITBPtr()->dumpAll(); 650 thread->getDTBPtr()->dumpAll(); 651 } 652 653 diffcount++; 654 if (diffcount > 2) 655 fatal("Differences found between Legion and M5\n"); 656 } else 657 diffcount = 0; 658 659 compared = true; 660 shared_data->flags = OWN_LEGION; 661 } 662 } // while 663 } // if not microop 664 } 665#endif 666} 667 668 669vector<bool> Trace::InstRecord::flags(NUM_BITS); 670string Trace::InstRecord::trace_system; 671 672//////////////////////////////////////////////////////////////////////// 673// 674// Parameter space for per-cycle execution address tracing options. 675// Derive from ParamContext so we can override checkParams() function. 676// 677class ExecutionTraceParamContext : public ParamContext 678{ 679 public: 680 ExecutionTraceParamContext(const string &_iniSection) 681 : ParamContext(_iniSection) 682 { 683 } 684 685 void checkParams(); // defined at bottom of file 686}; 687 688ExecutionTraceParamContext exeTraceParams("exetrace"); 689 690Param<bool> exe_trace_spec(&exeTraceParams, "speculative", 691 "capture speculative instructions", true); 692 693Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle", 694 "print cycle number", true); 695Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass", 696 "print op class", true); 697Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread", 698 "print thread number", true); 699Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr", 700 "print effective address", true); 701Param<bool> exe_trace_print_data(&exeTraceParams, "print_data", 702 "print result data", true); 703Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs", 704 "print all integer regs", false); 705Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq", 706 "print fetch sequence number", false); 707Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq", 708 "print correct-path sequence number", false); 709Param<bool> exe_trace_print_reg_delta(&exeTraceParams, "print_reg_delta", 710 "print which registers changed to what", false); 711Param<bool> exe_trace_pc_symbol(&exeTraceParams, "pc_symbol", 712 "Use symbols for the PC if available", true); 713Param<bool> exe_trace_intel_format(&exeTraceParams, "intel_format", 714 "print trace in intel compatible format", false); 715Param<bool> exe_trace_legion_lockstep(&exeTraceParams, "legion_lockstep", 716 "Compare sim state to legion state every cycle", 717 false); 718Param<string> exe_trace_system(&exeTraceParams, "trace_system", 719 "print trace of which system (client or server)", 720 "client"); 721 722 723// 724// Helper function for ExecutionTraceParamContext::checkParams() just 725// to get us into the InstRecord namespace 726// 727void 728Trace::InstRecord::setParams() 729{ 730 flags[TRACE_MISSPEC] = exe_trace_spec; 731 732 flags[PRINT_CYCLE] = exe_trace_print_cycle; 733 flags[PRINT_OP_CLASS] = exe_trace_print_opclass; 734 flags[PRINT_THREAD_NUM] = exe_trace_print_thread; 735 flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr; 736 flags[PRINT_EFF_ADDR] = exe_trace_print_data; 737 flags[PRINT_INT_REGS] = exe_trace_print_iregs; 738 flags[PRINT_FETCH_SEQ] = exe_trace_print_fetchseq; 739 flags[PRINT_CP_SEQ] = exe_trace_print_cp_seq; 740 flags[PRINT_REG_DELTA] = exe_trace_print_reg_delta; 741 flags[PC_SYMBOL] = exe_trace_pc_symbol; 742 flags[INTEL_FORMAT] = exe_trace_intel_format; 743 flags[LEGION_LOCKSTEP] = exe_trace_legion_lockstep; 744 trace_system = exe_trace_system; 745 746 // If were going to be in lockstep with Legion 747 // Setup shared memory, and get otherwise ready 748 if (flags[LEGION_LOCKSTEP]) { 749 int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777); 750 if (shmfd < 0) 751 fatal("Couldn't get shared memory fd. Is Legion running?"); 752 753 shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND); 754 if (shared_data == (SharedData*)-1) 755 fatal("Couldn't allocate shared memory"); 756 757 if (shared_data->flags != OWN_M5) 758 fatal("Shared memory has invalid owner"); 759 760 if (shared_data->version != VERSION) 761 fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION, 762 shared_data->version); 763 764 // step legion forward one cycle so we can get register values 765 shared_data->flags = OWN_LEGION; 766 } 767} 768 769void 770ExecutionTraceParamContext::checkParams() 771{ 772 Trace::InstRecord::setParams(); 773} 774 775