- case RTC_STAT_REGA:
- // The "update in progress" bit is read only.
- if ((data & ~RTCA_UIP) != (RTCA_32768HZ | RTCA_1024HZ))
- panic("Unimplemented RTC register A value write!\n");
- replaceBits(stat_regA, data, 6, 0);
- break;
+ case RTC_STAT_REGA: {
+ RtcRegA old_rega(stat_regA);
+ stat_regA = data;
+ // The "update in progress" bit is read only.
+ stat_regA.uip = old_rega;
+
+ 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;
+ }
+
+ if (stat_regA.rs != RTCA_RS_1024HZ) {
+ inform("RTC: Unimplemented interrupt rate: %i\n",
+ 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)) {
+ // According to the specification, the next tick
+ // happens after 0.5s when the divider chain goes
+ // from reset to active. So, we simply schedule the
+ // tick after 0.5s.
+ assert(!tickEvent.scheduled());
+ schedule(tickEvent, curTick() + SimClock::Int::s / 2);
+ }
+ } break;