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 |
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 |
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); |
532 |
533 if (checkLoads) 534 return checkViolations(load_idx, inst); |
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 |
589 return checkViolations(load_idx, store_inst); |
590 |
591} 592 593template <class Impl> 594void 595LSQUnit<Impl>::commitLoad() 596{ 597 assert(loadQueue[loadHead]); 598 --- 583 unchanged lines hidden --- |