summaryrefslogtreecommitdiff
path: root/src/cpu/o3/cpu.hh
diff options
context:
space:
mode:
authorAndreas Sandberg <Andreas.Sandberg@ARM.com>2013-01-07 13:05:46 -0500
committerAndreas Sandberg <Andreas.Sandberg@ARM.com>2013-01-07 13:05:46 -0500
commit1814a85a055732baf98fd030441bb4c5c5db9bdc (patch)
tree33dd6adc62342a55ac3b0f4dbe9fdb9d82faa323 /src/cpu/o3/cpu.hh
parent9e8003148f78811e600e51a900f96b71cb525b60 (diff)
downloadgem5-1814a85a055732baf98fd030441bb4c5c5db9bdc.tar.xz
cpu: Rewrite O3 draining to avoid stopping in microcode
Previously, the O3 CPU could stop in the middle of a microcode sequence. This patch makes sure that the pipeline stops when it has committed a normal instruction or exited from a microcode sequence. Additionally, it makes sure that the pipeline has no instructions in flight when it is drained, which should make draining more robust. Draining is controlled in the commit stage, which checks if the next PC after a committed instruction is in microcode. If this isn't the case, it requests a squash of all instructions after that the instruction that just committed and immediately signals a drain stall to the fetch stage. The CPU then continues to execute until the pipeline and all associated buffers are empty.
Diffstat (limited to 'src/cpu/o3/cpu.hh')
-rw-r--r--src/cpu/o3/cpu.hh45
1 files changed, 39 insertions, 6 deletions
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index 890598b0f..24c4b46a8 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 ARM Limited
+ * Copyright (c) 2011-2012 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -333,6 +333,33 @@ class FullO3CPU : public BaseO3CPU
/** The tick event used for scheduling CPU ticks. */
DeallocateContextEvent deallocateContextEvent[Impl::MaxThreads];
+ /**
+ * Check if the pipeline has drained and signal the DrainManager.
+ *
+ * This method checks if a drain has been requested and if the CPU
+ * has drained successfully (i.e., there are no instructions in
+ * the pipeline). If the CPU has drained, it deschedules the tick
+ * event and signals the drain manager.
+ *
+ * @return False if a drain hasn't been requested or the CPU
+ * hasn't drained, true otherwise.
+ */
+ bool tryDrain();
+
+ /**
+ * Perform sanity checks after a drain.
+ *
+ * This method is called from drain() when it has determined that
+ * the CPU is fully drained when gem5 is compiled with the NDEBUG
+ * macro undefined. The intention of this method is to do more
+ * extensive tests than the isDrained() method to weed out any
+ * draining bugs.
+ */
+ void drainSanityCheck() const;
+
+ /** Check if a system is in a drained state. */
+ bool isDrained() const;
+
public:
/** Constructs a CPU with the given parameters. */
FullO3CPU(DerivO3CPUParams *params);
@@ -416,6 +443,9 @@ class FullO3CPU : public BaseO3CPU
/** Update The Order In Which We Process Threads. */
void updateThreadPriority();
+ /** Is the CPU draining? */
+ bool isDraining() const { return getDrainState() == Drainable::Draining; }
+
/** Serialize state. */
virtual void serialize(std::ostream &os);
@@ -435,8 +465,14 @@ class FullO3CPU : public BaseO3CPU
/** Resumes execution after a drain. */
void drainResume();
- /** Signals to this CPU that a stage has completed switching out. */
- void signalDrained();
+ /**
+ * Commit has reached a safe point to drain a thread.
+ *
+ * Commit calls this method to inform the pipeline that it has
+ * reached a point where it is not executed microcode and is about
+ * to squash uncommitted instructions to fully drain the pipeline.
+ */
+ void commitDrained(ThreadID tid);
/** Switches out this CPU. */
virtual void switchOut();
@@ -732,9 +768,6 @@ class FullO3CPU : public BaseO3CPU
/** DrainManager to notify when draining has completed. */
DrainManager *drainManager;
- /** Counter of how many stages have completed draining. */
- int drainCount;
-
/** Pointers to all of the threads in the CPU. */
std::vector<Thread *> thread;