Subject: testers wanted for y2k clock.c patch
To: None <port-i386@netbsd.org>
From: Perry E. Metzger <perry@piermont.com>
List: port-i386
Date: 10/09/1998 00:23:36
My crash-n-burn i386 box has crashed and burned so badly I can't get
it to boot. Unfortunately, I need some good masochists, er, testers,
for a clock.c patch against current.

If someone (or several someones) could test that this doesn't cause
trouble when put in your kernel, I'd appreciate it. I'd *especially*
appreciate reports about what happens if you then try to go through a
1999->2000 time transition with this patch in place, and a 2000->2001
transition.

The patch is against src/sys/arch/i386/isa/clock.c

Anyway:

Index: clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/isa/clock.c,v
retrieving revision 1.53
diff -c -r1.53 clock.c
*** clock.c	1998/10/06 05:52:23	1.53
--- clock.c	1998/10/09 04:22:06
***************
*** 129,136 ****
  int	rtcget __P((mc_todregs *));
  void	rtcput __P((mc_todregs *));
  static int yeartoday __P((int));
! int 	hexdectodec __P((int));
! int	dectohexdec __P((int));
  
  
  __inline u_int mc146818_read __P((void *, u_int));
--- 129,136 ----
  int	rtcget __P((mc_todregs *));
  void	rtcput __P((mc_todregs *));
  static int yeartoday __P((int));
! int 	bcdtobin __P((int));
! int	bintobcd __P((int));
  
  
  __inline u_int mc146818_read __P((void *, u_int));
***************
*** 471,477 ****
  }
  
  int
! hexdectodec(n)
  	int n;
  {
  
--- 471,477 ----
  }
  
  int
! bcdtobin(n)
  	int n;
  {
  
***************
*** 479,485 ****
  }
  
  int
! dectohexdec(n)
  	int n;
  {
  
--- 479,485 ----
  }
  
  int
! bintobcd(n)
  	int n;
  {
  
***************
*** 498,504 ****
  {
  	mc_todregs rtclk;
  	time_t n;
! 	int sec, min, hr, dom, mon, yr;
  	int i, days = 0;
  	int s;
  
--- 498,504 ----
  {
  	mc_todregs rtclk;
  	time_t n;
! 	int sec, min, hr, dom, mon, yr, century, tcentury;
  	int i, days = 0;
  	int s;
  
***************
*** 522,536 ****
  		printf("WARNING: invalid time in clock chip\n");
  		goto fstime;
  	}
  	splx(s);
  
! 	sec = hexdectodec(rtclk[MC_SEC]);
! 	min = hexdectodec(rtclk[MC_MIN]);
! 	hr = hexdectodec(rtclk[MC_HOUR]);
! 	dom = hexdectodec(rtclk[MC_DOM]);
! 	mon = hexdectodec(rtclk[MC_MONTH]);
! 	yr = hexdectodec(rtclk[MC_YEAR]);
! 	yr = (yr < 70) ? yr+100 : yr;
   
  	/*
  	 * If time_t is 32 bits, then the "End of Time" is 
--- 522,556 ----
  		printf("WARNING: invalid time in clock chip\n");
  		goto fstime;
  	}
+ 	/* XXX Does reading the century from NVRAM need to be at splclock? */
+ 	century = mc146818_read(NULL, NVRAM_CENTURY); /* XXX softc */
  	splx(s);
  
! 	sec = bcdtobin(rtclk[MC_SEC]);
! 	min = bcdtobin(rtclk[MC_MIN]);
! 	hr = bcdtobin(rtclk[MC_HOUR]);
! 	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)) {
! 		printf("WARNING: Setting NVRAM century to 20\n");
! 		/* XXX Does writing the century need to be at splclock? */
! 		s = splclock();
! 		/* note: 0x20 = 20 in BCD. */
! 		mc146818_write(NULL, NVRAM_CENTURY, 0x20); /* XXX softc */
! 		splx(s);
! 	} else {
! 		printf("WARNING: CHECK AND RESET THE DATE!\n");
! 	}
! 	yr = (tcentury == 20) ? yr+100 : yr;
   
  	/*
  	 * If time_t is 32 bits, then the "End of Time" is 
***************
*** 593,599 ****
  {
  	mc_todregs rtclk;
  	time_t n;
! 	int diff, i, j;
  	int s;
  
  	/*
--- 613,619 ----
  {
  	mc_todregs rtclk;
  	time_t n;
! 	int diff, i, j, century;
  	int s;
  
  	/*
***************
*** 610,619 ****
  
  	diff = rtc_offset * 60;
  	n = (time.tv_sec - diff) % (3600 * 24);   /* hrs+mins+secs */
! 	rtclk[MC_SEC] = dectohexdec(n % 60);
  	n /= 60;
! 	rtclk[MC_MIN] = dectohexdec(n % 60);
! 	rtclk[MC_HOUR] = dectohexdec(n / 60);
  
  	n = (time.tv_sec - diff) / (3600 * 24);	/* days */
  	rtclk[MC_DOW] = (n + 4) % 7;  /* 1/1/70 is Thursday */
--- 630,639 ----
  
  	diff = rtc_offset * 60;
  	n = (time.tv_sec - diff) % (3600 * 24);   /* hrs+mins+secs */
! 	rtclk[MC_SEC] = bintobcd(n % 60);
  	n /= 60;
! 	rtclk[MC_MIN] = bintobcd(n % 60);
! 	rtclk[MC_HOUR] = bintobcd(n / 60);
  
  	n = (time.tv_sec - diff) / (3600 * 24);	/* days */
  	rtclk[MC_DOW] = (n + 4) % 7;  /* 1/1/70 is Thursday */
***************
*** 621,639 ****
  	for (j = 1970, i = yeartoday(j); n >= i; j++, i = yeartoday(j))
  		n -= i;
  
! 	rtclk[MC_YEAR] = dectohexdec((j - 1900)%100);
  
  	if (i == 366)
  		month[1] = 29;
  	for (i = 0; n >= month[i]; i++)
  		n -= month[i];
  	month[1] = 28;
! 	rtclk[MC_MONTH] = dectohexdec(++i);
  
! 	rtclk[MC_DOM] = dectohexdec(++n);
  
  	s = splclock();
  	rtcput(&rtclk);
  	splx(s);
  }
  
--- 641,662 ----
  	for (j = 1970, i = yeartoday(j); n >= i; j++, i = yeartoday(j))
  		n -= i;
  
! 	rtclk[MC_YEAR] = bintobcd((j - 1900)%100);
! 	century = bintobcd(j/100);
  
  	if (i == 366)
  		month[1] = 29;
  	for (i = 0; n >= month[i]; i++)
  		n -= month[i];
  	month[1] = 28;
! 	rtclk[MC_MONTH] = bintobcd(++i);
  
! 	rtclk[MC_DOM] = bintobcd(++n);
  
  	s = splclock();
  	rtcput(&rtclk);
+ 	/* XXX Does writing the century need to be at splclock? */
+ 	mc146818_write(NULL, NVRAM_CENTURY, century); /* XXX softc */
  	splx(s);
  }