Move kernel stats out of CPU and into XC.
authorKevin Lim <ktlim@umich.edu>
Tue, 23 May 2006 20:51:16 +0000 (16:51 -0400)
committerKevin Lim <ktlim@umich.edu>
Tue, 23 May 2006 20:51:16 +0000 (16:51 -0400)
arch/alpha/ev5.cc:
    Move kernel stats out of CPU and into XC.  Also be sure to check if the kernel stats exist prior to using them.

--HG--
extra : convert_revision : 565cd7026410fd7d8586f953d9b328c2e67a9473

15 files changed:
arch/alpha/ev5.cc
cpu/base.cc
cpu/base.hh
cpu/checker/exec_context.hh
cpu/cpu_exec_context.cc
cpu/cpu_exec_context.hh
cpu/exec_context.hh
cpu/o3/alpha_cpu.hh
cpu/o3/alpha_cpu_impl.hh
cpu/ozone/cpu.hh
cpu/ozone/cpu_impl.hh
cpu/simple/cpu.cc
cpu/thread_state.hh
kern/system_events.cc
sim/pseudo_inst.cc

index 019e83dd43035aa0d2987f2b6483ff6545f6153e..ad3a9ec4c22fbface974a9b27a3c1df0aa5578f7 100644 (file)
@@ -146,7 +146,7 @@ CPUExecContext::hwrei()
     setNextPC(readMiscReg(AlphaISA::IPR_EXC_ADDR));
 
     if (!misspeculating()) {
-        cpu->kernelStats->hwrei();
+        kernelStats->hwrei();
 
         cpu->checkInterrupts = true;
     }
@@ -336,7 +336,8 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
         // write entire quad w/ no side-effect
         old = ipr[idx];
         ipr[idx] = val;
-        xc->getCpuPtr()->kernelStats->context(old, val, xc);
+        if (xc->getKernelStats())
+            xc->getKernelStats()->context(old, val, xc);
         break;
 
       case AlphaISA::IPR_DTB_PTE:
@@ -363,14 +364,19 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
 
         // only write least significant five bits - interrupt level
         ipr[idx] = val & 0x1f;
-        xc->getCpuPtr()->kernelStats->swpipl(ipr[idx]);
+        if (xc->getKernelStats())
+            xc->getKernelStats()->swpipl(ipr[idx]);
         break;
 
       case AlphaISA::IPR_DTB_CM:
-        if (val & 0x18)
-            xc->getCpuPtr()->kernelStats->mode(Kernel::user, xc);
-        else
-            xc->getCpuPtr()->kernelStats->mode(Kernel::kernel, xc);
+        if (val & 0x18) {
+            if (xc->getKernelStats())
+                xc->getKernelStats()->mode(Kernel::user, xc);
+            else {
+                if (xc->getKernelStats())
+                    xc->getKernelStats()->mode(Kernel::kernel, xc);
+            }
+        }
 
       case AlphaISA::IPR_ICM:
         // only write two mode bits - processor mode
@@ -556,7 +562,7 @@ AlphaISA::MiscRegFile::copyIprs(ExecContext *xc)
 bool
 CPUExecContext::simPalCheck(int palFunc)
 {
-    cpu->kernelStats->callpal(palFunc, proxy);
+    kernelStats->callpal(palFunc, proxy);
 
     switch (palFunc) {
       case PAL::halt:
index 74b679d5d542c016a6883675732c13df7be09efa..de03b9eab5cb282c8f7f14faf2cdf3bbd33adee6 100644 (file)
 
 #include "base/trace.hh"
 
-#if FULL_SYSTEM
-#include "kern/kernel_stats.hh"
-#endif
-
 using namespace std;
 
 vector<BaseCPU *> BaseCPU::cpuList;
@@ -153,8 +149,6 @@ BaseCPU::BaseCPU(Params *p)
     profileEvent = NULL;
     if (params->profile)
         profileEvent = new ProfileEvent(this, params->profile);
-
-    kernelStats = new Kernel::Statistics(system);
 #endif
 
 }
@@ -175,10 +169,6 @@ BaseCPU::enableFunctionTrace()
 
 BaseCPU::~BaseCPU()
 {
-#if FULL_SYSTEM
-    if (kernelStats)
-        delete kernelStats;
-#endif
 }
 
 void
@@ -219,8 +209,6 @@ BaseCPU::regStats()
         execContexts[0]->regStats(name());
 
 #if FULL_SYSTEM
-    if (kernelStats)
-        kernelStats->regStats(name() + ".kern");
 #endif
 }
 
@@ -348,12 +336,6 @@ BaseCPU::serialize(std::ostream &os)
 {
     SERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
     SERIALIZE_SCALAR(intstatus);
-
-#if FULL_SYSTEM
-    if (kernelStats)
-        kernelStats->serialize(os);
-#endif
-
 }
 
 void
@@ -361,11 +343,6 @@ BaseCPU::unserialize(Checkpoint *cp, const std::string &section)
 {
     UNSERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
     UNSERIALIZE_SCALAR(intstatus);
-
-#if FULL_SYSTEM
-    if (kernelStats)
-        kernelStats->unserialize(cp, section);
-#endif
 }
 
 #endif // FULL_SYSTEM
index 20166d7eece06cac84337ec17e846c92c1df9708..dd776859d435dfab4cfbac0dc8e0de8e1d36ee32 100644 (file)
 #include "sim/sim_object.hh"
 #include "arch/isa_traits.hh"
 
-#if FULL_SYSTEM
-class System;
-namespace Kernel { class Statistics; }
-#endif
-
 class BranchPred;
 class CheckerCPU;
 class ExecContext;
+class System;
 
 class BaseCPU : public SimObject
 {
@@ -237,10 +233,6 @@ class BaseCPU : public SimObject
   public:
     // Number of CPU cycles simulated
     Stats::Scalar<> numCycles;
-
-#if FULL_SYSTEM
-    Kernel::Statistics *kernelStats;
-#endif
 };
 
 #endif // __CPU_BASE_HH__
index 4843d1cf0b8b5674221b495ba032101ff5b14328..38784867da01956222557a4271374a6a4e725d5e 100644 (file)
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
 #ifndef __CPU_CHECKER_EXEC_CONTEXT_HH__
 #define __CPU_CHECKER_EXEC_CONTEXT_HH__
 
@@ -6,6 +34,9 @@
 #include "cpu/exec_context.hh"
 
 class EndQuiesceEvent;
+namespace Kernel {
+    class Statistics;
+};
 
 template <class XC>
 class CheckerExecContext : public ExecContext
@@ -13,7 +44,8 @@ class CheckerExecContext : public ExecContext
   public:
     CheckerExecContext(XC *actual_xc,
                        CheckerCPU *checker_cpu)
-        : actualXC(actual_xc), checkerXC(checker_cpu->cpuXC), checkerCPU(checker_cpu)
+        : actualXC(actual_xc), checkerXC(checker_cpu->cpuXC),
+          checkerCPU(checker_cpu)
     { }
 
   private:
@@ -43,6 +75,8 @@ class CheckerExecContext : public ExecContext
     AlphaITB *getITBPtr() { return actualXC->getITBPtr(); }
 
     AlphaDTB *getDTBPtr() { return actualXC->getDTBPtr(); }
+
+    Kernel::Statistics *getKernelStats() { return actualXC->getKernelStats(); }
 #else
     Process *getProcessPtr() { return actualXC->getProcessPtr(); }
 #endif
@@ -50,8 +84,10 @@ class CheckerExecContext : public ExecContext
     Status status() const { return actualXC->status(); }
 
     void setStatus(Status new_status)
-    { actualXC->setStatus(new_status);
-    checkerXC->setStatus(new_status); }
+    {
+        actualXC->setStatus(new_status);
+        checkerXC->setStatus(new_status);
+    }
 
     /// Set the status to Active.  Optional delay indicates number of
     /// cycles to wait before beginning execution.
@@ -216,8 +252,6 @@ class CheckerExecContext : public ExecContext
         actualXC->setSyscallReturn(return_value);
     }
 
-//    void syscall() { actualXC->syscall(); }
-
     Counter readFuncExeInst() { return actualXC->readFuncExeInst(); }
 #endif
 };
index 24de6d450b467a0885a04e01e15909317991c8a0..78ce058e851359c1637b881a80a516623636e1c8 100644 (file)
@@ -188,7 +188,8 @@ CPUExecContext::serialize(ostream &os)
     if (quiesceEvent->scheduled())
         quiesceEndTick = quiesceEvent->when();
     SERIALIZE_SCALAR(quiesceEndTick);
-
+    if (kernelStats)
+        kernelStats->serialize(os);
 #endif
 }
 
@@ -207,6 +208,8 @@ CPUExecContext::unserialize(Checkpoint *cp, const std::string &section)
     UNSERIALIZE_SCALAR(quiesceEndTick);
     if (quiesceEndTick)
         quiesceEvent->schedule(quiesceEndTick);
+    if (kernelStats)
+        kernelStats->unserialize(cp, section);
 #endif
 }
 
@@ -275,6 +278,10 @@ CPUExecContext::halt()
 void
 CPUExecContext::regStats(const string &name)
 {
+#if FULL_SYSTEM
+    kernelStats = new Kernel::Statistics(system);
+    kernelStats->regStats(name + ".kern");
+#endif
 }
 
 void
index cac0069256e26a40b8e0c59b05e43db381377522..3d1428933cdb191da56ee54a21d9740006d218a2 100644 (file)
@@ -53,6 +53,10 @@ class FunctionProfile;
 class ProfileNode;
 class MemoryController;
 
+namespace Kernel {
+    class Statistics;
+};
+
 #else // !FULL_SYSTEM
 
 #include "sim/process.hh"
@@ -147,6 +151,9 @@ class CPUExecContext
 
     void profileSample();
 
+    Kernel::Statistics *getKernelStats() { return kernelStats; }
+
+    Kernel::Statistics *kernelStats;
 #else
     Process *process;
 
index 7bd7d5682485bb42611764b482f878d4a9d50434..e1f1016e5f044227565f86e6ec710ec9c01fa5af 100644 (file)
@@ -48,6 +48,9 @@ class FunctionalMemory;
 class PhysicalMemory;
 class Process;
 class System;
+namespace Kernel {
+    class Statistics;
+};
 
 class ExecContext
 {
@@ -98,6 +101,8 @@ class ExecContext
     virtual AlphaITB *getITBPtr() = 0;
 
     virtual AlphaDTB * getDTBPtr() = 0;
+
+    virtual Kernel::Statistics *getKernelStats() = 0;
 #else
     virtual Process *getProcessPtr() = 0;
 #endif
@@ -243,6 +248,8 @@ class ProxyExecContext : public ExecContext
     AlphaITB *getITBPtr() { return actualXC->getITBPtr(); }
 
     AlphaDTB *getDTBPtr() { return actualXC->getDTBPtr(); }
+
+    Kernel::Statistics *getKernelStats() { return actualXC->getKernelStats(); }
 #else
     Process *getProcessPtr() { return actualXC->getProcessPtr(); }
 #endif
index 78ad5f7d85b27e59e3992590463ccdfe904343e4..5c89e34628de2c96227ff2d65c28dece6a8ff425 100644 (file)
@@ -35,6 +35,9 @@
 #include "sim/byteswap.hh"
 
 class EndQuiesceEvent;
+namespace Kernel {
+    class Statistics;
+};
 
 template <class Impl>
 class AlphaFullCPU : public FullO3CPU<Impl>
@@ -60,11 +63,6 @@ class AlphaFullCPU : public FullO3CPU<Impl>
 
         O3ThreadState<Impl> *thread;
 
-        Tick lastActivate;
-        Tick lastSuspend;
-
-        EndQuiesceEvent *quiesceEvent;
-
         virtual BaseCPU *getCpuPtr() { return cpu; }
 
         virtual void setCpuId(int id) { cpu->cpu_id = id; }
@@ -81,6 +79,9 @@ class AlphaFullCPU : public FullO3CPU<Impl>
         virtual AlphaITB *getITBPtr() { return cpu->itb; }
 
         virtual AlphaDTB * getDTBPtr() { return cpu->dtb; }
+
+        virtual Kernel::Statistics *getKernelStats()
+        { return thread->kernelStats; }
 #else
         virtual Process *getProcessPtr() { return thread->process; }
 #endif
index 58b2b3548fb876aa130d0dd003a97bbc5297e729..91cd3d9e679697c969e4b947307868db33447c9f 100644 (file)
@@ -31,7 +31,6 @@
 #include "base/statistics.hh"
 #include "base/timebuf.hh"
 #include "cpu/checker/exec_context.hh"
-#include "cpu/quiesce_event.hh"
 #include "mem/mem_interface.hh"
 #include "sim/sim_events.hh"
 #include "sim/stats.hh"
@@ -44,6 +43,8 @@
 #if FULL_SYSTEM
 #include "arch/alpha/osfpal.hh"
 #include "arch/isa_traits.hh"
+#include "cpu/quiesce_event.hh"
+#include "kern/kernel_stats.hh"
 #endif
 
 using namespace TheISA;
@@ -101,11 +102,12 @@ AlphaFullCPU<Impl>::AlphaFullCPU(Params *params)
         alpha_xc_proxy->cpu = this;
         alpha_xc_proxy->thread = this->thread[i];
 
-        alpha_xc_proxy->quiesceEvent =
+#if FULL_SYSTEM
+        this->thread[i]->quiesceEvent =
             new EndQuiesceEvent(xc_proxy);
-        alpha_xc_proxy->lastActivate = 0;
-        alpha_xc_proxy->lastSuspend = 0;
-
+        this->thread[i]->lastActivate = 0;
+        this->thread[i]->lastSuspend = 0;
+#endif
         this->thread[i]->xcProxy = xc_proxy;
 
         this->execContexts.push_back(xc_proxy);
@@ -181,6 +183,9 @@ AlphaFullCPU<Impl>::AlphaXC::takeOverFrom(ExecContext *old_context)
     if (thread->quiesceEvent) {
         thread->quiesceEvent->xc = this;
     }
+
+    // Transfer kernel stats from one CPU to the other.
+    thread->kernelStats = old_context->getKernelStats();
 //    storeCondFailures = 0;
     cpu->lockFlag = false;
 #endif
@@ -200,7 +205,9 @@ AlphaFullCPU<Impl>::AlphaXC::activate(int delay)
     if (thread->status() == ExecContext::Active)
         return;
 
-    lastActivate = curTick;
+#if FULL_SYSTEM
+    thread->lastActivate = curTick;
+#endif
 
     if (thread->status() == ExecContext::Unallocated) {
         cpu->activateWhenReady(thread->tid);
@@ -222,8 +229,10 @@ AlphaFullCPU<Impl>::AlphaXC::suspend()
     if (thread->status() == ExecContext::Suspended)
         return;
 
-    lastActivate = curTick;
-    lastSuspend = curTick;
+#if FULL_SYSTEM
+    thread->lastActivate = curTick;
+    thread->lastSuspend = curTick;
+#endif
 /*
 #if FULL_SYSTEM
     // Don't change the status from active if there are pending interrupts
@@ -266,38 +275,55 @@ AlphaFullCPU<Impl>::AlphaXC::halt()
 template <class Impl>
 void
 AlphaFullCPU<Impl>::AlphaXC::regStats(const std::string &name)
-{}
+{
+#if FULL_SYSTEM
+    thread->kernelStats = new Kernel::Statistics(cpu->system);
+    thread->kernelStats->regStats(name + ".kern");
+#endif
+}
 
 template <class Impl>
 void
 AlphaFullCPU<Impl>::AlphaXC::serialize(std::ostream &os)
-{}
+{
+#if FULL_SYSTEM
+    if (thread->kernelStats)
+        thread->kernelStats->serialize(os);
+#endif
+
+}
 
 template <class Impl>
 void
 AlphaFullCPU<Impl>::AlphaXC::unserialize(Checkpoint *cp, const std::string &section)
-{}
+{
+#if FULL_SYSTEM
+    if (thread->kernelStats)
+        thread->kernelStats->unserialize(cp, section);
+#endif
+
+}
 
 #if FULL_SYSTEM
 template <class Impl>
 EndQuiesceEvent *
 AlphaFullCPU<Impl>::AlphaXC::getQuiesceEvent()
 {
-    return quiesceEvent;
+    return thread->quiesceEvent;
 }
 
 template <class Impl>
 Tick
 AlphaFullCPU<Impl>::AlphaXC::readLastActivate()
 {
-    return lastActivate;
+    return thread->lastActivate;
 }
 
 template <class Impl>
 Tick
 AlphaFullCPU<Impl>::AlphaXC::readLastSuspend()
 {
-    return lastSuspend;
+    return thread->lastSuspend;
 }
 
 template <class Impl>
@@ -595,7 +621,7 @@ AlphaFullCPU<Impl>::hwrei(unsigned tid)
     // Need to clear the lock flag upon returning from an interrupt.
     this->lockFlag = false;
 
-    this->kernelStats->hwrei();
+    this->thread[tid]->kernelStats->hwrei();
 
     this->checkInterrupts = true;
 
@@ -607,9 +633,9 @@ template <class Impl>
 bool
 AlphaFullCPU<Impl>::simPalCheck(int palFunc, unsigned tid)
 {
-    if (this->kernelStats)
-        this->kernelStats->callpal(palFunc,
-                                   this->execContexts[tid]);
+    if (this->thread[tid]->kernelStats)
+        this->thread[tid]->kernelStats->callpal(palFunc,
+                                                this->execContexts[tid]);
 
     switch (palFunc) {
       case PAL::halt:
index 7e12e75e51691f50111305746e1229d3aa97077b..5af2b02b227adff905d29fc1b049c1aeee117570 100644 (file)
@@ -57,6 +57,10 @@ class Sampler;
 class RemoteGDB;
 class GDBListener;
 
+namespace Kernel {
+    class Statistics;
+};
+
 #else
 
 class Process;
@@ -116,6 +120,8 @@ class OzoneCPU : public BaseCPU
         AlphaITB *getITBPtr() { return cpu->itb; }
 
         AlphaDTB * getDTBPtr() { return cpu->dtb; }
+
+        Kernel::Statistics *getKernelStats() { return thread->kernelStats; }
 #else
         Process *getProcessPtr() { return thread->process; }
 #endif
@@ -238,14 +244,7 @@ class OzoneCPU : public BaseCPU
 
   private:
     OzoneThreadState<Impl> thread;
-/*
-    // Squash event for when the XC needs to squash all inflight instructions.
-    struct XCSquashEvent : public Event
-    {
-        void process();
-        const char *description();
-    };
-*/
+
   public:
     // main simulation loop (one cycle)
     void tick();
@@ -288,7 +287,6 @@ class OzoneCPU : public BaseCPU
     void trace_data(T data);
 
   public:
-    //
     enum Status {
         Running,
         Idle,
@@ -325,8 +323,6 @@ class OzoneCPU : public BaseCPU
 
     int readCpuId() { return cpuId; }
 
-//    FunctionalMemory *getMemPtr() { return mem; }
-
     int cpuId;
 
     void switchOut(Sampler *sampler);
@@ -369,8 +365,6 @@ class OzoneCPU : public BaseCPU
     Status status() const { return _status; }
     void setStatus(Status new_status) { _status = new_status; }
 
-    // Not sure what an activate() call on the CPU's proxy XC would mean...
-
     virtual void activateContext(int thread_num, int delay);
     virtual void suspendContext(int thread_num);
     virtual void deallocateContext(int thread_num);
@@ -384,7 +378,6 @@ class OzoneCPU : public BaseCPU
   public:
     Counter numInst;
     Counter startNumInst;
-//    Stats::Scalar<> numInsts;
 
     virtual Counter totalInstructions() const
     {
@@ -392,9 +385,6 @@ class OzoneCPU : public BaseCPU
     }
 
   private:
-    // number of simulated memory references
-//    Stats::Scalar<> numMemRefs;
-
     // number of simulated loads
     Counter numLoad;
     Counter startNumLoad;
@@ -472,7 +462,6 @@ class OzoneCPU : public BaseCPU
     template <class T>
     Fault read(MemReqPtr &req, T &data)
     {
-//     panic("CPU READ NOT IMPLEMENTED W/NEW MEMORY\n");
 #if 0
 #if FULL_SYSTEM && defined(TARGET_ALPHA)
         if (req->flags & LOCKED) {
@@ -483,7 +472,6 @@ class OzoneCPU : public BaseCPU
 #endif
         Fault error;
         if (req->flags & LOCKED) {
-//            lockAddr = req->paddr;
             lockAddrList.insert(req->paddr);
             lockFlag = true;
         }
@@ -558,7 +546,7 @@ class OzoneCPU : public BaseCPU
             if (req->flags & UNCACHEABLE) {
                 req->result = 2;
             } else {
-                if (this->lockFlag/* && this->lockAddr == req->paddr*/) {
+                if (this->lockFlag) {
                     if (lockAddrList.find(req->paddr) !=
                         lockAddrList.end()) {
                         req->result = 1;
index 031b4b145e5764937e39f41abd0c6f2d2563b7ea..5675da3a89ae75aca890588bb6484592383938db 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005 The Regents of The University of Michigan
+ * Copyright (c) 2006 The Regents of The University of Michigan
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,8 +26,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <cstdio>
-#include <cstdlib>
+//#include <cstdio>
+//#include <cstdlib>
 
 #include "arch/isa_traits.hh" // For MachInst
 #include "base/trace.hh"
@@ -39,7 +39,7 @@
 #include "cpu/ozone/cpu.hh"
 #include "cpu/quiesce_event.hh"
 #include "cpu/static_inst.hh"
-#include "mem/base_mem.hh"
+//#include "mem/base_mem.hh"
 #include "mem/mem_interface.hh"
 #include "sim/sim_object.hh"
 #include "sim/stats.hh"
@@ -50,7 +50,7 @@
 #include "arch/alpha/tlb.hh"
 #include "arch/vtophys.hh"
 #include "base/callback.hh"
-#include "base/remote_gdb.hh"
+//#include "base/remote_gdb.hh"
 #include "cpu/profile.hh"
 #include "kern/kernel_stats.hh"
 #include "mem/functional/memory_control.hh"
@@ -94,80 +94,26 @@ OzoneCPU<Impl>::TickEvent::description()
 {
     return "OzoneCPU tick event";
 }
-/*
-template <class Impl>
-OzoneCPU<Impl>::ICacheCompletionEvent::ICacheCompletionEvent(OzoneCPU *_cpu)
-    : Event(&mainEventQueue),
-      cpu(_cpu)
-{
-}
-
-template <class Impl>
-void
-OzoneCPU<Impl>::ICacheCompletionEvent::process()
-{
-    cpu->processICacheCompletion();
-}
-
-template <class Impl>
-const char *
-OzoneCPU<Impl>::ICacheCompletionEvent::description()
-{
-    return "OzoneCPU I-cache completion event";
-}
-
-template <class Impl>
-OzoneCPU<Impl>::DCacheCompletionEvent::
-DCacheCompletionEvent(OzoneCPU *_cpu,
-                      DynInstPtr &_inst,
-                      DCacheCompEventIt &_dcceIt)
-    : Event(&mainEventQueue),
-      cpu(_cpu),
-      inst(_inst),
-      dcceIt(_dcceIt)
-{
-    this->setFlags(Event::AutoDelete);
-}
-
-template <class Impl>
-void
-OzoneCPU<Impl>::DCacheCompletionEvent::process()
-{
-    inst->setCompleted();
-
-    // Maybe remove the EA from the list of addrs?
-    cpu->eaList.clearAddr(inst->seqNum, inst->getEA());
-    cpu->dCacheCompList.erase(this->dcceIt);
-}
 
-template <class Impl>
-const char *
-OzoneCPU<Impl>::DCacheCompletionEvent::description()
-{
-    return "OzoneCPU D-cache completion event";
-}
-*/
 template <class Impl>
 OzoneCPU<Impl>::OzoneCPU(Params *p)
 #if FULL_SYSTEM
-    : BaseCPU(p), thread(this, 0, p->mem), tickEvent(this, p->width), mem(p->mem),
+    : BaseCPU(p), thread(this, 0, p->mem), tickEvent(this, p->width),
+      mem(p->mem),
 #else
     : BaseCPU(p), thread(this, 0, p->workload[0], 0), tickEvent(this, p->width),
       mem(p->workload[0]->getMemory()),
 #endif
       comm(5, 5)
 {
-    if (p->checker) {
-        BaseCPU *temp_checker = p->checker;
-        checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
-    } else {
-        checker = NULL;
-    }
     frontEnd = new FrontEnd(p);
     backEnd = new BackEnd(p);
 
     _status = Idle;
-    if (checker) {
+
+    if (p->checker) {
+        BaseCPU *temp_checker = p->checker;
+        checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
         checker->setMemory(mem);
 #if FULL_SYSTEM
         checker->setSystem(p->system);
@@ -176,19 +122,18 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
         thread.xcProxy = checkerXC;
         xcProxy = checkerXC;
     } else {
+        checker = NULL;
         thread.xcProxy = &ozoneXC;
         xcProxy = &ozoneXC;
     }
 
-    thread.inSyscall = false;
-
     ozoneXC.cpu = this;
     ozoneXC.thread = &thread;
 
+    thread.inSyscall = false;
+
     thread.setStatus(ExecContext::Suspended);
 #if FULL_SYSTEM
-//    xc = new ExecContext(this, 0, p->system, p->itb, p->dtb, p->mem);
-
     /***** All thread state stuff *****/
     thread.cpu = this;
     thread.tid = 0;
@@ -217,31 +162,15 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
     thread.profileNode = &dummyNode;
     thread.profilePC = 3;
 #else
-//    xc = new ExecContext(this, /* thread_num */ 0, p->workload[0], /* asid */ 0);
     thread.cpu = this;
     thread.tid = 0;
     thread.process = p->workload[0];
-//    thread.mem = thread.process->getMemory();
     thread.asid = 0;
 #endif // !FULL_SYSTEM
-/*
-    icacheInterface = p->icache_interface;
-    dcacheInterface = p->dcache_interface;
-
-    cacheMemReq = new MemReq();
-    cacheMemReq->xc = xc;
-    cacheMemReq->asid = 0;
-    cacheMemReq->data = new uint8_t[64];
-*/
+
     numInst = 0;
     startNumInst = 0;
-/*    numLoad = 0;
-    startNumLoad = 0;
-    lastIcacheStall = 0;
-    lastDcacheStall = 0;
 
-    issueWidth = p->issueWidth;
-*/
     execContexts.push_back(xcProxy);
 
     frontEnd->setCPU(this);
@@ -286,47 +215,7 @@ template <class Impl>
 OzoneCPU<Impl>::~OzoneCPU()
 {
 }
-/*
-template <class Impl>
-void
-OzoneCPU<Impl>::copyFromXC()
-{
-    for (int i = 0; i < TheISA::TotalNumRegs; ++i) {
-        if (i < TheISA::NumIntRegs) {
-            renameTable[i]->setIntResult(xc->readIntReg(i));
-        } else if (i < TheISA::NumFloatRegs) {
-            renameTable[i]->setDoubleResult(xc->readFloatRegDouble(i));
-        }
-    }
-
-    DPRINTF(OzoneCPU, "Func Exe inst is: %i\n", xc->func_exe_inst);
-    backEnd->funcExeInst = xc->func_exe_inst;
-//    PC = xc->readPC();
-//    nextPC = xc->regs.npc;
-}
-
-template <class Impl>
-void
-OzoneCPU<Impl>::copyToXC()
-{
-    for (int i = 0; i < TheISA::TotalNumRegs; ++i) {
-        if (i < TheISA::NumIntRegs) {
-            xc->setIntReg(i, renameTable[i]->readIntResult());
-        } else if (i < TheISA::NumFloatRegs) {
-            xc->setFloatRegDouble(i, renameTable[i]->readDoubleResult());
-        }
-    }
-
-    this->xc->regs.miscRegs.fpcr = this->regFile.miscRegs[tid].fpcr;
-    this->xc->regs.miscRegs.uniq = this->regFile.miscRegs[tid].uniq;
-    this->xc->regs.miscRegs.lock_flag = this->regFile.miscRegs[tid].lock_flag;
-    this->xc->regs.miscRegs.lock_addr = this->regFile.miscRegs[tid].lock_addr;
 
-    xc->func_exe_inst = backEnd->funcExeInst;
-    xc->regs.pc = PC;
-    xc->regs.npc = nextPC;
-}
-*/
 template <class Impl>
 void
 OzoneCPU<Impl>::switchOut(Sampler *_sampler)
@@ -394,7 +283,6 @@ OzoneCPU<Impl>::activateContext(int thread_num, int delay)
 {
     // Eventually change this in SMT.
     assert(thread_num == 0);
-//    assert(xcProxy);
 
     assert(_status == Idle);
     notIdleFraction++;
@@ -410,8 +298,8 @@ OzoneCPU<Impl>::suspendContext(int thread_num)
 {
     // Eventually change this in SMT.
     assert(thread_num == 0);
-//    assert(xcProxy);
-    // @todo: Figure out how to initially set the status properly so this is running.
+    // @todo: Figure out how to initially set the status properly so
+    // this is running.
 //    assert(_status == Running);
     notIdleFraction--;
     unscheduleTickEvent();
@@ -486,14 +374,7 @@ void
 OzoneCPU<Impl>::init()
 {
     BaseCPU::init();
-/*
-    copyFromXC();
 
-    // ALso copy over PC/nextPC.  This isn't normally copied in "copyFromXC()"
-    // so that the XC doesn't mess up the PC when returning from a syscall.
-    PC = xc->readPC();
-    nextPC = xc->regs.npc;
-*/
     // Mark this as in syscall so it won't need to squash
     thread.inSyscall = true;
 #if FULL_SYSTEM
@@ -514,8 +395,6 @@ template <class Impl>
 void
 OzoneCPU<Impl>::serialize(std::ostream &os)
 {
-    // At this point, all DCacheCompEvents should be processed.
-
     BaseCPU::serialize(os);
     SERIALIZE_ENUM(_status);
     nameOut(os, csprintf("%s.xc", name()));
@@ -631,31 +510,7 @@ OzoneCPU<Impl>::dbg_vtophys(Addr addr)
     return vtophys(xcProxy, addr);
 }
 #endif // FULL_SYSTEM
-/*
-template <class Impl>
-void
-OzoneCPU<Impl>::processICacheCompletion()
-{
-    switch (status()) {
-      case IcacheMiss:
-        DPRINTF(OzoneCPU, "OzoneCPU: Finished Icache miss.\n");
-
-        icacheStallCycles += curTick - lastIcacheStall;
-        _status = IcacheMissComplete;
-        cacheBlkValid = true;
-//     scheduleTickEvent(1);
-        break;
-      case SwitchedOut:
-        // If this CPU has been switched out due to sampling/warm-up,
-        // ignore any further status changes (e.g., due to cache
-        // misses outstanding at the time of the switch).
-        return;
-      default:
-        panic("OzoneCPU::processICacheCompletion: bad state");
-        break;
-    }
-}
-*/
+
 #if FULL_SYSTEM
 template <class Impl>
 void
@@ -663,7 +518,6 @@ OzoneCPU<Impl>::post_interrupt(int int_num, int index)
 {
     BaseCPU::post_interrupt(int_num, index);
 
-//    if (thread._status == ExecContext::Suspended) {
     if (_status == Idle) {
         DPRINTF(IPI,"Suspended Processor awoke\n");
 //     thread.activate();
@@ -690,9 +544,6 @@ OzoneCPU<Impl>::tick()
     frontEnd->tick();
     backEnd->tick();
 
-    // Do this here?  For now the front end will control the PC.
-//    PC = nextPC;
-
     // check for instruction-count-based events
     comInstEventQueue[0]->serviceEvents(numInst);
 
@@ -742,11 +593,13 @@ OzoneCPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid)
     if (return_value.successful()) {
         // no error
         thread.renameTable[SyscallSuccessReg]->setIntResult(0);
-        thread.renameTable[ReturnValueReg]->setIntResult(return_value.value());
+        thread.renameTable[ReturnValueReg]->setIntResult(
+            return_value.value());
     } else {
         // got an error, return details
         thread.renameTable[SyscallSuccessReg]->setIntResult((IntReg) -1);
-        thread.renameTable[ReturnValueReg]->setIntResult(-return_value.value());
+        thread.renameTable[ReturnValueReg]->setIntResult(
+            -return_value.value());
     }
 }
 #else
@@ -756,15 +609,10 @@ OzoneCPU<Impl>::hwrei()
 {
     // Need to move this to ISA code
     // May also need to make this per thread
-/*
-    if (!inPalMode())
-        return new UnimplementedOpcodeFault;
 
-    thread.setNextPC(thread.readMiscReg(AlphaISA::IPR_EXC_ADDR));
-*/
     lockFlag = false;
     lockAddrList.clear();
-    kernelStats->hwrei();
+    thread.kernelStats->hwrei();
 
     checkInterrupts = true;
 
@@ -835,7 +683,7 @@ OzoneCPU<Impl>::simPalCheck(int palFunc)
 {
     // Need to move this to ISA code
     // May also need to make this per thread
-    this->kernelStats->callpal(palFunc, xcProxy);
+    thread.kernelStats->callpal(palFunc, xcProxy);
 
     switch (palFunc) {
       case PAL::halt:
@@ -874,7 +722,6 @@ template <class Impl>
 void
 OzoneCPU<Impl>::OzoneXC::setStatus(Status new_status)
 {
-//    cpu->_status = new_status;
     thread->_status = new_status;
 }
 
@@ -932,6 +779,7 @@ OzoneCPU<Impl>::OzoneXC::takeOverFrom(ExecContext *old_context)
     setStatus(old_context->status());
     copyArchRegs(old_context);
     setCpuId(old_context->readCpuId());
+
 #if !FULL_SYSTEM
     setFuncExeInst(old_context->readFuncExeInst());
 #else
@@ -944,6 +792,8 @@ OzoneCPU<Impl>::OzoneXC::takeOverFrom(ExecContext *old_context)
     if (thread->quiesceEvent) {
         thread->quiesceEvent->xc = this;
     }
+
+    thread->kernelStats = old_context->getKernelStats();
 //    storeCondFailures = 0;
     cpu->lockFlag = false;
 #endif
@@ -954,7 +804,12 @@ OzoneCPU<Impl>::OzoneXC::takeOverFrom(ExecContext *old_context)
 template <class Impl>
 void
 OzoneCPU<Impl>::OzoneXC::regStats(const std::string &name)
-{ }
+{
+#if FULL_SYSTEM
+    thread->kernelStats = new Kernel::Statistics(cpu->system);
+    thread->kernelStats->regStats(name + ".kern");
+#endif
+}
 
 template <class Impl>
 void
index 07f9d0dadf2d4382271502a44fb255bd6c5df9d0..c03945ffa7cbeec755a3d0416f1737e1e5268089 100644 (file)
@@ -782,7 +782,7 @@ SimpleCPU::tick()
 
 #if FULL_SYSTEM
         if (system->kernelBinning->fnbin) {
-            assert(kernelStats);
+            assert(cpuXC->getKernelStats());
             system->kernelBinning->execute(xcProxy, inst);
         }
 
index e8381b9d31d07fa7f25c2aa75bd0272452c2563d..e09cb12fd099bc089ad88955da97cd64721fe532 100644 (file)
@@ -1,3 +1,30 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
 
 #ifndef __CPU_THREAD_STATE_HH__
 #define __CPU_THREAD_STATE_HH__
 class EndQuiesceEvent;
 class FunctionProfile;
 class ProfileNode;
+namespace Kernel {
+    class Statistics;
+};
 #else
-class Process;
 class FunctionalMemory;
+class Process;
 #endif
 
+/**
+ *  Struct for holding general thread state that is needed across CPU
+ *  models.  This includes things such as pointers to the process,
+ *  memory, quiesce events, and certain stats.  This can be expanded
+ *  to hold more thread-specific stats within it.
+ */
 struct ThreadState {
 #if FULL_SYSTEM
     ThreadState(int _cpuId, int _tid, FunctionalMemory *_mem)
@@ -55,6 +91,7 @@ struct ThreadState {
 
     EndQuiesceEvent *quiesceEvent;
 
+    Kernel::Statistics *kernelStats;
 #else
     Process *process;
 
index 9b98614970b9fbb390a5871623b902f5c1041355..221eb228d2c99fff7cf03d125b0c991c6a5b8007 100644 (file)
@@ -67,15 +67,17 @@ FnEvent::process(ExecContext *xc)
 void
 IdleStartEvent::process(ExecContext *xc)
 {
-    xc->getCpuPtr()->kernelStats->setIdleProcess(
-        xc->readMiscReg(AlphaISA::IPR_PALtemp23), xc);
+    if (xc->getKernelStats())
+        xc->getKernelStats()->setIdleProcess(
+            xc->readMiscReg(AlphaISA::IPR_PALtemp23), xc);
     remove();
 }
 
 void
 InterruptStartEvent::process(ExecContext *xc)
 {
-    xc->getCpuPtr()->kernelStats->mode(Kernel::interrupt, xc);
+    if (xc->getKernelStats())
+        xc->getKernelStats()->mode(Kernel::interrupt, xc);
 }
 
 void
@@ -83,5 +85,6 @@ InterruptEndEvent::process(ExecContext *xc)
 {
     // We go back to kernel, if we are user, inside the rti
     // pal code we will get switched to user because of the ICM write
-    xc->getCpuPtr()->kernelStats->mode(Kernel::kernel, xc);
+    if (xc->getKernelStats())
+        xc->getKernelStats()->mode(Kernel::kernel, xc);
 }
index 4d9541b58a9bdeeee84cbe586312f0dc9b63db16..0c20a6a537115dc3778b24e0d259a1d5d703df4d 100644 (file)
@@ -65,7 +65,8 @@ namespace AlphaPseudo
     void
     arm(ExecContext *xc)
     {
-        xc->getCpuPtr()->kernelStats->arm();
+        if (xc->getKernelStats())
+            xc->getKernelStats()->arm();
     }
 
     void
@@ -75,7 +76,8 @@ namespace AlphaPseudo
             return;
 
         xc->suspend();
-        xc->getCpuPtr()->kernelStats->quiesce();
+        if (xc->getKernelStats())
+            xc->getKernelStats()->arm();
     }
 
     void
@@ -92,7 +94,8 @@ namespace AlphaPseudo
             quiesceEvent->schedule(curTick + Clock::Int::ns * ns);
 
         xc->suspend();
-        xc->getCpuPtr()->kernelStats->quiesce();
+        if (xc->getKernelStats())
+            xc->getKernelStats()->quiesce();
     }
 
     void
@@ -111,7 +114,8 @@ namespace AlphaPseudo
                                    xc->getCpuPtr()->cycles(cycles));
 
         xc->suspend();
-        xc->getCpuPtr()->kernelStats->quiesce();
+        if (xc->getKernelStats())
+            xc->getKernelStats()->quiesce();
     }
 
     uint64_t
@@ -123,7 +127,8 @@ namespace AlphaPseudo
     void
     ivlb(ExecContext *xc)
     {
-        xc->getCpuPtr()->kernelStats->ivlb();
+        if (xc->getKernelStats())
+            xc->getKernelStats()->ivlb();
     }
 
     void