exetrace.cc revision 3903:f005d99d790a
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 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 // We took a trap on a micro-op... 321 if (wasMicro && !staticInst->isMicroOp()) 322 { 323 // let's skip comparing this cycle 324 while (!compared) 325 if (shared_data->flags == OWN_M5) { 326 shared_data->flags = OWN_LEGION; 327 compared = true; 328 } 329 compared = false; 330 wasMicro = false; 331 } 332 333 if (staticInst->isLastMicroOp()) 334 wasMicro = false; 335 else if (staticInst->isMicroOp()) 336 wasMicro = true; 337 338 339 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) { 340 while (!compared) { 341 if (shared_data->flags == OWN_M5) { 342 m5Pc = PC & TheISA::PAddrImplMask; 343 lgnPc = shared_data->pc & TheISA::PAddrImplMask; 344 if (lgnPc != m5Pc) 345 diffPC = true; 346 347 if (shared_data->cycle_count != 348 thread->getCpuPtr()->instCount()) 349 diffCC = true; 350 351 if (shared_data->instruction != 352 (SparcISA::MachInst)staticInst->machInst) { 353 diffInst = true; 354 } 355 for (int i = 0; i < TheISA::NumIntArchRegs; i++) { 356 if (thread->readIntReg(i) != shared_data->intregs[i]) { 357 diffRegs = true; 358 } 359 } 360 uint64_t oldTl = thread->readMiscReg(MISCREG_TL); 361 if (oldTl != shared_data->tl) 362 diffTl = true; 363 for (int i = 1; i <= MaxTL; i++) { 364 thread->setMiscReg(MISCREG_TL, i); 365 if (thread->readMiscReg(MISCREG_TPC) != 366 shared_data->tpc[i-1]) 367 diffTpc = true; 368 if (thread->readMiscReg(MISCREG_TNPC) != 369 shared_data->tnpc[i-1]) 370 diffTnpc = true; 371 if (thread->readMiscReg(MISCREG_TSTATE) != 372 shared_data->tstate[i-1]) 373 diffTstate = true; 374 if (thread->readMiscReg(MISCREG_TT) != 375 shared_data->tt[i-1]) 376 diffTt = true; 377 if (thread->readMiscReg(MISCREG_HTSTATE) != 378 shared_data->htstate[i-1]) 379 diffHtstate = true; 380 } 381 thread->setMiscReg(MISCREG_TL, oldTl); 382 383 if(shared_data->tba != thread->readMiscReg(MISCREG_TBA)) 384 diffTba = true; 385 //When the hpstate register is read by an instruction, 386 //legion has bit 11 set. When it's in storage, it doesn't. 387 //Since we don't directly support seperate interpretations 388 //of the registers like that, the bit is always set to 1 and 389 //we just don't compare it. It's not supposed to matter 390 //anyway. 391 if((shared_data->hpstate | (1 << 11)) != thread->readMiscReg(MISCREG_HPSTATE)) 392 diffHpstate = true; 393 if(shared_data->htba != thread->readMiscReg(MISCREG_HTBA)) 394 diffHtba = true; 395 if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE)) 396 diffPstate = true; 397 if(shared_data->y != thread->readMiscReg(MISCREG_Y)) 398 diffY = true; 399 if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR)) 400 diffCcr = true; 401 if(shared_data->gl != thread->readMiscReg(MISCREG_GL)) 402 diffGl = true; 403 if(shared_data->asi != thread->readMiscReg(MISCREG_ASI)) 404 diffAsi = true; 405 if(shared_data->pil != thread->readMiscReg(MISCREG_PIL)) 406 diffPil = true; 407 if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP)) 408 diffCwp = true; 409 if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE)) 410 diffCansave = true; 411 if(shared_data->canrestore != 412 thread->readMiscReg(MISCREG_CANRESTORE)) 413 diffCanrestore = true; 414 if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN)) 415 diffOtherwin = true; 416 if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN)) 417 diffCleanwin = true; 418 419 for (int i = 0; i < 64; i++) { 420 if (shared_data->itb[i] != thread->getITBPtr()->TteRead(i)) 421 diffTlb = true; 422 if (shared_data->dtb[i] != thread->getDTBPtr()->TteRead(i)) 423 diffTlb = true; 424 } 425 426 if ((diffPC || diffCC || diffInst || diffRegs || diffTpc || 427 diffTnpc || diffTstate || diffTt || diffHpstate || 428 diffHtstate || diffHtba || diffPstate || diffY || 429 diffCcr || diffTl || diffGl || diffAsi || diffPil || 430 diffCwp || diffCansave || diffCanrestore || 431 diffOtherwin || diffCleanwin || diffTlb) 432 && !((staticInst->machInst & 0xC1F80000) == 0x81D00000) 433 && !(((staticInst->machInst & 0xC0000000) == 0xC0000000) 434 && shared_data->tl == thread->readMiscReg(MISCREG_TL) + 1) 435 ) { 436 437 outs << "Differences found between M5 and Legion:"; 438 if (diffPC) 439 outs << " [PC]"; 440 if (diffCC) 441 outs << " [CC]"; 442 if (diffInst) 443 outs << " [Instruction]"; 444 if (diffRegs) 445 outs << " [IntRegs]"; 446 if (diffTpc) 447 outs << " [Tpc]"; 448 if (diffTnpc) 449 outs << " [Tnpc]"; 450 if (diffTstate) 451 outs << " [Tstate]"; 452 if (diffTt) 453 outs << " [Tt]"; 454 if (diffHpstate) 455 outs << " [Hpstate]"; 456 if (diffHtstate) 457 outs << " [Htstate]"; 458 if (diffHtba) 459 outs << " [Htba]"; 460 if (diffPstate) 461 outs << " [Pstate]"; 462 if (diffY) 463 outs << " [Y]"; 464 if (diffCcr) 465 outs << " [Ccr]"; 466 if (diffTl) 467 outs << " [Tl]"; 468 if (diffGl) 469 outs << " [Gl]"; 470 if (diffAsi) 471 outs << " [Asi]"; 472 if (diffPil) 473 outs << " [Pil]"; 474 if (diffCwp) 475 outs << " [Cwp]"; 476 if (diffCansave) 477 outs << " [Cansave]"; 478 if (diffCanrestore) 479 outs << " [Canrestore]"; 480 if (diffOtherwin) 481 outs << " [Otherwin]"; 482 if (diffCleanwin) 483 outs << " [Cleanwin]"; 484 if (diffTlb) 485 outs << " [Tlb]"; 486 outs << endl << endl; 487 488 outs << right << setfill(' ') << setw(15) 489 << "M5 PC: " << "0x"<< setw(16) << setfill('0') 490 << hex << m5Pc << endl; 491 outs << setfill(' ') << setw(15) 492 << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex 493 << lgnPc << endl << endl; 494 495 outs << right << setfill(' ') << setw(15) 496 << "M5 CC: " << "0x"<< setw(16) << setfill('0') 497 << hex << thread->getCpuPtr()->instCount() << endl; 498 outs << setfill(' ') << setw(15) 499 << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex 500 << shared_data->cycle_count << endl << endl; 501 502 outs << setfill(' ') << setw(15) 503 << "M5 Inst: " << "0x"<< setw(8) 504 << setfill('0') << hex << staticInst->machInst 505 << staticInst->disassemble(m5Pc, debugSymbolTable) 506 << endl; 507 508 StaticInstPtr legionInst = 509 StaticInst::decode(makeExtMI(shared_data->instruction, 510 thread)); 511 outs << setfill(' ') << setw(15) 512 << " Legion Inst: " 513 << "0x" << setw(8) << setfill('0') << hex 514 << shared_data->instruction 515 << legionInst->disassemble(lgnPc, debugSymbolTable) 516 << endl << endl; 517 518 printSectionHeader(outs, "General State"); 519 printColumnLabels(outs); 520 printRegPair(outs, "HPstate", 521 thread->readMiscReg(MISCREG_HPSTATE), 522 shared_data->hpstate | (1 << 11)); 523 printRegPair(outs, "Htba", 524 thread->readMiscReg(MISCREG_HTBA), 525 shared_data->htba); 526 printRegPair(outs, "Pstate", 527 thread->readMiscReg(MISCREG_PSTATE), 528 shared_data->pstate); 529 printRegPair(outs, "Y", 530 thread->readMiscReg(MISCREG_Y), 531 shared_data->y); 532 printRegPair(outs, "Ccr", 533 thread->readMiscReg(MISCREG_CCR), 534 shared_data->ccr); 535 printRegPair(outs, "Tl", 536 thread->readMiscReg(MISCREG_TL), 537 shared_data->tl); 538 printRegPair(outs, "Gl", 539 thread->readMiscReg(MISCREG_GL), 540 shared_data->gl); 541 printRegPair(outs, "Asi", 542 thread->readMiscReg(MISCREG_ASI), 543 shared_data->asi); 544 printRegPair(outs, "Pil", 545 thread->readMiscReg(MISCREG_PIL), 546 shared_data->pil); 547 printRegPair(outs, "Cwp", 548 thread->readMiscReg(MISCREG_CWP), 549 shared_data->cwp); 550 printRegPair(outs, "Cansave", 551 thread->readMiscReg(MISCREG_CANSAVE), 552 shared_data->cansave); 553 printRegPair(outs, "Canrestore", 554 thread->readMiscReg(MISCREG_CANRESTORE), 555 shared_data->canrestore); 556 printRegPair(outs, "Otherwin", 557 thread->readMiscReg(MISCREG_OTHERWIN), 558 shared_data->otherwin); 559 printRegPair(outs, "Cleanwin", 560 thread->readMiscReg(MISCREG_CLEANWIN), 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 if (diffTlb) { 611 printColumnLabels(outs); 612 char label[8]; 613 for (int x = 0; x < 64; x++) { 614 if (shared_data->itb[x] != ULL(0xFFFFFFFFFFFFFFFF) || 615 thread->getITBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) { 616 sprintf(label, "I-TLB:%02d", x); 617 printRegPair(outs, label, thread->getITBPtr()->TteRead(x), 618 shared_data->itb[x]); 619 } 620 } 621 for (int x = 0; x < 64; x++) { 622 if (shared_data->dtb[x] != ULL(0xFFFFFFFFFFFFFFFF) || 623 thread->getDTBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) { 624 sprintf(label, "D-TLB:%02d", x); 625 printRegPair(outs, label, thread->getDTBPtr()->TteRead(x), 626 shared_data->dtb[x]); 627 } 628 } 629 thread->getITBPtr()->dumpAll(); 630 thread->getDTBPtr()->dumpAll(); 631 } 632 633 diffcount++; 634 if (diffcount > 2) 635 fatal("Differences found between Legion and M5\n"); 636 } else 637 diffcount = 0; 638 639 compared = true; 640 shared_data->flags = OWN_LEGION; 641 } 642 } // while 643 } // if not microop 644 } 645#endif 646} 647 648 649vector<bool> Trace::InstRecord::flags(NUM_BITS); 650string Trace::InstRecord::trace_system; 651 652//////////////////////////////////////////////////////////////////////// 653// 654// Parameter space for per-cycle execution address tracing options. 655// Derive from ParamContext so we can override checkParams() function. 656// 657class ExecutionTraceParamContext : public ParamContext 658{ 659 public: 660 ExecutionTraceParamContext(const string &_iniSection) 661 : ParamContext(_iniSection) 662 { 663 } 664 665 void checkParams(); // defined at bottom of file 666}; 667 668ExecutionTraceParamContext exeTraceParams("exetrace"); 669 670Param<bool> exe_trace_spec(&exeTraceParams, "speculative", 671 "capture speculative instructions", true); 672 673Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle", 674 "print cycle number", true); 675Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass", 676 "print op class", true); 677Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread", 678 "print thread number", true); 679Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr", 680 "print effective address", true); 681Param<bool> exe_trace_print_data(&exeTraceParams, "print_data", 682 "print result data", true); 683Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs", 684 "print all integer regs", false); 685Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq", 686 "print fetch sequence number", false); 687Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq", 688 "print correct-path sequence number", false); 689Param<bool> exe_trace_print_reg_delta(&exeTraceParams, "print_reg_delta", 690 "print which registers changed to what", false); 691Param<bool> exe_trace_pc_symbol(&exeTraceParams, "pc_symbol", 692 "Use symbols for the PC if available", true); 693Param<bool> exe_trace_intel_format(&exeTraceParams, "intel_format", 694 "print trace in intel compatible format", false); 695Param<bool> exe_trace_legion_lockstep(&exeTraceParams, "legion_lockstep", 696 "Compare sim state to legion state every cycle", 697 false); 698Param<string> exe_trace_system(&exeTraceParams, "trace_system", 699 "print trace of which system (client or server)", 700 "client"); 701 702 703// 704// Helper function for ExecutionTraceParamContext::checkParams() just 705// to get us into the InstRecord namespace 706// 707void 708Trace::InstRecord::setParams() 709{ 710 flags[TRACE_MISSPEC] = exe_trace_spec; 711 712 flags[PRINT_CYCLE] = exe_trace_print_cycle; 713 flags[PRINT_OP_CLASS] = exe_trace_print_opclass; 714 flags[PRINT_THREAD_NUM] = exe_trace_print_thread; 715 flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr; 716 flags[PRINT_EFF_ADDR] = exe_trace_print_data; 717 flags[PRINT_INT_REGS] = exe_trace_print_iregs; 718 flags[PRINT_FETCH_SEQ] = exe_trace_print_fetchseq; 719 flags[PRINT_CP_SEQ] = exe_trace_print_cp_seq; 720 flags[PRINT_REG_DELTA] = exe_trace_print_reg_delta; 721 flags[PC_SYMBOL] = exe_trace_pc_symbol; 722 flags[INTEL_FORMAT] = exe_trace_intel_format; 723 flags[LEGION_LOCKSTEP] = exe_trace_legion_lockstep; 724 trace_system = exe_trace_system; 725 726 // If were going to be in lockstep with Legion 727 // Setup shared memory, and get otherwise ready 728 if (flags[LEGION_LOCKSTEP]) { 729 int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777); 730 if (shmfd < 0) 731 fatal("Couldn't get shared memory fd. Is Legion running?"); 732 733 shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND); 734 if (shared_data == (SharedData*)-1) 735 fatal("Couldn't allocate shared memory"); 736 737 if (shared_data->flags != OWN_M5) 738 fatal("Shared memory has invalid owner"); 739 740 if (shared_data->version != VERSION) 741 fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION, 742 shared_data->version); 743 744 // step legion forward one cycle so we can get register values 745 shared_data->flags = OWN_LEGION; 746 } 747} 748 749void 750ExecutionTraceParamContext::checkParams() 751{ 752 Trace::InstRecord::setParams(); 753} 754 755