summaryrefslogtreecommitdiff
path: root/src/cpu/base_dyn_inst.hh
diff options
context:
space:
mode:
authorTimothy M. Jones <tjones1@inf.ed.ac.uk>2010-02-12 19:53:19 +0000
committerTimothy M. Jones <tjones1@inf.ed.ac.uk>2010-02-12 19:53:19 +0000
commit7fe9f92cfc73147a1a024c1632c9a7619c1779d1 (patch)
treeb24813482ae150b76c8ba095774f525ee0413e3c /src/cpu/base_dyn_inst.hh
parentdd60902152321a698682e4f53e29e4043ff321e5 (diff)
downloadgem5-7fe9f92cfc73147a1a024c1632c9a7619c1779d1.tar.xz
BaseDynInst: Make the TLB translation timing instead of atomic.
This initiates a timing translation and passes the read or write on to the processor before waiting for it to finish. Once the translation is finished, the instruction's state is updated via the 'finish' function. A new DataTranslation class is created to handle this. The idea is taken from the implementation of timing translations in TimingSimpleCPU by Gabe Black. This patch also separates out the timing translations from this CPU and uses the new DataTranslation class.
Diffstat (limited to 'src/cpu/base_dyn_inst.hh')
-rw-r--r--src/cpu/base_dyn_inst.hh93
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__