summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Sandberg <Andreas.Sandberg@ARM.com>2013-04-22 13:20:31 -0400
committerAndreas Sandberg <Andreas.Sandberg@ARM.com>2013-04-22 13:20:31 -0400
commitaa08069b3fb9a564df755ec558fd64ba076b0ef3 (patch)
tree663e54fb3287ac7522457381e49190d1da36a823
parentc9e4678c16164ca12de951ea6faffc9ab9600b0b (diff)
downloadgem5-aa08069b3fb9a564df755ec558fd64ba076b0ef3.tar.xz
sim: Add helper functions that add PCEvents with custom arguments
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.
-rw-r--r--src/arch/alpha/linux/system.cc8
-rw-r--r--src/arch/alpha/tru64/system.cc8
-rw-r--r--src/arch/arm/linux/system.cc21
-rw-r--r--src/sim/system.hh67
4 files changed, 70 insertions, 34 deletions
diff --git a/src/arch/alpha/linux/system.cc b/src/arch/alpha/linux/system.cc
index 0507af029..80d13cdfa 100644
--- a/src/arch/alpha/linux/system.cc
+++ b/src/arch/alpha/linux/system.cc
@@ -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
diff --git a/src/arch/alpha/tru64/system.cc b/src/arch/alpha/tru64/system.cc
index cb4b8dd56..dad65a6ab 100644
--- a/src/arch/alpha/tru64/system.cc
+++ b/src/arch/alpha/tru64/system.cc
@@ -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");
diff --git a/src/arch/arm/linux/system.cc b/src/arch/arm/linux/system.cc
index 4478aadf4..de4c27d8b 100644
--- a/src/arch/arm/linux/system.cc
+++ b/src/arch/arm/linux/system.cc
@@ -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;
diff --git a/src/sim/system.hh b/src/sim/system.hh
index 38db86cb2..e7407105a 100644
--- a/src/sim/system.hh
+++ b/src/sim/system.hh
@@ -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;