lsq_unit_impl.hh (10023:91faf6649de0) lsq_unit_impl.hh (10030:b531e328342d)
1
2/*
1
2/*
3 * Copyright (c) 2010-2012 ARM Limited
3 * Copyright (c) 2010-2013 ARM Limited
4 * All rights reserved
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder. You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated

--- 416 unchanged lines hidden (view full) ---

428 }
429}
430
431template <class Impl>
432void
433LSQUnit<Impl>::checkSnoop(PacketPtr pkt)
434{
435 int load_idx = loadHead;
4 * All rights reserved
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder. You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated

--- 416 unchanged lines hidden (view full) ---

428 }
429}
430
431template <class Impl>
432void
433LSQUnit<Impl>::checkSnoop(PacketPtr pkt)
434{
435 int load_idx = loadHead;
436 DPRINTF(LSQUnit, "Got snoop for address %#x\n", pkt->getAddr());
436
437 // Unlock the cpu-local monitor when the CPU sees a snoop to a locked
438 // address. The CPU can speculatively execute a LL operation after a pending
439 // SC operation in the pipeline and that can make the cache monitor the CPU
440 // is connected to valid while it really shouldn't be.
437
438 // Unlock the cpu-local monitor when the CPU sees a snoop to a locked
439 // address. The CPU can speculatively execute a LL operation after a pending
440 // SC operation in the pipeline and that can make the cache monitor the CPU
441 // is connected to valid while it really shouldn't be.
441 for (int x = 0; x < cpu->numActiveThreads(); x++) {
442 for (int x = 0; x < cpu->numContexts(); x++) {
442 ThreadContext *tc = cpu->getContext(x);
443 bool no_squash = cpu->thread[x]->noSquashFromTC;
444 cpu->thread[x]->noSquashFromTC = true;
445 TheISA::handleLockedSnoop(tc, pkt, cacheBlockMask);
446 cpu->thread[x]->noSquashFromTC = no_squash;
447 }
448
443 ThreadContext *tc = cpu->getContext(x);
444 bool no_squash = cpu->thread[x]->noSquashFromTC;
445 cpu->thread[x]->noSquashFromTC = true;
446 TheISA::handleLockedSnoop(tc, pkt, cacheBlockMask);
447 cpu->thread[x]->noSquashFromTC = no_squash;
448 }
449
450 Addr invalidate_addr = pkt->getAddr() & cacheBlockMask;
451
452 DynInstPtr ld_inst = loadQueue[load_idx];
453 if (ld_inst) {
454 Addr load_addr = ld_inst->physEffAddr & cacheBlockMask;
455 // Check that this snoop didn't just invalidate our lock flag
456 if (ld_inst->effAddrValid() && load_addr == invalidate_addr &&
457 ld_inst->memReqFlags & Request::LLSC)
458 TheISA::handleLockedSnoopHit(ld_inst.get());
459 }
460
449 // If this is the only load in the LSQ we don't care
450 if (load_idx == loadTail)
451 return;
461 // If this is the only load in the LSQ we don't care
462 if (load_idx == loadTail)
463 return;
464
452 incrLdIdx(load_idx);
453
465 incrLdIdx(load_idx);
466
454 DPRINTF(LSQUnit, "Got snoop for address %#x\n", pkt->getAddr());
455 Addr invalidate_addr = pkt->getAddr() & cacheBlockMask;
456 while (load_idx != loadTail) {
457 DynInstPtr ld_inst = loadQueue[load_idx];
458
459 if (!ld_inst->effAddrValid() || ld_inst->uncacheable()) {
460 incrLdIdx(load_idx);
461 continue;
462 }
463
464 Addr load_addr = ld_inst->physEffAddr & cacheBlockMask;
465 DPRINTF(LSQUnit, "-- inst [sn:%lli] load_addr: %#x to pktAddr:%#x\n",
466 ld_inst->seqNum, load_addr, invalidate_addr);
467
468 if (load_addr == invalidate_addr) {
469 if (ld_inst->possibleLoadViolation()) {
470 DPRINTF(LSQUnit, "Conflicting load at addr %#x [sn:%lli]\n",
467 while (load_idx != loadTail) {
468 DynInstPtr ld_inst = loadQueue[load_idx];
469
470 if (!ld_inst->effAddrValid() || ld_inst->uncacheable()) {
471 incrLdIdx(load_idx);
472 continue;
473 }
474
475 Addr load_addr = ld_inst->physEffAddr & cacheBlockMask;
476 DPRINTF(LSQUnit, "-- inst [sn:%lli] load_addr: %#x to pktAddr:%#x\n",
477 ld_inst->seqNum, load_addr, invalidate_addr);
478
479 if (load_addr == invalidate_addr) {
480 if (ld_inst->possibleLoadViolation()) {
481 DPRINTF(LSQUnit, "Conflicting load at addr %#x [sn:%lli]\n",
471 ld_inst->physEffAddr, pkt->getAddr(), ld_inst->seqNum);
482 pkt->getAddr(), ld_inst->seqNum);
472
473 // Mark the load for re-execution
474 ld_inst->fault = new ReExec;
475 } else {
483
484 // Mark the load for re-execution
485 ld_inst->fault = new ReExec;
486 } else {
487 DPRINTF(LSQUnit, "HitExternal Snoop for addr %#x [sn:%lli]\n",
488 pkt->getAddr(), ld_inst->seqNum);
489
490 // Make sure that we don't lose a snoop hitting a LOCKED
491 // address since the LOCK* flags don't get updated until
492 // commit.
493 if (ld_inst->memReqFlags & Request::LLSC)
494 TheISA::handleLockedSnoopHit(ld_inst.get());
495
476 // If a older load checks this and it's true
477 // then we might have missed the snoop
478 // in which case we need to invalidate to be sure
479 ld_inst->hitExternalSnoop(true);
480 }
481 }
482 incrLdIdx(load_idx);
483 }

--- 360 unchanged lines hidden (view full) ---

844
845 // @todo: Remove this SC hack once the memory system handles it.
846 if (inst->isStoreConditional()) {
847 assert(!storeQueue[storeWBIdx].isSplit);
848 // Disable recording the result temporarily. Writing to
849 // misc regs normally updates the result, but this is not
850 // the desired behavior when handling store conditionals.
851 inst->recordResult(false);
496 // If a older load checks this and it's true
497 // then we might have missed the snoop
498 // in which case we need to invalidate to be sure
499 ld_inst->hitExternalSnoop(true);
500 }
501 }
502 incrLdIdx(load_idx);
503 }

--- 360 unchanged lines hidden (view full) ---

864
865 // @todo: Remove this SC hack once the memory system handles it.
866 if (inst->isStoreConditional()) {
867 assert(!storeQueue[storeWBIdx].isSplit);
868 // Disable recording the result temporarily. Writing to
869 // misc regs normally updates the result, but this is not
870 // the desired behavior when handling store conditionals.
871 inst->recordResult(false);
852 bool success = TheISA::handleLockedWrite(inst.get(), req);
872 bool success = TheISA::handleLockedWrite(inst.get(), req, cacheBlockMask);
853 inst->recordResult(true);
854
855 if (!success) {
856 // Instantly complete this store.
857 DPRINTF(LSQUnit, "Store conditional [sn:%lli] failed. "
858 "Instantly completing it.\n",
859 inst->seqNum);
860 WritebackEvent *wb = new WritebackEvent(inst, data_pkt, this);

--- 440 unchanged lines hidden ---
873 inst->recordResult(true);
874
875 if (!success) {
876 // Instantly complete this store.
877 DPRINTF(LSQUnit, "Store conditional [sn:%lli] failed. "
878 "Instantly completing it.\n",
879 inst->seqNum);
880 WritebackEvent *wb = new WritebackEvent(inst, data_pkt, this);

--- 440 unchanged lines hidden ---