summaryrefslogtreecommitdiff
path: root/src/sim
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim')
-rw-r--r--src/sim/eventq.hh6
-rw-r--r--src/sim/main.cc17
-rw-r--r--src/sim/pseudo_inst.cc58
-rw-r--r--src/sim/pseudo_inst.hh1
-rw-r--r--src/sim/root.cc2
-rw-r--r--src/sim/serialize.cc36
-rw-r--r--src/sim/sim_events.cc17
-rw-r--r--src/sim/sim_events.hh18
-rw-r--r--src/sim/sim_exit.hh8
-rw-r--r--src/sim/stat_control.cc17
-rw-r--r--src/sim/stat_control.hh4
-rw-r--r--src/sim/system.hh1
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 &section)
{
return db->sectionExists(section);
}
+
+/** Hacked stat reset event */
+
+class StatresetParamContext : public ParamContext
+{
+ public:
+ StatresetParamContext(const string &section);
+ ~StatresetParamContext();
+ void startup();
+};
+
+StatresetParamContext statParams("statsreset");
+
+Param<Tick> reset_cycle(&statParams, "reset_cycle",
+ "Cycle to reset stats on", 0);
+
+StatresetParamContext::StatresetParamContext(const string &section)
+ : 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
};