From 5821fde9067b70ee07162ca7048549562fcc050b Mon Sep 17 00:00:00 2001 From: Peeter Must Date: Sat, 5 Jul 2014 19:34:09 +0900 Subject: [PATCH] Improve timecount at boot for some BIOSes that don't correctly read the RTC Changes brought in from FreeBSD --- sys/boot/pc32/libi386/time.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/sys/boot/pc32/libi386/time.c b/sys/boot/pc32/libi386/time.c index 5dfb198..ec128fe 100644 --- a/sys/boot/pc32/libi386/time.c +++ b/sys/boot/pc32/libi386/time.c @@ -59,20 +59,30 @@ bios_seconds(void) return (now); } +/* + * Some BIOSes (notably qemu) don't correctly read the RTC + * registers in an atomic way, sometimes returning bogus values. + * Therefore we "debounce" the reading by accepting it only when + * we got 8 identical values in succession. + * + * If we pass midnight, don't wrap back to 0. + */ time_t time(time_t *t) { static time_t lasttime; time_t now, check; - int try; + int same, try; - try = 0; - now = bios_seconds(); - while (now != (check = bios_seconds())) { + try = same = 0; + check = bios_seconds(); + do { now = check; - if (++try == 1000) - break; - } + check = bios_seconds(); + if (check != now) + same = 0; + } while (++same < 8 && ++try < 1000); + if (now < lasttime) now += 24 * 3600; lasttime = now; -- 1.9.3