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

Reply via email to