164a165,167
> depCheckShift = params->LSQDepCheckShift;
> checkLoads = params->LSQCheckLoads;
>
440a444,492
> LSQUnit<Impl>::checkViolations(int load_idx, DynInstPtr &inst)
> {
> Addr inst_eff_addr1 = inst->effAddr >> depCheckShift;
> Addr inst_eff_addr2 = (inst->effAddr + inst->effSize - 1) >> depCheckShift;
>
> /** @todo in theory you only need to check an instruction that has executed
> * however, there isn't a good way in the pipeline at the moment to check
> * all instructions that will execute before the store writes back. Thus,
> * like the implementation that came before it, we're overly conservative.
> */
> while (load_idx != loadTail) {
> DynInstPtr ld_inst = loadQueue[load_idx];
> if (!ld_inst->effAddrValid || ld_inst->uncacheable()) {
> incrLdIdx(load_idx);
> continue;
> }
>
> Addr ld_eff_addr1 = ld_inst->effAddr >> depCheckShift;
> Addr ld_eff_addr2 =
> (ld_inst->effAddr + ld_inst->effSize - 1) >> depCheckShift;
>
> if ((inst_eff_addr2 > ld_eff_addr1 && inst_eff_addr1 < ld_eff_addr2) ||
> inst_eff_addr1 == ld_eff_addr1) {
> // A load/store incorrectly passed this load/store.
> // Check if we already have a violator, or if it's newer
> // squash and refetch.
> if (memDepViolator && ld_inst->seqNum > memDepViolator->seqNum)
> break;
>
> DPRINTF(LSQUnit, "Detected fault with inst [sn:%lli] and [sn:%lli]"
> " at address %#x\n", inst->seqNum, ld_inst->seqNum,
> ld_eff_addr1);
> memDepViolator = ld_inst;
>
> ++lsqMemOrderViolation;
>
> return TheISA::genMachineCheckFault();
> }
>
> incrLdIdx(load_idx);
> }
> return NoFault;
> }
>
>
>
>
> template <class Impl>
> Fault
480,481d531
< while (load_idx != loadTail) {
< // Really only need to check loads that have actually executed
483,512c533,534
< // @todo: For now this is extra conservative, detecting a
< // violation if the addresses match assuming all accesses
< // are quad word accesses.
<
< // @todo: Fix this, magic number being used here
<
< // @todo: Uncachable load is not executed until it reaches
< // the head of the ROB. Once this if checks only the executed
< // loads(as noted above), this check can be removed
< if (loadQueue[load_idx]->effAddrValid &&
< ((loadQueue[load_idx]->effAddr >> 8)
< == (inst->effAddr >> 8)) &&
< !loadQueue[load_idx]->uncacheable()) {
< // A load incorrectly passed this load. Squash and refetch.
< // For now return a fault to show that it was unsuccessful.
< DynInstPtr violator = loadQueue[load_idx];
< if (!memDepViolator ||
< (violator->seqNum < memDepViolator->seqNum)) {
< memDepViolator = violator;
< } else {
< break;
< }
<
< ++lsqMemOrderViolation;
<
< return genMachineCheckFault();
< }
<
< incrLdIdx(load_idx);
< }
---
> if (checkLoads)
> return checkViolations(load_idx, inst);
567,571c589
< assert(store_inst->effAddrValid);
< while (load_idx != loadTail) {
< // Really only need to check loads that have actually executed
< // It's safe to check all loads because effAddr is set to
< // InvalAddr when the dyn inst is created.
---
> return checkViolations(load_idx, store_inst);
573,604d590
< // @todo: For now this is extra conservative, detecting a
< // violation if the addresses match assuming all accesses
< // are quad word accesses.
<
< // @todo: Fix this, magic number being used here
<
< // @todo: Uncachable load is not executed until it reaches
< // the head of the ROB. Once this if checks only the executed
< // loads(as noted above), this check can be removed
< if (loadQueue[load_idx]->effAddrValid &&
< ((loadQueue[load_idx]->effAddr >> 8)
< == (store_inst->effAddr >> 8)) &&
< !loadQueue[load_idx]->uncacheable()) {
< // A load incorrectly passed this store. Squash and refetch.
< // For now return a fault to show that it was unsuccessful.
< DynInstPtr violator = loadQueue[load_idx];
< if (!memDepViolator ||
< (violator->seqNum < memDepViolator->seqNum)) {
< memDepViolator = violator;
< } else {
< break;
< }
<
< ++lsqMemOrderViolation;
<
< return genMachineCheckFault();
< }
<
< incrLdIdx(load_idx);
< }
<
< return store_fault;