lsq_impl.hh (13710:5ba1d8066ef0) | lsq_impl.hh (13954:2f400a5f2627) |
---|---|
1/* 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 --- 667 unchanged lines hidden (view full) --- 676 677 while (threads != end) { 678 ThreadID tid = *threads++; 679 680 thread[tid].dumpInsts(); 681 } 682} 683 | 1/* 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 --- 667 unchanged lines hidden (view full) --- 676 677 while (threads != end) { 678 ThreadID tid = *threads++; 679 680 thread[tid].dumpInsts(); 681 } 682} 683 |
684static Addr 685addrBlockOffset(Addr addr, unsigned int block_size) 686{ 687 return addr & (block_size - 1); 688} 689 690static Addr 691addrBlockAlign(Addr addr, uint64_t block_size) 692{ 693 return addr & ~(block_size - 1); 694} 695 696static bool 697transferNeedsBurst(Addr addr, uint64_t size, uint64_t block_size) 698{ 699 return (addrBlockOffset(addr, block_size) + size) > block_size; 700} 701 | |
702template<class Impl> 703Fault 704LSQ<Impl>::pushRequest(const DynInstPtr& inst, bool isLoad, uint8_t *data, 705 unsigned int size, Addr addr, Request::Flags flags, | 684template<class Impl> 685Fault 686LSQ<Impl>::pushRequest(const DynInstPtr& inst, bool isLoad, uint8_t *data, 687 unsigned int size, Addr addr, Request::Flags flags, |
706 uint64_t *res, AtomicOpFunctor *amo_op) | 688 uint64_t *res, AtomicOpFunctor *amo_op, 689 const std::vector<bool>& byteEnable) |
707{ 708 // This comming request can be either load, store or atomic. 709 // Atomic request has a corresponding pointer to its atomic memory 710 // operation 711 bool isAtomic M5_VAR_USED = !isLoad && amo_op; 712 713 ThreadID tid = cpu->contextToThread(inst->contextId()); 714 auto cacheLineSize = cpu->cacheLineSize(); --- 15 unchanged lines hidden (view full) --- 730 if (needs_burst) { 731 req = new SplitDataRequest(&thread[tid], inst, isLoad, addr, 732 size, flags, data, res); 733 } else { 734 req = new SingleDataRequest(&thread[tid], inst, isLoad, addr, 735 size, flags, data, res, amo_op); 736 } 737 assert(req); | 690{ 691 // This comming request can be either load, store or atomic. 692 // Atomic request has a corresponding pointer to its atomic memory 693 // operation 694 bool isAtomic M5_VAR_USED = !isLoad && amo_op; 695 696 ThreadID tid = cpu->contextToThread(inst->contextId()); 697 auto cacheLineSize = cpu->cacheLineSize(); --- 15 unchanged lines hidden (view full) --- 713 if (needs_burst) { 714 req = new SplitDataRequest(&thread[tid], inst, isLoad, addr, 715 size, flags, data, res); 716 } else { 717 req = new SingleDataRequest(&thread[tid], inst, isLoad, addr, 718 size, flags, data, res, amo_op); 719 } 720 assert(req); |
721 if (!byteEnable.empty()) { 722 req->_byteEnable = byteEnable; 723 } |
|
738 inst->setRequest(); 739 req->taskId(cpu->taskId()); 740 741 req->initiateTranslation(); 742 } 743 744 /* This is the place were instructions get the effAddr. */ 745 if (req->isTranslationComplete()) { --- 5 unchanged lines hidden (view full) --- 751 if (cpu->checker) { 752 inst->reqToVerify = std::make_shared<Request>(*req->request()); 753 } 754 if (isLoad) 755 inst->getFault() = cpu->read(req, inst->lqIdx); 756 else 757 inst->getFault() = cpu->write(req, data, inst->sqIdx); 758 } else if (isLoad) { | 724 inst->setRequest(); 725 req->taskId(cpu->taskId()); 726 727 req->initiateTranslation(); 728 } 729 730 /* This is the place were instructions get the effAddr. */ 731 if (req->isTranslationComplete()) { --- 5 unchanged lines hidden (view full) --- 737 if (cpu->checker) { 738 inst->reqToVerify = std::make_shared<Request>(*req->request()); 739 } 740 if (isLoad) 741 inst->getFault() = cpu->read(req, inst->lqIdx); 742 else 743 inst->getFault() = cpu->write(req, data, inst->sqIdx); 744 } else if (isLoad) { |
745 inst->setMemAccPredicate(false); |
|
759 // Commit will have to clean up whatever happened. Set this 760 // instruction as executed. 761 inst->setExecuted(); 762 } 763 } 764 765 if (inst->traceData) 766 inst->traceData->setMem(addr, size, flags); --- 76 unchanged lines hidden (view full) --- 843 } 844 } 845} 846 847template<class Impl> 848void 849LSQ<Impl>::SingleDataRequest::initiateTranslation() 850{ | 746 // Commit will have to clean up whatever happened. Set this 747 // instruction as executed. 748 inst->setExecuted(); 749 } 750 } 751 752 if (inst->traceData) 753 inst->traceData->setMem(addr, size, flags); --- 76 unchanged lines hidden (view full) --- 830 } 831 } 832} 833 834template<class Impl> 835void 836LSQ<Impl>::SingleDataRequest::initiateTranslation() 837{ |
851 _inst->translationStarted(true); 852 setState(State::Translation); 853 flags.set(Flag::TranslationStarted); | 838 assert(_requests.size() == 0); |
854 | 839 |
855 _inst->savedReq = this; 856 sendFragmentToTranslation(0); | 840 this->addRequest(_addr, _size, _byteEnable); |
857 | 841 |
858 if (isTranslationComplete()) { | 842 if (_requests.size() > 0) { 843 _requests.back()->setReqInstSeqNum(_inst->seqNum); 844 _requests.back()->taskId(_taskId); 845 _inst->translationStarted(true); 846 setState(State::Translation); 847 flags.set(Flag::TranslationStarted); 848 849 _inst->savedReq = this; 850 sendFragmentToTranslation(0); 851 } else { 852 _inst->setMemAccPredicate(false); |
859 } 860} 861 862template<class Impl> 863PacketPtr 864LSQ<Impl>::SplitDataRequest::mainPacket() 865{ 866 return _mainPacket; --- 5 unchanged lines hidden (view full) --- 872{ 873 return mainReq; 874} 875 876template<class Impl> 877void 878LSQ<Impl>::SplitDataRequest::initiateTranslation() 879{ | 853 } 854} 855 856template<class Impl> 857PacketPtr 858LSQ<Impl>::SplitDataRequest::mainPacket() 859{ 860 return _mainPacket; --- 5 unchanged lines hidden (view full) --- 866{ 867 return mainReq; 868} 869 870template<class Impl> 871void 872LSQ<Impl>::SplitDataRequest::initiateTranslation() 873{ |
880 _inst->translationStarted(true); 881 setState(State::Translation); 882 flags.set(Flag::TranslationStarted); 883 884 unsigned int cacheLineSize = _port.cacheLineSize(); | 874 auto cacheLineSize = _port.cacheLineSize(); |
885 Addr base_addr = _addr; 886 Addr next_addr = addrBlockAlign(_addr + cacheLineSize, cacheLineSize); 887 Addr final_addr = addrBlockAlign(_addr + _size, cacheLineSize); 888 uint32_t size_so_far = 0; 889 890 mainReq = std::make_shared<Request>(_inst->getASID(), base_addr, 891 _size, _flags, _inst->masterId(), 892 _inst->instAddr(), _inst->contextId()); | 875 Addr base_addr = _addr; 876 Addr next_addr = addrBlockAlign(_addr + cacheLineSize, cacheLineSize); 877 Addr final_addr = addrBlockAlign(_addr + _size, cacheLineSize); 878 uint32_t size_so_far = 0; 879 880 mainReq = std::make_shared<Request>(_inst->getASID(), base_addr, 881 _size, _flags, _inst->masterId(), 882 _inst->instAddr(), _inst->contextId()); |
883 if (!_byteEnable.empty()) { 884 mainReq->setByteEnable(_byteEnable); 885 } |
|
893 894 // Paddr is not used in mainReq. However, we will accumulate the flags 895 // from the sub requests into mainReq by calling setFlags() in finish(). 896 // setFlags() assumes that paddr is set so flip the paddr valid bit here to 897 // avoid a potential assert in setFlags() when we call it from finish(). 898 mainReq->setPaddr(0); 899 900 /* Get the pre-fix, possibly unaligned. */ | 886 887 // Paddr is not used in mainReq. However, we will accumulate the flags 888 // from the sub requests into mainReq by calling setFlags() in finish(). 889 // setFlags() assumes that paddr is set so flip the paddr valid bit here to 890 // avoid a potential assert in setFlags() when we call it from finish(). 891 mainReq->setPaddr(0); 892 893 /* Get the pre-fix, possibly unaligned. */ |
901 _requests.push_back(std::make_shared<Request>(_inst->getASID(), base_addr, 902 next_addr - base_addr, _flags, _inst->masterId(), 903 _inst->instAddr(), _inst->contextId())); | 894 if (_byteEnable.empty()) { 895 this->addRequest(base_addr, next_addr - base_addr, _byteEnable); 896 } else { 897 auto it_start = _byteEnable.begin(); 898 auto it_end = _byteEnable.begin() + (next_addr - base_addr); 899 this->addRequest(base_addr, next_addr - base_addr, 900 std::vector<bool>(it_start, it_end)); 901 } |
904 size_so_far = next_addr - base_addr; 905 906 /* We are block aligned now, reading whole blocks. */ 907 base_addr = next_addr; 908 while (base_addr != final_addr) { | 902 size_so_far = next_addr - base_addr; 903 904 /* We are block aligned now, reading whole blocks. */ 905 base_addr = next_addr; 906 while (base_addr != final_addr) { |
909 _requests.push_back(std::make_shared<Request>(_inst->getASID(), 910 base_addr, cacheLineSize, _flags, _inst->masterId(), 911 _inst->instAddr(), _inst->contextId())); | 907 if (_byteEnable.empty()) { 908 this->addRequest(base_addr, cacheLineSize, _byteEnable); 909 } else { 910 auto it_start = _byteEnable.begin() + size_so_far; 911 auto it_end = _byteEnable.begin() + size_so_far + cacheLineSize; 912 this->addRequest(base_addr, cacheLineSize, 913 std::vector<bool>(it_start, it_end)); 914 } |
912 size_so_far += cacheLineSize; 913 base_addr += cacheLineSize; 914 } 915 916 /* Deal with the tail. */ 917 if (size_so_far < _size) { | 915 size_so_far += cacheLineSize; 916 base_addr += cacheLineSize; 917 } 918 919 /* Deal with the tail. */ 920 if (size_so_far < _size) { |
918 _requests.push_back(std::make_shared<Request>(_inst->getASID(), 919 base_addr, _size - size_so_far, _flags, _inst->masterId(), 920 _inst->instAddr(), _inst->contextId())); | 921 if (_byteEnable.empty()) { 922 this->addRequest(base_addr, _size - size_so_far, _byteEnable); 923 } else { 924 auto it_start = _byteEnable.begin() + size_so_far; 925 auto it_end = _byteEnable.end(); 926 this->addRequest(base_addr, _size - size_so_far, 927 std::vector<bool>(it_start, it_end)); 928 } |
921 } 922 | 929 } 930 |
923 /* Setup the requests and send them to translation. */ 924 for (auto& r: _requests) { 925 r->setReqInstSeqNum(_inst->seqNum); 926 r->taskId(_taskId); 927 } 928 this->_inst->savedReq = this; 929 numInTranslationFragments = 0; 930 numTranslatedFragments = 0; | 931 if (_requests.size() > 0) { 932 /* Setup the requests and send them to translation. */ 933 for (auto& r: _requests) { 934 r->setReqInstSeqNum(_inst->seqNum); 935 r->taskId(_taskId); 936 } |
931 | 937 |
932 for (uint32_t i = 0; i < _requests.size(); i++) { 933 sendFragmentToTranslation(i); | 938 _inst->translationStarted(true); 939 setState(State::Translation); 940 flags.set(Flag::TranslationStarted); 941 this->_inst->savedReq = this; 942 numInTranslationFragments = 0; 943 numTranslatedFragments = 0; 944 _fault.resize(_requests.size()); 945 946 for (uint32_t i = 0; i < _requests.size(); i++) { 947 sendFragmentToTranslation(i); 948 } 949 } else { 950 _inst->setMemAccPredicate(false); |
934 } 935} 936 937template<class Impl> 938void 939LSQ<Impl>::LSQRequest::sendFragmentToTranslation(int i) 940{ 941 numInTranslationFragments++; --- 21 unchanged lines hidden (view full) --- 963bool 964LSQ<Impl>::SplitDataRequest::recvTimingResp(PacketPtr pkt) 965{ 966 auto state = dynamic_cast<LSQSenderState*>(pkt->senderState); 967 uint32_t pktIdx = 0; 968 while (pktIdx < _packets.size() && pkt != _packets[pktIdx]) 969 pktIdx++; 970 assert(pktIdx < _packets.size()); | 951 } 952} 953 954template<class Impl> 955void 956LSQ<Impl>::LSQRequest::sendFragmentToTranslation(int i) 957{ 958 numInTranslationFragments++; --- 21 unchanged lines hidden (view full) --- 980bool 981LSQ<Impl>::SplitDataRequest::recvTimingResp(PacketPtr pkt) 982{ 983 auto state = dynamic_cast<LSQSenderState*>(pkt->senderState); 984 uint32_t pktIdx = 0; 985 while (pktIdx < _packets.size() && pkt != _packets[pktIdx]) 986 pktIdx++; 987 assert(pktIdx < _packets.size()); |
971 assert(pkt->req == _requests[pktIdx]); 972 assert(pkt == _packets[pktIdx]); | |
973 numReceivedPackets++; 974 state->outstanding--; 975 if (numReceivedPackets == _packets.size()) { 976 setState(State::Complete); 977 flags.set(Flag::Complete); 978 /* Assemble packets. */ 979 PacketPtr resp = isLoad() 980 ? Packet::createRead(mainReq) --- 26 unchanged lines hidden (view full) --- 1007 assert(_packets.size() == 1); 1008} 1009 1010template<class Impl> 1011void 1012LSQ<Impl>::SplitDataRequest::buildPackets() 1013{ 1014 /* Extra data?? */ | 988 numReceivedPackets++; 989 state->outstanding--; 990 if (numReceivedPackets == _packets.size()) { 991 setState(State::Complete); 992 flags.set(Flag::Complete); 993 /* Assemble packets. */ 994 PacketPtr resp = isLoad() 995 ? Packet::createRead(mainReq) --- 26 unchanged lines hidden (view full) --- 1022 assert(_packets.size() == 1); 1023} 1024 1025template<class Impl> 1026void 1027LSQ<Impl>::SplitDataRequest::buildPackets() 1028{ 1029 /* Extra data?? */ |
1015 ptrdiff_t offset = 0; | 1030 Addr base_address = _addr; 1031 |
1016 if (_packets.size() == 0) { 1017 /* New stuff */ 1018 if (isLoad()) { 1019 _mainPacket = Packet::createRead(mainReq); 1020 _mainPacket->dataStatic(_inst->memData); 1021 } | 1032 if (_packets.size() == 0) { 1033 /* New stuff */ 1034 if (isLoad()) { 1035 _mainPacket = Packet::createRead(mainReq); 1036 _mainPacket->dataStatic(_inst->memData); 1037 } |
1022 for (auto& r: _requests) { | 1038 for (int i = 0; i < _requests.size() && _fault[i] == NoFault; i++) { 1039 RequestPtr r = _requests[i]; |
1023 PacketPtr pkt = isLoad() ? Packet::createRead(r) | 1040 PacketPtr pkt = isLoad() ? Packet::createRead(r) |
1024 : Packet::createWrite(r); | 1041 : Packet::createWrite(r); 1042 ptrdiff_t offset = r->getVaddr() - base_address; |
1025 if (isLoad()) { 1026 pkt->dataStatic(_inst->memData + offset); 1027 } else { 1028 uint8_t* req_data = new uint8_t[r->getSize()]; 1029 std::memcpy(req_data, 1030 _inst->memData + offset, 1031 r->getSize()); 1032 pkt->dataDynamic(req_data); 1033 } | 1043 if (isLoad()) { 1044 pkt->dataStatic(_inst->memData + offset); 1045 } else { 1046 uint8_t* req_data = new uint8_t[r->getSize()]; 1047 std::memcpy(req_data, 1048 _inst->memData + offset, 1049 r->getSize()); 1050 pkt->dataDynamic(req_data); 1051 } |
1034 offset += r->getSize(); | |
1035 pkt->senderState = _senderState; 1036 _packets.push_back(pkt); 1037 } 1038 } | 1052 pkt->senderState = _senderState; 1053 _packets.push_back(pkt); 1054 } 1055 } |
1039 assert(_packets.size() == _requests.size()); | 1056 assert(_packets.size() > 0); |
1040} 1041 1042template<class Impl> 1043void 1044LSQ<Impl>::SingleDataRequest::sendPacketToCache() 1045{ 1046 assert(_numOutstandingPackets == 0); 1047 if (lsqUnit()->trySendPacket(isLoad(), _packets.at(0))) --- 88 unchanged lines hidden --- | 1057} 1058 1059template<class Impl> 1060void 1061LSQ<Impl>::SingleDataRequest::sendPacketToCache() 1062{ 1063 assert(_numOutstandingPackets == 0); 1064 if (lsqUnit()->trySendPacket(isLoad(), _packets.at(0))) --- 88 unchanged lines hidden --- |