summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dev/mc146818.cc22
1 files changed, 16 insertions, 6 deletions
diff --git a/src/dev/mc146818.cc b/src/dev/mc146818.cc
index 276c98581..abacd8742 100644
--- a/src/dev/mc146818.cc
+++ b/src/dev/mc146818.cc
@@ -144,7 +144,8 @@ MC146818::writeData(const uint8_t addr, const uint8_t data)
// The "update in progress" bit is read only.
stat_regA.uip = old_rega;
- if (stat_regA.dv != RTCA_DV_32768HZ) {
+ if (!rega_dv_disabled(stat_regA) &&
+ stat_regA.dv != RTCA_DV_32768HZ) {
inform("RTC: Unimplemented divider configuration: %i\n",
stat_regA.dv);
panic_unsupported = true;
@@ -155,14 +156,21 @@ MC146818::writeData(const uint8_t addr, const uint8_t data)
stat_regA.rs);
panic_unsupported = true;
}
+
+ if (rega_dv_disabled(stat_regA)) {
+ // The divider is disabled, make sure that we don't
+ // schedule any ticks.
+ if (tickEvent.scheduled())
+ deschedule(tickEvent);
+ } else if (rega_dv_disabled(old_rega)) {
+ // If the divider chain goes from reset to active, we
+ // need to schedule a tick after precisely 0.5s.
+ assert(!tickEvent.scheduled());
+ schedule(tickEvent, curTick() + SimClock::Int::s / 2);
+ }
} break;
case RTC_STAT_REGB:
stat_regB = data;
- if (stat_regB.set) {
- inform("RTC: Updating stopping not implemented.\n");
- panic_unsupported = true;
- }
-
if (stat_regB.aie || stat_regB.uie) {
inform("RTC: Unimplemented interrupt configuration: %s %s\n",
stat_regB.aie ? "alarm" : "",
@@ -233,6 +241,8 @@ MC146818::readData(uint8_t addr)
void
MC146818::tickClock()
{
+ assert(!rega_dv_disabled(stat_regA));
+
if (stat_regB.set)
return;
time_t calTime = mkutctime(&curTime);