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