changeset e8001be2e86e in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=e8001be2e86e
description:
        cpu: Enable fast-forwarding for MIPS InOrderCPU and O3CPU
        A copyRegs() function is added to MIPS utilities
        to copy architectural state from the old CPU to
        the new CPU during fast-forwarding. This
        addition alone enables fast-forwarding for the
        o3 cpu model running MIPS.

        The patch also adds takeOverFrom() and
        drainResume() functions to the InOrderCPU to
        enable it to take over from another CPU. This
        change enables fast-forwarding for the inorder
        cpu model running MIPS, but not for Alpha.

        Committed by: Nilay Vaish <[email protected]>

diffstat:

 src/arch/mips/utility.cc          |  18 ++++++++++-
 src/cpu/inorder/InOrderCPU.py     |   4 ++
 src/cpu/inorder/cpu.cc            |  62 +++++++++++++++++++++++++++++++++++++++
 src/cpu/inorder/cpu.hh            |   9 +++++
 src/cpu/inorder/first_stage.cc    |  10 ++++++
 src/cpu/inorder/first_stage.hh    |   3 +
 src/cpu/inorder/pipeline_stage.hh |   2 +-
 7 files changed, 106 insertions(+), 2 deletions(-)

diffs (182 lines):

diff -r 5be102721895 -r e8001be2e86e src/arch/mips/utility.cc
--- a/src/arch/mips/utility.cc  Sat Mar 01 23:35:21 2014 -0600
+++ b/src/arch/mips/utility.cc  Sat Mar 01 23:35:23 2014 -0600
@@ -241,7 +241,23 @@
 void
 copyRegs(ThreadContext *src, ThreadContext *dest)
 {
-    panic("Copy Regs Not Implemented Yet\n");
+    // First loop through the integer registers.
+    for (int i = 0; i < NumIntRegs; i++)
+        dest->setIntRegFlat(i, src->readIntRegFlat(i));
+
+    // Then loop through the floating point registers.
+    for (int i = 0; i < NumFloatRegs; i++)
+        dest->setFloatRegFlat(i, src->readFloatRegFlat(i));
+
+    // Would need to add condition-code regs if implemented
+    assert(NumCCRegs == 0);
+
+    // Copy misc. registers
+    for (int i = 0; i < NumMiscRegs; i++)
+        dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
+
+    // Copy over the PC State
+    dest->pcState(src->pcState());
 }
 
 void
diff -r 5be102721895 -r e8001be2e86e src/cpu/inorder/InOrderCPU.py
--- a/src/cpu/inorder/InOrderCPU.py     Sat Mar 01 23:35:21 2014 -0600
+++ b/src/cpu/inorder/InOrderCPU.py     Sat Mar 01 23:35:23 2014 -0600
@@ -47,6 +47,10 @@
     def require_caches(cls):
         return True
 
+    @classmethod
+    def support_take_over(cls):
+        return True
+
     threadModel = Param.ThreadModel('SMT', "Multithreading model (SE-MODE 
only)")
     
     cachePorts = Param.Unsigned(2, "Cache Ports")
diff -r 5be102721895 -r e8001be2e86e src/cpu/inorder/cpu.cc
--- a/src/cpu/inorder/cpu.cc    Sat Mar 01 23:35:21 2014 -0600
+++ b/src/cpu/inorder/cpu.cc    Sat Mar 01 23:35:23 2014 -0600
@@ -64,6 +64,7 @@
 #include "cpu/simple_thread.hh"
 #include "cpu/thread_context.hh"
 #include "debug/Activity.hh"
+#include "debug/Drain.hh"
 #include "debug/InOrderCPU.hh"
 #include "debug/InOrderCachePort.hh"
 #include "debug/Interrupt.hh"
@@ -1490,6 +1491,67 @@
     instsPerSwitch = 0;
 }
 
+
+void
+InOrderCPU::drainResume()
+{
+    setDrainState(Drainable::Running);
+    if (switchedOut())
+        return;
+
+    DPRINTF(Drain, "Resuming...\n");
+    verifyMemoryMode();
+
+    assert(!tickEvent.scheduled());
+
+    // Activate threads and also signal the resource pool to activate
+    // the thread on all resources.
+    _status = Idle;
+    for (ThreadID i = 0; i < thread.size(); i++) {
+        if (thread[i]->status() == ThreadContext::Active) {
+            DPRINTF(Drain, "Activating thread: %i\n", i);
+            activateThread(i);
+            resPool->activateThread(i);
+            _status = Running;
+        }
+    }
+}
+
+void
+InOrderCPU::switchOut()
+{
+    DPRINTF(InOrderCPU, "Switching out\n");
+    BaseCPU::switchOut();
+
+    activityRec.reset();
+
+    _status = SwitchedOut;
+}
+
+void
+InOrderCPU::takeOverFrom(BaseCPU *oldCPU)
+{
+    BaseCPU::takeOverFrom(oldCPU);
+
+    // Call takeOverFrom() on each pipeline stage
+    for (int stNum=0; stNum < NumStages; stNum++) {
+        pipelineStage[stNum]->takeOverFrom();
+    }
+
+    assert(!tickEvent.scheduled());
+
+    // Copy over the current instruction sequence numbers if we are
+    // taking over from another InOrderCPU.
+    InOrderCPU *oldIOCPU = dynamic_cast<InOrderCPU*>(oldCPU);
+    if (oldIOCPU) {
+      for (ThreadID tid = 0; tid < numThreads; tid++)
+        globalSeqNum[tid] = oldIOCPU->globalSeqNum[tid];
+    }
+
+    lastRunningCycle = curCycle();
+    _status = Idle;
+}
+
     
 void
 InOrderCPU::instDone(DynInstPtr inst, ThreadID tid)
diff -r 5be102721895 -r e8001be2e86e src/cpu/inorder/cpu.hh
--- a/src/cpu/inorder/cpu.hh    Sat Mar 01 23:35:21 2014 -0600
+++ b/src/cpu/inorder/cpu.hh    Sat Mar 01 23:35:23 2014 -0600
@@ -866,6 +866,15 @@
     Stats::Average instsPerCtxtSwitch;    
     Stats::Scalar numCtxtSwitches;
     
+    /** Resumes execution after a drain. */
+    void drainResume();
+
+    /** Switches out this CPU. */
+    virtual void switchOut();
+
+    /** Takes over from another CPU. */
+    virtual void takeOverFrom(BaseCPU *oldCPU);
+
     /** Update Thread , used for statistic purposes*/
     inline void tickThreadStats();
 
diff -r 5be102721895 -r e8001be2e86e src/cpu/inorder/first_stage.cc
--- a/src/cpu/inorder/first_stage.cc    Sat Mar 01 23:35:21 2014 -0600
+++ b/src/cpu/inorder/first_stage.cc    Sat Mar 01 23:35:23 2014 -0600
@@ -277,3 +277,13 @@
 
     return InvalidThreadID;
 }
+
+void
+FirstStage::takeOverFrom()
+{
+    PipelineStage::takeOverFrom();
+
+    for(ThreadID tid = 0; tid < this->numThreads; tid++) {
+        stageStatus[tid] = Running;
+    }
+}
diff -r 5be102721895 -r e8001be2e86e src/cpu/inorder/first_stage.hh
--- a/src/cpu/inorder/first_stage.hh    Sat Mar 01 23:35:21 2014 -0600
+++ b/src/cpu/inorder/first_stage.hh    Sat Mar 01 23:35:23 2014 -0600
@@ -88,6 +88,9 @@
 
     /** Return next thread given Round Robin Policy for Thread Fetching */
     ThreadID roundRobin();
+
+    /** Takes over from another CPU's thread. */
+    void takeOverFrom();
 };
 
 #endif // __CPU_INORDER_FIRST_STAGE_HH__
diff -r 5be102721895 -r e8001be2e86e src/cpu/inorder/pipeline_stage.hh
--- a/src/cpu/inorder/pipeline_stage.hh Sat Mar 01 23:35:21 2014 -0600
+++ b/src/cpu/inorder/pipeline_stage.hh Sat Mar 01 23:35:23 2014 -0600
@@ -135,7 +135,7 @@
     void switchOut();
 
     /** Takes over from another CPU's thread. */
-    void takeOverFrom();
+    virtual void takeOverFrom();
 
     /** Ticks stage, processing all input signals and executing as many
      *  instructions as possible.
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to