diff options
author | Andreas Sandberg <Andreas.Sandberg@ARM.com> | 2013-04-22 13:20:31 -0400 |
---|---|---|
committer | Andreas Sandberg <Andreas.Sandberg@ARM.com> | 2013-04-22 13:20:31 -0400 |
commit | aa08069b3fb9a564df755ec558fd64ba076b0ef3 (patch) | |
tree | 663e54fb3287ac7522457381e49190d1da36a823 | |
parent | c9e4678c16164ca12de951ea6faffc9ab9600b0b (diff) | |
download | gem5-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.cc | 8 | ||||
-rw-r--r-- | src/arch/alpha/tru64/system.cc | 8 | ||||
-rw-r--r-- | src/arch/arm/linux/system.cc | 21 | ||||
-rw-r--r-- | src/sim/system.hh | 67 |
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; |