summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dev/alpha/tsunami_io.cc11
-rw-r--r--src/dev/alpha/tsunami_io.hh6
-rw-r--r--src/dev/intel_8254_timer.cc29
-rw-r--r--src/dev/intel_8254_timer.hh12
-rw-r--r--src/dev/mc146818.cc25
-rw-r--r--src/dev/mc146818.hh6
6 files changed, 80 insertions, 9 deletions
diff --git a/src/dev/alpha/tsunami_io.cc b/src/dev/alpha/tsunami_io.cc
index c90f06b5a..1a76c2c32 100644
--- a/src/dev/alpha/tsunami_io.cc
+++ b/src/dev/alpha/tsunami_io.cc
@@ -249,6 +249,17 @@ TsunamiIO::clearPIC(uint8_t bitvector)
}
}
+unsigned int
+TsunamiIO::drain(Event *de)
+{
+ unsigned int count = 0;
+ count += pitimer.drain(de);
+ count += rtc.drain(de);
+ assert(count == 0);
+ changeState(SimObject::Drained);
+ return count;
+}
+
void
TsunamiIO::serialize(ostream &os)
{
diff --git a/src/dev/alpha/tsunami_io.hh b/src/dev/alpha/tsunami_io.hh
index b6d63322b..f649247e2 100644
--- a/src/dev/alpha/tsunami_io.hh
+++ b/src/dev/alpha/tsunami_io.hh
@@ -141,6 +141,12 @@ class TsunamiIO : public BasicPioDevice
void clearPIC(uint8_t bitvector);
/**
+ * Drain the io state including all associated events.
+ * @param drainEvent
+ */
+ unsigned int drain(Event *de);
+
+ /**
* Serialize this object to the given output stream.
* @param os The stream to serialize to.
*/
diff --git a/src/dev/intel_8254_timer.cc b/src/dev/intel_8254_timer.cc
index 9e507b968..b61aa7c56 100644
--- a/src/dev/intel_8254_timer.cc
+++ b/src/dev/intel_8254_timer.cc
@@ -32,6 +32,7 @@
#include "base/misc.hh"
#include "dev/intel_8254_timer.hh"
+#include "sim/sim_object.hh"
using namespace std;
@@ -69,6 +70,17 @@ Intel8254Timer::writeControl(const CtrlReg data)
}
}
+unsigned int
+Intel8254Timer::drain(Event *de)
+{
+ unsigned int count = 0;
+ count += counter[0]->drain(de);
+ count += counter[1]->drain(de);
+ count += counter[2]->drain(de);
+ assert(count == 0);
+ return count;
+}
+
void
Intel8254Timer::serialize(const string &base, ostream &os)
{
@@ -216,6 +228,18 @@ Intel8254Timer::Counter::outputHigh()
return output_high;
}
+unsigned int
+Intel8254Timer::Counter::drain(Event *de)
+{
+ if (event.scheduled()) {
+ event_tick = event.when();
+ parent->deschedule(event);
+ } else {
+ event_tick = 0;
+ }
+ return 0;
+}
+
void
Intel8254Timer::Counter::serialize(const string &base, ostream &os)
{
@@ -227,10 +251,6 @@ Intel8254Timer::Counter::serialize(const string &base, ostream &os)
paramOut(os, base + ".latch_on", latch_on);
paramOut(os, base + ".read_byte", read_byte);
paramOut(os, base + ".write_byte", write_byte);
-
- Tick event_tick = 0;
- if (event.scheduled())
- event_tick = event.when();
paramOut(os, base + ".event_tick", event_tick);
}
@@ -247,7 +267,6 @@ Intel8254Timer::Counter::unserialize(const string &base, Checkpoint *cp,
paramIn(cp, section, base + ".read_byte", read_byte);
paramIn(cp, section, base + ".write_byte", write_byte);
- Tick event_tick;
paramIn(cp, section, base + ".event_tick", event_tick);
if (event_tick)
parent->schedule(event, event_tick);
diff --git a/src/dev/intel_8254_timer.hh b/src/dev/intel_8254_timer.hh
index 30ddc7bca..26ea0687e 100644
--- a/src/dev/intel_8254_timer.hh
+++ b/src/dev/intel_8254_timer.hh
@@ -137,6 +137,10 @@ class Intel8254Timer : public EventManager
/** Pointer to container */
Intel8254Timer *parent;
+ /** if non-zero, the scheduled tick of an event used for drain
+ serialization coordination */
+ Tick event_tick;
+
public:
Counter(Intel8254Timer *p, const std::string &name, unsigned int num);
@@ -165,6 +169,12 @@ class Intel8254Timer : public EventManager
bool outputHigh();
/**
+ * Drain all associated events.
+ * @param drainEvent
+ */
+ unsigned int drain(Event *de);
+
+ /**
* Serialize this object to the given output stream.
* @param base The base name of the counter object.
* @param os The stream to serialize to.
@@ -229,6 +239,8 @@ class Intel8254Timer : public EventManager
return counter[num]->outputHigh();
}
+ unsigned int drain(Event *de);
+
/**
* Serialize this object to the given output stream.
* @param base The base name of the counter object.
diff --git a/src/dev/mc146818.cc b/src/dev/mc146818.cc
index 16ed58e46..fd70b503b 100644
--- a/src/dev/mc146818.cc
+++ b/src/dev/mc146818.cc
@@ -40,6 +40,7 @@
#include "base/trace.hh"
#include "dev/mc146818.hh"
#include "dev/rtcreg.h"
+#include "sim/sim_object.hh"
using namespace std;
@@ -105,8 +106,12 @@ MC146818::MC146818(EventManager *em, const string &n, const struct tm time,
MC146818::~MC146818()
{
- deschedule(tickEvent);
- deschedule(event);
+ if (tickEvent.scheduled()) {
+ deschedule(tickEvent);
+ }
+ if (event.scheduled()) {
+ deschedule(event);
+ }
}
void
@@ -203,6 +208,20 @@ MC146818::tickClock()
setTime(*gmtime(&calTime));
}
+unsigned int
+MC146818::drain(Event *de)
+{
+ if (event.scheduled()) {
+ rtcTimerInterruptTickOffset = event.when() - curTick;
+ rtcClockTickOffset = event.when() - curTick;
+ deschedule(event);
+ }
+ if (tickEvent.scheduled()) {
+ deschedule(tickEvent);
+ }
+ return 0;
+}
+
void
MC146818::serialize(const string &base, ostream &os)
{
@@ -214,9 +233,7 @@ MC146818::serialize(const string &base, ostream &os)
// save the timer tick and rtc clock tick values to correctly reschedule
// them during unserialize
//
- Tick rtcTimerInterruptTickOffset = event.when() - curTick;
SERIALIZE_SCALAR(rtcTimerInterruptTickOffset);
- Tick rtcClockTickOffset = event.when() - curTick;
SERIALIZE_SCALAR(rtcClockTickOffset);
}
diff --git a/src/dev/mc146818.hh b/src/dev/mc146818.hh
index 699785199..507abab5a 100644
--- a/src/dev/mc146818.hh
+++ b/src/dev/mc146818.hh
@@ -119,6 +119,10 @@ class MC146818 : public EventManager
/** RTC status register B */
uint8_t stat_regB;
+ /** RTC event times for drain and serialization coordination */
+ Tick rtcTimerInterruptTickOffset;
+ Tick rtcClockTickOffset;
+
public:
MC146818(EventManager *em, const std::string &name, const struct tm time,
bool bcd, Tick frequency);
@@ -132,6 +136,8 @@ class MC146818 : public EventManager
void tickClock();
+ unsigned int drain(Event *de);
+
/**
* Serialize this object to the given output stream.
* @param base The base name of the counter object.