2c2
< * Copyright (c) 2011,2013,2016 ARM Limited
---
> * Copyright (c) 2011, 2013, 2016-2018 ARM Limited
86a87,90
> using LSQRequestPtr = typename Impl::CPUPol::LSQ::LSQRequest*;
> using LQIterator = typename Impl::CPUPol::LSQUnit::LQIterator;
> using SQIterator = typename Impl::CPUPol::LSQUnit::SQIterator;
>
206c210
< Addr physEffAddrLow;
---
> Addr physEffAddr;
208,212d211
< /** The effective physical address
< * of the second request for a split request
< */
< Addr physEffAddrHigh;
<
226a226
> LQIterator lqIt;
229a230
> SQIterator sqIt;
234c235
< * Saved memory requests (needed when the DTB address translation is
---
> * Saved memory request (needed when the DTB address translation is
237,239c238
< RequestPtr savedReq;
< RequestPtr savedSreqLow;
< RequestPtr savedSreqHigh;
---
> LSQRequestPtr savedReq;
272a272
> void effAddrValid(bool b) { instFlags[EffAddrValid] = b; }
306,317d305
< /** Splits a request in two if it crosses a dcache block. */
< void splitRequest(const RequestPtr &req, RequestPtr &sreqLow,
< RequestPtr &sreqHigh);
<
< /** Initiate a DTB address translation. */
< void initiateTranslation(const RequestPtr &req, const RequestPtr &sreqLow,
< const RequestPtr &sreqHigh, uint64_t *res,
< BaseTLB::Mode mode);
<
< /** Finish a DTB address translation. */
< void finishTranslation(WholeTranslationState *state);
<
456a445,447
> /** TODO: This I added for the LSQRequest side to be able to modify the
> * fault. There should be a better mechanism in place. */
> Fault& getFault() { return fault; }
592c583,584
< int8_t numVecElemDestRegs() const {
---
> int8_t numVecElemDestRegs() const
> {
839a832
> short getASID() { return asid; }
855a849
> void strictlyOrdered(bool so) { instFlags[IsStrictlyOrdered] = so; }
858a853,854
> /** Assert this instruction has generated a memory request. */
> void setRequest() { instFlags[ReqMade] = true; }
890,933c886,888
< instFlags[ReqMade] = true;
< RequestPtr req = NULL;
< RequestPtr sreqLow = NULL;
< RequestPtr sreqHigh = NULL;
<
< if (instFlags[ReqMade] && translationStarted()) {
< req = savedReq;
< sreqLow = savedSreqLow;
< sreqHigh = savedSreqHigh;
< } else {
< req = std::make_shared<Request>(
< asid, addr, size, flags, masterId(),
< this->pc.instAddr(), thread->contextId());
<
< req->taskId(cpu->taskId());
<
< // Only split the request if the ISA supports unaligned accesses.
< if (TheISA::HasUnalignedMemAcc) {
< splitRequest(req, sreqLow, sreqHigh);
< }
< initiateTranslation(req, sreqLow, sreqHigh, NULL, BaseTLB::Read);
< }
<
< if (translationCompleted()) {
< if (fault == NoFault) {
< effAddr = req->getVaddr();
< effSize = size;
< instFlags[EffAddrValid] = true;
<
< if (cpu->checker) {
< reqToVerify = std::make_shared<Request>(*req);
< }
< fault = cpu->read(req, sreqLow, sreqHigh, lqIdx);
< } else {
< // Commit will have to clean up whatever happened. Set this
< // instruction as executed.
< this->setExecuted();
< }
< }
<
< if (traceData)
< traceData->setMem(addr, size, flags);
<
< return fault;
---
> return cpu->pushRequest(
> dynamic_cast<typename DynInstPtr::PtrType>(this),
> /* ld */ true, nullptr, size, addr, flags, nullptr);
941,978c896,898
< if (traceData)
< traceData->setMem(addr, size, flags);
<
< instFlags[ReqMade] = true;
< RequestPtr req = NULL;
< RequestPtr sreqLow = NULL;
< RequestPtr sreqHigh = NULL;
<
< if (instFlags[ReqMade] && translationStarted()) {
< req = savedReq;
< sreqLow = savedSreqLow;
< sreqHigh = savedSreqHigh;
< } else {
< req = std::make_shared<Request>(
< asid, addr, size, flags, masterId(),
< this->pc.instAddr(), thread->contextId());
<
< req->taskId(cpu->taskId());
<
< // Only split the request if the ISA supports unaligned accesses.
< if (TheISA::HasUnalignedMemAcc) {
< splitRequest(req, sreqLow, sreqHigh);
< }
< initiateTranslation(req, sreqLow, sreqHigh, res, BaseTLB::Write);
< }
<
< if (fault == NoFault && translationCompleted()) {
< effAddr = req->getVaddr();
< effSize = size;
< instFlags[EffAddrValid] = true;
<
< if (cpu->checker) {
< reqToVerify = std::make_shared<Request>(*req);
< }
< fault = cpu->write(req, sreqLow, sreqHigh, data, sqIdx);
< }
<
< return fault;
---
> return cpu->pushRequest(
> dynamic_cast<typename DynInstPtr::PtrType>(this),
> /* st */ false, data, size, addr, flags, res);
981,1090d900
< template<class Impl>
< inline void
< BaseDynInst<Impl>::splitRequest(const RequestPtr &req, RequestPtr &sreqLow,
< RequestPtr &sreqHigh)
< {
< // Check to see if the request crosses the next level block boundary.
< unsigned block_size = cpu->cacheLineSize();
< Addr addr = req->getVaddr();
< Addr split_addr = roundDown(addr + req->getSize() - 1, block_size);
< assert(split_addr <= addr || split_addr - addr < block_size);
<
< // Spans two blocks.
< if (split_addr > addr) {
< req->splitOnVaddr(split_addr, sreqLow, sreqHigh);
< }
< }
<
< template<class Impl>
< inline void
< BaseDynInst<Impl>::initiateTranslation(const RequestPtr &req,
< const RequestPtr &sreqLow,
< const RequestPtr &sreqHigh,
< uint64_t *res,
< BaseTLB::Mode mode)
< {
< translationStarted(true);
<
< if (!TheISA::HasUnalignedMemAcc || sreqLow == NULL) {
< WholeTranslationState *state =
< new WholeTranslationState(req, NULL, res, mode);
<
< // One translation if the request isn't split.
< DataTranslation<BaseDynInstPtr> *trans =
< new DataTranslation<BaseDynInstPtr>(this, state);
<
< cpu->dtb->translateTiming(req, thread->getTC(), trans, mode);
<
< if (!translationCompleted()) {
< // The translation isn't yet complete, so we can't possibly have a
< // fault. Overwrite any existing fault we might have from a previous
< // execution of this instruction (e.g. an uncachable load that
< // couldn't execute because it wasn't at the head of the ROB).
< fault = NoFault;
<
< // Save memory requests.
< savedReq = state->mainReq;
< savedSreqLow = state->sreqLow;
< savedSreqHigh = state->sreqHigh;
< }
< } else {
< WholeTranslationState *state =
< new WholeTranslationState(req, sreqLow, sreqHigh, NULL, res, mode);
<
< // Two translations when the request is split.
< DataTranslation<BaseDynInstPtr> *stransLow =
< new DataTranslation<BaseDynInstPtr>(this, state, 0);
< DataTranslation<BaseDynInstPtr> *stransHigh =
< new DataTranslation<BaseDynInstPtr>(this, state, 1);
<
< cpu->dtb->translateTiming(sreqLow, thread->getTC(), stransLow, mode);
< cpu->dtb->translateTiming(sreqHigh, thread->getTC(), stransHigh, mode);
<
< if (!translationCompleted()) {
< // The translation isn't yet complete, so we can't possibly have a
< // fault. Overwrite any existing fault we might have from a previous
< // execution of this instruction (e.g. an uncachable load that
< // couldn't execute because it wasn't at the head of the ROB).
< fault = NoFault;
<
< // Save memory requests.
< savedReq = state->mainReq;
< savedSreqLow = state->sreqLow;
< savedSreqHigh = state->sreqHigh;
< }
< }
< }
<
< template<class Impl>
< inline void
< BaseDynInst<Impl>::finishTranslation(WholeTranslationState *state)
< {
< fault = state->getFault();
<
< instFlags[IsStrictlyOrdered] = state->isStrictlyOrdered();
<
< if (fault == NoFault) {
< // save Paddr for a single req
< physEffAddrLow = state->getPaddr();
<
< // case for the request that has been split
< if (state->isSplit) {
< physEffAddrLow = state->sreqLow->getPaddr();
< physEffAddrHigh = state->sreqHigh->getPaddr();
< }
<
< memReqFlags = state->getFlags();
<
< if (state->mainReq->isCondSwap()) {
< assert(state->res);
< state->mainReq->setExtraData(*state->res);
< }
<
< } else {
< state->deleteReqs();
< }
< delete state;
<
< translationCompleted(true);
< }
<