diff options
Diffstat (limited to 'src/sim')
-rw-r--r-- | src/sim/eventq.hh | 6 | ||||
-rw-r--r-- | src/sim/main.cc | 17 | ||||
-rw-r--r-- | src/sim/pseudo_inst.cc | 58 | ||||
-rw-r--r-- | src/sim/pseudo_inst.hh | 1 | ||||
-rw-r--r-- | src/sim/root.cc | 2 | ||||
-rw-r--r-- | src/sim/serialize.cc | 36 | ||||
-rw-r--r-- | src/sim/sim_events.cc | 17 | ||||
-rw-r--r-- | src/sim/sim_events.hh | 18 | ||||
-rw-r--r-- | src/sim/sim_exit.hh | 8 | ||||
-rw-r--r-- | src/sim/stat_control.cc | 17 | ||||
-rw-r--r-- | src/sim/stat_control.hh | 4 | ||||
-rw-r--r-- | src/sim/system.hh | 1 |
12 files changed, 153 insertions, 32 deletions
diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh index 430473df3..537bfb918 100644 --- a/src/sim/eventq.hh +++ b/src/sim/eventq.hh @@ -46,6 +46,7 @@ #include "sim/host.hh" // for Tick #include "base/fast_alloc.hh" +#include "base/misc.hh" #include "base/trace.hh" #include "sim/serialize.hh" @@ -135,7 +136,7 @@ class Event : public Serializable, public FastAlloc /// same cycle (after unscheduling the old CPU's tick event). /// The switch needs to come before any tick events to make /// sure we don't tick both CPUs in the same cycle. - CPU_Switch_Pri = 31, + CPU_Switch_Pri = -31, /// Serailization needs to occur before tick events also, so /// that a serialize/unserialize is identical to an on-line @@ -351,7 +352,8 @@ inline void Event::schedule(Tick t) { assert(!scheduled()); - assert(t >= curTick); +// if (t < curTick) +// warn("t is less than curTick, ensure you don't want cycles"); setFlags(Scheduled); #if TRACING_ON diff --git a/src/sim/main.cc b/src/sim/main.cc index 5725897f8..874d0ac85 100644 --- a/src/sim/main.cc +++ b/src/sim/main.cc @@ -317,8 +317,8 @@ simulate(Tick num_cycles = -1) else num_cycles = curTick + num_cycles; - Event *limit_event = new SimLoopExitEvent(num_cycles, - "simulate() limit reached"); + Event *limit_event = schedExitSimLoop("simulate() limit reached", + num_cycles); while (1) { // there should always be at least one event (the SimLoopExitEvent @@ -414,7 +414,12 @@ unserializeAll(const std::string &cpt_dir) /** * Queue of C++ callbacks to invoke on simulator exit. */ -CallbackQueue exitCallbacks; +CallbackQueue& +exitCallbacks() +{ + static CallbackQueue theQueue; + return theQueue; +} /** * Register an exit callback. @@ -422,7 +427,7 @@ CallbackQueue exitCallbacks; void registerExitCallback(Callback *callback) { - exitCallbacks.add(callback); + exitCallbacks().add(callback); } BaseCPU * @@ -442,8 +447,8 @@ convertToBaseCPUPtr(SimObject *obj) void doExitCleanup() { - exitCallbacks.process(); - exitCallbacks.clear(); + exitCallbacks().process(); + exitCallbacks().clear(); cout.flush(); diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc index bd26e9dc5..addf897c6 100644 --- a/src/sim/pseudo_inst.cc +++ b/src/sim/pseudo_inst.cc @@ -138,14 +138,62 @@ namespace AlphaPseudo void m5exit_old(ThreadContext *tc) { - exitSimLoop(curTick, "m5_exit_old instruction encountered"); + exitSimLoop("m5_exit_old instruction encountered"); } void m5exit(ThreadContext *tc, Tick delay) { Tick when = curTick + delay * Clock::Int::ns; - exitSimLoop(when, "m5_exit instruction encountered"); + schedExitSimLoop("m5_exit instruction encountered", when); + } + + void + loadsymbol(ThreadContext *tc) + { + const string &filename = tc->getCpuPtr()->system->params()->symbolfile; + if (filename.empty()) { + return; + } + + std::string buffer; + ifstream file(filename.c_str()); + + if (!file) + fatal("file error: Can't open symbol table file %s\n", filename); + + while (!file.eof()) { + getline(file, buffer); + + if (buffer.empty()) + continue; + + int idx = buffer.find(' '); + if (idx == string::npos) + continue; + + string address = "0x" + buffer.substr(0, idx); + eat_white(address); + if (address.empty()) + continue; + + // Skip over letter and space + string symbol = buffer.substr(idx + 3); + eat_white(symbol); + if (symbol.empty()) + continue; + + Addr addr; + if (!to_number(address, addr)) + continue; + + if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol)) + continue; + + + DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); + } + file.close(); } void @@ -222,7 +270,11 @@ namespace AlphaPseudo { if (!doCheckpointInsts) return; - exitSimLoop("checkpoint"); + + Tick when = curTick + delay * Clock::Int::ns; + Tick repeat = period * Clock::Int::ns; + + schedExitSimLoop("checkpoint", when, repeat); } uint64_t diff --git a/src/sim/pseudo_inst.hh b/src/sim/pseudo_inst.hh index da2fb4ee3..d211de44e 100644 --- a/src/sim/pseudo_inst.hh +++ b/src/sim/pseudo_inst.hh @@ -51,6 +51,7 @@ namespace AlphaPseudo void ivle(ThreadContext *tc); void m5exit(ThreadContext *tc, Tick delay); void m5exit_old(ThreadContext *tc); + void loadsymbol(ThreadContext *xc); void resetstats(ThreadContext *tc, Tick delay, Tick period); void dumpstats(ThreadContext *tc, Tick delay, Tick period); void dumpresetstats(ThreadContext *tc, Tick delay, Tick period); diff --git a/src/sim/root.cc b/src/sim/root.cc index ec5e2f7e2..565b57269 100644 --- a/src/sim/root.cc +++ b/src/sim/root.cc @@ -100,7 +100,7 @@ void Root::startup() { if (max_tick != 0) - exitSimLoop(curTick + max_tick, "reached maximum cycle count"); + schedExitSimLoop("reached maximum cycle count", curTick + max_tick); if (progress_interval != 0) new ProgressEvent(&mainEventQueue, progress_interval); diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc index 6a1d084b7..941f0b1c6 100644 --- a/src/sim/serialize.cc +++ b/src/sim/serialize.cc @@ -52,6 +52,9 @@ #include "sim/sim_exit.hh" #include "sim/sim_object.hh" +// For stat reset hack +#include "sim/stat_control.hh" + using namespace std; int Serializable::ckptMaxCount = 0; @@ -404,3 +407,36 @@ Checkpoint::sectionExists(const std::string §ion) { return db->sectionExists(section); } + +/** Hacked stat reset event */ + +class StatresetParamContext : public ParamContext +{ + public: + StatresetParamContext(const string §ion); + ~StatresetParamContext(); + void startup(); +}; + +StatresetParamContext statParams("statsreset"); + +Param<Tick> reset_cycle(&statParams, "reset_cycle", + "Cycle to reset stats on", 0); + +StatresetParamContext::StatresetParamContext(const string §ion) + : ParamContext(section) +{ } + +StatresetParamContext::~StatresetParamContext() +{ +} + +void +StatresetParamContext::startup() +{ + if (reset_cycle > 0) { + Stats::SetupEvent(Stats::Reset, curTick + reset_cycle, 0); + cprintf("Stats reset event scheduled for %lli\n", + curTick + reset_cycle); + } +} diff --git a/src/sim/sim_events.cc b/src/sim/sim_events.cc index d9e8bdeaa..2ccc9dad2 100644 --- a/src/sim/sim_events.cc +++ b/src/sim/sim_events.cc @@ -57,6 +57,11 @@ SimLoopExitEvent::process() // otherwise do nothing... the IsExitEvent flag takes care of // exiting the simulation loop and returning this object to Python + + // but if you are doing this on intervals, don't forget to make another + if (repeat) { + schedule(curTick + repeat); + } } @@ -66,16 +71,20 @@ SimLoopExitEvent::description() return "simulation loop exit"; } -void -exitSimLoop(Tick when, const std::string &message, int exit_code) +SimLoopExitEvent * +schedExitSimLoop(const std::string &message, Tick when, Tick repeat, + EventQueue *q, int exit_code) { - new SimLoopExitEvent(when, message, exit_code); + if (q == NULL) + q = &mainEventQueue; + + return new SimLoopExitEvent(q, when, repeat, message, exit_code); } void exitSimLoop(const std::string &message, int exit_code) { - exitSimLoop(curTick, message, exit_code); + schedExitSimLoop(message, curTick, 0, NULL, exit_code); } void diff --git a/src/sim/sim_events.hh b/src/sim/sim_events.hh index 3c4a9dd05..e1576b38c 100644 --- a/src/sim/sim_events.hh +++ b/src/sim/sim_events.hh @@ -42,6 +42,7 @@ class SimLoopExitEvent : public Event // string explaining why we're terminating std::string cause; int code; + Tick repeat; public: // Default constructor. Only really used for derived classes. @@ -49,16 +50,19 @@ class SimLoopExitEvent : public Event : Event(&mainEventQueue, Sim_Exit_Pri) { } - SimLoopExitEvent(Tick _when, const std::string &_cause, int c = 0) - : Event(&mainEventQueue, Sim_Exit_Pri), cause(_cause), - code(c) - { setFlags(IsExitEvent); schedule(_when); } - SimLoopExitEvent(EventQueue *q, - Tick _when, const std::string &_cause, int c = 0) - : Event(q, Sim_Exit_Pri), cause(_cause), code(c) + Tick _when, Tick _repeat, const std::string &_cause, + int c = 0) + : Event(q, Sim_Exit_Pri), cause(_cause), + code(c), repeat(_repeat) { setFlags(IsExitEvent); schedule(_when); } +// SimLoopExitEvent(EventQueue *q, +// Tick _when, const std::string &_cause, +// Tick _repeat = 0, int c = 0) +// : Event(q, Sim_Exit_Pri), cause(_cause), code(c), repeat(_repeat) +// { setFlags(IsExitEvent); schedule(_when); } + std::string getCause() { return cause; } int getCode() { return code; } diff --git a/src/sim/sim_exit.hh b/src/sim/sim_exit.hh index 545bf4ae0..d4b31d1ea 100644 --- a/src/sim/sim_exit.hh +++ b/src/sim/sim_exit.hh @@ -38,6 +38,8 @@ // forward declaration class Callback; +class EventQueue; +class SimLoopExitEvent; /// Register a callback to be called when Python exits. Defined in /// sim/main.cc. @@ -47,12 +49,14 @@ void registerExitCallback(Callback *); /// Python) at the indicated tick. The message and exit_code /// parameters are saved in the SimLoopExitEvent to indicate why the /// exit occurred. -void exitSimLoop(Tick when, const std::string &message, int exit_code = 0); +SimLoopExitEvent *schedExitSimLoop(const std::string &message, Tick when, + Tick repeat = 0, EventQueue *q = NULL, + int exit_code = 0); /// Schedule an event to exit the simulation loop (returning to /// Python) at the end of the current cycle (curTick). The message /// and exit_code parameters are saved in the SimLoopExitEvent to /// indicate why the exit occurred. -void exitSimLoop(const std::string &cause, int exit_code = 0); +void exitSimLoop(const std::string &message, int exit_code = 0); #endif // __SIM_EXIT_HH__ diff --git a/src/sim/stat_control.cc b/src/sim/stat_control.cc index 041830ab7..3fad8beb5 100644 --- a/src/sim/stat_control.cc +++ b/src/sim/stat_control.cc @@ -160,13 +160,13 @@ class StatEvent : public Event Tick repeat; public: - StatEvent(int _flags, Tick _when, Tick _repeat); + StatEvent(EventQueue *queue, int _flags, Tick _when, Tick _repeat); virtual void process(); virtual const char *description(); }; -StatEvent::StatEvent(int _flags, Tick _when, Tick _repeat) - : Event(&mainEventQueue, Stat_Event_Pri), +StatEvent::StatEvent(EventQueue *queue, int _flags, Tick _when, Tick _repeat) + : Event(queue, Stat_Event_Pri), flags(_flags), repeat(_repeat) { setFlags(AutoDelete); @@ -185,8 +185,10 @@ StatEvent::process() if (flags & Stats::Dump) DumpNow(); - if (flags & Stats::Reset) + if (flags & Stats::Reset) { + cprintf("Resetting stats at cycle %d!\n", curTick); reset(); + } if (repeat) schedule(curTick + repeat); @@ -214,9 +216,12 @@ DumpNow() } void -SetupEvent(int flags, Tick when, Tick repeat) +SetupEvent(int flags, Tick when, Tick repeat, EventQueue *queue) { - new StatEvent(flags, when, repeat); + if (queue == NULL) + queue = &mainEventQueue; + + new StatEvent(queue, flags, when, repeat); } /* namespace Stats */ } diff --git a/src/sim/stat_control.hh b/src/sim/stat_control.hh index fb369f640..67f7cc491 100644 --- a/src/sim/stat_control.hh +++ b/src/sim/stat_control.hh @@ -34,6 +34,8 @@ #include <fstream> #include <list> +class EventQueue; + namespace Stats { enum { @@ -45,7 +47,7 @@ class Output; extern std::list<Output *> OutputList; void DumpNow(); -void SetupEvent(int flags, Tick when, Tick repeat = 0); +void SetupEvent(int flags, Tick when, Tick repeat = 0, EventQueue *queue = NULL); void InitSimStats(); diff --git a/src/sim/system.hh b/src/sim/system.hh index 11f4f0c90..3ab1d81f2 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -182,6 +182,7 @@ class System : public SimObject std::string kernel_path; std::string readfile; + std::string symbolfile; #endif }; |