diff options
-rw-r--r-- | sys/conf/files.ia64 | 2 | ||||
-rw-r--r-- | sys/ia64/ia64/clock.c | 312 | ||||
-rw-r--r-- | sys/ia64/ia64/clock_if.m | 52 | ||||
-rw-r--r-- | sys/ia64/ia64/eficlock.c | 111 | ||||
-rw-r--r-- | sys/ia64/include/clockvar.h | 53 |
5 files changed, 130 insertions, 400 deletions
diff --git a/sys/conf/files.ia64 b/sys/conf/files.ia64 index 6a050f8..304a0f0 100644 --- a/sys/conf/files.ia64 +++ b/sys/conf/files.ia64 @@ -88,13 +88,11 @@ ia64/ia32/ia32_trap.c optional compat_ia32 ia64/ia64/autoconf.c standard ia64/ia64/busdma_machdep.c standard ia64/ia64/clock.c standard -ia64/ia64/clock_if.m standard ia64/ia64/context.S standard ia64/ia64/db_interface.c optional ddb ia64/ia64/db_trace.c optional ddb ia64/ia64/dump_machdep.c standard ia64/ia64/efi.c standard -ia64/ia64/eficlock.c standard ia64/ia64/elf_machdep.c standard ia64/ia64/exception.S standard ia64/ia64/gdb_machdep.c optional gdb diff --git a/sys/ia64/ia64/clock.c b/sys/ia64/ia64/clock.c index 0199452..434f239 100644 --- a/sys/ia64/ia64/clock.c +++ b/sys/ia64/ia64/clock.c @@ -1,41 +1,28 @@ /*- - * Copyright (c) 1988 University of Utah. - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * the Systems Programming Group of the University of Utah Computer - * Science Department and Ralph Campbell. + * Copyright (c) 2005 Marcel Moolenaar + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. * - * from: Utah Hdr: clock.c 1.18 91/01/21 - * - * @(#)clock.c 8.1 (Berkeley) 6/10/93 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $NetBSD: clock.c,v 1.20 1998/01/31 10:32:47 ross Exp $ */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -50,40 +37,72 @@ __FBSDID("$FreeBSD$"); #include <sys/pcpu.h> #include <machine/clock.h> -#include <machine/clockvar.h> #include <machine/cpu.h> - -#define SECMIN ((unsigned)60) /* seconds per minute */ -#define SECHOUR ((unsigned)(60*SECMIN)) /* seconds per hour */ -#define SECDAY ((unsigned)(24*SECHOUR)) /* seconds per day */ -#define SECYR ((unsigned)(365*SECDAY)) /* seconds per common year */ - -/* - * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we - * can use a simple formula for leap years. - * XXX time_t is 64-bits on ia64. - */ -#define LEAPYEAR(y) (((y) % 4) == 0) +#include <machine/efi.h> static int sysctl_machdep_adjkerntz(SYSCTL_HANDLER_ARGS); -int disable_rtc_set; /* disable resettodr() if != 0 */ +int disable_rtc_set; /* disable resettodr() if != 0 */ SYSCTL_INT(_machdep, CPU_DISRTCSET, disable_rtc_set, CTLFLAG_RW, &disable_rtc_set, 0, ""); -int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ +int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ SYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock, CTLFLAG_RW, &wall_cmos_clock, 0, ""); -int adjkerntz; /* local offset from GMT in seconds */ +int adjkerntz; /* local offset from GMT in seconds */ SYSCTL_PROC(_machdep, CPU_ADJKERNTZ, adjkerntz, CTLTYPE_INT|CTLFLAG_RW, &adjkerntz, 0, sysctl_machdep_adjkerntz, "I", ""); -kobj_t clockdev; -int todr_initialized; +static int +sysctl_machdep_adjkerntz(SYSCTL_HANDLER_ARGS) +{ + int error; + + error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req); + if (!error && req->newptr) + resettodr(); + return (error); +} uint64_t ia64_clock_reload; +static int clock_initialized = 0; + +static short dayyr[12] = { + 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 +}; + +/* + * Leap years + * + * Our well-known calendar, the Gregorian calendar, is intended to be of the + * same length as the cycle of the seasons (the tropical year). However, the + * tropical year is approximately 365.2422 days. If the calendar year always + * consisted of 365 days, it would be short of the tropical year by about + * 0.2422 days every year. Over a century, the beginning of spring in the + * northern hemisphere would shift from March 20 to April 13. + * + * When Pope Gregory XIII instituted the Gregorian calendar in 1582, the + * calendar was shifted to make the beginning of spring fall on March 21 and + * a new system of leap days was introduced. Instead of intercalating a leap + * day every fourth year, 97 leap days would be introduced every 400 years, + * according to the following rule: + * + * Years evenly divisible by 4 are leap years, with the exception of + * centurial years that are not evenly divisible by 400. + * + * Thus, the average Gregorian calendar year is 365.2425 days in length. This + * agrees to within half a minute of the length of the tropical year. + */ + +static __inline +int isleap(int yr) +{ + + return ((yr % 4) ? 0 : (yr % 100) ? 1 : (yr % 400) ? 0 : 1); +} + #ifndef SMP static timecounter_get_t ia64_get_timecount; @@ -102,34 +121,6 @@ ia64_get_timecount(struct timecounter* tc) } #endif -static int -sysctl_machdep_adjkerntz(SYSCTL_HANDLER_ARGS) -{ - int error; - - error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req); - if (!error && req->newptr) - resettodr(); - return (error); -} - -void -clockattach(kobj_t dev) -{ - - if (clockdev) - panic("clockattach: multiple clocks"); - - clockdev = dev; - -#ifdef EVCNT_COUNTERS - evcnt_attach(dev, "intr", &clock_intr_evcnt); -#endif - - /* Get the clock started. */ - CLOCK_INIT(clockdev); -} - void pcpu_initclock(void) { @@ -176,88 +167,59 @@ cpu_stopprofclock(void) /* nothing to do */ } -/* - * This code is defunct after 2099. - * Will Unix still be here then?? - */ -static short dayyr[12] = { - 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 -}; - -/* - * Initialize the time of day register, based on the time base which is, - * e.g. from a filesystem. Base provides the time to within six months, - * and the time of year clock (if any) provides the rest. - */ void inittodr(time_t base) { - struct clocktime ct; + struct efi_tm tm; struct timespec ts; - time_t deltat; - int badbase, days, s, yr; - - if (base < 5*SECYR) { - printf("WARNING: preposterous time in filesystem"); - /* read the system clock anyway */ - base = 6*SECYR + 186*SECDAY + SECDAY/2; - badbase = 1; - } else - badbase = 0; - - CLOCK_GET(clockdev, base, &ct); - todr_initialized = 1; - - /* simple sanity checks */ - if (ct.year < 70 || ct.mon < 1 || ct.mon > 12 || ct.day < 1 || - ct.day > 31 || ct.hour > 23 || ct.min > 59 || ct.sec > 59) { - /* - * Believe the time in the filesystem for lack of - * anything better, resetting the TODR. - */ - s = splclock(); + long days; + int yr; + + efi_get_time(&tm); + + /* + * This code was written in 2005, so logically EFI cannot return + * a year smaller than that. Assume the EFI clock is out of whack + * in that case and reset the EFI clock. + */ + if (tm.tm_year < 2005) { + printf("WARNING: CHECK AND RESET THE DATE!\n"); + memset(&tm, 0, sizeof(tm)); + tm.tm_year = 2005; + tm.tm_mon = tm.tm_mday = 1; + if (efi_set_time(&tm)) + printf("ERROR: COULD NOT RESET EFI CLOCK!\n"); + } + + days = 0L; + for (yr = 1970; yr < (int)tm.tm_year; yr++) + days += isleap(yr) ? 366L : 365L; + days += dayyr[tm.tm_mon - 1] + tm.tm_mday - 1L; + if (isleap(tm.tm_year) && tm.tm_mon > 2) + days++; + + ts.tv_sec = ((days * 24L + tm.tm_hour) * 60L + tm.tm_min) * 60L + + tm.tm_sec + ((wall_cmos_clock) ? adjkerntz : 0L); + ts.tv_nsec = tm.tm_nsec; + + /* + * The EFI clock is supposed to be a real-time clock, whereas the + * base argument is coming from a saved (as on disk) time. It's + * impossible for a saved time to represent a time in the future, + * so we expect the EFI clock to be larger. If not, the EFI clock + * may not be reliable and we trust the base. + * Warn if the EFI clock was off by 2 or more days. + */ + if (ts.tv_sec < base) { + days = (base - ts.tv_sec) / (60L * 60L * 24L); + if (days >= 2) + printf("WARNING: EFI clock lost %ld days!\n", days); ts.tv_sec = base; ts.tv_nsec = 0; - tc_setclock(&ts); - splx(s); - if (!badbase) { - printf("WARNING: preposterous clock chip time\n"); - resettodr(); - } - goto bad; } - days = 0; - for (yr = 70; yr < ct.year; yr++) - days += LEAPYEAR(yr) ? 366 : 365; - days += dayyr[ct.mon - 1] + ct.day - 1; - if (LEAPYEAR(yr) && ct.mon > 2) - days++; - /* now have days since Jan 1, 1970; the rest is easy... */ - s = splclock(); - ts.tv_sec = - days * SECDAY + ct.hour * SECHOUR + ct.min * SECMIN + ct.sec; - if (wall_cmos_clock) - ts.tv_sec += adjkerntz; - ts.tv_nsec = 0; tc_setclock(&ts); - splx(s); - - if (!badbase) { - /* - * See if we gained/lost two or more days; - * if so, assume something is amiss. - */ - deltat = ts.tv_sec - base; - if (deltat < 0) - deltat = -deltat; - if (deltat < 2 * SECDAY) - return; - printf("WARNING: clock %s %ld days", - ts.tv_sec < base ? "lost" : "gained", deltat / SECDAY); - } -bad: - printf(" -- CHECK AND RESET THE DATE!\n"); + clock_initialized = 1; } /* @@ -270,49 +232,35 @@ bad: void resettodr() { - struct clocktime ct; - unsigned long tm; - int s, t, t2; + struct efi_tm tm; + long t; + int x; - if (!todr_initialized || disable_rtc_set) + if (!clock_initialized || disable_rtc_set) return; - s = splclock(); - tm = time_second; - splx(s); + efi_get_time(&tm); + tm.tm_nsec = 0; - /* Calculate local time to put in RTC */ - tm -= (wall_cmos_clock ? adjkerntz : 0); + t = time_second - ((wall_cmos_clock) ? adjkerntz : 0L); - /* compute the day of week. */ - t2 = tm / SECDAY; - ct.dow = (t2 + 4) % 7; /* 1/1/1970 was thursday */ + tm.tm_sec = t % 60; t /= 60L; + tm.tm_min = t % 60; t /= 60L; + tm.tm_hour = t % 24; t /= 24L; - /* compute the year */ - ct.year = 69; - t = t2; /* XXX ? */ - while (t2 >= 0) { /* whittle off years */ - t = t2; - ct.year++; - t2 -= LEAPYEAR(ct.year) ? 366 : 365; + tm.tm_year = 1970; + x = (isleap(tm.tm_year)) ? 366 : 365; + while (t > x) { + t -= x; + tm.tm_year++; + x = (isleap(tm.tm_year)) ? 366 : 365; } - /* t = month + day; separate */ - t2 = LEAPYEAR(ct.year); - for (ct.mon = 1; ct.mon < 12; ct.mon++) - if (t < dayyr[ct.mon] + (t2 && ct.mon > 1)) - break; - - ct.day = t - dayyr[ct.mon - 1] + 1; - if (t2 && ct.mon > 2) - ct.day--; - - /* the rest is easy */ - t = tm % SECDAY; - ct.hour = t / SECHOUR; - t %= 3600; - ct.min = t / SECMIN; - ct.sec = t % SECMIN; - - CLOCK_SET(clockdev, &ct); + x = 11; + while (t < dayyr[x]) + x--; + tm.tm_mon = x + 1; + tm.tm_mday = t - dayyr[x] + 1; + if (efi_set_time(&tm)) + printf("ERROR: COULD NOT RESET EFI CLOCK!\n"); } diff --git a/sys/ia64/ia64/clock_if.m b/sys/ia64/ia64/clock_if.m deleted file mode 100644 index 86dbf1c..0000000 --- a/sys/ia64/ia64/clock_if.m +++ /dev/null @@ -1,52 +0,0 @@ -#- -# Copyright (c) 1998 Doug Rabson -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# $FreeBSD$ -# - -#include <sys/bus.h> -#include <machine/clockvar.h> - -INTERFACE clock; - -METHOD void init { - kobj_t dev; -}; - -METHOD void get { - kobj_t dev; - time_t base; - struct clocktime *ct; -}; - -METHOD void set { - kobj_t dev; - struct clocktime *ct; -}; - -METHOD int getsecs { - kobj_t dev; - int *secp; -}; diff --git a/sys/ia64/ia64/eficlock.c b/sys/ia64/ia64/eficlock.c deleted file mode 100644 index e48cb5c..0000000 --- a/sys/ia64/ia64/eficlock.c +++ /dev/null @@ -1,111 +0,0 @@ -/*- - * Copyright (c) 2000 Doug Rabson - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/kernel.h> -#include <sys/systm.h> -#include <sys/bus.h> -#include <sys/malloc.h> - -#include <machine/clockvar.h> -#include <machine/efi.h> - -static void -eficlock_init(kobj_t dev) -{ -} - -/* - * Get the time of day, based on the clock's value and/or the base value. - */ -static void -eficlock_get(kobj_t dev, time_t base, struct clocktime *ct) -{ - struct efi_tm tm; - - efi_get_time(&tm); - - ct->sec = tm.tm_sec; - ct->min = tm.tm_min; - ct->hour = tm.tm_hour; - ct->dow = 0; /* XXX not used */ - ct->day = tm.tm_mday; - ct->mon = tm.tm_mon; - ct->year = tm.tm_year - 1900; -} - -/* - * Reset the TODR based on the time value. - */ -static void -eficlock_set(kobj_t dev, struct clocktime *ct) -{ - struct efi_tm tm; - efi_status status; - - efi_get_time(&tm); - tm.tm_sec = ct->sec; - tm.tm_min = ct->min; - tm.tm_hour = ct->hour; - tm.tm_mday = ct->day; - tm.tm_mon = ct->mon; - tm.tm_year = ct->year + 1900; - status = efi_set_time(&tm); - if (status) - printf("eficlock_set: could not set TODR\n"); -} - -static int -eficlock_getsecs(kobj_t dev, int *secp) -{ - return ETIMEDOUT; -} - -static device_method_t eficlock_methods[] = { - /* clock interface */ - DEVMETHOD(clock_init, eficlock_init), - DEVMETHOD(clock_get, eficlock_get), - DEVMETHOD(clock_set, eficlock_set), - DEVMETHOD(clock_getsecs, eficlock_getsecs), - - { 0, 0 } -}; - -DEFINE_CLASS(eficlock, eficlock_methods, sizeof(struct kobj)); - -static void -eficlock_create(void *arg) -{ - kobj_t clock; - clock = (kobj_t) - kobj_create(&eficlock_class, M_TEMP, M_NOWAIT); - clockattach(clock); -} - -SYSINIT(eficlock, SI_SUB_DRIVERS,SI_ORDER_MIDDLE, eficlock_create, NULL); diff --git a/sys/ia64/include/clockvar.h b/sys/ia64/include/clockvar.h deleted file mode 100644 index 30f39d0..0000000 --- a/sys/ia64/include/clockvar.h +++ /dev/null @@ -1,53 +0,0 @@ -/* $FreeBSD$ */ -/* $NetBSD: clockvar.h,v 1.4 1997/06/22 08:02:18 jonathan Exp $ */ - -/*- - * Copyright (c) 1994, 1995 Carnegie-Mellon University. - * All rights reserved. - * - * Author: Chris G. Demetriou - * - * Permission to use, copy, modify and distribute this software and - * its documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND - * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie the - * rights to redistribute these changes. - */ - -/* - * Definitions for cpu-independent clock handling for the alpha and pmax. - */ - -/* - * clocktime structure: - * - * structure passed to TOY clocks when setting them. broken out this - * way, so that the time_t -> field conversion can be shared. - */ -struct clocktime { - int year; /* year - 1900 */ - int mon; /* month (1 - 12) */ - int day; /* day (1 - 31) */ - int hour; /* hour (0 - 23) */ - int min; /* minute (0 - 59) */ - int sec; /* second (0 - 59) */ - int dow; /* day of week (0 - 6; 0 = Sunday) */ -}; - -#include "clock_if.h" - -void clockattach(kobj_t); |