}
}
+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)
{
*/
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.
#include "base/misc.hh"
#include "dev/intel_8254_timer.hh"
+#include "sim/sim_object.hh"
using namespace std;
}
}
+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)
{
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)
{
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);
}
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);
/** 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);
/** Is the output high? */
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.
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.
#include "base/trace.hh"
#include "dev/mc146818.hh"
#include "dev/rtcreg.h"
+#include "sim/sim_object.hh"
using namespace std;
MC146818::~MC146818()
{
- deschedule(tickEvent);
- deschedule(event);
+ if (tickEvent.scheduled()) {
+ deschedule(tickEvent);
+ }
+ if (event.scheduled()) {
+ deschedule(event);
+ }
}
void
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)
{
// 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);
}
/** 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);
void tickClock();
+ unsigned int drain(Event *de);
+
/**
* Serialize this object to the given output stream.
* @param base The base name of the counter object.