Index: dev/dec/clockvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/dec/clockvar.h,v retrieving revision 1.8 diff -d -p -u -r1.8 clockvar.h --- dev/dec/clockvar.h 11 Dec 2005 12:21:20 -0000 1.8 +++ dev/dec/clockvar.h 21 Sep 2006 05:31:16 -0000 @@ -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 *); Index: dev/dec/mcclock.c =================================================================== RCS file: /cvsroot/src/sys/dev/dec/mcclock.c,v retrieving revision 1.17 diff -d -p -u -r1.17 mcclock.c --- dev/dec/mcclock.c 11 Dec 2005 12:21:20 -0000 1.17 +++ dev/dec/mcclock.c 21 Sep 2006 05:31:16 -0000 @@ -34,6 +34,7 @@ __KERNEL_RCSID(0, "$NetBSD: mcclock.c,v #include #include #include +#include #include #include @@ -51,11 +52,11 @@ __KERNEL_RCSID(0, "$NetBSD: mcclock.c,v 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; } Index: dev/dec/mcclock_pad32.c =================================================================== RCS file: /cvsroot/src/sys/dev/dec/mcclock_pad32.c,v retrieving revision 1.13 diff -d -p -u -r1.13 mcclock_pad32.c --- dev/dec/mcclock_pad32.c 11 Dec 2005 12:21:20 -0000 1.13 +++ dev/dec/mcclock_pad32.c 21 Sep 2006 05:31:16 -0000 @@ -49,6 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: mcclock_pad3 #include #include #include +#include #include #include Index: dev/dec/mcclockvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/dec/mcclockvar.h,v retrieving revision 1.6 diff -d -p -u -r1.6 mcclockvar.h --- dev/dec/mcclockvar.h 11 Dec 2005 12:21:20 -0000 1.6 +++ dev/dec/mcclockvar.h 21 Sep 2006 05:31:16 -0000 @@ -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 { Index: arch/pmax/ibus/mcclock_ibus.c =================================================================== RCS file: /cvsroot/src/sys/arch/pmax/ibus/mcclock_ibus.c,v retrieving revision 1.12 diff -d -p -u -r1.12 mcclock_ibus.c --- arch/pmax/ibus/mcclock_ibus.c 2 Oct 2002 04:15:09 -0000 1.12 +++ arch/pmax/ibus/mcclock_ibus.c 21 Sep 2006 05:31:16 -0000 @@ -34,6 +34,7 @@ __KERNEL_RCSID(0, "$NetBSD: mcclock_ibus #include #include #include +#include #include #include Index: arch/pmax/include/sysconf.h =================================================================== RCS file: /cvsroot/src/sys/arch/pmax/include/sysconf.h,v retrieving revision 1.10 diff -d -p -u -r1.10 sysconf.h --- arch/pmax/include/sysconf.h 6 Jun 2000 00:08:27 -0000 1.10 +++ arch/pmax/include/sysconf.h 21 Sep 2006 05:31:16 -0000 @@ -63,7 +63,7 @@ struct platform { * iointr - I/O interrupt handler * intr_establish - establish interrupt handler * intr_disestablish - disestablish interrupt handler - * clkread - interporate HZ with hi-resolution timer + * tc_init - initialize timecounters */ void (*bus_reset) __P((void)); void (*cons_init) __P((void)); @@ -71,7 +71,7 @@ struct platform { void (*intr_establish) __P((struct device *, void *, int, int (*)(void *), void *)); int (*memsize) __P((caddr_t)); - unsigned (*clkread) __P((void)); + void (*tc_init) __P((void)); }; /* Index: arch/pmax/include/types.h =================================================================== RCS file: /cvsroot/src/sys/arch/pmax/include/types.h,v retrieving revision 1.21 diff -d -p -u -r1.21 types.h --- arch/pmax/include/types.h 5 Aug 2002 02:13:15 -0000 1.21 +++ arch/pmax/include/types.h 21 Sep 2006 05:31:16 -0000 @@ -4,6 +4,8 @@ #define __HAVE_DEVICE_REGISTER #define __HAVE_GENERIC_SOFT_INTERRUPTS +#define __HAVE_GENERIC_TODR +#define __HAVE_TIMECOUNTER /* MIPS specific options */ #define __HAVE_BOOTINFO_H Index: arch/pmax/pmax/clock.c =================================================================== RCS file: /cvsroot/src/sys/arch/pmax/pmax/clock.c,v retrieving revision 1.34 diff -d -p -u -r1.34 clock.c --- arch/pmax/pmax/clock.c 11 Dec 2005 12:18:39 -0000 1.34 +++ arch/pmax/pmax/clock.c 21 Sep 2006 05:31:16 -0000 @@ -87,11 +87,10 @@ __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1. #include #include +#include #include "opt_ntp.h" -#define MINYEAR 1998 /* "today" */ - struct device *clockdev; const struct clockfns *clockfns; int clockinitted; @@ -126,12 +125,6 @@ clockattach(dev, fns) * * Startrtclock restarts the real-time clock, which provides * hardclock interrupts to kern_clock.c. - * - * Inittodr initializes the time of day hardware which provides - * date functions. Its primary function is to use some file - * system information in case the hardare clock lost state. - * - * Resettodr restores the time of day hardware after a time change. */ /* @@ -168,17 +161,10 @@ cpu_initclocks() * case the initialisation routines adjusted hz. */ tick = 1000000 / hz; /* number of microseconds between interrupts */ - tickfix = 1000000 - (hz * tick); -#ifdef NTP - fixtick = tickfix; -#endif - if (tickfix) { - int ftp; - ftp = min(ffs(tickfix), ffs(hz)); - tickfix >>= (ftp - 1); - tickfixinterval = hz >> (ftp - 1); - } + /* setup time counters */ + if (platform.tc_init) + (*platform.tc_init)(); } /* @@ -194,160 +180,3 @@ setstatclockrate(newhz) /* nothing we can do */ } -/* - * 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? -*/ - -/* - * Initialze 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(base) - time_t base; -{ - struct clocktime ct; - struct clock_ymdhms dt; - time_t yearsecs; - time_t deltat; - int badbase; - - if (base < (MINYEAR-1970)*SECYR) { - printf("WARNING: preposterous time in file system"); - /* read the system clock anyway */ - base = (MINYEAR-1970)*SECYR; - badbase = 1; - } else - badbase = 0; - - (*clockfns->cf_get)(clockdev, base, &ct); -#ifdef DEBUG - printf("readclock: %d/%d/%d/%d/%d/%d", ct.year, ct.mon, ct.day, - ct.hour, ct.min, ct.sec); -#endif - clockinitted = 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 file system for lack of - * anything better, resetting the TODR. - */ - time.tv_sec = base; - if (!badbase) { - printf("WARNING: preposterous clock chip time\n"); - resettodr(); - } - goto bad; - } - - /* - * The clock lives in 1972 (leapyear!); - * calculate seconds relative to this year. - */ - dt.dt_year = 1972; - dt.dt_mon = ct.mon; - dt.dt_day = ct.day; - dt.dt_hour = ct.hour; - dt.dt_min = ct.min; - dt.dt_sec = ct.sec; - 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(;;) { - time.tv_sec = yearsecs + clock_ymdhms_to_secs(&dt); - if (badbase || (time.tv_sec > base - 2 * SECDAY)) - break; - dt.dt_year++; - } -#ifdef DEBUG - printf("=>%ld (%ld)\n", time.tv_sec, base); -#endif - - if (!badbase) { - /* - * See if we gained/lost two or more days; - * if so, assume something is amiss. - */ - deltat = time.tv_sec - base; - if (deltat < 0) - deltat = -deltat; - if (deltat < 2 * SECDAY) - return; - printf("WARNING: clock %s %d days", - time.tv_sec < base ? "lost" : "gained", - (int) (deltat / SECDAY)); - } -bad: - printf(" -- CHECK AND RESET THE DATE!\n"); -} - -/* - * Reset the TODR based on the time value; used when the TODR - * has a preposterous value and also when the time is reset - * by the stime system call. Also called when the TODR goes past - * TODRZERO + 100*(SECYEAR+2*SECDAY) (e.g. on Jan 2 just after midnight) - * to wrap the TODR around. - */ -void -resettodr() -{ - time_t yearsecs; - struct clock_ymdhms dt; - struct clocktime ct; - - if (!clockinitted) - return; - - /* - * calculate seconds relative to this year - */ - clock_secs_to_ymdhms(time.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 = time.tv_sec - clock_ymdhms_to_secs(&dt); - - /* - * The clock lives in 1972 (leapyear!); calc fictious date. - */ -#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 - ct.year = dt.dt_year % 100; /* rt clock wants 2 digits */ - ct.mon = dt.dt_mon; - ct.day = dt.dt_day; - ct.hour = dt.dt_hour; - ct.min = dt.dt_min; - ct.sec = dt.dt_sec; - ct.dow = dt.dt_wday; -#ifdef DEBUG - printf("setclock: %d/%d/%d/%d/%d/%d\n", ct.year, ct.mon, ct.day, - ct.hour, ct.min, ct.sec); -#endif - - (*clockfns->cf_set)(clockdev, &ct); -} Index: arch/pmax/pmax/dec_3maxplus.c =================================================================== RCS file: /cvsroot/src/sys/arch/pmax/pmax/dec_3maxplus.c,v retrieving revision 1.55 diff -d -p -u -r1.55 dec_3maxplus.c --- arch/pmax/pmax/dec_3maxplus.c 29 Jul 2006 19:10:58 -0000 1.55 +++ arch/pmax/pmax/dec_3maxplus.c 21 Sep 2006 05:31:16 -0000 @@ -111,6 +111,7 @@ __KERNEL_RCSID(0, "$NetBSD: dec_3maxplus #include #include #include +#include #include #include @@ -140,7 +141,8 @@ static void dec_3maxplus_intr_establish int, int (*)(void *), void *)); static void kn03_wbflush __P((void)); -static unsigned kn03_clkread __P((void)); + +static void dec_3maxplus_tc_init(void); /* * Local declarations @@ -159,8 +161,8 @@ dec_3maxplus_init() platform.iointr = dec_3maxplus_intr; platform.intr_establish = dec_3maxplus_intr_establish; platform.memsize = memsize_bitmap; - platform.clkread = kn03_clkread; /* 3MAX+ has IOASIC free-running high resolution timer */ + platform.tc_init = dec_3maxplus_tc_init; /* clear any memory errors */ *(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN03_SYS_ERRADR) = 0; @@ -333,7 +335,6 @@ dec_3maxplus_intr(status, cause, pc, ipe __asm volatile("lbu $0,48(%0)" :: "r"(ioasic_base + IOASIC_SLOT_8_START)); - latched_cycle_cnt = *(u_int32_t *)(ioasic_base + IOASIC_CTR); cf.pc = pc; cf.sr = status; hardclock(&cf); @@ -451,34 +452,25 @@ kn03_wbflush() } /* - * TURBOchannel bus-cycle counter provided by IOASIC; - * Interpolate micro-seconds since the last RTC clock tick. The - * interpolation base is the copy of the bus cycle-counter taken by - * the RTC interrupt handler. + * TURBOchannel bus-cycle counter provided by IOASIC; 25 MHz */ + static unsigned -kn03_clkread() +dec_3maxplus_get_timecount(struct timecounter *tc) { - u_int32_t usec, cycles; - - cycles = *(u_int32_t*)(ioasic_base + IOASIC_CTR); - cycles = cycles - latched_cycle_cnt; - - /* - * Scale from 40ns to microseconds. - * Avoid a kernel FP divide (by 25) using the approximation - * 1/25 = 40/1000 =~ 41/ 1024, which is good to 0.0975 % - */ - usec = cycles + (cycles << 3) + (cycles << 5); - usec = usec >> 10; + return *(u_int32_t*)(ioasic_base + IOASIC_CTR); +} -#ifdef CLOCK_DEBUG - if (usec > 3906 +4) { - addlog("clkread: usec %d, counter=%lx\n", - usec, latched_cycle_cnt); - stacktrace(); - } -#endif /*CLOCK_DEBUG*/ +static void +dec_3maxplus_tc_init(void) +{ + static struct timecounter tc = { + .tc_get_timecount = dec_3maxplus_get_timecount, + .tc_quality = 100, + .tc_frequency = 25000000, + .tc_counter_mask = ~0, + .tc_name = "turbochannel_counter", + }; - return usec; + tc_init(&tc); } Index: arch/pmax/pmax/dec_3min.c =================================================================== RCS file: /cvsroot/src/sys/arch/pmax/pmax/dec_3min.c,v retrieving revision 1.56 diff -d -p -u -r1.56 dec_3min.c --- arch/pmax/pmax/dec_3min.c 29 Jul 2006 19:10:58 -0000 1.56 +++ arch/pmax/pmax/dec_3min.c 21 Sep 2006 05:31:16 -0000 @@ -111,6 +111,7 @@ __KERNEL_RCSID(0, "$NetBSD: dec_3min.c,v #include #include #include +#include #include #include @@ -140,19 +141,14 @@ static void dec_3min_intr_establish __P( int, int (*)(void *), void *)); static void kn02ba_wbflush __P((void)); -static unsigned kn02ba_clkread __P((void)); +static void dec_3min_tc_init(void); /* * Local declarations. */ static u_int32_t kmin_tc3_imask; -#ifdef MIPS3 -static unsigned latched_cycle_cnt; -#endif - - void dec_3min_init() { @@ -162,7 +158,7 @@ dec_3min_init() platform.iointr = dec_3min_intr; platform.intr_establish = dec_3min_intr_establish; platform.memsize = memsize_bitmap; - platform.clkread = kn02ba_clkread; + platform.tc_init = dec_3min_tc_init; /* clear any memory errors */ *(u_int32_t *)MIPS_PHYS_TO_KSEG1(KMIN_REG_TIMEOUT) = 0; @@ -406,11 +402,7 @@ dec_3min_intr(status, cause, pc, ipendin __asm volatile("lbu $0,48(%0)" :: "r"(ioasic_base + IOASIC_SLOT_8_START)); -#ifdef MIPS3 - if (CPUISMIPS3) { - latched_cycle_cnt = mips3_cp0_count_read(); - } -#endif + cf.pc = pc; cf.sr = status; hardclock(&cf); @@ -499,18 +491,26 @@ kn02ba_wbflush() "i"(MIPS_PHYS_TO_KSEG1(KMIN_REG_IMSK))); } -static unsigned -kn02ba_clkread() +/* + * Support for using the MIPS 3 clock as a timecounter. + */ + +void +dec_3min_tc_init(void) { -#ifdef MIPS3 - if (CPUISMIPS3) { - u_int32_t mips3_cycles; + static struct timecounter tc = { + .tc_get_timecount = (timecounter_get_t *)mips3_cp0_count_read, + .tc_counter_mask = ~0u, + .tc_name = "mips3_cp0_counter", + .tc_quality = 100, + }; - mips3_cycles = mips3_cp0_count_read() - latched_cycle_cnt; - /* XXX divides take 78 cycles: approximate with * 41/2048 */ - return((mips3_cycles >> 6) + (mips3_cycles >> 8) + - (mips3_cycles >> 11)); + if (MIPS_HAS_CLOCK) { + tc.tc_frequency = cpu_mhz * 1000000; + if (mips_cpu_flags & CPU_MIPS_DOUBLE_COUNT) { + tc.tc_frequency /= 2; + } + + tc_init(&tc); } -#endif - return 0; } Index: arch/pmax/pmax/dec_maxine.c =================================================================== RCS file: /cvsroot/src/sys/arch/pmax/pmax/dec_maxine.c,v retrieving revision 1.49 diff -d -p -u -r1.49 dec_maxine.c --- arch/pmax/pmax/dec_maxine.c 29 Jul 2006 19:10:58 -0000 1.49 +++ arch/pmax/pmax/dec_maxine.c 21 Sep 2006 05:31:16 -0000 @@ -111,6 +111,7 @@ __KERNEL_RCSID(0, "$NetBSD: dec_maxine.c #include #include #include +#include #include #include @@ -137,14 +138,14 @@ static void dec_maxine_intr __P((unsigne static void dec_maxine_intr_establish __P((struct device *, void *, int, int (*)(void *), void *)); +static void dec_maxine_tc_init(void); + static void kn02ca_wbflush __P((void)); -static unsigned kn02ca_clkread __P((void)); /* * local declarations */ static u_int32_t xine_tc3_imask; -static unsigned latched_cycle_cnt; void @@ -156,7 +157,7 @@ dec_maxine_init() platform.iointr = dec_maxine_intr; platform.intr_establish = dec_maxine_intr_establish; platform.memsize = memsize_bitmap; - platform.clkread = kn02ca_clkread; + platform.tc_init = dec_maxine_tc_init; /* MAXINE has 1 microsec. free-running high resolution timer */ /* clear any memory errors */ @@ -328,8 +329,6 @@ dec_maxine_intr(status, cause, pc, ipend __asm volatile("lbu $0,48(%0)" :: "r"(ioasic_base + IOASIC_SLOT_8_START)); - latched_cycle_cnt = - *(u_int32_t *)MIPS_PHYS_TO_KSEG1(XINE_REG_FCTR); cf.pc = pc; cf.sr = status; hardclock(&cf); @@ -405,11 +404,22 @@ kn02ca_wbflush() "i"(MIPS_PHYS_TO_KSEG1(XINE_REG_IMSK))); } -static unsigned -kn02ca_clkread() +static uint32_t +dec_maxine_get_timecount(struct timecounter *tc) { - u_int32_t cycles; + return *(u_int32_t *)MIPS_PHYS_TO_KSEG1(XINE_REG_FCTR); +} - cycles = *(u_int32_t *)MIPS_PHYS_TO_KSEG1(XINE_REG_FCTR); - return cycles - latched_cycle_cnt; +static void +dec_maxine_tc_init(void) +{ + static struct timecounter tc = { + .tc_get_timecount = dec_maxine_get_timecount, + .tc_quality = 100, + .tc_frequency = 1000000, + .tc_counter_mask = ~0, + .tc_name = "maxine_fctr", + }; + + tc_init(&tc); } Index: arch/pmax/pmax/machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/pmax/pmax/machdep.c,v retrieving revision 1.214 diff -d -p -u -r1.214 machdep.c --- arch/pmax/pmax/machdep.c 15 Apr 2006 17:51:34 -0000 1.214 +++ arch/pmax/pmax/machdep.c 21 Sep 2006 05:31:16 -0000 @@ -706,38 +706,6 @@ nullwork() } /* - * Return the best possible estimate of the time in the timeval to - * which tvp points. We guarantee that the time will be greater than - * the value obtained by a previous call. Some models of DECstations - * provide a high resolution timer circuit. - */ -void -microtime(tvp) - struct timeval *tvp; -{ - int s = splclock(); - static struct timeval lasttime; - - *tvp = time; -#if defined(DEC_3MIN) || defined(DEC_MAXINE) || defined(DEC_3MAXPLUS) - tvp->tv_usec += (*platform.clkread)(); -#endif - if (tvp->tv_usec >= 1000000) { - tvp->tv_usec -= 1000000; - tvp->tv_sec++; - } - - if (tvp->tv_sec == lasttime.tv_sec && - tvp->tv_usec <= lasttime.tv_usec && - (tvp->tv_usec = lasttime.tv_usec + 1) >= 1000000) { - tvp->tv_sec++; - tvp->tv_usec -= 1000000; - } - lasttime = *tvp; - splx(s); -} - -/* * Wait "n" microseconds. (scsi code needs this). */ void Index: arch/pmax/tc/mcclock_ioasic.c =================================================================== RCS file: /cvsroot/src/sys/arch/pmax/tc/mcclock_ioasic.c,v retrieving revision 1.18 diff -d -p -u -r1.18 mcclock_ioasic.c --- arch/pmax/tc/mcclock_ioasic.c 2 Oct 2002 04:15:10 -0000 1.18 +++ arch/pmax/tc/mcclock_ioasic.c 21 Sep 2006 05:31:16 -0000 @@ -33,6 +33,7 @@ __KERNEL_RCSID(0, "$NetBSD: mcclock_ioas #include #include #include +#include #include #include