I should have said, this patch is to be applied on top of these patches: http://m5sim.org/mailman/private/m5-dev/2009-November/007714.html
Tim On Wed, 25 Nov 2009 15:20:01 -0000, Timothy M. Jones <[email protected]> wrote: > # HG changeset patch > # User Timothy M. Jones <[email protected]> > # Date 1259064162 0 > # Node ID 77dffd16710c4ad8e308b7dfee75cce4219b30a0 > # Parent b431ed08a6b7d809df9bfed51365e4d3bdf81f93 > Cpu: Make TimingSimpleCPU use new DTB translation code. > > This patch removes the duplicate code from cpu/simple/timing.hh and makes > TimingSimpleCPU use the new code in cpu/translation.hh. I've had to make > a few additional changes to get it to work ok for both O3 and Timing. > > diff --git a/src/cpu/base.hh b/src/cpu/base.hh > --- a/src/cpu/base.hh > +++ b/src/cpu/base.hh > @@ -53,6 +53,7 @@ > class ThreadContext; > class System; > class Port; > +class WholeTranslationState; > namespace TheISA > { > @@ -276,6 +277,12 @@ > virtual Counter totalInstructions() const { return 0; } > + /** > + * Finish a DTB translation. > + * @param state The DTB translation state. > + */ > + virtual void finishTranslation(WholeTranslationState *state) {} > + > // Function tracing > private: > bool functionTracingEnabled; > diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh > --- a/src/cpu/base_dyn_inst.hh > +++ b/src/cpu/base_dyn_inst.hh > @@ -979,9 +979,9 @@ > BaseTLB::Mode mode) > { > WholeTranslationState *state = > - new WholeTranslationState(req, res, mode); > - DataTranslation<Impl> *trans = > - new DataTranslation<Impl>(this, state); > + new WholeTranslationState(req, NULL, res, mode); > + DataTranslationInst<Impl> *trans = > + new DataTranslationInst<Impl>(this, state); > cpu->dtb->translateTiming(req, thread->getTC(), trans, mode); > } > @@ -993,11 +993,11 @@ > { > // Set up the translation state. > WholeTranslationState *state = > - new WholeTranslationState(req, sreqLow, sreqHigh, res, mode); > - DataTranslation<Impl> *stransLow = > - new DataTranslation<Impl>(this, state, 0); > - DataTranslation<Impl> *stransHigh = > - new DataTranslation<Impl>(this, state, 1); > + new WholeTranslationState(req, sreqLow, sreqHigh, NULL, res, > mode); > + DataTranslationInst<Impl> *stransLow = > + new DataTranslationInst<Impl>(this, state, 0); > + DataTranslationInst<Impl> *stransHigh = > + new DataTranslationInst<Impl>(this, state, 1); > // Perform the translation. > cpu->dtb->translateTiming(sreqLow, thread->getTC(), stransLow, > mode); > diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc > --- a/src/cpu/simple/timing.cc > +++ b/src/cpu/simple/timing.cc > @@ -268,19 +268,9 @@ > } > void > -TimingSimpleCPU::sendData(Fault fault, RequestPtr req, > - uint8_t *data, uint64_t *res, bool read) > +TimingSimpleCPU::sendData(RequestPtr req, uint8_t *data, uint64_t *res, > + bool read) > { > - _status = Running; > - if (fault != NoFault) { > - if (req->isPrefetch()) > - fault = NoFault; > - delete data; > - delete req; > - > - translationFault(fault); > - return; > - } > PacketPtr pkt; > buildPacket(pkt, req, read); > pkt->dataDynamic<uint8_t>(data); > @@ -311,25 +301,9 @@ > } > void > -TimingSimpleCPU::sendSplitData(Fault fault1, Fault fault2, > - RequestPtr req1, RequestPtr req2, RequestPtr req, > - uint8_t *data, bool read) > +TimingSimpleCPU::sendSplitData(RequestPtr req1, RequestPtr req2, > + RequestPtr req, uint8_t *data, bool read) > { > - _status = Running; > - if (fault1 != NoFault || fault2 != NoFault) { > - if (req1->isPrefetch()) > - fault1 = NoFault; > - if (req2->isPrefetch()) > - fault2 = NoFault; > - delete data; > - delete req1; > - delete req2; > - if (fault1 != NoFault) > - translationFault(fault1); > - else if (fault2 != NoFault) > - translationFault(fault2); > - return; > - } > PacketPtr pkt1, pkt2; > buildSplitPacket(pkt1, pkt2, req1, req2, req, data, read); > if (req->getFlags().isSet(Request::NO_ACCESS)) { > @@ -450,6 +424,7 @@ > const Addr pc = thread->readPC(); > unsigned block_size = dcachePort.peerBlockSize(); > int data_size = sizeof(T); > + BaseTLB::Mode mode = BaseTLB::Read; > RequestPtr req = new Request(asid, addr, data_size, > flags, pc, _cpuId, tid); > @@ -457,24 +432,27 @@ > Addr split_addr = roundDown(addr + data_size - 1, block_size); > assert(split_addr <= addr || split_addr - addr < block_size); > - > _status = DTBWaitResponse; > if (split_addr > addr) { > RequestPtr req1, req2; > assert(!req->isLLSC() && !req->isSwap()); > req->splitOnVaddr(split_addr, req1, req2); > - typedef SplitDataTranslation::WholeTranslationState WholeState; > - WholeState *state = new WholeState(req1, req2, req, > - (uint8_t *)(new T), > BaseTLB::Read); > - thread->dtb->translateTiming(req1, tc, > - new SplitDataTranslation(this, 0, state), > BaseTLB::Read); > - thread->dtb->translateTiming(req2, tc, > - new SplitDataTranslation(this, 1, state), > BaseTLB::Read); > + WholeTranslationState *state = > + new WholeTranslationState(req, req1, req2, (uint8_t *)(new > T), > + NULL, mode); > + DataTranslationCpu *trans1 = > + new DataTranslationCpu(this, state, 0); > + DataTranslationCpu *trans2 = > + new DataTranslationCpu(this, state, 1); > + > + thread->dtb->translateTiming(req1, tc, trans1, mode); > + thread->dtb->translateTiming(req2, tc, trans2, mode); > } else { > - DataTranslation *translation = > - new DataTranslation(this, (uint8_t *)(new T), NULL, > BaseTLB::Read); > - thread->dtb->translateTiming(req, tc, translation, > BaseTLB::Read); > + WholeTranslationState *state = > + new WholeTranslationState(req, (uint8_t *)(new T), NULL, > mode); > + DataTranslationCpu *translation = new DataTranslationCpu(this, > state); > + thread->dtb->translateTiming(req, tc, translation, mode); > } > if (traceData) { > @@ -568,6 +546,7 @@ > const Addr pc = thread->readPC(); > unsigned block_size = dcachePort.peerBlockSize(); > int data_size = sizeof(T); > + BaseTLB::Mode mode = BaseTLB::Write; > RequestPtr req = new Request(asid, addr, data_size, > flags, pc, _cpuId, tid); > @@ -583,17 +562,21 @@ > assert(!req->isLLSC() && !req->isSwap()); > req->splitOnVaddr(split_addr, req1, req2); > - typedef SplitDataTranslation::WholeTranslationState WholeState; > - WholeState *state = new WholeState(req1, req2, req, > - (uint8_t *)dataP, BaseTLB::Write); > - thread->dtb->translateTiming(req1, tc, > - new SplitDataTranslation(this, 0, state), > BaseTLB::Write); > - thread->dtb->translateTiming(req2, tc, > - new SplitDataTranslation(this, 1, state), > BaseTLB::Write); > + WholeTranslationState *state = > + new WholeTranslationState(req, req1, req2, (uint8_t *)dataP, > + res, mode); > + DataTranslationCpu *trans1 = > + new DataTranslationCpu(this, state, 0); > + DataTranslationCpu *trans2 = > + new DataTranslationCpu(this, state, 1); > + > + thread->dtb->translateTiming(req1, tc, trans1, mode); > + thread->dtb->translateTiming(req2, tc, trans2, mode); > } else { > - DataTranslation *translation = > - new DataTranslation(this, (uint8_t *)dataP, res, > BaseTLB::Write); > - thread->dtb->translateTiming(req, tc, translation, > BaseTLB::Write); > + WholeTranslationState *state = > + new WholeTranslationState(req, (uint8_t *)dataP, res, mode); > + DataTranslationCpu *translation = new DataTranslationCpu(this, > state); > + thread->dtb->translateTiming(req, tc, translation, mode); > } > if (traceData) { > @@ -668,6 +651,32 @@ > void > +TimingSimpleCPU::finishTranslation(WholeTranslationState *state) > +{ > + _status = Running; > + > + if (state->getFault() != NoFault) { > + if (state->isPrefetch()) { > + state->setNoFault(); > + } > + delete state->data; > + state->deleteReqs(); > + translationFault(state->getFault()); > + } else { > + if (!state->isSplit) { > + sendData(state->mainReq, state->data, state->res, > + state->mode == BaseTLB::Read); > + } else { > + sendSplitData(state->sreqLow, state->sreqHigh, > state->mainReq, > + state->data, state->mode == BaseTLB::Read); > + } > + } > + > + delete state; > +} > + > + > +void > TimingSimpleCPU::fetch() > { > DPRINTF(SimpleCPU, "Fetch\n"); > diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh > --- a/src/cpu/simple/timing.hh > +++ b/src/cpu/simple/timing.hh > @@ -32,6 +32,7 @@ > #define __CPU_SIMPLE_TIMING_HH__ > #include "cpu/simple/base.hh" > +#include "cpu/translation.hh" > #include "params/TimingSimpleCPU.hh" > @@ -115,95 +116,9 @@ > }; > FetchTranslation fetchTranslation; > - class DataTranslation : public BaseTLB::Translation > - { > - protected: > - TimingSimpleCPU *cpu; > - uint8_t *data; > - uint64_t *res; > - BaseTLB::Mode mode; > - > - public: > - DataTranslation(TimingSimpleCPU *_cpu, > - uint8_t *_data, uint64_t *_res, BaseTLB::Mode _mode) > - : cpu(_cpu), data(_data), res(_res), mode(_mode) > - { > - assert(mode == BaseTLB::Read || mode == BaseTLB::Write); > - } > - > - void > - finish(Fault fault, RequestPtr req, ThreadContext *tc, > - BaseTLB::Mode mode) > - { > - assert(mode == this->mode); > - cpu->sendData(fault, req, data, res, mode == BaseTLB::Read); > - delete this; > - } > - }; > - > - class SplitDataTranslation : public BaseTLB::Translation > - { > - public: > - struct WholeTranslationState > - { > - public: > - int outstanding; > - RequestPtr requests[2]; > - RequestPtr mainReq; > - Fault faults[2]; > - uint8_t *data; > - BaseTLB::Mode mode; > - > - WholeTranslationState(RequestPtr req1, RequestPtr req2, > - RequestPtr main, uint8_t *data, BaseTLB::Mode mode) > - { > - assert(mode == BaseTLB::Read || mode == BaseTLB::Write); > - > - outstanding = 2; > - requests[0] = req1; > - requests[1] = req2; > - mainReq = main; > - faults[0] = faults[1] = NoFault; > - this->data = data; > - this->mode = mode; > - } > - }; > - > - TimingSimpleCPU *cpu; > - int index; > - WholeTranslationState *state; > - > - SplitDataTranslation(TimingSimpleCPU *_cpu, int _index, > - WholeTranslationState *_state) > - : cpu(_cpu), index(_index), state(_state) > - {} > - > - void > - finish(Fault fault, RequestPtr req, ThreadContext *tc, > - BaseTLB::Mode mode) > - { > - assert(state); > - assert(state->outstanding); > - state->faults[index] = fault; > - if (--state->outstanding == 0) { > - cpu->sendSplitData(state->faults[0], > - state->faults[1], > - state->requests[0], > - state->requests[1], > - state->mainReq, > - state->data, > - state->mode == BaseTLB::Read); > - delete state; > - } > - delete this; > - } > - }; > - > - void sendData(Fault fault, RequestPtr req, > - uint8_t *data, uint64_t *res, bool read); > - void sendSplitData(Fault fault1, Fault fault2, > - RequestPtr req1, RequestPtr req2, RequestPtr req, > - uint8_t *data, bool read); > + void sendData(RequestPtr req, uint8_t *data, uint64_t *res, bool > read); > + void sendSplitData(RequestPtr req1, RequestPtr req2, RequestPtr req, > + uint8_t *data, bool read); > void translationFault(Fault fault); > @@ -351,6 +266,12 @@ > */ > void printAddr(Addr a); > + /** > + * Finish a DTB translation. > + * @param state The DTB translation state. > + */ > + virtual void finishTranslation(WholeTranslationState *state); > + > private: > typedef EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch> > FetchEvent; > diff --git a/src/cpu/translation.hh b/src/cpu/translation.hh > --- a/src/cpu/translation.hh > +++ b/src/cpu/translation.hh > @@ -34,6 +34,7 @@ > #define __CPU_TRANSLATION_HH__ > #include "sim/tlb.hh" > +#include "cpu/base.hh" > // Forward declaration > template <class Impl> > @@ -50,13 +51,15 @@ > RequestPtr mainReq; > RequestPtr sreqLow; > RequestPtr sreqHigh; > + uint8_t *data; > uint64_t *res; > BaseTLB::Mode mode; > /** Single translation state. */ > - WholeTranslationState(RequestPtr _req, uint64_t *_res, > BaseTLB::Mode _mode) > + WholeTranslationState(RequestPtr _req, uint8_t *_data, uint64_t > *_res, > + BaseTLB::Mode _mode) > : outstanding(1), isSplit(false), mainReq(_req), sreqLow(NULL), > - sreqHigh(NULL), res(_res), mode(_mode) > + sreqHigh(NULL), data(_data), res(_res), mode(_mode) > { > faults[0] = faults[1] = NoFault; > assert(mode == BaseTLB::Read || mode == BaseTLB::Write); > @@ -64,10 +67,10 @@ > /** Split translation state. */ > WholeTranslationState(RequestPtr _req, RequestPtr _sreqLow, > - RequestPtr _sreqHigh, uint64_t *_res, > + RequestPtr _sreqHigh, uint8_t *_data, > uint64_t *_res, > BaseTLB::Mode _mode) > : outstanding(2), isSplit(true), mainReq(_req), > sreqLow(_sreqLow), > - sreqHigh(_sreqHigh), res(_res), mode(_mode) > + sreqHigh(_sreqHigh), data(_data), res(_res), mode(_mode) > { > faults[0] = faults[1] = NoFault; > assert(mode == BaseTLB::Read || mode == BaseTLB::Write); > @@ -104,12 +107,24 @@ > return NoFault; > } > + void > + setNoFault() > + { > + faults[0] = faults[1] = NoFault; > + } > + > bool > isUncacheable() const > { > return mainReq->isUncacheable(); > } > + bool > + isPrefetch() const > + { > + return mainReq->isPrefetch(); > + } > + > Addr > getPaddr() const > { > @@ -134,7 +149,7 @@ > }; > template <class Impl> > -class DataTranslation : public BaseTLB::Translation > +class DataTranslationInst : public BaseTLB::Translation > { > protected: > typedef BaseDynInst<Impl> DynInst; > @@ -145,13 +160,13 @@ > int index; > public: > - DataTranslation(DynInstPtr _inst, WholeTranslationState *_state) > + DataTranslationInst(DynInstPtr _inst, WholeTranslationState *_state) > : inst(_inst), state(_state), index(0) > { > } > - DataTranslation(DynInstPtr _inst, WholeTranslationState *_state, > - int _index) > + DataTranslationInst(DynInstPtr _inst, WholeTranslationState *_state, > + int _index) > : inst(_inst), state(_state), index(_index) > { > } > @@ -163,10 +178,44 @@ > assert(state); > assert(mode == state->mode); > if (state->finish(fault, index)) { > + assert(inst); > inst->finishTranslation(state); > } > delete this; > } > }; > +class DataTranslationCpu : public BaseTLB::Translation > +{ > + protected: > + BaseCPU *cpu; > + WholeTranslationState *state; > + int index; > + > + public: > + DataTranslationCpu(BaseCPU *_cpu, WholeTranslationState *_state) > + : cpu(_cpu), state(_state), index(0) > + { > + } > + > + DataTranslationCpu(BaseCPU *_cpu, WholeTranslationState *_state, > + int _index) > + : cpu(_cpu), state(_state), index(_index) > + { > + } > + > + virtual void > + finish(Fault fault, RequestPtr req, ThreadContext *tc, > + BaseTLB::Mode mode) > + { > + assert(state); > + assert(mode == state->mode); > + if (state->finish(fault, index)) { > + assert(cpu); > + cpu->finishTranslation(state); > + } > + delete this; > + } > +}; > + > #endif // __CPU_TRANSLATION_HH__ > -- The University of Edinburgh is a charitable body, registered in Scotland, with registration number SC005336. _______________________________________________ m5-dev mailing list [email protected] http://m5sim.org/mailman/listinfo/m5-dev
