Subject: Generic TODR patch
To: None <port-xen@netbsd.org>
From: Joerg Sonnenberger <joerg@britannica.bec.de>
List: port-xen
Date: 01/04/2008 00:39:45
--3lcZGd9BuhuYXNfi
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi all,
can someone please test the attached patch? The  Xen instance should
still get the correct time on boot and changes of the walltime should be
written back for Dom 0.

Joerg

--3lcZGd9BuhuYXNfi
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="xen-todr.diff"

Index: xen/include/types.h
===================================================================
RCS file: /data/repo/netbsd/src/sys/arch/xen/include/types.h,v
retrieving revision 1.7
diff -u -p -r1.7 types.h
--- xen/include/types.h	17 Oct 2007 19:58:29 -0000	1.7
+++ xen/include/types.h	3 Jan 2008 21:12:27 -0000
@@ -79,5 +79,6 @@ typedef	volatile unsigned char		__cpu_si
 #endif
 
 #define __HAVE_TIMECOUNTER
+#define __HAVE_GENERIC_TODR
 
 #endif	/* _MACHTYPES_H_ */
Index: xen/xen/clock.c
===================================================================
RCS file: /data/repo/netbsd/src/sys/arch/xen/xen/clock.c,v
retrieving revision 1.42
diff -u -p -r1.42 clock.c
--- xen/xen/clock.c	22 Nov 2007 16:17:06 -0000	1.42
+++ xen/xen/clock.c	3 Jan 2008 21:02:36 -0000
@@ -79,8 +79,6 @@ static volatile uint32_t shadow_freq_mul
 static volatile int8_t shadow_freq_shift;
 static volatile struct timespec shadow_ts;
 
-static int timeset;
-
 /* The time when the last hardclock(9) call should have taken place. */
 static volatile uint64_t processed_system_time;
 
@@ -298,86 +296,33 @@ xen_wall_time(struct timespec *wt)
 #endif
 }
 
-void
-inittodr(time_t base)
+static int
+xen_rtc_get(todr_chip_handle_t todr, volatile struct timeval *tvp)
 {
 	struct timespec wt;
 
-	/*
-	 * if the file system time is more than a year older than the
-	 * kernel, warn and then set the base time to the CONFIG_TIME.
-	 */
-	if (base && base < (CONFIG_TIME-SECYR)) {
-		printf("WARNING: preposterous time in file system\n");
-		base = CONFIG_TIME;
-	}
-
 	xen_wall_time(&wt);
-	tc_setclock(&wt); /* XXX what about rtc_offset? */
-	
-	if (base != 0 && base < time_second - 5*SECYR)
-		printf("WARNING: file system time much less than clock time\n");
-	else if (base > time_second + 5*SECYR) {
-		printf("WARNING: clock time much less than file system time\n");
-		printf("WARNING: using file system time\n");
-		goto fstime;
-	}
+	tvp->tv_sec = wt.tv_sec;
+	tvp->tv_usec = wt.tv_nsec / 1000;
 
-	timeset = 1;
-	return;
-
-fstime:
-	timeset = 1;
-	wt.tv_sec = base;
-	tc_setclock(&wt);
-	printf("WARNING: CHECK AND RESET THE DATE!\n");
+	return 0;
 }
 
-void
-resettodr(void)
+static int
+xen_rtc_set(todr_chip_handle_t todr, volatile struct timeval *tvp)
 {
 #ifdef DOM0OPS
 	dom0_op_t op;
 	int s;
-#endif
-#ifdef DEBUG_CLOCK
-	struct timeval sent_delta;
-#endif
 
-	/*
-	 * We might have been called by boot() due to a crash early
-	 * on.  Don't reset the clock chip in this case.
-	 */
-	if (!timeset)
-		return;
-
-#ifdef XXX_DEBUG_CLOCK
-        {       /* XXX annoying debug printf not yet timecounterized */
-		char pm;
- 
-		if (timercmp(&time, &shadow_tv, >)) {
-			timersub(&time, &shadow_tv, &sent_delta);
-			pm = '+';
-		} else {
-			timersub(&shadow_tv, &time, &sent_delta);
-			pm = '-';
-		}
-		printf("resettodr: stepping Xen clock by %c%ld.%06ld\n",
-	    pm, sent_delta.tv_sec, sent_delta.tv_usec);
-	}
-#endif
-#ifdef DOM0OPS
 	if (xen_start_info.flags & SIF_PRIVILEGED) {
-		struct timespec now;
-
 		op.cmd = DOM0_SETTIME;
-		nanotime(&now);
 		/* XXX is rtc_offset handled correctly everywhere? */
-		op.u.settime.secs	 = now.tv_sec - rtc_offset * 60;
+		op.u.settime.secs	 = tvp->tv_sec;
 #ifdef XEN3
-		op.u.settime.nsecs	 = now.tv_nsec;
+		op.u.settime.nsecs	 = tvp->tv_usec * 1000;
 #else
-		op.u.settime.usecs	 = now.tv_nsec / 1000;
+		op.u.settime.usecs	 = tvp->tv_usec;
 #endif
 		s = splhigh();
 		op.u.settime.system_time = get_system_time();
@@ -385,13 +330,19 @@ resettodr(void)
 		HYPERVISOR_dom0_op(&op);
 	}
 #endif
-}
 
+	return 0;
+}
 
 void
 startrtclock()
 {
+	static struct todr_chip_handle	tch;
+	tch.todr_gettime = xen_rtc_get;
+	tch.todr_settime = xen_rtc_set;
+	tch.todr_setwen = NULL;
 
+	todr_attach(&tch);
 }
 
 /*

--3lcZGd9BuhuYXNfi--