Gabe is really the one that should review these. (Or perhaps steve.) Can one of you take a quick look?
Thanks, Nate On Mon, Nov 30, 2009 at 3:16 AM, Timothy M Jones <[email protected]> wrote: > 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 > > _______________________________________________ m5-dev mailing list [email protected] http://m5sim.org/mailman/listinfo/m5-dev
