lsq_unit_impl.hh (8133:9f704aa10eb4) | lsq_unit_impl.hh (8199:3d6c08c877a9) |
---|---|
1/* 2 * Copyright (c) 2010 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 148 unchanged lines hidden (view full) --- 157 158 // Add 1 for the sentinel entry (they are circular queues). 159 LQEntries = maxLQEntries + 1; 160 SQEntries = maxSQEntries + 1; 161 162 loadQueue.resize(LQEntries); 163 storeQueue.resize(SQEntries); 164 | 1/* 2 * Copyright (c) 2010 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 148 unchanged lines hidden (view full) --- 157 158 // Add 1 for the sentinel entry (they are circular queues). 159 LQEntries = maxLQEntries + 1; 160 SQEntries = maxSQEntries + 1; 161 162 loadQueue.resize(LQEntries); 163 storeQueue.resize(SQEntries); 164 |
165 depCheckShift = params->LSQDepCheckShift; 166 checkLoads = params->LSQCheckLoads; 167 |
|
165 loadHead = loadTail = 0; 166 167 storeHead = storeWBIdx = storeTail = 0; 168 169 usedPorts = 0; 170 cachePorts = params->cachePorts; 171 172 retryPkt = NULL; --- 260 unchanged lines hidden (view full) --- 433 } 434 } 435 436 return retval; 437} 438 439template <class Impl> 440Fault | 168 loadHead = loadTail = 0; 169 170 storeHead = storeWBIdx = storeTail = 0; 171 172 usedPorts = 0; 173 cachePorts = params->cachePorts; 174 175 retryPkt = NULL; --- 260 unchanged lines hidden (view full) --- 436 } 437 } 438 439 return retval; 440} 441 442template <class Impl> 443Fault |
444LSQUnit<Impl>::checkViolations(int load_idx, DynInstPtr &inst) 445{ 446 Addr inst_eff_addr1 = inst->effAddr >> depCheckShift; 447 Addr inst_eff_addr2 = (inst->effAddr + inst->effSize - 1) >> depCheckShift; 448 449 /** @todo in theory you only need to check an instruction that has executed 450 * however, there isn't a good way in the pipeline at the moment to check 451 * all instructions that will execute before the store writes back. Thus, 452 * like the implementation that came before it, we're overly conservative. 453 */ 454 while (load_idx != loadTail) { 455 DynInstPtr ld_inst = loadQueue[load_idx]; 456 if (!ld_inst->effAddrValid || ld_inst->uncacheable()) { 457 incrLdIdx(load_idx); 458 continue; 459 } 460 461 Addr ld_eff_addr1 = ld_inst->effAddr >> depCheckShift; 462 Addr ld_eff_addr2 = 463 (ld_inst->effAddr + ld_inst->effSize - 1) >> depCheckShift; 464 465 if ((inst_eff_addr2 > ld_eff_addr1 && inst_eff_addr1 < ld_eff_addr2) || 466 inst_eff_addr1 == ld_eff_addr1) { 467 // A load/store incorrectly passed this load/store. 468 // Check if we already have a violator, or if it's newer 469 // squash and refetch. 470 if (memDepViolator && ld_inst->seqNum > memDepViolator->seqNum) 471 break; 472 473 DPRINTF(LSQUnit, "Detected fault with inst [sn:%lli] and [sn:%lli]" 474 " at address %#x\n", inst->seqNum, ld_inst->seqNum, 475 ld_eff_addr1); 476 memDepViolator = ld_inst; 477 478 ++lsqMemOrderViolation; 479 480 return TheISA::genMachineCheckFault(); 481 } 482 483 incrLdIdx(load_idx); 484 } 485 return NoFault; 486} 487 488 489 490 491template <class Impl> 492Fault |
|
441LSQUnit<Impl>::executeLoad(DynInstPtr &inst) 442{ 443 using namespace TheISA; 444 // Execute a specific load. 445 Fault load_fault = NoFault; 446 447 DPRINTF(LSQUnit, "Executing load PC %s, [sn:%lli]\n", 448 inst->pcState(), inst->seqNum); --- 23 unchanged lines hidden (view full) --- 472 inst->setExecuted(); 473 } 474 iewStage->instToCommit(inst); 475 iewStage->activityThisCycle(); 476 } else if (!loadBlocked()) { 477 assert(inst->effAddrValid); 478 int load_idx = inst->lqIdx; 479 incrLdIdx(load_idx); | 493LSQUnit<Impl>::executeLoad(DynInstPtr &inst) 494{ 495 using namespace TheISA; 496 // Execute a specific load. 497 Fault load_fault = NoFault; 498 499 DPRINTF(LSQUnit, "Executing load PC %s, [sn:%lli]\n", 500 inst->pcState(), inst->seqNum); --- 23 unchanged lines hidden (view full) --- 524 inst->setExecuted(); 525 } 526 iewStage->instToCommit(inst); 527 iewStage->activityThisCycle(); 528 } else if (!loadBlocked()) { 529 assert(inst->effAddrValid); 530 int load_idx = inst->lqIdx; 531 incrLdIdx(load_idx); |
480 while (load_idx != loadTail) { 481 // Really only need to check loads that have actually executed | |
482 | 532 |
483 // @todo: For now this is extra conservative, detecting a 484 // violation if the addresses match assuming all accesses 485 // are quad word accesses. 486 487 // @todo: Fix this, magic number being used here 488 489 // @todo: Uncachable load is not executed until it reaches 490 // the head of the ROB. Once this if checks only the executed 491 // loads(as noted above), this check can be removed 492 if (loadQueue[load_idx]->effAddrValid && 493 ((loadQueue[load_idx]->effAddr >> 8) 494 == (inst->effAddr >> 8)) && 495 !loadQueue[load_idx]->uncacheable()) { 496 // A load incorrectly passed this load. Squash and refetch. 497 // For now return a fault to show that it was unsuccessful. 498 DynInstPtr violator = loadQueue[load_idx]; 499 if (!memDepViolator || 500 (violator->seqNum < memDepViolator->seqNum)) { 501 memDepViolator = violator; 502 } else { 503 break; 504 } 505 506 ++lsqMemOrderViolation; 507 508 return genMachineCheckFault(); 509 } 510 511 incrLdIdx(load_idx); 512 } | 533 if (checkLoads) 534 return checkViolations(load_idx, inst); |
513 } 514 515 return load_fault; 516} 517 518template <class Impl> 519Fault 520LSQUnit<Impl>::executeStore(DynInstPtr &store_inst) --- 38 unchanged lines hidden (view full) --- 559 if (store_inst->isStoreConditional()) { 560 // Store conditionals need to set themselves as able to 561 // writeback if we haven't had a fault by here. 562 storeQueue[store_idx].canWB = true; 563 564 ++storesToWB; 565 } 566 | 535 } 536 537 return load_fault; 538} 539 540template <class Impl> 541Fault 542LSQUnit<Impl>::executeStore(DynInstPtr &store_inst) --- 38 unchanged lines hidden (view full) --- 581 if (store_inst->isStoreConditional()) { 582 // Store conditionals need to set themselves as able to 583 // writeback if we haven't had a fault by here. 584 storeQueue[store_idx].canWB = true; 585 586 ++storesToWB; 587 } 588 |
567 assert(store_inst->effAddrValid); 568 while (load_idx != loadTail) { 569 // Really only need to check loads that have actually executed 570 // It's safe to check all loads because effAddr is set to 571 // InvalAddr when the dyn inst is created. | 589 return checkViolations(load_idx, store_inst); |
572 | 590 |
573 // @todo: For now this is extra conservative, detecting a 574 // violation if the addresses match assuming all accesses 575 // are quad word accesses. 576 577 // @todo: Fix this, magic number being used here 578 579 // @todo: Uncachable load is not executed until it reaches 580 // the head of the ROB. Once this if checks only the executed 581 // loads(as noted above), this check can be removed 582 if (loadQueue[load_idx]->effAddrValid && 583 ((loadQueue[load_idx]->effAddr >> 8) 584 == (store_inst->effAddr >> 8)) && 585 !loadQueue[load_idx]->uncacheable()) { 586 // A load incorrectly passed this store. Squash and refetch. 587 // For now return a fault to show that it was unsuccessful. 588 DynInstPtr violator = loadQueue[load_idx]; 589 if (!memDepViolator || 590 (violator->seqNum < memDepViolator->seqNum)) { 591 memDepViolator = violator; 592 } else { 593 break; 594 } 595 596 ++lsqMemOrderViolation; 597 598 return genMachineCheckFault(); 599 } 600 601 incrLdIdx(load_idx); 602 } 603 604 return store_fault; | |
605} 606 607template <class Impl> 608void 609LSQUnit<Impl>::commitLoad() 610{ 611 assert(loadQueue[loadHead]); 612 --- 583 unchanged lines hidden --- | 591} 592 593template <class Impl> 594void 595LSQUnit<Impl>::commitLoad() 596{ 597 assert(loadQueue[loadHead]); 598 --- 583 unchanged lines hidden --- |