diff options
author | Giacomo Gabrielli <giacomo.gabrielli@arm.com> | 2017-07-07 14:13:11 +0100 |
---|---|---|
committer | Giacomo Gabrielli <giacomo.gabrielli@arm.com> | 2019-05-11 12:48:58 +0000 |
commit | c58cb8c9dbeef377da180f1fdaaa1c0eadf85550 (patch) | |
tree | 7591abeb888d8c8e645332749bcaea627628f9bf /src/cpu/o3/lsq.hh | |
parent | d0e4cdc9c36466a3dbef8c9f9f509cce8f1a6c34 (diff) | |
download | gem5-c58cb8c9dbeef377da180f1fdaaa1c0eadf85550.tar.xz |
cpu,mem: Add support for partial loads/stores and wide mem. accesses
This changeset adds support for partial (or masked) loads/stores, i.e.
loads/stores that can disable accesses to individual bytes within the
target address range. In addition, this changeset extends the code to
crack memory accesses across most CPU models (TimingSimpleCPU still
TBD), so that arbitrarily wide memory accesses are supported. These
changes are required for supporting ISAs with wide vectors.
Additional authors:
- Gabor Dozsa <gabor.dozsa@arm.com>
- Tiago Muck <tiago.muck@arm.com>
Change-Id: Ibad33541c258ad72925c0b1d5abc3e5e8bf92d92
Signed-off-by: Giacomo Gabrielli <giacomo.gabrielli@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/13518
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
Diffstat (limited to 'src/cpu/o3/lsq.hh')
-rw-r--r-- | src/cpu/o3/lsq.hh | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/src/cpu/o3/lsq.hh b/src/cpu/o3/lsq.hh index a6037b7f4..84f1411a5 100644 --- a/src/cpu/o3/lsq.hh +++ b/src/cpu/o3/lsq.hh @@ -50,6 +50,7 @@ #include "arch/generic/tlb.hh" #include "cpu/inst_seq.hh" #include "cpu/o3/lsq_unit.hh" +#include "cpu/utils.hh" #include "enums/SMTQueuePolicy.hh" #include "mem/port.hh" #include "sim/sim_object.hh" @@ -251,6 +252,7 @@ class LSQ const Addr _addr; const uint32_t _size; const Request::Flags _flags; + std::vector<bool> _byteEnable; uint32_t _numOutstandingPackets; AtomicOpFunctor *_amo_op; protected: @@ -351,6 +353,28 @@ class LSQ } } + /** Helper function used to add a (sub)request, given its address + * `addr`, size `size` and byte-enable mask `byteEnable`. + * + * The request is only added if the mask is empty or if there is at + * least an active element in it. + */ + void + addRequest(Addr addr, unsigned size, + const std::vector<bool>& byteEnable) + { + if (byteEnable.empty() || + isAnyActiveElement(byteEnable.begin(), byteEnable.end())) { + auto request = std::make_shared<Request>(_inst->getASID(), + addr, size, _flags, _inst->masterId(), + _inst->instAddr(), _inst->contextId()); + if (!byteEnable.empty()) { + request->setByteEnable(byteEnable); + } + _requests.push_back(request); + } + } + /** Destructor. * The LSQRequest owns the request. If the packet has already been * sent, the sender state will be deleted upon receiving the reply. @@ -609,11 +633,17 @@ class LSQ * declaration of the names in the parent class. */ using Flag = typename LSQRequest::Flag; using State = typename LSQRequest::State; + using LSQRequest::_addr; using LSQRequest::_fault; + using LSQRequest::_flags; + using LSQRequest::_size; + using LSQRequest::_byteEnable; + using LSQRequest::_requests; using LSQRequest::_inst; using LSQRequest::_packets; using LSQRequest::_port; using LSQRequest::_res; + using LSQRequest::_taskId; using LSQRequest::_senderState; using LSQRequest::_state; using LSQRequest::flags; @@ -635,14 +665,8 @@ class LSQ uint64_t* res = nullptr, AtomicOpFunctor* amo_op = nullptr) : LSQRequest(port, inst, isLoad, addr, size, flags_, data, res, - amo_op) - { - LSQRequest::_requests.push_back( - std::make_shared<Request>(inst->getASID(), addr, size, - flags_, inst->masterId(), inst->instAddr(), - inst->contextId(), amo_op)); - LSQRequest::_requests.back()->setReqInstSeqNum(inst->seqNum); - } + amo_op) {} + inline virtual ~SingleDataRequest() {} virtual void initiateTranslation(); virtual void finish(const Fault &fault, const RequestPtr &req, @@ -671,6 +695,7 @@ class LSQ using LSQRequest::_port; using LSQRequest::_requests; using LSQRequest::_res; + using LSQRequest::_byteEnable; using LSQRequest::_senderState; using LSQRequest::_size; using LSQRequest::_state; @@ -691,14 +716,14 @@ class LSQ RequestPtr mainReq; PacketPtr _mainPacket; - public: SplitDataRequest(LSQUnit* port, const DynInstPtr& inst, bool isLoad, const Addr& addr, const uint32_t& size, const Request::Flags & flags_, PacketDataPtr data = nullptr, uint64_t* res = nullptr) : - LSQRequest(port, inst, isLoad, addr, size, flags_, data, res), + LSQRequest(port, inst, isLoad, addr, size, flags_, data, res, + nullptr), numFragments(0), numReceivedPackets(0), mainReq(nullptr), @@ -949,7 +974,8 @@ class LSQ Fault pushRequest(const DynInstPtr& inst, bool isLoad, uint8_t *data, unsigned int size, Addr addr, Request::Flags flags, - uint64_t *res, AtomicOpFunctor *amo_op); + uint64_t *res, AtomicOpFunctor *amo_op, + const std::vector<bool>& byteEnable); /** The CPU pointer. */ O3CPU *cpu; |