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.
This commit is contained in:
parent
c9e4678c16
commit
aa08069b3f
4 changed files with 70 additions and 34 deletions
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue