Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/67574?usp=email )

Change subject: cpu: Add a generic model_reset port on the BaseCPU.
......................................................................

cpu: Add a generic model_reset port on the BaseCPU.

This port will stop execution on the CPU when raised. When lowered, it
will allow execution to reset the state of the CPU and allow execution
to resume. The state could theoretically be reset when the reset state
starts, but then it wouldn't reflect the most up to date condition of
the CPU when resuming. For instance, if a reset vector was set
somehow, that wouldn't be updated if it was changed while reset was
asserted. The tradeoff is that the state won't look like it will when
execution resumes while reset is held (to GDB for instance), but that
seems like a more obvious and less common sort of problem.

This signal is managed by the BaseCPU itself, but is backed by a
virtual method which can be overridden by other CPU types which may
not work the same way or have the same components. For instance, a
fast model CPU could toggle reset lines on the underlying model and
let it handle resetting all the state.

The fast models in particular already have a generic reset line with
the same name, but they have it at the level of the fast model which
may have multiple cores within it, each represented by a gem5 CPU.

It isn't implemented here, but there could be some sort of cooperation
between these signals where the reset at the core level is considered
an "or" of the cluster level reset and the individual core level
resets. At least in the A76 model, there are resets for each individual
core within the cluster as well, which the generic reset toggles.

Another option would be to get rid of the whole cluster reset pin, and
make the user gang the resets for each of the cores together to
whatever reset signal they're using. That's effectively what the
cluster level reset is doing, but within the C++ of the model wrapper
instead of in the python config.

Change-Id: Ie6b4769298ea224ec5dc88360cbb52ee8fbbf69c
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/67574
Tested-by: kokoro <noreply+kok...@google.com>
Reviewed-by: Roger Chang <rogerycch...@google.com>
Maintainer: Gabe Black <gabebl...@google.com>
Reviewed-by: Yu-hsin Wang <yuhsi...@google.com>
---
M src/cpu/BaseCPU.py
M src/cpu/base.cc
M src/cpu/base.hh
3 files changed, 106 insertions(+), 0 deletions(-)

Approvals:
  Gabe Black: Looks good to me, approved
  Yu-hsin Wang: Looks good to me, approved
  kokoro: Regressions pass
  Roger Chang: Looks good to me, but someone else must approve




diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py
index 438d4f4..d77036a 100644
--- a/src/cpu/BaseCPU.py
+++ b/src/cpu/BaseCPU.py
@@ -53,6 +53,7 @@
 from m5.objects.SubSystem import SubSystem
 from m5.objects.ClockDomain import *
 from m5.objects.Platform import Platform
+from m5.objects.ResetPort import ResetResponsePort

 default_tracer = ExeTracer()

@@ -153,6 +154,8 @@
         "between CPU models)",
     )

+    model_reset = ResetResponsePort("Generic reset for the CPU")
+
     tracer = Param.InstTracer(default_tracer, "Instruction tracer")

     icache_port = RequestPort("Instruction Port")
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index 98c53d4..60d443a 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -47,6 +47,8 @@
 #include <sstream>
 #include <string>

+#include "arch/generic/decoder.hh"
+#include "arch/generic/isa.hh"
 #include "arch/generic/tlb.hh"
 #include "base/cprintf.hh"
 #include "base/loader/symtab.hh"
@@ -130,6 +132,7 @@
       _dataRequestorId(p.system->getRequestorId(this, "data")),
       _taskId(context_switch_task_id::Unknown), _pid(invldPid),
_switchedOut(p.switched_out), _cacheLineSize(p.system->cacheLineSize()),
+      modelResetPort(p.name + ".model_reset"),
       interrupts(p.interrupts), numThreads(p.numThreads), system(p.system),
       previousCycle(0), previousState(CPU_STATE_SLEEP),
       functionTraceStream(nullptr), currentFunctionStart(0),
@@ -178,6 +181,10 @@
fatal("Number of ISAs (%i) assigned to the CPU does not equal number "
               "of threads (%i).\n", params().isa.size(), numThreads);
     }
+
+    modelResetPort.onChange([this](const bool &new_val) {
+        setReset(new_val);
+    });
 }

 void
@@ -413,6 +420,8 @@
         return getDataPort();
     else if (if_name == "icache_port")
         return getInstPort();
+    else if (if_name == "model_reset")
+        return modelResetPort;
     else
         return ClockedObject::getPort(if_name, idx);
 }
@@ -479,6 +488,12 @@
 void
 BaseCPU::activateContext(ThreadID thread_num)
 {
+    if (modelResetPort.state()) {
+        DPRINTF(Thread, "CPU in reset, not activating context %d\n",
+                threadContexts[thread_num]->contextId());
+        return;
+    }
+
     DPRINTF(Thread, "activate contextId %d\n",
             threadContexts[thread_num]->contextId());
     // Squash enter power gating event while cpu gets activated
@@ -602,6 +617,32 @@
     // we are switching to.
     getInstPort().takeOverFrom(&oldCPU->getInstPort());
     getDataPort().takeOverFrom(&oldCPU->getDataPort());
+
+    // Switch over the reset line as well, if necessary.
+    if (oldCPU->modelResetPort.isConnected())
+        modelResetPort.takeOverFrom(&oldCPU->modelResetPort);
+}
+
+void
+BaseCPU::setReset(bool state)
+{
+    for (auto tc: threadContexts) {
+        if (state) {
+            // As we enter reset, stop execution.
+            tc->quiesce();
+        } else {
+            // As we leave reset, first reset thread state,
+            tc->getIsaPtr()->resetThread();
+ // reset the decoder in case it had partially decoded something,
+            tc->getDecoderPtr()->reset();
+            // flush the TLBs,
+            tc->getMMUPtr()->flushAll();
+            // Clear any interrupts,
+            interrupts[tc->threadId()]->clearAll();
+            // and finally reenable execution.
+            tc->activate();
+        }
+    }
 }

 void
diff --git a/src/cpu/base.hh b/src/cpu/base.hh
index 0d56fba..084d9b9 100644
--- a/src/cpu/base.hh
+++ b/src/cpu/base.hh
@@ -55,6 +55,7 @@
 #include "sim/insttracer.hh"
 #include "sim/probe/pmu.hh"
 #include "sim/probe/probe.hh"
+#include "sim/signal.hh"
 #include "sim/system.hh"

 namespace gem5
@@ -161,6 +162,8 @@
      * group. */
     static std::unique_ptr<GlobalStats> globalStats;

+    SignalSinkPort<bool> modelResetPort;
+
   public:

     /**
@@ -338,6 +341,19 @@
     virtual void takeOverFrom(BaseCPU *cpu);

     /**
+     * Set the reset of the CPU to be either asserted or deasserted.
+     *
+ * When asserted, the CPU should be stopped and waiting. When deasserted, + * the CPU should start running again, unless some other condition would
+     * also prevent it. At the point the reset is deasserted, it should be
+ * reinitialized as defined by the ISA it's running and any other relevant
+     * part of its configuration (reset address, etc).
+     *
+     * @param state The new state of the reset signal to this CPU.
+     */
+    virtual void setReset(bool state);
+
+    /**
      * Flush all TLBs in the CPU.
      *
      * This method is mainly used to flush stale translations when

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/67574?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: Ie6b4769298ea224ec5dc88360cbb52ee8fbbf69c
Gerrit-Change-Number: 67574
Gerrit-PatchSet: 6
Gerrit-Owner: Gabe Black <gabe.bl...@gmail.com>
Gerrit-Reviewer: Earl Ou <shunhsin...@google.com>
Gerrit-Reviewer: Gabe Black <gabe.bl...@gmail.com>
Gerrit-Reviewer: Giacomo Travaglini <giacomo.travagl...@arm.com>
Gerrit-Reviewer: Jason Lowe-Power <ja...@lowepower.com>
Gerrit-Reviewer: Roger Chang <rogerycch...@google.com>
Gerrit-Reviewer: Yu-hsin Wang <yuhsi...@google.com>
Gerrit-Reviewer: kokoro <noreply+kok...@google.com>
Gerrit-CC: Gabe Black <gabebl...@google.com>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org

Reply via email to