summaryrefslogtreecommitdiff
path: root/src/sim
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim')
-rw-r--r--src/sim/sim_object.cc29
-rw-r--r--src/sim/sim_object.hh15
-rw-r--r--src/sim/system.cc8
-rw-r--r--src/sim/system.hh17
4 files changed, 40 insertions, 29 deletions
diff --git a/src/sim/sim_object.cc b/src/sim/sim_object.cc
index a0278dba0..d12b06b7a 100644
--- a/src/sim/sim_object.cc
+++ b/src/sim/sim_object.cc
@@ -72,7 +72,7 @@ SimObject::SimObject(Params *p)
doRecordEvent = !Stats::event_ignore.match(name());
simObjectList.push_back(this);
- state = Atomic;
+ state = Running;
}
//
@@ -88,7 +88,7 @@ SimObject::SimObject(const string &_name)
doRecordEvent = !Stats::event_ignore.match(name());
simObjectList.push_back(this);
- state = Atomic;
+ state = Running;
}
void
@@ -269,38 +269,23 @@ SimObject::recordEvent(const std::string &stat)
Stats::recordEvent(stat);
}
-bool
+unsigned int
SimObject::drain(Event *drain_event)
{
- if (state != DrainedAtomic && state != Atomic) {
- panic("Must implement your own drain function if it is to be used "
- "in timing mode!");
- }
- state = DrainedAtomic;
- return true;
+ state = Drained;
+ return 0;
}
void
SimObject::resume()
{
- if (state == DrainedAtomic) {
- state = Atomic;
- } else if (state == DrainedTiming) {
- state = Timing;
- }
+ state = Running;
}
void
SimObject::setMemoryMode(State new_mode)
{
- assert(new_mode == Timing || new_mode == Atomic);
- if (state == DrainedAtomic && new_mode == Timing) {
- state = DrainedTiming;
- } else if (state == DrainedTiming && new_mode == Atomic) {
- state = DrainedAtomic;
- } else {
- state = new_mode;
- }
+ panic("setMemoryMode() should only be called on systems");
}
void
diff --git a/src/sim/sim_object.hh b/src/sim/sim_object.hh
index 7ecc00958..38f2bdd23 100644
--- a/src/sim/sim_object.hh
+++ b/src/sim/sim_object.hh
@@ -60,16 +60,15 @@ class SimObject : public Serializable, protected StartupCallback
};
enum State {
- Atomic,
- Timing,
+ Running,
Draining,
- DrainedAtomic,
- DrainedTiming
+ Drained
};
+ private:
+ State state;
protected:
Params *_params;
- State state;
void changeState(State new_state) { state = new_state; }
@@ -116,8 +115,10 @@ class SimObject : public Serializable, protected StartupCallback
// Methods to drain objects in order to take checkpoints
// Or switch from timing -> atomic memory model
- // Drain returns false if the SimObject cannot drain immediately.
- virtual bool drain(Event *drain_event);
+ // Drain returns 0 if the simobject can drain immediately or
+ // the number of times the drain_event's process function will be called
+ // before the object will be done draining. Normally this should be 1
+ virtual unsigned int drain(Event *drain_event);
virtual void resume();
virtual void setMemoryMode(State new_mode);
virtual void switchOut();
diff --git a/src/sim/system.cc b/src/sim/system.cc
index 89e7b8542..2780d0fda 100644
--- a/src/sim/system.cc
+++ b/src/sim/system.cc
@@ -143,6 +143,14 @@ int rgdb_wait = -1;
#endif // FULL_SYSTEM
+
+void
+System::setMemoryMode(MemoryMode mode)
+{
+ assert(getState() == Drained);
+ memoryMode = mode;
+}
+
int
System::registerThreadContext(ThreadContext *tc, int id)
{
diff --git a/src/sim/system.hh b/src/sim/system.hh
index 059dc92dc..77777aed4 100644
--- a/src/sim/system.hh
+++ b/src/sim/system.hh
@@ -61,6 +61,21 @@ class RemoteGDB;
class System : public SimObject
{
public:
+ enum MemoryMode {
+ Invalid=0,
+ Atomic,
+ Timing
+ };
+
+
+ MemoryMode getMemoryMode() { assert(memoryMode); return memoryMode; }
+
+ /** Change the memory mode of the system. This should only be called by the
+ * python!!
+ * @param mode Mode to change to (atomic/timing)
+ */
+ void setMemoryMode(MemoryMode mode);
+
PhysicalMemory *physmem;
PCEventQueue pcEventQueue;
@@ -108,6 +123,8 @@ class System : public SimObject
protected:
+ MemoryMode memoryMode;
+
#if FULL_SYSTEM
/**
* Fix up an address used to match PCs for hooking simulator