added system option to bin interrupt code seperately.
authorAli Saidi <saidi@eecs.umich.edu>
Fri, 3 Sep 2004 18:12:59 +0000 (14:12 -0400)
committerAli Saidi <saidi@eecs.umich.edu>
Fri, 3 Sep 2004 18:12:59 +0000 (14:12 -0400)
arch/alpha/ev5.cc:
    set the mode explictly rather than having a bool user/notuser
cpu/simple_cpu/simple_cpu.hh:
    there is no class Kernel
kern/kernel_stats.cc:
    use cpu_mode_num
kern/kernel_stats.hh:
    add interrupt mode and use cpu_mode_num rather than constant
kern/linux/linux_system.cc:
kern/linux/linux_system.hh:
kern/system_events.cc:
kern/system_events.hh:
    add events to change the mode to/from interrupt
sim/system.cc:
sim/system.hh:
    add a pal symbol table

--HG--
extra : convert_revision : 9d30e826b72122062a5ea12d094f94760e75c66a

arch/alpha/ev5.cc
cpu/simple_cpu/simple_cpu.hh
kern/kernel_stats.cc
kern/kernel_stats.hh
kern/linux/linux_system.cc
kern/linux/linux_system.hh
kern/system_events.cc
kern/system_events.hh
sim/system.cc
sim/system.hh

index b0f2251dcfe6da25248b01c2c82b26e5769979c0..70b71735309acd03df1785629552cffd9672efe5 100644 (file)
@@ -447,7 +447,10 @@ ExecContext::setIpr(int idx, uint64_t val)
         break;
 
       case AlphaISA::IPR_DTB_CM:
-        kernelStats->mode((val & 0x18) != 0);
+        if (val & 0x18)
+            kernelStats->mode(Kernel::user);
+        else
+            kernelStats->mode(Kernel::kernel);
 
       case AlphaISA::IPR_ICM:
         // only write two mode bits - processor mode
index 6ab231e7e404f1a1f82ee95649cd206ce2ecab1e..451c801ee525d4fd65f497acff82544edd5f9223 100644 (file)
@@ -40,7 +40,6 @@
 // forward declarations
 #ifdef FULL_SYSTEM
 class Processor;
-class Kernel;
 class AlphaITB;
 class AlphaDTB;
 class PhysicalMemory;
index c8c04e6d14bdda327633fc5b1913440a00bc3194..c08ee08f787f080180dde94800e65a51a78e87af 100644 (file)
@@ -45,12 +45,13 @@ using namespace Stats;
 
 namespace Kernel {
 
-const char *modestr[] = { "kernel", "user", "idle" };
+const char *modestr[] = { "kernel", "user", "idle", "interrupt" };
 
 Statistics::Statistics(ExecContext *context)
     : xc(context), idleProcess((Addr)-1), themode(kernel), lastModeTick(0),
       iplLast(0), iplLastTick(0)
 {
+    bin_int = xc->system->params->bin_int;
 }
 
 void
@@ -153,20 +154,20 @@ Statistics::regStats(const string &_name)
     }
 
     _mode
-        .init(3)
+        .init(cpu_mode_num)
         .name(name() + ".mode_switch")
         .desc("number of protection mode switches")
         ;
 
-    for (int i = 0; i < 3; ++i)
+    for (int i = 0; i < cpu_mode_num; ++i)
         _mode.subname(i, modestr[i]);
 
     _modeGood
-        .init(3)
+        .init(cpu_mode_num)
         .name(name() + ".mode_good")
         ;
 
-    for (int i = 0; i < 3; ++i)
+    for (int i = 0; i < cpu_mode_num; ++i)
         _modeGood.subname(i, modestr[i]);
 
     _modeFraction
@@ -175,18 +176,18 @@ Statistics::regStats(const string &_name)
         .flags(total)
         ;
 
-    for (int i = 0; i < 3; ++i)
+    for (int i = 0; i < cpu_mode_num; ++i)
         _modeFraction.subname(i, modestr[i]);
 
     _modeFraction = _modeGood / _mode;
 
     _modeTicks
-        .init(3)
+        .init(cpu_mode_num)
         .name(name() + ".mode_ticks")
         .desc("number of ticks spent at the given mode")
         .flags(pdf)
         ;
-    for (int i = 0; i < 3; ++i)
+    for (int i = 0; i < cpu_mode_num; ++i)
         _modeTicks.subname(i, modestr[i]);
 
     _swap_context
@@ -198,7 +199,7 @@ Statistics::regStats(const string &_name)
 void
 Statistics::setIdleProcess(Addr idlepcbb)
 {
-    assert(themode == kernel);
+    assert(themode == kernel || themode == interrupt);
     idleProcess = idlepcbb;
     themode = idle;
     changeMode(themode);
@@ -241,14 +242,17 @@ Statistics::swpipl(int ipl)
 }
 
 void
-Statistics::mode(bool usermode)
+Statistics::mode(cpu_mode newmode)
 {
     Addr pcbb = xc->regs.ipr[AlphaISA::IPR_PALtemp23];
 
-    cpu_mode newmode = usermode ? user : kernel;
-    if (newmode == kernel && pcbb == idleProcess)
+    if ((newmode == kernel || newmode == interrupt) &&
+            pcbb == idleProcess)
         newmode = idle;
 
+    if (bin_int == false && newmode == interrupt)
+        newmode = kernel;
+
     changeMode(newmode);
 }
 
index 8339c578c4430325fc4e75d83adc497f3e56be3b..af93eb95c85d82ab371eb92c253286904622544d 100644 (file)
@@ -45,7 +45,7 @@ enum Fault;
 
 namespace Kernel {
 
-enum cpu_mode { kernel, user, idle, cpu_mode_num };
+enum cpu_mode { kernel, user, idle, interrupt, cpu_mode_num };
 extern const char *modestr[];
 
 class Binning
@@ -98,7 +98,7 @@ class Binning
     std::vector<std::string> binned_fns;
 
   private:
-    Stats::MainBin *modeBin[3];
+    Stats::MainBin *modeBin[cpu_mode_num];
 
   public:
     const bool bin;
@@ -133,6 +133,7 @@ class Statistics : public Serializable
     Addr idleProcess;
     cpu_mode themode;
     Tick lastModeTick;
+    bool bin_int;
 
     void changeMode(cpu_mode newmode);
 
@@ -177,7 +178,7 @@ class Statistics : public Serializable
     void hwrei() { _hwrei++; }
     void fault(Fault fault) { _faults[fault]++; }
     void swpipl(int ipl);
-    void mode(bool usermode);
+    void mode(cpu_mode newmode);
     void context(Addr oldpcbb, Addr newpcbb);
     void callpal(int code);
 
index 10641de874644f742b365e0c1146761af8aab748..91ad45157bacb4f426a511b75778f628f6da63e5 100644 (file)
@@ -143,6 +143,16 @@ LinuxSystem::LinuxSystem(Params *p)
     printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo");
     if (kernelSymtab->findAddress("alpha_switch_to", addr) && DTRACE(Thread))
         printThreadEvent->schedule(addr + sizeof(MachInst) * 6);
+
+    intStartEvent = new InterruptStartEvent(&pcEventQueue, "intStartEvent");
+    if (kernelSymtab->findAddress("do_entInt", addr))
+        intStartEvent->schedule(addr + sizeof(MachInst) * 2);
+
+    intEndEvent = new InterruptEndEvent(&pcEventQueue, "intStartEvent");
+    if (palSymtab->findAddress("Call_Pal_Rti", addr))
+        intEndEvent->schedule(addr + sizeof(MachInst));
+    else
+        panic("could not find symbol\n");
 }
 
 LinuxSystem::~LinuxSystem()
@@ -155,6 +165,8 @@ LinuxSystem::~LinuxSystem()
     delete skipCacheProbeEvent;
     delete debugPrintkEvent;
     delete idleStartEvent;
+    delete printThreadEvent;
+    delete intStartEvent;
 }
 
 
@@ -193,6 +205,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem)
 
     Param<bool> bin;
     VectorParam<string> binned_fns;
+    Param<bool> bin_int;
 
 END_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem)
 
@@ -210,7 +223,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxSystem)
     INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
     INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10),
     INIT_PARAM_DFLT(bin, "is this system to be binned", false),
-    INIT_PARAM(binned_fns, "functions to be broken down and binned")
+    INIT_PARAM(binned_fns, "functions to be broken down and binned"),
+    INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", false)
 
 END_INIT_SIM_OBJECT_PARAMS(LinuxSystem)
 
@@ -230,7 +244,7 @@ CREATE_SIM_OBJECT(LinuxSystem)
     p->system_rev = system_rev;
     p->bin = bin;
     p->binned_fns = binned_fns;
-
+    p->bin_int = bin_int;
     return new LinuxSystem(p);
 }
 
index 7072046077cc992e4253d063e38e1f99fe8eceaf..f5fd2b06b18d82e4407c49762191dae518ac3908 100644 (file)
@@ -83,8 +83,22 @@ class LinuxSystem : public System
      */
     LinuxSkipDelayLoopEvent *skipDelayLoopEvent;
 
+    /**
+     * Event to print information about thread switches if the trace flag
+     * Thread is set
+     */
     PrintThreadInfo *printThreadEvent;
 
+    /**
+     * Event to bin Interrupts seperately from kernel code
+     */
+    InterruptStartEvent *intStartEvent;
+
+    /**
+     * Event to bin Interrupts seperately from kernel code
+     */
+    InterruptEndEvent *intEndEvent;
+
     /** Grab the PCBB of the idle process when it starts */
     IdleStartEvent *idleStartEvent;
 
index 91daf53ca4e80339cfabf9ade0174d0f609e3a80..b6526d1939ba3399055a845e78d528ed58ff27b7 100644 (file)
@@ -71,3 +71,17 @@ IdleStartEvent::process(ExecContext *xc)
 {
     xc->kernelStats->setIdleProcess(xc->regs.ipr[AlphaISA::IPR_PALtemp23]);
 }
+
+void
+InterruptStartEvent::process(ExecContext *xc)
+{
+    xc->kernelStats->mode(Kernel::interrupt);
+}
+
+void
+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->kernelStats->mode(Kernel::kernel);
+}
index 95027572f67c112783ab1c312011fa2f00d5171c..8a8549d034a8cf6067b5ec9778d5fe7841e045f5 100644 (file)
@@ -64,4 +64,24 @@ class IdleStartEvent : public PCEvent
     {}
     virtual void process(ExecContext *xc);
 };
+
+class InterruptStartEvent : public PCEvent
+{
+  public:
+    InterruptStartEvent(PCEventQueue *q, const std::string &desc)
+        : PCEvent(q, desc)
+    {}
+    virtual void process(ExecContext *xc);
+};
+
+class InterruptEndEvent : public PCEvent
+{
+  public:
+    InterruptEndEvent(PCEventQueue *q, const std::string &desc)
+        : PCEvent(q, desc)
+    {}
+    virtual void process(ExecContext *xc);
+};
+
+
 #endif // __SYSTEM_EVENTS_HH__
index de988f8d712a21eea68732fc48426350b798bf99..f59d8b32ba47191d05b1e2dca103254b76083e88 100644 (file)
@@ -55,6 +55,7 @@ System::System(Params *p)
 
     kernelSymtab = new SymbolTable;
     consoleSymtab = new SymbolTable;
+    palSymtab = new SymbolTable;
     debugSymbolTable = new SymbolTable;
 
     /**
@@ -96,7 +97,10 @@ System::System(Params *p)
     if (!console->loadGlobalSymbols(consoleSymtab))
         panic("could not load console symbols\n");
 
-     if (!kernel->loadGlobalSymbols(debugSymbolTable))
+    if (!pal->loadGlobalSymbols(palSymtab))
+        panic("could not load pal symbols\n");
+
+    if (!kernel->loadGlobalSymbols(debugSymbolTable))
         panic("could not load kernel symbols\n");
 
     if (!kernel->loadLocalSymbols(debugSymbolTable))
index 05b97ad62987226b46707115a1231c9449f14e0c..5294f417e5dbbff2d979dae5310101bcbc80fdb6 100644 (file)
@@ -64,6 +64,9 @@ class System : public SimObject
     /** console symbol table */
     SymbolTable *consoleSymtab;
 
+    /** pal symbol table */
+    SymbolTable *palSymtab;
+
     /** Object pointer for the kernel code */
     ObjectFile *kernel;
 
@@ -103,6 +106,7 @@ class System : public SimObject
         uint64_t init_param;
         bool bin;
         std::vector<std::string> binned_fns;
+        bool bin_int;
 
         std::string kernel_path;
         std::string console_path;