sim: Add helper functions that add PCEvents with custom arguments
authorAndreas Sandberg <Andreas.Sandberg@ARM.com>
Mon, 22 Apr 2013 17:20:31 +0000 (13:20 -0400)
committerAndreas Sandberg <Andreas.Sandberg@ARM.com>
Mon, 22 Apr 2013 17:20:31 +0000 (13:20 -0400)
This changeset adds support for forwarding arguments to the PC
event constructors to following methods:

addKernelFuncEvent
addFuncEvent

Additionally, this changeset adds the following helper method to the
System base class:

addFuncEventOrPanic - Hook a PCEvent to a symbol, panic on failure.

addKernelFuncEventOrPanic - Hook a PCEvent to a kernel symbol, panic
                            on failure.

System implementations have been updated to use the new functionality
where appropriate.

src/arch/alpha/linux/system.cc
src/arch/alpha/tru64/system.cc
src/arch/arm/linux/system.cc
src/sim/system.hh

index 0507af0299cd812d223e1278a569476c6e25c1c7..80d13cdfaa1c08fde82edcbf773202089fc1f906 100644 (file)
@@ -120,14 +120,10 @@ LinuxAlphaSystem::setupFuncEvents()
 {
     AlphaSystem::setupFuncEvents();
 #ifndef NDEBUG
-    kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
-    if (!kernelPanicEvent)
-        panic("could not find kernel symbol \'panic\'");
+    kernelPanicEvent = addKernelFuncEventOrPanic<BreakPCEvent>("panic");
 
 #if 0
-    kernelDieEvent = addKernelFuncEvent<BreakPCEvent>("die_if_kernel");
-    if (!kernelDieEvent)
-        panic("could not find kernel symbol \'die_if_kernel\'");
+    kernelDieEvent = addKernelFuncEventOrPanic<BreakPCEvent>("die_if_kernel");
 #endif
 
 #endif
index cb4b8dd5687ef24bd4abdc0f55bf157f3e09f959..dad65a6ab2018548074f6739b1add727d81cdf7b 100644 (file)
@@ -51,14 +51,10 @@ Tru64AlphaSystem::Tru64AlphaSystem(Tru64AlphaSystem::Params *p)
     }
 
 #ifdef DEBUG
-    kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
-    if (!kernelPanicEvent)
-        panic("could not find kernel symbol \'panic\'");
+    kernelPanicEvent = addKernelFuncEventOrPanic<BreakPCEvent>("panic");
 #endif
 
-    badaddrEvent = addKernelFuncEvent<BadAddrEvent>("badaddr");
-    if (!badaddrEvent)
-        panic("could not find kernel symbol \'badaddr\'");
+    badaddrEvent = addKernelFuncEventOrPanic<BadAddrEvent>("badaddr");
 
     skipPowerStateEvent =
         addKernelFuncEvent<SkipFuncEvent>("tl_v48_capture_power_state");
index 4478aadf40cf473ec1910a64902531015d0a13b8..de4c27d8b25058fbf0f8c90e1ba8d5650ef19800 100644 (file)
@@ -65,28 +65,17 @@ LinuxArmSystem::LinuxArmSystem(Params *p)
       enableContextSwitchStatsDump(p->enable_context_switch_stats_dump)
 {
 #ifndef NDEBUG
-    kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
-    if (!kernelPanicEvent)
-        panic("could not find kernel symbol \'panic\'");
+    kernelPanicEvent = addKernelFuncEventOrPanic<BreakPCEvent>("panic");
 #endif
 
     // With ARM udelay() is #defined to __udelay
-    Addr addr = 0;
-    if (kernelSymtab->findAddress("__udelay", addr)) {
-        uDelaySkipEvent = new UDelayEvent(&pcEventQueue, "__udelay",
-                fixFuncEventAddr(addr), 1000, 0);
-    } else {
-        panic("couldn't find kernel symbol \'udelay\'");
-    }
+    uDelaySkipEvent = addKernelFuncEventOrPanic<UDelayEvent>(
+        "__udelay", "__udelay", 1000, 0);
 
     // constant arguments to udelay() have some precomputation done ahead of
     // time. Constant comes from code.
-    if (kernelSymtab->findAddress("__const_udelay", addr)) {
-        constUDelaySkipEvent = new UDelayEvent(&pcEventQueue, "__const_udelay",
-                fixFuncEventAddr(addr), 1000, 107374);
-    } else {
-        panic("couldn't find kernel symbol \'udelay\'");
-    }
+    constUDelaySkipEvent = addKernelFuncEventOrPanic<UDelayEvent>(
+        "__const_udelay", "__const_udelay", 1000, 107374);
 
     secDataPtrAddr = 0;
     secDataAddr = 0;
index 38db86cb29f0db6d812da4fe1bea669cd88c8417..e7407105abee612fff39b0bb8ccfb246f8a84cf3 100644 (file)
@@ -48,6 +48,7 @@
 #define __SYSTEM_HH__
 
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "base/loader/symtab.hh"
@@ -353,30 +354,84 @@ class System : public MemObject
         panic("Base fixFuncEventAddr not implemented.\n");
     }
 
+    /** @{ */
     /**
      * Add a function-based event to the given function, to be looked
      * up in the specified symbol table.
+     *
+     * The ...OrPanic flavor of the method causes the simulator to
+     * panic if the symbol can't be found.
+     *
+     * @param symtab Symbol table to use for look up.
+     * @param lbl Function to hook the event to.
+     * @param desc Description to be passed to the event.
+     * @param args Arguments to be forwarded to the event constructor.
      */
-    template <class T>
-    T *addFuncEvent(SymbolTable *symtab, const char *lbl)
+    template <class T, typename... Args>
+    T *addFuncEvent(const SymbolTable *symtab, const char *lbl,
+                    const std::string &desc, Args... args)
     {
         Addr addr = 0; // initialize only to avoid compiler warning
 
         if (symtab->findAddress(lbl, addr)) {
-            T *ev = new T(&pcEventQueue, lbl, fixFuncEventAddr(addr));
+            T *ev = new T(&pcEventQueue, desc, fixFuncEventAddr(addr),
+                          std::forward<Args>(args)...);
             return ev;
         }
 
         return NULL;
     }
 
-    /** Add a function-based event to kernel code. */
     template <class T>
-    T *addKernelFuncEvent(const char *lbl)
+    T *addFuncEvent(const SymbolTable *symtab, const char *lbl)
     {
-        return addFuncEvent<T>(kernelSymtab, lbl);
+        return addFuncEvent<T>(symtab, lbl, lbl);
     }
 
+    template <class T, typename... Args>
+    T *addFuncEventOrPanic(const SymbolTable *symtab, const char *lbl,
+                           Args... args)
+    {
+        T *e(addFuncEvent<T>(symtab, lbl, std::forward<Args>(args)...));
+        if (!e)
+            panic("Failed to find symbol '%s'", lbl);
+        return e;
+    }
+    /** @} */
+
+    /** @{ */
+    /**
+     * Add a function-based event to a kernel symbol.
+     *
+     * These functions work like their addFuncEvent() and
+     * addFuncEventOrPanic() counterparts. The only difference is that
+     * they automatically use the kernel symbol table. All arguments
+     * are forwarded to the underlying method.
+     *
+     * @see addFuncEvent()
+     * @see addFuncEventOrPanic()
+     *
+     * @param lbl Function to hook the event to.
+     * @param args Arguments to be passed to addFuncEvent
+     */
+    template <class T, typename... Args>
+    T *addKernelFuncEvent(const char *lbl, Args... args)
+    {
+        return addFuncEvent<T>(kernelSymtab, lbl,
+                               std::forward<Args>(args)...);
+    }
+
+    template <class T, typename... Args>
+    T *addKernelFuncEventOrPanic(const char *lbl, Args... args)
+    {
+        T *e(addFuncEvent<T>(kernelSymtab, lbl,
+                             std::forward<Args>(args)...));
+        if (!e)
+            panic("Failed to find kernel symbol '%s'", lbl);
+        return e;
+    }
+    /** @} */
+
   public:
     std::vector<BaseRemoteGDB *> remoteGDB;
     std::vector<GDBListener *> gdbListen;