Date: Fri, 6 Jan 2006 18:48:40 GMT From: Kip Macy <kmacy@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 89281 for review Message-ID: <200601061848.k06Imedr037066@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=89281 Change 89281 by kmacy@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@edvz.tu-graz.ac.at> - * - * reintroduced and updated by Chris Stenton <chris@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.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200601061848.k06Imedr037066>