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