From aa08069b3fb9a564df755ec558fd64ba076b0ef3 Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Mon, 22 Apr 2013 13:20:31 -0400 Subject: [PATCH] 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. --- src/arch/alpha/linux/system.cc | 8 +--- src/arch/alpha/tru64/system.cc | 8 +--- src/arch/arm/linux/system.cc | 21 +++-------- 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("panic"); - if (!kernelPanicEvent) - panic("could not find kernel symbol \'panic\'"); + kernelPanicEvent = addKernelFuncEventOrPanic("panic"); #if 0 - kernelDieEvent = addKernelFuncEvent("die_if_kernel"); - if (!kernelDieEvent) - panic("could not find kernel symbol \'die_if_kernel\'"); + kernelDieEvent = addKernelFuncEventOrPanic("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("panic"); - if (!kernelPanicEvent) - panic("could not find kernel symbol \'panic\'"); + kernelPanicEvent = addKernelFuncEventOrPanic("panic"); #endif - badaddrEvent = addKernelFuncEvent("badaddr"); - if (!badaddrEvent) - panic("could not find kernel symbol \'badaddr\'"); + badaddrEvent = addKernelFuncEventOrPanic("badaddr"); skipPowerStateEvent = addKernelFuncEvent("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("panic"); - if (!kernelPanicEvent) - panic("could not find kernel symbol \'panic\'"); + kernelPanicEvent = addKernelFuncEventOrPanic("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( + "__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( + "__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 +#include #include #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 - T *addFuncEvent(SymbolTable *symtab, const char *lbl) + template + 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)...); return ev; } return NULL; } - /** Add a function-based event to kernel code. */ template - T *addKernelFuncEvent(const char *lbl) + T *addFuncEvent(const SymbolTable *symtab, const char *lbl) { - return addFuncEvent(kernelSymtab, lbl); + return addFuncEvent(symtab, lbl, lbl); } + template + T *addFuncEventOrPanic(const SymbolTable *symtab, const char *lbl, + Args... args) + { + T *e(addFuncEvent(symtab, lbl, std::forward(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 + T *addKernelFuncEvent(const char *lbl, Args... args) + { + return addFuncEvent(kernelSymtab, lbl, + std::forward(args)...); + } + + template + T *addKernelFuncEventOrPanic(const char *lbl, Args... args) + { + T *e(addFuncEvent(kernelSymtab, lbl, + std::forward(args)...)); + if (!e) + panic("Failed to find kernel symbol '%s'", lbl); + return e; + } + /** @} */ + public: std::vector remoteGDB; std::vector gdbListen;