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;
436 DPRINTF(LSQUnit, "Got snoop for address %#x\n", pkt->getAddr());
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++) {
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
461 // If this is the only load in the LSQ we don't care
462 if (load_idx == loadTail)
463 return;
464
465 incrLdIdx(load_idx);
466
454 DPRINTF(LSQUnit, "Got snoop for address %#x\n", pkt->getAddr());
455 Addr invalidate_addr = pkt->getAddr() & cacheBlockMask;
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);
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
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);
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 ---