Subject: port-sparc64/15611: Netra X1 cannot handle correct date
To: None <gnats-bugs@gnats.netbsd.org>
From: None <t-nkyma@tcp-ip.or.jp>
List: netbsd-bugs
Date: 02/14/2002 23:45:58
>Number:         15611
>Category:       port-sparc64
>Synopsis:       Netra X1 cannot handle correct date
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    port-sparc64-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Feb 14 06:46:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Takeshi Nakayama
>Release:        NetBSD 1.5ZA (2002-02-13)
>Organization:
	none
>Environment:
System: NetBSD nyx 1.5ZA NetBSD 1.5ZA (NYX32) #34: Thu Feb 14 22:53:59 JST 2002 takeshi@nyx:/usr/src/sys/arch/sparc64/compile/NYX32 sparc64
Architecture: sparc
Machine: sparc64

>Description:
	First, arch/sparc64/conf/GENRIC32 lacks `rtc* at ebus?',
	so we cannot treat the clock device.

 :
rtc at ebus0 addr 70-71 not configured
 :
WARNING: clock lost 11732 days -- CHECK AND RESET THE DATE!
root file system type: ffs
Enter pathname of shell or RETURN for sh: 
We recommend creating a non-root account and using su(1) for root access.
# date
Thu Jan  1 09:00:25 JST 1970
# 

	Second, base year in arch/sparc64/sparc64/clock.c is wrong.

>How-To-Repeat:
	Boot with the GENERIC kernel, and check the date.

>Fix:
	Add the `rtc* at ebus?' line to arch/sparc64/conf/GENERIC32,
	and apply the next patch to arch/sparc64/sparc64/clock.c.

Index: clock.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sparc64/sparc64/clock.c,v
retrieving revision 1.44
diff -u -r1.44 clock.c
--- clock.c	2001/10/22 08:00:12	1.44
+++ clock.c	2002/02/14 13:49:57
@@ -512,8 +512,8 @@
 	handle->todr_setwen = NULL;
 	rtc->rtc_bt = bt;
 	rtc->rtc_bh = ebi.ei_bh;
-	/* Our TOD clock year 0 is 1968 */
-	rtc->rtc_year0 = 1968;	/* XXX Really? */
+	/* Our TOD clock year 0 is 1900 */
+	rtc->rtc_year0 = 1900;
 
 	/* Save info for the clock wenable call. */
 	ebi.ei_bt = bt;


	On the other hand, Solaris kernel module seems to use
	NVRAM area offset 0x32 to remember upper 2 digit of the year.

	The following patch is an example to use this area.

Index: clock.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sparc64/sparc64/clock.c,v
retrieving revision 1.44
diff -u -r1.44 clock.c
--- clock.c	2001/10/22 08:00:12	1.44
+++ clock.c	2002/02/14 13:49:57
@@ -1019,6 +1019,7 @@
 /*
  * RTC todr routines.
  */
+#define MC_CENT 0x32
 
 /*
  * Get time-of-day and convert to a `struct timeval'
@@ -1033,7 +1034,7 @@
 	bus_space_tag_t bt = rtc->rtc_bt;
 	bus_space_handle_t bh = rtc->rtc_bh;
 	struct clock_ymdhms dt;
-	int year;
+	int year, cent;
 	u_int8_t csr;
 
 	todr_wenable(handle, 1);
@@ -1051,13 +1052,16 @@
 	dt.dt_wday = rtc_read_reg(bt, bh, MC_DOW);
 	dt.dt_mon = rtc_read_reg(bt, bh, MC_MONTH);
 	year = rtc_read_reg(bt, bh, MC_YEAR);
-printf("rtc_gettime: read y %x/%d m %x/%d wd %d d %x/%d "
-	"h %x/%d m %x/%d s %x/%d\n",
-	year, year, dt.dt_mon, dt.dt_mon, dt.dt_wday,
-	dt.dt_day, dt.dt_day, dt.dt_hour, dt.dt_hour,
-	dt.dt_min, dt.dt_min, dt.dt_sec, dt.dt_sec);
+	cent = rtc_read_reg(bt, bh, MC_CENT);
+#ifdef DIAGNOSTIC
+	printf("rtc_gettime: read c %x/%d y %x/%d m %x/%d wd %d d %x/%d "
+	       "h %x/%d m %x/%d s %x/%d\n",
+	       cent, cent, year, year, dt.dt_mon, dt.dt_mon, dt.dt_wday,
+	       dt.dt_day, dt.dt_day, dt.dt_hour, dt.dt_hour,
+	       dt.dt_min, dt.dt_min, dt.dt_sec, dt.dt_sec);
+#endif
 
-	year += rtc->rtc_year0;
+	year += (cent >= 19) ? cent * 100 : rtc->rtc_year0;
 	if (year < POSIX_BASE_YEAR && rtc_auto_century_adjust != 0)
 		year += 100;
 
@@ -1093,14 +1097,13 @@
 	bus_space_handle_t bh = rtc->rtc_bh;
 	struct clock_ymdhms dt;
 	u_int8_t csr;
-	int year;
+	int year, cent;
 
 	/* Note: we ignore `tv_usec' */
 	clock_secs_to_ymdhms(tv->tv_sec, &dt);
 
-	year = dt.dt_year - rtc->rtc_year0;
-	if (year > 99 && rtc_auto_century_adjust != 0)
-		year -= 100;
+	year = dt.dt_year % 100;
+	cent = dt.dt_year / 100;
 
 	todr_wenable(handle, 1);
 	/* enable write */
@@ -1115,6 +1118,7 @@
 	rtc_write_reg(bt, bh, MC_DOM, dt.dt_day);
 	rtc_write_reg(bt, bh, MC_MONTH, dt.dt_mon);
 	rtc_write_reg(bt, bh, MC_YEAR, year);
+	rtc_write_reg(bt, bh, MC_CENT, cent);
 
 	/* load them up */
 	csr = rtc_read_reg(bt, bh, MC_REGB);

>Release-Note:
>Audit-Trail:
>Unformatted: