1/* 2 * Copyright (c) 2012-2014,2017 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 496 unchanged lines hidden (view full) --- 505 /** Number of loads that were rescheduled. */ 506 Stats::Scalar lsqRescheduledLoads; 507 508 /** Number of times the LSQ is blocked due to the cache. */ 509 Stats::Scalar lsqCacheBlocked; 510 511 public: 512 /** Executes the load at the given index. */ |
513 Fault read(const RequestPtr &req, 514 RequestPtr &sreqLow, RequestPtr &sreqHigh, |
515 int load_idx); 516 517 /** Executes the store at the given index. */ |
518 Fault write(const RequestPtr &req, 519 const RequestPtr &sreqLow, const RequestPtr &sreqHigh, |
520 uint8_t *data, int store_idx); 521 522 /** Returns the index of the head load instruction. */ 523 int getLoadHead() { return loadHead; } 524 /** Returns the sequence number of the head load instruction. */ 525 InstSeqNum getLoadHeadSeqNum() 526 { 527 if (loadQueue[loadHead]) { --- 18 unchanged lines hidden (view full) --- 546 } 547 548 /** Returns whether or not the LSQ unit is stalled. */ 549 bool isStalled() { return stalled; } 550}; 551 552template <class Impl> 553Fault |
554LSQUnit<Impl>::read(const RequestPtr &req, 555 RequestPtr &sreqLow, RequestPtr &sreqHigh, |
556 int load_idx) 557{ 558 DynInstPtr load_inst = loadQueue[load_idx]; 559 560 assert(load_inst); 561 562 assert(!load_inst->isExecuted()); 563 564 // Make sure this isn't a strictly ordered load 565 // A bit of a hackish way to get strictly ordered accesses to work 566 // only if they're at the head of the LSQ and are ready to commit 567 // (at the head of the ROB too). 568 if (req->isStrictlyOrdered() && 569 (load_idx != loadHead || !load_inst->isAtCommit())) { 570 iewStage->rescheduleMemInst(load_inst); 571 ++lsqRescheduledLoads; 572 DPRINTF(LSQUnit, "Strictly ordered load [sn:%lli] PC %s\n", 573 load_inst->seqNum, load_inst->pcState()); 574 |
575 return std::make_shared<GenericISA::M5PanicFault>( 576 "Strictly ordered load [sn:%llx] PC %s\n", 577 load_inst->seqNum, load_inst->pcState()); 578 } 579 580 // Check the SQ for any previous stores that might lead to forwarding 581 int store_idx = load_inst->sqIdx; 582 --- 33 unchanged lines hidden (view full) --- 616 fst_data_pkt->dataStatic(load_inst->memData); 617 snd_data_pkt->dataStatic(load_inst->memData + sreqLow->getSize()); 618 619 delay = TheISA::handleIprRead(thread, fst_data_pkt); 620 Cycles delay2 = TheISA::handleIprRead(thread, snd_data_pkt); 621 if (delay2 > delay) 622 delay = delay2; 623 |
624 delete fst_data_pkt; 625 delete snd_data_pkt; 626 } 627 WritebackEvent *wb = new WritebackEvent(load_inst, data_pkt, this); 628 cpu->schedule(wb, cpu->clockEdge(delay)); 629 return NoFault; 630 } 631 --- 60 unchanged lines hidden (view full) --- 692 693 WritebackEvent *wb = new WritebackEvent(load_inst, data_pkt, this); 694 695 // We'll say this has a 1 cycle load-store forwarding latency 696 // for now. 697 // @todo: Need to make this a parameter. 698 cpu->schedule(wb, curTick()); 699 |
700 ++lsqForwLoads; 701 return NoFault; 702 } else if ( 703 (!req->isLLSC() && 704 ((store_has_lower_limit && lower_load_has_store_part) || 705 (store_has_upper_limit && upper_load_has_store_part) || 706 (lower_load_has_store_part && upper_load_has_store_part))) || 707 (req->isLLSC() && --- 29 unchanged lines hidden (view full) --- 737 ++lsqRescheduledLoads; 738 739 // Do not generate a writeback event as this instruction is not 740 // complete. 741 DPRINTF(LSQUnit, "Load-store forwarding mis-match. " 742 "Store idx %i to load addr %#x\n", 743 store_idx, req->getVaddr()); 744 |
745 return NoFault; 746 } 747 } 748 749 // If there's no forwarding case, then go access memory 750 DPRINTF(LSQUnit, "Doing memory access for inst [sn:%lli] PC %s\n", 751 load_inst->seqNum, load_inst->pcState()); 752 --- 63 unchanged lines hidden (view full) --- 816 } 817 818 // If the cache was blocked, or has become blocked due to the access, 819 // handle it. 820 if (!successful_load) { 821 if (!sreqLow) { 822 // Packet wasn't split, just delete main packet info 823 delete state; |
824 delete data_pkt; 825 } 826 827 if (TheISA::HasUnalignedMemAcc && sreqLow) { 828 if (!completedFirst) { 829 // Split packet, but first failed. Delete all state. 830 delete state; |
831 delete data_pkt; 832 delete fst_data_pkt; 833 delete snd_data_pkt; |
834 sreqLow.reset(); 835 sreqHigh.reset(); |
836 } else { 837 // Can't delete main packet data or state because first packet 838 // was sent to the memory system 839 delete data_pkt; |
840 delete snd_data_pkt; |
841 sreqHigh.reset(); |
842 } 843 } 844 845 ++lsqCacheBlocked; 846 847 iewStage->blockMemInst(load_inst); 848 849 // No fault occurred, even though the interface is blocked. 850 return NoFault; 851 } 852 853 return NoFault; 854} 855 856template <class Impl> 857Fault |
858LSQUnit<Impl>::write(const RequestPtr &req, 859 const RequestPtr &sreqLow, const RequestPtr &sreqHigh, |
860 uint8_t *data, int store_idx) 861{ 862 assert(storeQueue[store_idx].inst); 863 864 DPRINTF(LSQUnit, "Doing write to store idx %i, addr %#x" 865 " | storeHead:%i [sn:%i]\n", 866 store_idx, req->getPaddr(), storeHead, 867 storeQueue[store_idx].inst->seqNum); --- 26 unchanged lines hidden --- |