changeset a123bd350935 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=a123bd350935
description:
        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:

5 files changed, 306 insertions(+), 183 deletions(-)
src/cpu/base_dyn_inst.hh |   95 +++++++++++++-----------
src/cpu/exec_context.hh  |    3 
src/cpu/simple/timing.cc |  113 +++++++++++++++--------------
src/cpu/simple/timing.hh |   99 ++-----------------------
src/cpu/translation.hh   |  179 ++++++++++++++++++++++++++++++++++++++++++++++

diffs (truncated from 650 to 300 lines):

diff -r b6482c4c89e3 -r a123bd350935 src/cpu/base_dyn_inst.hh
--- a/src/cpu/base_dyn_inst.hh  Fri Feb 12 19:53:19 2010 +0000
+++ b/src/cpu/base_dyn_inst.hh  Fri Feb 12 19:53:19 2010 +0000
@@ -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 @@
      * @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 @@
     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();
+        cpu->read(req, data, lqIdx);
+    } else {
 
-#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
-    } else {
         // Return a fixed value to keep simulation deterministic even
         // along misspeculated paths.
         data = (T)-1;
@@ -891,7 +885,6 @@
         // Commit will have to clean up whatever happened.  Set this
         // instruction as executed.
         this->setExecuted();
-        delete req;
     }
 
     if (traceData) {
@@ -916,35 +909,51 @@
     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();
-
-        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);
-        }
-#else
-        fault = cpu->write(req, data, sqIdx);
-#endif
-    } else {
-        delete req;
+        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 {
+        state->deleteReqs();
+    }
+    delete state;
+}
+
 #endif // __CPU_BASE_DYN_INST_HH__
diff -r b6482c4c89e3 -r a123bd350935 src/cpu/exec_context.hh
--- a/src/cpu/exec_context.hh   Fri Feb 12 19:53:19 2010 +0000
+++ b/src/cpu/exec_context.hh   Fri Feb 12 19:53:19 2010 +0000
@@ -140,4 +140,7 @@
     /** Executes a syscall specified by the callnum. */
     void syscall(int64_t callnum);
 #endif
+
+    /** Finish a DTB address translation. */
+    void finishTranslation(WholeTranslationState *state);
 };
diff -r b6482c4c89e3 -r a123bd350935 src/cpu/simple/timing.cc
--- a/src/cpu/simple/timing.cc  Fri Feb 12 19:53:19 2010 +0000
+++ b/src/cpu/simple/timing.cc  Fri Feb 12 19:53:19 2010 +0000
@@ -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,28 @@
     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 @@
     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 @@
         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 {
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to