diff options
Diffstat (limited to 'src/cpu/simple/timing.cc')
-rw-r--r-- | src/cpu/simple/timing.cc | 113 |
1 files changed, 62 insertions, 51 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"); |