O3: Track if the RAS has been pushed or not to pop the RAS if neccessary.
[gem5.git] / src / cpu / base.hh
index 5622031f857ccf74e9553ca28492cf75d51f79d1..b99b25d1745a64d415212db11f44563fdfa210c2 100644 (file)
 
 #include <vector>
 
+#include "arch/interrupts.hh"
 #include "arch/isa_traits.hh"
 #include "arch/microcode_rom.hh"
 #include "base/statistics.hh"
-#include "config/full_system.hh"
 #include "config/the_isa.hh"
 #include "mem/mem_object.hh"
 #include "sim/eventq.hh"
+#include "sim/full_system.hh"
 #include "sim/insttracer.hh"
 
-#if FULL_SYSTEM
-#include "arch/interrupts.hh"
-#endif
-
-class BaseCPUParams;
+struct BaseCPUParams;
 class BranchPred;
 class CheckerCPU;
 class ThreadContext;
 class System;
-class Port;
-
-namespace TheISA
-{
-    class Predecoder;
-}
 
 class CPUProgressEvent : public Event
 {
@@ -107,6 +98,12 @@ class BaseCPU : public MemObject
     // therefore no setCpuId() method is provided
     int _cpuId;
 
+    /** instruction side request id that must be placed in all requests */
+    MasterID _instMasterId;
+
+    /** data side request id that must be placed in all requests */
+    MasterID _dataMasterId;
+
     /**
      * Define a base class for the CPU ports (instruction and data)
      * that is refined in the subclasses. This class handles the
@@ -115,7 +112,7 @@ class BaseCPU : public MemObject
      * both atomic and timing access is to panic and the corresponding
      * subclasses have to override these methods.
      */
-    class CpuPort : public Port
+    class CpuPort : public MasterPort
     {
       public:
 
@@ -126,42 +123,57 @@ class BaseCPU : public MemObject
          * @param _name structural owner of this port
          */
         CpuPort(const std::string& _name, MemObject* _owner) :
-            Port(_name, _owner), snoopRangeSent(false)
+            MasterPort(_name, _owner)
         { }
 
       protected:
 
-        virtual bool recvTiming(PacketPtr pkt);
-
-        virtual Tick recvAtomic(PacketPtr pkt);
+        virtual bool recvTimingResp(PacketPtr pkt);
 
         virtual void recvRetry();
 
-        void recvFunctional(PacketPtr pkt);
-
-        void recvStatusChange(Status status);
+        virtual void recvFunctionalSnoop(PacketPtr pkt);
 
-        /**
-         * Add CPU ports are master ports and do not respond to any
-         * address ranges. Note that the LSQ snoops for specific ISAs
-         * and thus has to override this method.
-         *
-         * @param resp list of ranges this port responds to
-         * @param snoop indicating if the port snoops or not
-         */
-        virtual void getDeviceAddressRanges(AddrRangeList& resp,
-                                            bool& snoop);
+    };
 
-      private:
+  public:
 
-        bool snoopRangeSent;
+    /**
+     * Purely virtual method that returns a reference to the data
+     * port. All subclasses must implement this method.
+     *
+     * @return a reference to the data port
+     */
+    virtual CpuPort &getDataPort() = 0;
 
-    };
+    /**
+     * Purely virtual method that returns a reference to the instruction
+     * port. All subclasses must implement this method.
+     *
+     * @return a reference to the instruction port
+     */
+    virtual CpuPort &getInstPort() = 0;
 
-  public:
     /** Reads this CPU's ID. */
     int cpuId() { return _cpuId; }
 
+    /** Reads this CPU's unique data requestor ID */
+    MasterID dataMasterId() { return _dataMasterId; }
+    /** Reads this CPU's unique instruction requestor ID */
+    MasterID instMasterId() { return _instMasterId; }
+
+    /**
+     * Get a master port on this CPU. All CPUs have a data and
+     * instruction port, and this method uses getDataPort and
+     * getInstPort of the subclasses to resolve the two ports.
+     *
+     * @param if_name the port name
+     * @param idx ignored index
+     *
+     * @return a reference to the port with the given name
+     */
+    MasterPort &getMasterPort(const std::string &if_name, int idx = -1);
+
 //    Tick currentTick;
     inline Tick frequency() const { return SimClock::Frequency / clock; }
     inline Tick ticks(int numCycles) const { return clock * numCycles; }
@@ -188,7 +200,6 @@ class BaseCPU : public MemObject
 
     TheISA::MicrocodeRom microcodeRom;
 
-#if FULL_SYSTEM
   protected:
     TheISA::Interrupts *interrupts;
 
@@ -205,7 +216,8 @@ class BaseCPU : public MemObject
     postInterrupt(int int_num, int index)
     {
         interrupts->post(int_num, index);
-        wakeup();
+        if (FullSystem)
+            wakeup();
     }
 
     void
@@ -223,7 +235,7 @@ class BaseCPU : public MemObject
     bool
     checkInterrupts(ThreadContext *tc) const
     {
-        return interrupts->checkInterrupts(tc);
+        return FullSystem && interrupts->checkInterrupts(tc);
     }
 
     class ProfileEvent : public Event
@@ -237,11 +249,9 @@ class BaseCPU : public MemObject
         void process();
     };
     ProfileEvent *profileEvent;
-#endif
 
   protected:
     std::vector<ThreadContext *> threadContexts;
-    std::vector<TheISA::Predecoder *> predecoders;
 
     Trace::InstTracer * tracer;
 
@@ -256,16 +266,16 @@ class BaseCPU : public MemObject
     /// Notify the CPU that the indicated context is now active.  The
     /// delay parameter indicates the number of ticks to wait before
     /// executing (typically 0 or 1).
-    virtual void activateContext(int thread_num, int delay) {}
+    virtual void activateContext(ThreadID thread_num, int delay) {}
 
     /// Notify the CPU that the indicated context is now suspended.
-    virtual void suspendContext(int thread_num) {}
+    virtual void suspendContext(ThreadID thread_num) {}
 
     /// Notify the CPU that the indicated context is now deallocated.
-    virtual void deallocateContext(int thread_num) {}
+    virtual void deallocateContext(ThreadID thread_num) {}
 
     /// Notify the CPU that the indicated context is now halted.
-    virtual void haltContext(int thread_num) {}
+    virtual void haltContext(ThreadID thread_num) {}
 
    /// Given a Thread Context pointer return the thread num
    int findContext(ThreadContext *tc);
@@ -277,7 +287,7 @@ class BaseCPU : public MemObject
     typedef BaseCPUParams Params;
     const Params *params() const
     { return reinterpret_cast<const Params *>(_params); }
-    BaseCPU(Params *params);
+    BaseCPU(Params *params, bool is_checker = false);
     virtual ~BaseCPU();
 
     virtual void init();
@@ -294,7 +304,7 @@ class BaseCPU : public MemObject
 
     /// Take over execution from the given CPU.  Used for warm-up and
     /// sampling.
-    virtual void takeOverFrom(BaseCPU *, Port *ic, Port *dc);
+    virtual void takeOverFrom(BaseCPU *);
 
     /**
      *  Number of threads we're actually simulating (<= SMT_MAX_THREADS).
@@ -320,7 +330,6 @@ class BaseCPU : public MemObject
 
     Tick phase;
 
-#if FULL_SYSTEM
     /**
      * Serialize this object to the given output stream.
      * @param os The stream to serialize to.
@@ -334,15 +343,15 @@ class BaseCPU : public MemObject
      */
     virtual void unserialize(Checkpoint *cp, const std::string &section);
 
-#endif
-
     /**
      * Return pointer to CPU's branch predictor (NULL if none).
      * @return Branch predictor pointer.
      */
     virtual BranchPred *getBranchPred() { return NULL; };
 
-    virtual Counter totalInstructions() const = 0;
+    virtual Counter totalInsts() const = 0;
+
+    virtual Counter totalOps() const = 0;
 
     // Function tracing
   private:
@@ -365,13 +374,24 @@ class BaseCPU : public MemObject
     }
 
     static int numSimulatedCPUs() { return cpuList.size(); }
-    static Counter numSimulatedInstructions()
+    static Counter numSimulatedInsts()
+    {
+        Counter total = 0;
+
+        int size = cpuList.size();
+        for (int i = 0; i < size; ++i)
+            total += cpuList[i]->totalInsts();
+
+        return total;
+    }
+
+    static Counter numSimulatedOps()
     {
         Counter total = 0;
 
         int size = cpuList.size();
         for (int i = 0; i < size; ++i)
-            total += cpuList[i]->totalInstructions();
+            total += cpuList[i]->totalOps();
 
         return total;
     }