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 <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 
 
 
 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, &regs)
 	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, &regs);
 	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, &regs);
 	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 <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>
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 <sys/kernel.h>
 #include <sys/device.h>
 #include <sys/systm.h>
+#include <dev/clock_subr.h>
 
 #include <dev/dec/mcclockvar.h>
 #include <dev/dec/mcclock_pad32.h>
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 <dev/clock_subr.h>
 
 #include <dev/dec/clockvar.h>
+#include <machine/sysconf.h>
 
 #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 <sys/param.h>
 #include <sys/systm.h>
 #include <sys/device.h>
+#include <sys/timetc.h>
 
 #include <machine/cpu.h>
 #include <machine/sysconf.h>
@@ -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 <sys/param.h>
 #include <sys/systm.h>
 #include <sys/device.h>
+#include <sys/timetc.h>
 
 #include <machine/cpu.h>
 #include <machine/intr.h>
@@ -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 <sys/param.h>
 #include <sys/systm.h>
 #include <sys/device.h>
+#include <sys/timetc.h>
 
 #include <machine/cpu.h>
 #include <machine/sysconf.h>
@@ -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 <sys/param.h>
 #include <sys/device.h>
 #include <sys/systm.h>
+#include <dev/clock_subr.h>
 
 #include <dev/dec/mcclockvar.h>
 #include <dev/dec/mcclock_pad32.h>
