Hi everyone, I'd like to commit these patches fairly soon. If anyone has any comments on them, can they get them to me soonish. I'd like to commit next Monday (7th) if no-one's got any issues with this?
Thanks Tim On 25/11/09 15:23, Timothy M Jones wrote: > 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
