diff options
| author | joerg <joerg@NetBSD.org> | 2008-01-03 23:02:24 +0000 |
|---|---|---|
| committer | joerg <joerg@NetBSD.org> | 2008-01-03 23:02:24 +0000 |
| commit | 28b31e738fa993dd2cbd87e89978a6c5f199897e (patch) | |
| tree | fec1eb6a54cb3615a33b330929c022bcde7aa7e0 /sys/dev/dec | |
| parent | 26ecc8b33ad5f179433c5efb59ecaca3f174e4c7 (diff) | |
Timecounter and generic todr support for pmax. From Garret D'Amore.
Diffstat (limited to 'sys/dev/dec')
| -rw-r--r-- | sys/dev/dec/clockvar.h | 20 | ||||
| -rw-r--r-- | sys/dev/dec/mcclock.c | 119 | ||||
| -rw-r--r-- | sys/dev/dec/mcclock_pad32.c | 5 | ||||
| -rw-r--r-- | sys/dev/dec/mcclockvar.h | 3 |
4 files changed, 94 insertions, 53 deletions
diff --git a/sys/dev/dec/clockvar.h b/sys/dev/dec/clockvar.h index 331a56a26fd..e43b5e3741b 100644 --- a/sys/dev/dec/clockvar.h +++ b/sys/dev/dec/clockvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: clockvar.h,v 1.8 2005/12/11 12:21:20 christos Exp $ */ +/* $NetBSD: clockvar.h,v 1.9 2008/01/03 23:02:25 joerg Exp $ */ /* * Copyright (c) 1994, 1995 Carnegie-Mellon University. @@ -32,22 +32,6 @@ */ /* - * 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) */ -}; - -/* * clockfns structure: * * function switch used by chip-independent clock code, to access @@ -55,8 +39,6 @@ struct clocktime { */ struct clockfns { void (*cf_init)(struct device *); - void (*cf_get)(struct device *, time_t, struct clocktime *); - void (*cf_set)(struct device *, struct clocktime *); }; void clockattach(struct device *, const struct clockfns *); diff --git a/sys/dev/dec/mcclock.c b/sys/dev/dec/mcclock.c index 7e2ee64dd54..cb424c68763 100644 --- a/sys/dev/dec/mcclock.c +++ b/sys/dev/dec/mcclock.c @@ -1,4 +1,4 @@ -/* $NetBSD: mcclock.c,v 1.17 2005/12/11 12:21:20 christos Exp $ */ +/* $NetBSD: mcclock.c,v 1.18 2008/01/03 23:02:25 joerg Exp $ */ /* * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University. @@ -28,12 +28,13 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mcclock.c,v 1.17 2005/12/11 12:21:20 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mcclock.c,v 1.18 2008/01/03 23:02:25 joerg Exp $"); #include <sys/param.h> #include <sys/kernel.h> #include <sys/systm.h> #include <sys/device.h> +#include <dev/clock_subr.h> #include <dev/dec/clockvar.h> #include <dev/dec/mcclockvar.h> @@ -51,11 +52,11 @@ __KERNEL_RCSID(0, "$NetBSD: mcclock.c,v 1.17 2005/12/11 12:21:20 christos Exp $" void mcclock_init(struct device *); -void mcclock_get(struct device *, time_t, struct clocktime *); -void mcclock_set(struct device *, struct clocktime *); +int mcclock_get(todr_chip_handle_t, volatile struct timeval *); +int mcclock_set(todr_chip_handle_t, volatile struct timeval *); const struct clockfns mcclock_clockfns = { - mcclock_init, mcclock_get, mcclock_set, + mcclock_init, }; #define mc146818_write(dev, reg, datum) \ @@ -69,7 +70,7 @@ mcclock_attach(sc, busfns) const struct mcclock_busfns *busfns; { - printf(": mc146818 or compatible"); + printf(": mc146818 or compatible\n"); sc->sc_busfns = busfns; @@ -77,6 +78,11 @@ mcclock_attach(sc, busfns) mc146818_write(sc, MC_REGB, MC_REGB_BINARY | MC_REGB_24HR); clockattach(&sc->sc_dev, &mcclock_clockfns); + + sc->sc_todr.todr_gettime = mcclock_get; + sc->sc_todr.todr_settime = mcclock_set; + sc->sc_todr.cookie = sc; + todr_attach(&sc->sc_todr); } void @@ -133,56 +139,107 @@ again: } /* + * Experiments (and passing years) show that Decstation PROMS + * assume the kernel uses the clock chip as a time-of-year clock. + * The PROM assumes the clock is always set to 1972 or 1973, and contains + * time-of-year in seconds. The PROM checks the clock at boot time, + * and if it's outside that range, sets it to 1972-01-01. + * + * XXX should be at the mc146818 layer? +*/ + +/* * Get the time of day, based on the clock's value and/or the base value. */ -void -mcclock_get(dev, base, ct) - struct device *dev; - time_t base; - struct clocktime *ct; +int +mcclock_get(todr_chip_handle_t tch, volatile struct timeval *tvp) { - struct mcclock_softc *sc = (struct mcclock_softc *)dev; + struct mcclock_softc *sc = (struct mcclock_softc *)tch->cookie; + uint32_t yearsecs; mc_todregs regs; int s; + struct clock_ymdhms dt; s = splclock(); MC146818_GETTOD(sc, ®s) splx(s); - ct->sec = regs[MC_SEC]; - ct->min = regs[MC_MIN]; - ct->hour = regs[MC_HOUR]; - ct->dow = regs[MC_DOW]; - ct->day = regs[MC_DOM]; - ct->mon = regs[MC_MONTH]; - ct->year = regs[MC_YEAR]; + dt.dt_sec = regs[MC_SEC]; + dt.dt_min = regs[MC_MIN]; + dt.dt_hour = regs[MC_HOUR]; + dt.dt_day = regs[MC_DOM]; + dt.dt_mon = regs[MC_MONTH]; + dt.dt_year = 1972; + + yearsecs = clock_ymdhms_to_secs(&dt) - (72 - 70) * SECYR; + + /* + * Take the actual year from the filesystem if possible; + * allow for 2 days of clock loss and 363 days of clock gain. + */ + dt.dt_year = 1972; /* or MINYEAR or base/SECYR+1970 ... */ + dt.dt_mon = 1; + dt.dt_day = 1; + dt.dt_hour = 0; + dt.dt_min = 0; + dt.dt_sec = 0; + for(;;) { + tvp->tv_sec = yearsecs + clock_ymdhms_to_secs(&dt); + if (tvp->tv_sec > tch->base_time - 2 * SECDAY) + break; + dt.dt_year++; + } + + tvp->tv_usec = 0; + return 0; } /* * Reset the TODR based on the time value. */ -void -mcclock_set(dev, ct) - struct device *dev; - struct clocktime *ct; +int +mcclock_set(todr_chip_handle_t tch, volatile struct timeval *tvp) { - struct mcclock_softc *sc = (struct mcclock_softc *)dev; + struct mcclock_softc *sc = (struct mcclock_softc *)tch->cookie; + struct clock_ymdhms dt; + uint32_t yearsecs; mc_todregs regs; int s; + /* + * calculate seconds relative to this year + */ + clock_secs_to_ymdhms(tvp->tv_sec, &dt); /* get the year */ + dt.dt_mon = 1; + dt.dt_day = 1; + dt.dt_hour = 0; + dt.dt_min = 0; + dt.dt_sec = 0; + yearsecs = tvp->tv_sec - clock_ymdhms_to_secs(&dt); + +#define first72 ((72 - 70) * SECYR) + clock_secs_to_ymdhms(first72 + yearsecs, &dt); + +#ifdef DEBUG + if (dt.dt_year != 1972) + printf("resettodr: botch (%ld, %ld)\n", yearsecs, time.tv_sec); +#endif + s = splclock(); MC146818_GETTOD(sc, ®s); splx(s); - regs[MC_SEC] = ct->sec; - regs[MC_MIN] = ct->min; - regs[MC_HOUR] = ct->hour; - regs[MC_DOW] = ct->dow; - regs[MC_DOM] = ct->day; - regs[MC_MONTH] = ct->mon; - regs[MC_YEAR] = ct->year; + regs[MC_SEC] = dt.dt_sec; + regs[MC_MIN] = dt.dt_min; + regs[MC_HOUR] = dt.dt_hour; + regs[MC_DOW] = dt.dt_wday; + regs[MC_DOM] = dt.dt_day; + regs[MC_MONTH] = dt.dt_mon; + regs[MC_YEAR] = dt.dt_year; s = splclock(); MC146818_PUTTOD(sc, ®s); splx(s); + + return 0; } diff --git a/sys/dev/dec/mcclock_pad32.c b/sys/dev/dec/mcclock_pad32.c index d7ea12311f0..c2319df1f13 100644 --- a/sys/dev/dec/mcclock_pad32.c +++ b/sys/dev/dec/mcclock_pad32.c @@ -1,4 +1,4 @@ -/* $NetBSD: mcclock_pad32.c,v 1.13 2005/12/11 12:21:20 christos Exp $ */ +/* $NetBSD: mcclock_pad32.c,v 1.14 2008/01/03 23:02:25 joerg Exp $ */ /* * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University. @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mcclock_pad32.c,v 1.13 2005/12/11 12:21:20 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mcclock_pad32.c,v 1.14 2008/01/03 23:02:25 joerg Exp $"); /* @@ -49,6 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: mcclock_pad32.c,v 1.13 2005/12/11 12:21:20 christos #include <sys/kernel.h> #include <sys/systm.h> #include <sys/device.h> +#include <dev/clock_subr.h> #include <machine/autoconf.h> #include <dev/dec/clockvar.h> diff --git a/sys/dev/dec/mcclockvar.h b/sys/dev/dec/mcclockvar.h index 1fa5abba443..f7e3f63107a 100644 --- a/sys/dev/dec/mcclockvar.h +++ b/sys/dev/dec/mcclockvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: mcclockvar.h,v 1.6 2005/12/11 12:21:20 christos Exp $ */ +/* $NetBSD: mcclockvar.h,v 1.7 2008/01/03 23:02:25 joerg Exp $ */ /* * Copyright (c) 1996 Carnegie-Mellon University. @@ -30,6 +30,7 @@ struct mcclock_softc { struct device sc_dev; const struct mcclock_busfns *sc_busfns; + struct todr_chip_handle sc_todr; }; struct mcclock_busfns { |
