Hi Ali,

Yes, certainly.  I'll try to get round to doing this today or tomorrow.

Cheers
Tim

On Sun, 21 Mar 2010 11:13:22 -0400, Ali Saidi <[email protected]> wrote:

> Hi Tim,
>
> When you have a moment, would you mind adding some comments to src/cpu/
> translation.hh?
>
> Thanks,
> Ali
>
> On Nov 25, 2009, at 3:20 PM, Timothy M. Jones 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
>


-- 
Timothy M. Jones
http://homepages.inf.ed.ac.uk/tjones1

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