PERFORCE change 89281 for review

Kip Macy kmacy at FreeBSD.org
Fri Jan 6 10:48:42 PST 2006


http://perforce.freebsd.org/chv.cgi?CH=89281

Change 89281 by kmacy at kmacy:freebsd7_xen3 on 2006/01/06 18:48:06

	add dom0 support to clock driver still confused between setting time of day
	and rtc add in new option for setting hardware rtc

Affected files ...

.. //depot/projects/xen3/src/sys/conf/options.i386-xen#3 edit
.. //depot/projects/xen3/src/sys/i386-xen/i386-xen/clock.c#7 edit

Differences ...

==== //depot/projects/xen3/src/sys/conf/options.i386-xen#3 (text+ko) ====

@@ -39,6 +39,10 @@
 # support physical device access
 XEN_PHYSDEV_ACCESS	opt_global.h
 
+# unclear how this differs from the being PHYSDEV_ACCESS + INITDOMAIN but
+# stay consistent with mainline for now
+XEN_PRIVILEGED_GUEST	opt_global.h
+
 
 # Physical address extensions and support for >4G ram.  As above.
 PAE			opt_global.h

==== //depot/projects/xen3/src/sys/i386-xen/i386-xen/clock.c#7 (text+ko) ====

@@ -44,16 +44,7 @@
  * Routines to handle clock hardware.
  */
 
-/*
- * inittodr, settodr and support routines written
- * by Christoph Robitschko <chmr at edvz.tu-graz.ac.at>
- *
- * reintroduced and updated by Chris Stenton <chris at gnome.co.uk> 8/10/94
- */
-
 #include "opt_clock.h"
-#include "opt_isa.h"
-#include "opt_mca.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -110,6 +101,7 @@
 #define TIMER_FREQ   1193182
 #endif
 int     wall_cmos_clock;
+int     independent_wallclock;
 u_int	timer_freq = TIMER_FREQ;
 struct mtx clock_lock;
 
@@ -134,7 +126,10 @@
 
 uint32_t shadow_tv_version;
 
+SYSCTL_INT(_machdep, OID_AUTO, independent_wallclock,
+	CTLFLAG_RW, &independent_wallclock, 0, "");
 
+
 #define do_div(n,base) ({ \
         unsigned long __upper, __low, __high, __mod, __base; \
         __base = (base); \
@@ -518,6 +513,7 @@
 	rdtscll(alarm);
 }
 
+#ifdef XEN_PRIVILEGED_GUEST
 /*
  * Initialize the time of day register, based on the time base which is, e.g.
  * from a filesystem.
@@ -525,6 +521,143 @@
 void
 inittodr(time_t base)
 {
+	unsigned long	sec, days;
+	int		year, month;
+	int		y, m, s;
+	struct timespec ts;
+
+	if (base) {
+		s = splclock();
+		ts.tv_sec = base;
+		ts.tv_nsec = 0;
+		tc_setclock(&ts);
+		splx(s);
+	}
+
+	/* Look if we have a RTC present and the time is valid */
+	if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
+		goto wrong_time;
+
+	/* wait for time update to complete */
+	/* If RTCSA_TUP is zero, we have at least 244us before next update */
+	s = splhigh();
+	while (rtcin(RTC_STATUSA) & RTCSA_TUP) {
+		splx(s);
+		s = splhigh();
+	}
+
+	days = 0;
+#ifdef USE_RTC_CENTURY
+	year = readrtc(RTC_YEAR) + readrtc(RTC_CENTURY) * 100;
+#else
+	year = readrtc(RTC_YEAR) + 1900;
+	if (year < 1970)
+		year += 100;
+#endif
+	if (year < 1970) {
+		splx(s);
+		goto wrong_time;
+	}
+	month = readrtc(RTC_MONTH);
+	for (m = 1; m < month; m++)
+		days += daysinmonth[m-1];
+	if ((month > 2) && LEAPYEAR(year))
+		days ++;
+	days += readrtc(RTC_DAY) - 1;
+	for (y = 1970; y < year; y++)
+		days += DAYSPERYEAR + LEAPYEAR(y);
+	sec = ((( days * 24 +
+		  readrtc(RTC_HRS)) * 60 +
+		  readrtc(RTC_MIN)) * 60 +
+		  readrtc(RTC_SEC));
+	/* sec now contains the number of seconds, since Jan 1 1970,
+	   in the local time zone */
+
+	sec += tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
+
+	y = time_second - sec;
+	if (y <= -2 || y >= 2) {
+		/* badly off, adjust it */
+		ts.tv_sec = sec;
+		ts.tv_nsec = 0;
+		tc_setclock(&ts);
+	}
+	splx(s);
+	return;
+
+wrong_time:
+	printf("Invalid time in real time clock.\n");
+	printf("Check and reset the date immediately!\n");
+}
+
+
+
+/*
+ * Write system time back to RTC
+ */
+void
+resettodr()
+{
+	unsigned long	tm;
+	int		y, m, s;
+
+	if (disable_rtc_set)
+		return;
+
+	s = splclock();
+	tm = time_second;
+	splx(s);
+
+	/* Disable RTC updates and interrupts. */
+	writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
+
+	/* Calculate local time to put in RTC */
+
+	tm -= tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
+
+	writertc(RTC_SEC, bin2bcd(tm%60)); tm /= 60;	/* Write back Seconds */
+	writertc(RTC_MIN, bin2bcd(tm%60)); tm /= 60;	/* Write back Minutes */
+	writertc(RTC_HRS, bin2bcd(tm%24)); tm /= 24;	/* Write back Hours   */
+
+	/* We have now the days since 01-01-1970 in tm */
+	writertc(RTC_WDAY, (tm + 4) % 7 + 1);		/* Write back Weekday */
+	for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y);
+	     tm >= m;
+	     y++,      m = DAYSPERYEAR + LEAPYEAR(y))
+	     tm -= m;
+
+	/* Now we have the years in y and the day-of-the-year in tm */
+	writertc(RTC_YEAR, bin2bcd(y%100));		/* Write back Year    */
+#ifdef USE_RTC_CENTURY
+	writertc(RTC_CENTURY, bin2bcd(y/100));		/* ... and Century    */
+#endif
+	for (m = 0; ; m++) {
+		int ml;
+
+		ml = daysinmonth[m];
+		if (m == 1 && LEAPYEAR(y))
+			ml++;
+		if (tm < ml)
+			break;
+		tm -= ml;
+	}
+
+	writertc(RTC_MONTH, bin2bcd(m + 1));            /* Write back Month   */
+	writertc(RTC_DAY, bin2bcd(tm + 1));             /* Write back Month Day */
+
+	/* Reenable RTC updates and interrupts. */
+	writertc(RTC_STATUSB, rtc_statusb);
+	rtcin(RTC_INTR);
+}
+
+#else
+/*
+ * Initialize the time of day register, based on the time base which is, e.g.
+ * from a filesystem.
+ */
+void
+inittodr(time_t base)
+{
 	unsigned long   sec;
 	int		s, y;
 	struct timespec ts;
@@ -549,13 +682,41 @@
 }
 
 /*
- * Write system time back to RTC.  Not supported for guest domains.
+ * Write system time back to RTC.  
  */
 void
 resettodr()
 {
+	unsigned long tm;
+	int s;
+	dom0_op_t op;
+	struct shadow_time_info *shadow;
+
+	shadow = &per_cpu(shadow_time, smp_processor_id());
+	if (disable_rtc_set)
+		return;
+	
+	s = splclock();
+	tm = time_second;
+	splx(s);
+	
+	tm -= tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
+	
+	if ((xen_start_info->flags & SIF_INITDOMAIN) &&
+	    !independent_wallclock)
+	{
+		op.cmd = DOM0_SETTIME;
+		op.u.settime.secs        = tm;
+		op.u.settime.nsecs       = 0;
+		op.u.settime.system_time = shadow->system_timestamp;
+		HYPERVISOR_dom0_op(&op);
+		update_wallclock();
+	} else if (independent_wallclock) {
+		/* notyet */
+		;
+	}		
 }
-
+#endif
 
 /*
  * Start clocks running.


More information about the p4-projects mailing list