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 ---