CODE2 void rdtime32(uint32_t *tloc);
CODE2 void wrtime(time_t *tloc);
CODE2 extern void updatetod(void);
+CODE2 extern void inittod(void);
/* provided by architecture or helpers */
CODE2 void device_init(void); /* provided by platform */
CODE2 uint8_t *swapin_prepare_uarea(ptptr p);
CODE2 void map_init(void);
CODE2 void platform_idle(void);
+CODE2 uint8_t rtc_secs(void);
+
/* Will need a uptr_t eventually */
extern uint16_t ramtop; /* Note: ramtop must be in common in some cases */
CODE2 extern void platform_interrupt(void);
{
irqflags_t irq = di();
memcpy(&tod, tloc, sizeof(tod));
-#ifdef CONFIG_RTC
- machine_set_clock(tloc);
-#endif
irqrestore(irq);
}
if (!++tod.low)
++tod.high;
}
+#else
+
+static uint8_t rtcsec;
+
+/*
+ * We use the seconds counter on the RTC as a time counter and lock our
+ * time progression to it. This avoids doing horrible piles of math to
+ * use the RTC itself and avoids problems with non Y2K devices.
+ *
+ * We allow for multi-second leaps. On boxes with many of the directly
+ * interfaced floppy controllers we can reasonably expect to lose IRQ
+ * service for annoyingly long times.
+ */
+void updatetod(void)
+{
+ uint8_t rtcnew = rtc_secs(); /* platform function */
+ int8_t slide;
+
+ if (rtcnew == rtcsec)
+ return;
+ slide = rtcnew - rtcsec; /* Seconds elapsed */
+ if (slide < 0)
+ slide += 60; /* Seconds wrapped */
+ tod.low += slide;
+ if (tod.low < slide) /* 32bit wrap ? */
+ tod.high++;
+ rtcsec = rtcnew;
+}
+
+void inittod(void)
+{
+ rtcsec = rtc_secs();
+}
+
#endif /* NO_RTC */