1 2/* |
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. |
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 |
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", |
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); |
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 --- |