diff options
Diffstat (limited to 'src/cpu/base_dyn_inst.hh')
-rw-r--r-- | src/cpu/base_dyn_inst.hh | 93 |
1 files changed, 51 insertions, 42 deletions
diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh index 31206c81e..7732b71f8 100644 --- a/src/cpu/base_dyn_inst.hh +++ b/src/cpu/base_dyn_inst.hh @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2006 The Regents of The University of Michigan + * Copyright (c) 2009 The University of Edinburgh * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,6 +27,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Kevin Lim + * Timothy M. Jones */ #ifndef __CPU_BASE_DYN_INST_HH__ @@ -45,6 +47,7 @@ #include "cpu/inst_seq.hh" #include "cpu/op_class.hh" #include "cpu/static_inst.hh" +#include "cpu/translation.hh" #include "mem/packet.hh" #include "sim/system.hh" #include "sim/tlb.hh" @@ -126,8 +129,14 @@ class BaseDynInst : public FastAlloc, public RefCounted * @return Returns any fault due to the write. */ template <class T> - Fault write(T data, Addr addr, unsigned flags, - uint64_t *res); + Fault write(T data, Addr addr, unsigned flags, uint64_t *res); + + /** Initiate a DTB address translation. */ + void initiateTranslation(RequestPtr req, uint64_t *res, + BaseTLB::Mode mode); + + /** Finish a DTB address translation. */ + void finishTranslation(WholeTranslationState *state); void prefetch(Addr addr, unsigned flags); void writeHint(Addr addr, int size, unsigned flags); @@ -861,29 +870,14 @@ BaseDynInst<Impl>::read(Addr addr, T &data, unsigned flags) Request *req = new Request(asid, addr, sizeof(T), flags, this->PC, thread->contextId(), threadNumber); - fault = cpu->dtb->translateAtomic(req, thread->getTC(), BaseTLB::Read); - - if (req->isUncacheable()) - isUncacheable = true; + initiateTranslation(req, NULL, BaseTLB::Read); if (fault == NoFault) { effAddr = req->getVaddr(); effAddrValid = true; - physEffAddr = req->getPaddr(); - memReqFlags = req->getFlags(); - -#if 0 - if (cpu->system->memctrl->badaddr(physEffAddr)) { - fault = TheISA::genMachineCheckFault(); - data = (T)-1; - this->setExecuted(); - } else { - fault = cpu->read(req, data, lqIdx); - } -#else - fault = cpu->read(req, data, lqIdx); -#endif + cpu->read(req, data, lqIdx); } else { + // Return a fixed value to keep simulation deterministic even // along misspeculated paths. data = (T)-1; @@ -891,7 +885,6 @@ BaseDynInst<Impl>::read(Addr addr, T &data, unsigned flags) // Commit will have to clean up whatever happened. Set this // instruction as executed. this->setExecuted(); - delete req; } if (traceData) { @@ -916,35 +909,51 @@ BaseDynInst<Impl>::write(T data, Addr addr, unsigned flags, uint64_t *res) Request *req = new Request(asid, addr, sizeof(T), flags, this->PC, thread->contextId(), threadNumber); - fault = cpu->dtb->translateAtomic(req, thread->getTC(), BaseTLB::Write); - - if (req->isUncacheable()) - isUncacheable = true; + initiateTranslation(req, res, BaseTLB::Write); if (fault == NoFault) { effAddr = req->getVaddr(); effAddrValid = true; - physEffAddr = req->getPaddr(); - memReqFlags = req->getFlags(); + cpu->write(req, data, sqIdx); + } - if (req->isCondSwap()) { - assert(res); - req->setExtraData(*res); - } -#if 0 - if (cpu->system->memctrl->badaddr(physEffAddr)) { - fault = TheISA::genMachineCheckFault(); - } else { - fault = cpu->write(req, data, sqIdx); + return fault; +} + +template<class Impl> +inline void +BaseDynInst<Impl>::initiateTranslation(RequestPtr req, uint64_t *res, + BaseTLB::Mode mode) +{ + WholeTranslationState *state = + new WholeTranslationState(req, NULL, res, mode); + DataTranslation<BaseDynInst<Impl> > *trans = + new DataTranslation<BaseDynInst<Impl> >(this, state); + cpu->dtb->translateTiming(req, thread->getTC(), trans, mode); +} + +template<class Impl> +inline void +BaseDynInst<Impl>::finishTranslation(WholeTranslationState *state) +{ + fault = state->getFault(); + + if (state->isUncacheable()) + isUncacheable = true; + + if (fault == NoFault) { + physEffAddr = state->getPaddr(); + memReqFlags = state->getFlags(); + + if (state->mainReq->isCondSwap()) { + assert(state->res); + state->mainReq->setExtraData(*state->res); } -#else - fault = cpu->write(req, data, sqIdx); -#endif + } else { - delete req; + state->deleteReqs(); } - - return fault; + delete state; } #endif // __CPU_BASE_DYN_INST_HH__ |