put all century related code into an own function clock_expandyear(),

touch the CMOS century byte only if the CMOS contents passes a
checksum test which qualifies it as "known compliant"
This commit is contained in:
drochner 1999-02-07 16:18:00 +00:00
parent cc5f9932f8
commit 0f145938b4

View File

@ -1,4 +1,4 @@
/* $NetBSD: clock.c,v 1.56 1999/01/18 10:50:23 drochner Exp $ */
/* $NetBSD: clock.c,v 1.57 1999/02/07 16:18:00 drochner Exp $ */
/*-
* Copyright (c) 1993, 1994 Charles M. Hannum.
@ -488,14 +488,86 @@ bintobcd(n)
static int timeset;
/*
* check whether the CMOS layout is "standard"-like (ie, not PS/2-like),
* to be called at splclock()
*/
static int cmoscheck __P((void));
static int
cmoscheck()
{
int i;
unsigned short cksum = 0;
for (i = 0x10; i <= 0x2d; i++)
cksum += mc146818_read(NULL, i); /* XXX softc */
return (cksum == (mc146818_read(NULL, 0x2e) << 8)
+ mc146818_read(NULL, 0x2f));
}
/*
* patchable to control century byte handling:
* 1: always update in resettodr()
* 1: always update
* -1: never touch
* 0: try to figure out itself
*/
int rtc_update_century = 0;
/*
* Expand a two-digit year as read from the clock chip
* into an offset relative to 1900.
* Being here, deal with the CMOS century byte.
*/
static int clock_expandyear __P((int));
static int
clock_expandyear(clockyear)
int clockyear;
{
int s, clockcentury, cmoscentury;
clockcentury = (clockyear < 70) ? 20 : 19;
clockyear = ((clockcentury == 20) ? clockyear + 100 : clockyear);
if (rtc_update_century < 0)
return (clockyear);
s = splclock();
if (cmoscheck())
cmoscentury = mc146818_read(NULL, NVRAM_CENTURY);
else
cmoscentury = 0;
splx(s);
if (!cmoscentury) {
#ifdef DEBUG
printf("clock: unknown CMOS layout\n");
#endif
return (clockyear);
}
cmoscentury = bcdtobin(cmoscentury);
if (cmoscentury != clockcentury) {
/* XXX note: saying "century is 20" might confuse the naive. */
printf("WARNING: NVRAM century is %d but RTC year is %d\n",
cmoscentury, clockyear);
/* Kludge to roll over century. */
if ((rtc_update_century > 0) ||
((cmoscentury == 19) && (clockcentury == 20) &&
(clockyear == 00))) {
printf("WARNING: Setting NVRAM century to %d\n",
clockcentury);
s = splclock();
mc146818_write(NULL, NVRAM_CENTURY,
bintobcd(clockcentury));
splx(s);
}
} else if (cmoscentury == 19 && rtc_update_century == 0)
rtc_update_century = 1; /* will update later in resettodr() */
return (clockyear);
}
/*
* Initialize the time of day register, based on the time base which is, e.g.
* from a filesystem.
@ -506,7 +578,7 @@ inittodr(base)
{
mc_todregs rtclk;
time_t n;
int sec, min, hr, dom, mon, yr, century, tcentury;
int sec, min, hr, dom, mon, yr;
int i, days = 0;
int s;
@ -530,7 +602,6 @@ inittodr(base)
printf("WARNING: invalid time in clock chip\n");
goto fstime;
}
century = mc146818_read(NULL, NVRAM_CENTURY); /* XXX softc */
splx(s);
sec = bcdtobin(rtclk[MC_SEC]);
@ -539,27 +610,9 @@ inittodr(base)
dom = bcdtobin(rtclk[MC_DOM]);
mon = bcdtobin(rtclk[MC_MONTH]);
yr = bcdtobin(rtclk[MC_YEAR]);
century = bcdtobin(century);
tcentury = (yr < 70) ? 20 : 19;
if (century != tcentury) {
/* XXX note: saying "century is 20" might confuse the naive. */
printf("WARNING: NVRAM century is %d but RTC year is %d\n",
century, yr);
/* Kludge to roll over century. */
if ((century == 19) && (tcentury == 20) && (yr == 00) &&
rtc_update_century >= 0) {
printf("WARNING: Setting NVRAM century to 20\n");
s = splclock();
/* note: 0x20 = 20 in BCD. */
mc146818_write(NULL, NVRAM_CENTURY, 0x20); /*XXXsoftc*/
splx(s);
}
} else if (century == 19 && rtc_update_century == 0)
rtc_update_century = 1; /* will update later in resettodr() */
yr = clock_expandyear(yr);
yr = (tcentury == 20) ? yr+100 : yr;
/*
* If time_t is 32 bits, then the "End of Time" is
* Mon Jan 18 22:14:07 2038 (US/Eastern)