lsq_impl.hh (13560:f8732494c155) | lsq_impl.hh (13590:d7e018859709) |
---|---|
1/* | 1/* |
2 * Copyright (c) 2011-2012, 2014 ARM Limited | 2 * Copyright (c) 2011-2012, 2014, 2017-2018 ARM Limited |
3 * Copyright (c) 2013 Advanced Micro Devices, Inc. 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 --- 45 unchanged lines hidden (view full) --- 56#include "debug/Writeback.hh" 57#include "params/DerivO3CPU.hh" 58 59using namespace std; 60 61template <class Impl> 62LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params) 63 : cpu(cpu_ptr), iewStage(iew_ptr), | 3 * Copyright (c) 2013 Advanced Micro Devices, Inc. 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 --- 45 unchanged lines hidden (view full) --- 56#include "debug/Writeback.hh" 57#include "params/DerivO3CPU.hh" 58 59using namespace std; 60 61template <class Impl> 62LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params) 63 : cpu(cpu_ptr), iewStage(iew_ptr), |
64 _cacheBlocked(false), 65 cacheStorePorts(params->cacheStorePorts), usedStorePorts(0), |
|
64 lsqPolicy(params->smtLSQPolicy), 65 LQEntries(params->LQEntries), 66 SQEntries(params->SQEntries), 67 maxLQEntries(maxLSQAllocation(lsqPolicy, LQEntries, params->numThreads, 68 params->smtLSQThreshold)), 69 maxSQEntries(maxLSQAllocation(lsqPolicy, SQEntries, params->numThreads, 70 params->smtLSQThreshold)), 71 numThreads(params->numThreads) 72{ 73 assert(numThreads > 0 && numThreads <= Impl::MaxThreads); 74 75 //**********************************************/ 76 //************ Handle SMT Parameters ***********/ 77 //**********************************************/ 78 | 66 lsqPolicy(params->smtLSQPolicy), 67 LQEntries(params->LQEntries), 68 SQEntries(params->SQEntries), 69 maxLQEntries(maxLSQAllocation(lsqPolicy, LQEntries, params->numThreads, 70 params->smtLSQThreshold)), 71 maxSQEntries(maxLSQAllocation(lsqPolicy, SQEntries, params->numThreads, 72 params->smtLSQThreshold)), 73 numThreads(params->numThreads) 74{ 75 assert(numThreads > 0 && numThreads <= Impl::MaxThreads); 76 77 //**********************************************/ 78 //************ Handle SMT Parameters ***********/ 79 //**********************************************/ 80 |
79 //Figure out fetch policy 80 if (lsqPolicy == SMTQueuePolicy::Dynamic) { | 81 /* Run SMT olicy checks. */ 82 if (lsqPolicy == SMTQueuePolicy::Dynamic) { |
81 DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n"); 82 } else if (lsqPolicy == SMTQueuePolicy::Partitioned) { 83 DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: " 84 "%i entries per LQ | %i entries per SQ\n", 85 maxLQEntries,maxSQEntries); 86 } else if (lsqPolicy == SMTQueuePolicy::Threshold) { 87 | 83 DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n"); 84 } else if (lsqPolicy == SMTQueuePolicy::Partitioned) { 85 DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: " 86 "%i entries per LQ | %i entries per SQ\n", 87 maxLQEntries,maxSQEntries); 88 } else if (lsqPolicy == SMTQueuePolicy::Threshold) { 89 |
88 assert(params->smtLSQThreshold > LQEntries); 89 assert(params->smtLSQThreshold > SQEntries); | 90 assert(params->smtLSQThreshold > params->LQEntries); 91 assert(params->smtLSQThreshold > params->SQEntries); |
90 91 DPRINTF(LSQ, "LSQ sharing policy set to Threshold: " 92 "%i entries per LQ | %i entries per SQ\n", 93 maxLQEntries,maxSQEntries); 94 } else { 95 panic("Invalid LSQ sharing policy. Options are: Dynamic, " 96 "Partitioned, Threshold"); 97 } --- 60 unchanged lines hidden (view full) --- 158 159 return drained; 160} 161 162template <class Impl> 163void 164LSQ<Impl>::takeOverFrom() 165{ | 92 93 DPRINTF(LSQ, "LSQ sharing policy set to Threshold: " 94 "%i entries per LQ | %i entries per SQ\n", 95 maxLQEntries,maxSQEntries); 96 } else { 97 panic("Invalid LSQ sharing policy. Options are: Dynamic, " 98 "Partitioned, Threshold"); 99 } --- 60 unchanged lines hidden (view full) --- 160 161 return drained; 162} 163 164template <class Impl> 165void 166LSQ<Impl>::takeOverFrom() 167{ |
168 usedStorePorts = 0; 169 _cacheBlocked = false; 170 |
|
166 for (ThreadID tid = 0; tid < numThreads; tid++) { 167 thread[tid].takeOverFrom(); 168 } 169} 170 | 171 for (ThreadID tid = 0; tid < numThreads; tid++) { 172 thread[tid].takeOverFrom(); 173 } 174} 175 |
171template <class Impl> 172int 173LSQ<Impl>::entryAmount(ThreadID num_threads) | 176template 177bool 178LSQ<Impl>::cacheBlocked() const |
174{ | 179{ |
175 if (lsqPolicy == SMTQueuePolicy::Partitioned) { 176 return LQEntries / num_threads; 177 } else { 178 return 0; 179 } | 180 return _cacheBlocked; |
180} 181 | 181} 182 |
182template <class Impl> 183void 184LSQ<Impl>::resetEntries() 185{ 186 if (lsqPolicy != SMTQueuePolicy::Dynamic || numThreads > 1) { 187 int active_threads = activeThreads->size(); 188 189 int maxEntries; 190 191 if (lsqPolicy == SMTQueuePolicy::Partitioned) { 192 maxEntries = LQEntries / active_threads; 193 } else if (lsqPolicy == SMTQueuePolicy::Threshold && 194 active_threads == 1) { 195 maxEntries = LQEntries; 196 } else { 197 maxEntries = LQEntries; 198 } 199 200 list<ThreadID>::iterator threads = activeThreads->begin(); 201 list<ThreadID>::iterator end = activeThreads->end(); 202 203 while (threads != end) { 204 ThreadID tid = *threads++; 205 206 resizeEntries(maxEntries, tid); 207 } 208 } 209} 210 | |
211template<class Impl> 212void | 183template<class Impl> 184void |
213LSQ<Impl>::removeEntries(ThreadID tid) | 185LSQ<Impl>::cacheBlocked(bool v) |
214{ | 186{ |
215 thread[tid].clearLQ(); 216 thread[tid].clearSQ(); | 187 _cacheBlocked = v; |
217} 218 219template<class Impl> | 188} 189 190template<class Impl> |
220void 221LSQ<Impl>::resizeEntries(unsigned size, ThreadID tid) | 191bool 192LSQ<Impl>::storePortAvailable() const |
222{ | 193{ |
223 thread[tid].resizeLQ(size); 224 thread[tid].resizeSQ(size); | 194 return usedStorePorts < cacheStorePorts; |
225} 226 227template<class Impl> 228void | 195} 196 197template<class Impl> 198void |
229LSQ<Impl>::tick() | 199LSQ<Impl>::storePortBusy() |
230{ | 200{ |
231 list<ThreadID>::iterator threads = activeThreads->begin(); 232 list<ThreadID>::iterator end = activeThreads->end(); 233 234 while (threads != end) { 235 ThreadID tid = *threads++; 236 237 thread[tid].tick(); 238 } | 201 usedStorePorts++; 202 assert(usedStorePorts <= cacheStorePorts); |
239} 240 241template<class Impl> 242void 243LSQ<Impl>::insertLoad(const DynInstPtr &load_inst) 244{ 245 ThreadID tid = load_inst->threadNumber; 246 --- 64 unchanged lines hidden (view full) --- 311 return false; 312} 313 314template <class Impl> 315void 316LSQ<Impl>::recvReqRetry() 317{ 318 iewStage->cacheUnblocked(); | 203} 204 205template<class Impl> 206void 207LSQ<Impl>::insertLoad(const DynInstPtr &load_inst) 208{ 209 ThreadID tid = load_inst->threadNumber; 210 --- 64 unchanged lines hidden (view full) --- 275 return false; 276} 277 278template <class Impl> 279void 280LSQ<Impl>::recvReqRetry() 281{ 282 iewStage->cacheUnblocked(); |
283 cacheBlocked(false); |
|
319 320 for (ThreadID tid : *activeThreads) { 321 thread[tid].recvRetry(); 322 } 323} 324 325template <class Impl> | 284 285 for (ThreadID tid : *activeThreads) { 286 thread[tid].recvRetry(); 287 } 288} 289 290template <class Impl> |
291void 292LSQ<Impl>::completeDataAccess(PacketPtr pkt) 293{ 294 auto senderState = dynamic_cast<LSQSenderState*>(pkt->senderState); 295 thread[cpu->contextToThread(senderState->contextId())] 296 .completeDataAccess(pkt); 297} 298 299template <class Impl> |
|
326bool 327LSQ<Impl>::recvTimingResp(PacketPtr pkt) 328{ 329 if (pkt->isError()) 330 DPRINTF(LSQ, "Got error packet back for address: %#X\n", 331 pkt->getAddr()); 332 | 300bool 301LSQ<Impl>::recvTimingResp(PacketPtr pkt) 302{ 303 if (pkt->isError()) 304 DPRINTF(LSQ, "Got error packet back for address: %#X\n", 305 pkt->getAddr()); 306 |
333 thread[cpu->contextToThread(pkt->req->contextId())] 334 .completeDataAccess(pkt); | 307 auto senderState = dynamic_cast<LSQSenderState*>(pkt->senderState); 308 panic_if(!senderState, "Got packet back with unknown sender state\n"); |
335 | 309 |
310 thread[cpu->contextToThread(senderState->contextId())].recvTimingResp(pkt); 311 |
|
336 if (pkt->isInvalidate()) { 337 // This response also contains an invalidate; e.g. this can be the case 338 // if cmd is ReadRespWithInvalidate. 339 // 340 // The calling order between completeDataAccess and checkSnoop matters. 341 // By calling checkSnoop after completeDataAccess, we ensure that the 342 // fault set by checkSnoop is not lost. Calling writeback (more 343 // specifically inst->completeAcc) in completeDataAccess overwrites 344 // fault, and in case this instruction requires squashing (as 345 // determined by checkSnoop), the ReExec fault set by checkSnoop would 346 // be lost otherwise. 347 348 DPRINTF(LSQ, "received invalidation with response for addr:%#x\n", 349 pkt->getAddr()); 350 351 for (ThreadID tid = 0; tid < numThreads; tid++) { 352 thread[tid].checkSnoop(pkt); 353 } 354 } | 312 if (pkt->isInvalidate()) { 313 // This response also contains an invalidate; e.g. this can be the case 314 // if cmd is ReadRespWithInvalidate. 315 // 316 // The calling order between completeDataAccess and checkSnoop matters. 317 // By calling checkSnoop after completeDataAccess, we ensure that the 318 // fault set by checkSnoop is not lost. Calling writeback (more 319 // specifically inst->completeAcc) in completeDataAccess overwrites 320 // fault, and in case this instruction requires squashing (as 321 // determined by checkSnoop), the ReExec fault set by checkSnoop would 322 // be lost otherwise. 323 324 DPRINTF(LSQ, "received invalidation with response for addr:%#x\n", 325 pkt->getAddr()); 326 327 for (ThreadID tid = 0; tid < numThreads; tid++) { 328 thread[tid].checkSnoop(pkt); 329 } 330 } |
331 // Update the LSQRequest state (this may delete the request) 332 senderState->request()->packetReplied(); |
|
355 | 333 |
356 delete pkt; | |
357 return true; 358} 359 360template <class Impl> 361void 362LSQ<Impl>::recvTimingSnoopReq(PacketPtr pkt) 363{ 364 DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(), --- 311 unchanged lines hidden (view full) --- 676 677 while (threads != end) { 678 ThreadID tid = *threads++; 679 680 thread[tid].dumpInsts(); 681 } 682} 683 | 334 return true; 335} 336 337template <class Impl> 338void 339LSQ<Impl>::recvTimingSnoopReq(PacketPtr pkt) 340{ 341 DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(), --- 311 unchanged lines hidden (view full) --- 653 654 while (threads != end) { 655 ThreadID tid = *threads++; 656 657 thread[tid].dumpInsts(); 658 } 659} 660 |
661static Addr 662addrBlockOffset(Addr addr, unsigned int block_size) 663{ 664 return addr & (block_size - 1); 665} 666 667static Addr 668addrBlockAlign(Addr addr, uint64_t block_size) 669{ 670 return addr & ~(block_size - 1); 671} 672 673static bool 674transferNeedsBurst(Addr addr, uint64_t size, uint64_t block_size) 675{ 676 return (addrBlockOffset(addr, block_size) + size) > block_size; 677} 678 679template<class Impl> 680Fault 681LSQ<Impl>::pushRequest(const DynInstPtr& inst, bool isLoad, uint8_t *data, 682 unsigned int size, Addr addr, Request::Flags flags, 683 uint64_t *res) 684{ 685 ThreadID tid = cpu->contextToThread(inst->contextId()); 686 auto cacheLineSize = cpu->cacheLineSize(); 687 bool needs_burst = transferNeedsBurst(addr, size, cacheLineSize); 688 LSQRequest* req = nullptr; 689 690 if (inst->translationStarted()) { 691 req = inst->savedReq; 692 assert(req); 693 } else { 694 if (needs_burst) { 695 req = new SplitDataRequest(&thread[tid], inst, isLoad, addr, 696 size, flags, data, res); 697 } else { 698 req = new SingleDataRequest(&thread[tid], inst, isLoad, addr, 699 size, flags, data, res); 700 } 701 assert(req); 702 inst->setRequest(); 703 req->taskId(cpu->taskId()); 704 705 req->initiateTranslation(); 706 } 707 708 /* This is the place were instructions get the effAddr. */ 709 if (req->isTranslationComplete()) { 710 if (inst->getFault() == NoFault) { 711 inst->effAddr = req->getVaddr(); 712 inst->effSize = size; 713 inst->effAddrValid(true); 714 715 if (cpu->checker) { 716 inst->reqToVerify = std::make_shared<Request>(*req->request()); 717 } 718 if (isLoad) 719 inst->getFault() = cpu->read(req, inst->lqIdx); 720 else 721 inst->getFault() = cpu->write(req, data, inst->sqIdx); 722 } else if (isLoad) { 723 // Commit will have to clean up whatever happened. Set this 724 // instruction as executed. 725 inst->setExecuted(); 726 } 727 } 728 729 if (inst->traceData) 730 inst->traceData->setMem(addr, size, flags); 731 732 return inst->getFault(); 733} 734 735template<class Impl> 736void 737LSQ<Impl>::SingleDataRequest::finish(const Fault &fault, const RequestPtr &req, 738 ThreadContext* tc, BaseTLB::Mode mode) 739{ 740 _fault.push_back(fault); 741 numInTranslationFragments = 0; 742 numTranslatedFragments = 1; 743 /* If the instruction has been squahsed, let the request know 744 * as it may have to self-destruct. */ 745 if (_inst->isSquashed()) { 746 this->squashTranslation(); 747 } else { 748 _inst->strictlyOrdered(req->isStrictlyOrdered()); 749 750 flags.set(Flag::TranslationFinished); 751 if (fault == NoFault) { 752 _inst->physEffAddr = req->getPaddr(); 753 _inst->memReqFlags = req->getFlags(); 754 if (req->isCondSwap()) { 755 assert(_res); 756 req->setExtraData(*_res); 757 } 758 setState(State::Request); 759 } else { 760 setState(State::Fault); 761 } 762 763 LSQRequest::_inst->fault = fault; 764 LSQRequest::_inst->translationCompleted(true); 765 } 766} 767 768template<class Impl> 769void 770LSQ<Impl>::SplitDataRequest::finish(const Fault &fault, const RequestPtr &req, 771 ThreadContext* tc, BaseTLB::Mode mode) 772{ 773 _fault.push_back(fault); 774 assert(req == _requests[numTranslatedFragments] || this->isDelayed()); 775 776 numInTranslationFragments--; 777 numTranslatedFragments++; 778 779 mainReq->setFlags(req->getFlags()); 780 781 if (numTranslatedFragments == _requests.size()) { 782 if (_inst->isSquashed()) { 783 this->squashTranslation(); 784 } else { 785 _inst->strictlyOrdered(mainReq->isStrictlyOrdered()); 786 flags.set(Flag::TranslationFinished); 787 auto fault_it = _fault.begin(); 788 /* Ffwd to the first NoFault. */ 789 while (fault_it != _fault.end() && *fault_it == NoFault) 790 fault_it++; 791 /* If none of the fragments faulted: */ 792 if (fault_it == _fault.end()) { 793 _inst->physEffAddr = request(0)->getPaddr(); 794 795 _inst->memReqFlags = mainReq->getFlags(); 796 if (mainReq->isCondSwap()) { 797 assert(_res); 798 mainReq->setExtraData(*_res); 799 } 800 setState(State::Request); 801 _inst->fault = NoFault; 802 } else { 803 setState(State::Fault); 804 _inst->fault = *fault_it; 805 } 806 _inst->translationCompleted(true); 807 } 808 } 809} 810 811template<class Impl> 812void 813LSQ<Impl>::SingleDataRequest::initiateTranslation() 814{ 815 _inst->translationStarted(true); 816 setState(State::Translation); 817 flags.set(Flag::TranslationStarted); 818 819 _inst->savedReq = this; 820 sendFragmentToTranslation(0); 821 822 if (isTranslationComplete()) { 823 } 824} 825 826template<class Impl> 827PacketPtr 828LSQ<Impl>::SplitDataRequest::mainPacket() 829{ 830 return _mainPacket; 831} 832 833template<class Impl> 834RequestPtr 835LSQ<Impl>::SplitDataRequest::mainRequest() 836{ 837 return mainReq; 838} 839 840template<class Impl> 841void 842LSQ<Impl>::SplitDataRequest::initiateTranslation() 843{ 844 _inst->translationStarted(true); 845 setState(State::Translation); 846 flags.set(Flag::TranslationStarted); 847 848 unsigned int cacheLineSize = _port.cacheLineSize(); 849 Addr base_addr = _addr; 850 Addr next_addr = addrBlockAlign(_addr + cacheLineSize, cacheLineSize); 851 Addr final_addr = addrBlockAlign(_addr + _size, cacheLineSize); 852 uint32_t size_so_far = 0; 853 854 mainReq = std::make_shared<Request>(_inst->getASID(), base_addr, 855 _size, _flags, _inst->masterId(), 856 _inst->instAddr(), _inst->contextId()); 857 858 // Paddr is not used in mainReq. However, we will accumulate the flags 859 // from the sub requests into mainReq by calling setFlags() in finish(). 860 // setFlags() assumes that paddr is set so flip the paddr valid bit here to 861 // avoid a potential assert in setFlags() when we call it from finish(). 862 mainReq->setPaddr(0); 863 864 /* Get the pre-fix, possibly unaligned. */ 865 _requests.push_back(std::make_shared<Request>(_inst->getASID(), base_addr, 866 next_addr - base_addr, _flags, _inst->masterId(), 867 _inst->instAddr(), _inst->contextId())); 868 size_so_far = next_addr - base_addr; 869 870 /* We are block aligned now, reading whole blocks. */ 871 base_addr = next_addr; 872 while (base_addr != final_addr) { 873 _requests.push_back(std::make_shared<Request>(_inst->getASID(), 874 base_addr, cacheLineSize, _flags, _inst->masterId(), 875 _inst->instAddr(), _inst->contextId())); 876 size_so_far += cacheLineSize; 877 base_addr += cacheLineSize; 878 } 879 880 /* Deal with the tail. */ 881 if (size_so_far < _size) { 882 _requests.push_back(std::make_shared<Request>(_inst->getASID(), 883 base_addr, _size - size_so_far, _flags, _inst->masterId(), 884 _inst->instAddr(), _inst->contextId())); 885 } 886 887 /* Setup the requests and send them to translation. */ 888 for (auto& r: _requests) { 889 r->setReqInstSeqNum(_inst->seqNum); 890 r->taskId(_taskId); 891 } 892 this->_inst->savedReq = this; 893 numInTranslationFragments = 0; 894 numTranslatedFragments = 0; 895 896 for (uint32_t i = 0; i < _requests.size(); i++) { 897 sendFragmentToTranslation(i); 898 } 899} 900 901template<class Impl> 902void 903LSQ<Impl>::LSQRequest::sendFragmentToTranslation(int i) 904{ 905 numInTranslationFragments++; 906 _port.dTLB()->translateTiming( 907 this->request(i), 908 this->_inst->thread->getTC(), this, 909 this->isLoad() ? BaseTLB::Read : BaseTLB::Write); 910} 911 912template<class Impl> 913bool 914LSQ<Impl>::SingleDataRequest::recvTimingResp(PacketPtr pkt) 915{ 916 assert(_numOutstandingPackets == 1); 917 auto state = dynamic_cast<LSQSenderState*>(pkt->senderState); 918 setState(State::Complete); 919 flags.set(Flag::Complete); 920 state->outstanding--; 921 assert(pkt == _packets.front()); 922 _port.completeDataAccess(pkt); 923 return true; 924} 925 926template<class Impl> 927bool 928LSQ<Impl>::SplitDataRequest::recvTimingResp(PacketPtr pkt) 929{ 930 auto state = dynamic_cast<LSQSenderState*>(pkt->senderState); 931 uint32_t pktIdx = 0; 932 while (pktIdx < _packets.size() && pkt != _packets[pktIdx]) 933 pktIdx++; 934 assert(pktIdx < _packets.size()); 935 assert(pkt->req == _requests[pktIdx]); 936 assert(pkt == _packets[pktIdx]); 937 numReceivedPackets++; 938 state->outstanding--; 939 if (numReceivedPackets == _packets.size()) { 940 setState(State::Complete); 941 flags.set(Flag::Complete); 942 /* Assemble packets. */ 943 PacketPtr resp = isLoad() 944 ? Packet::createRead(mainReq) 945 : Packet::createWrite(mainReq); 946 if (isLoad()) 947 resp->dataStatic(_inst->memData); 948 else 949 resp->dataStatic(_data); 950 resp->senderState = _senderState; 951 _port.completeDataAccess(resp); 952 delete resp; 953 } 954 return true; 955} 956 957template<class Impl> 958void 959LSQ<Impl>::SingleDataRequest::buildPackets() 960{ 961 assert(_senderState); 962 /* Retries do not create new packets. */ 963 if (_packets.size() == 0) { 964 _packets.push_back( 965 isLoad() 966 ? Packet::createRead(request()) 967 : Packet::createWrite(request())); 968 _packets.back()->dataStatic(_inst->memData); 969 _packets.back()->senderState = _senderState; 970 } 971 assert(_packets.size() == 1); 972} 973 974template<class Impl> 975void 976LSQ<Impl>::SplitDataRequest::buildPackets() 977{ 978 /* Extra data?? */ 979 ptrdiff_t offset = 0; 980 if (_packets.size() == 0) { 981 /* New stuff */ 982 if (isLoad()) { 983 _mainPacket = Packet::createRead(mainReq); 984 _mainPacket->dataStatic(_inst->memData); 985 } 986 for (auto& r: _requests) { 987 PacketPtr pkt = isLoad() ? Packet::createRead(r) 988 : Packet::createWrite(r); 989 if (isLoad()) { 990 pkt->dataStatic(_inst->memData + offset); 991 } else { 992 uint8_t* req_data = new uint8_t[r->getSize()]; 993 std::memcpy(req_data, 994 _inst->memData + offset, 995 r->getSize()); 996 pkt->dataDynamic(req_data); 997 } 998 offset += r->getSize(); 999 pkt->senderState = _senderState; 1000 _packets.push_back(pkt); 1001 } 1002 } 1003 assert(_packets.size() == _requests.size()); 1004} 1005 1006template<class Impl> 1007void 1008LSQ<Impl>::SingleDataRequest::sendPacketToCache() 1009{ 1010 assert(_numOutstandingPackets == 0); 1011 if (lsqUnit()->trySendPacket(isLoad(), _packets.at(0))) 1012 _numOutstandingPackets = 1; 1013} 1014 1015template<class Impl> 1016void 1017LSQ<Impl>::SplitDataRequest::sendPacketToCache() 1018{ 1019 /* Try to send the packets. */ 1020 while (numReceivedPackets + _numOutstandingPackets < _packets.size() && 1021 lsqUnit()->trySendPacket(isLoad(), 1022 _packets.at(numReceivedPackets + _numOutstandingPackets))) { 1023 _numOutstandingPackets++; 1024 } 1025} 1026 1027template<class Impl> 1028void 1029LSQ<Impl>::SingleDataRequest::handleIprWrite(ThreadContext *thread, 1030 PacketPtr pkt) 1031{ 1032 TheISA::handleIprWrite(thread, pkt); 1033} 1034 1035template<class Impl> 1036void 1037LSQ<Impl>::SplitDataRequest::handleIprWrite(ThreadContext *thread, 1038 PacketPtr mainPkt) 1039{ 1040 unsigned offset = 0; 1041 for (auto r: _requests) { 1042 PacketPtr pkt = new Packet(r, MemCmd::WriteReq); 1043 pkt->dataStatic(mainPkt->getPtr<uint8_t>() + offset); 1044 TheISA::handleIprWrite(thread, pkt); 1045 offset += r->getSize(); 1046 delete pkt; 1047 } 1048} 1049 1050template<class Impl> 1051Cycles 1052LSQ<Impl>::SingleDataRequest::handleIprRead(ThreadContext *thread, 1053 PacketPtr pkt) 1054{ 1055 return TheISA::handleIprRead(thread, pkt); 1056} 1057 1058template<class Impl> 1059Cycles 1060LSQ<Impl>::SplitDataRequest::handleIprRead(ThreadContext *thread, 1061 PacketPtr mainPkt) 1062{ 1063 Cycles delay(0); 1064 unsigned offset = 0; 1065 1066 for (auto r: _requests) { 1067 PacketPtr pkt = new Packet(r, MemCmd::ReadReq); 1068 pkt->dataStatic(mainPkt->getPtr<uint8_t>() + offset); 1069 Cycles d = TheISA::handleIprRead(thread, pkt); 1070 if (d > delay) 1071 delay = d; 1072 offset += r->getSize(); 1073 delete pkt; 1074 } 1075 return delay; 1076} 1077 1078template<class Impl> 1079bool 1080LSQ<Impl>::SingleDataRequest::isCacheBlockHit(Addr blockAddr, Addr blockMask) 1081{ 1082 return ( (LSQRequest::_requests[0]->getPaddr() & blockMask) == blockAddr); 1083} 1084 1085template<class Impl> 1086bool 1087LSQ<Impl>::SplitDataRequest::isCacheBlockHit(Addr blockAddr, Addr blockMask) 1088{ 1089 bool is_hit = false; 1090 for (auto &r: _requests) { 1091 if ((r->getPaddr() & blockMask) == blockAddr) { 1092 is_hit = true; 1093 break; 1094 } 1095 } 1096 return is_hit; 1097} 1098 |
|
684#endif//__CPU_O3_LSQ_IMPL_HH__ | 1099#endif//__CPU_O3_LSQ_IMPL_HH__ |