diff options
Diffstat (limited to 'src/cpu/simple')
-rw-r--r-- | src/cpu/simple/timing.cc | 113 | ||||
-rw-r--r-- | src/cpu/simple/timing.hh | 99 |
2 files changed, 72 insertions, 140 deletions
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 6b22d2fcf..db972d030 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -268,19 +268,9 @@ TimingSimpleCPU::handleReadPacket(PacketPtr pkt) } 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 @@ TimingSimpleCPU::sendData(Fault fault, RequestPtr req, } 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 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags) 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,28 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags) 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); + DataTranslation<TimingSimpleCPU> *trans1 = + new DataTranslation<TimingSimpleCPU>(this, state, 0); + DataTranslation<TimingSimpleCPU> *trans2 = + new DataTranslation<TimingSimpleCPU>(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); + DataTranslation<TimingSimpleCPU> *translation + = new DataTranslation<TimingSimpleCPU>(this, state); + thread->dtb->translateTiming(req, tc, translation, mode); } if (traceData) { @@ -568,6 +547,7 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) 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 +563,22 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) 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); + DataTranslation<TimingSimpleCPU> *trans1 = + new DataTranslation<TimingSimpleCPU>(this, state, 0); + DataTranslation<TimingSimpleCPU> *trans2 = + new DataTranslation<TimingSimpleCPU>(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); + DataTranslation<TimingSimpleCPU> *translation = + new DataTranslation<TimingSimpleCPU>(this, state); + thread->dtb->translateTiming(req, tc, translation, mode); } if (traceData) { @@ -668,6 +653,32 @@ TimingSimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res) 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 index 6f6b02bb7..62c105418 100644 --- 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 @@ class TimingSimpleCPU : public BaseSimpleCPU }; 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 @@ class TimingSimpleCPU : public BaseSimpleCPU */ void printAddr(Addr a); + /** + * Finish a DTB translation. + * @param state The DTB translation state. + */ + void finishTranslation(WholeTranslationState *state); + private: typedef EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch> FetchEvent; |