Subject: Re: Need help with timecounters/todr
To: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
From: Garrett D'Amore <garrett_damore@tadpole.com>
List: port-alpha
Date: 09/19/2006 07:14:27
Izumi Tsutsui wrote:
> garrett_damore@tadpole.com wrote:
>
>   
>> This was exactly the part I wasn't sure about.  I _think_ this should be
>> done (or similar logic) as part of timecounters -- i.e. each processor
>> needs to have some kind of synchronization -- probably implementing the
>> tc_pps method for timecounters.  I'm not an alpha expert though, so I'm
>> not 100% sure.
>>     
>
> Hmm. Anyway, here is current diff.
> Tested on DEC3000/300 (mcclock_ioasic) and EB164 (mcclock_isa).
>
> In this patch, each bus attachments call common mcclock_attach()
> to set alpha common settings (interval timer etc.), and in this way
> we can't share mcclock_isa.c with other ports.
>
> Should we have some MD hooks to set such bus-independent but
> MACHINE dependent settings in MI driver?
>   

Thanks.  We really do need a better way of handling MI code for
mcclock.  I have some thoughts along that line (I started an MI mcclock
driver), but there are non-trivial considerations.

For what its worth, it appears that every port uses a 32KHz frequency. 
The "Base" rate used for periodic interrupts (and handling of those
periodic interrupts) is very port specific.

The other stuff could easily be handled by device properties, or such. 
I sent out some mail about this a day or two ago.

    -- Garrett

> ---
> Izumi Tsutsui
>
>
> Index: a12/if_xb.c
> ===================================================================
> RCS file: /cvsroot/src/sys/arch/alpha/a12/if_xb.c,v
> retrieving revision 1.14
> diff -u -r1.14 if_xb.c
> --- a12/if_xb.c	24 Dec 2005 20:06:46 -0000	1.14
> +++ a12/if_xb.c	19 Sep 2006 13:31:32 -0000
> @@ -99,7 +99,6 @@
>  
>  #include <dev/isa/isareg.h>
>  #include <dev/isa/isavar.h>
> -#include <dev/dec/clockvar.h>
>  #include <dev/pci/pcireg.h>
>  #include <dev/pci/pcivar.h>
>  
> Index: alpha/clock.c
> ===================================================================
> RCS file: /cvsroot/src/sys/arch/alpha/alpha/clock.c,v
> retrieving revision 1.36
> diff -u -r1.36 clock.c
> --- alpha/clock.c	11 Dec 2005 12:16:10 -0000	1.36
> +++ alpha/clock.c	19 Sep 2006 13:31:32 -0000
> @@ -88,17 +88,11 @@
>  #include <sys/device.h>
>  #include <sys/sched.h>
>  
> -#include <dev/clock_subr.h>
> -
>  #include <machine/autoconf.h>
>  #include <machine/cpuconf.h>
>  
> -#include <dev/dec/clockvar.h>
> -
> -#include "opt_clock_compat_osf1.h"
> -#include "opt_ntp.h"
> +#include <alpha/alpha/clockvar.h>
>  
> -#define MINYEAR 1998 /* "today" */
>  #ifdef CLOCK_COMPAT_OSF1
>  /*
>   * According to OSF/1's /usr/sys/include/arch/alpha/clock.h,
> @@ -112,25 +106,20 @@
>  #define UNIX_YEAR_OFFSET 0
>  #endif
>  
> -struct device *clockdev;
> -const struct clockfns *clockfns;
> -int clockinitted;
> +void (*clock_init)(void *);
> +void *clockdev;
>  
>  void
> -clockattach(dev, fns)
> -	struct device *dev;
> -	const struct clockfns *fns;
> +clockattach(void (*fns)(void *), void *dev)
>  {
>  
>  	/*
>  	 * Just bookkeeping.
>  	 */
> -	printf("\n");
> -
> -	if (clockfns != NULL)
> +	if (clock_init != NULL)
>  		panic("clockattach: multiple clocks");
> +	clock_init = fns;
>  	clockdev = dev;
> -	clockfns = fns;
>  }
>  
>  /*
> @@ -151,9 +140,10 @@
>   * are no other timers available.
>   */
>  void
> -cpu_initclocks()
> +cpu_initclocks(void)
>  {
> -	if (clockfns == NULL)
> +
> +	if (clock_init == NULL)
>  		panic("cpu_initclocks: no clock attached");
>  
>  	tick = 1000000 / hz;	/* number of microseconds between interrupts */
> @@ -184,7 +174,7 @@
>  	/*
>  	 * Get the clock started.
>  	 */
> -	(*clockfns->cf_init)(clockdev);
> +	(*clock_init)(clockdev);
>  }
>  
>  /*
> @@ -199,123 +189,3 @@
>  
>  	/* nothing we can do */
>  }
> -
> -/*
> - * 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(base)
> -	time_t base;
> -{
> -	struct clocktime ct;
> -	int year;
> -	struct clock_ymdhms dt;
> -	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;
> -
> -	year = 1900 + UNIX_YEAR_OFFSET + ct.year;
> -	if (year < 1970)
> -		year += 100;
> -	/* simple sanity checks (2037 = time_t overflow) */
> -	if (year < MINYEAR || year > 2037 ||
> -	    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;
> -	}
> -
> -	dt.dt_year = year;
> -	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;
> -	time.tv_sec = clock_ymdhms_to_secs(&dt);
> -#ifdef DEBUG
> -	printf("=>%ld (%d)\n", time.tv_sec, base);
> -#endif
> -	cc_microset_time = time;
> -	cc_microset(curcpu());
> -
> -	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 %ld days",
> -		    time.tv_sec < base ? "lost" : "gained",
> -		    (long)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()
> -{
> -	struct clock_ymdhms dt;
> -	struct clocktime ct;
> -
> -	if (!clockinitted)
> -		return;
> -
> -	cc_microset_time = time;
> -#if defined(MULTIPROCESSOR)
> -	alpha_multicast_ipi(cpus_running, ALPHA_IPI_MICROSET);
> -#endif	
> -	cc_microset(curcpu());
> -	
> -	clock_secs_to_ymdhms(time.tv_sec, &dt);
> -
> -	/* rt clock wants 2 digits */
> -	ct.year = (dt.dt_year - UNIX_YEAR_OFFSET) % 100;
> -	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: alpha/mcclock.c
> ===================================================================
> RCS file: /cvsroot/src/sys/arch/alpha/alpha/mcclock.c,v
> retrieving revision 1.10
> diff -u -r1.10 mcclock.c
> --- alpha/mcclock.c	12 Jan 1998 10:21:04 -0000	1.10
> +++ alpha/mcclock.c	19 Sep 2006 13:31:32 -0000
> @@ -31,106 +31,64 @@
>  
>  __KERNEL_RCSID(0, "$NetBSD: mcclock.c,v 1.10 1998/01/12 10:21:04 thorpej Exp $");
>  
> +#include "opt_clock_compat_osf1.h"
> +
>  #include <sys/param.h>
>  #include <sys/kernel.h>
>  #include <sys/systm.h>
>  #include <sys/device.h>
>  
> -#include <dev/dec/clockvar.h>
> -#include <dev/dec/mcclockvar.h>
> +#include <machine/bus.h>
> +
> +#include <dev/clock_subr.h>
> +
>  #include <dev/ic/mc146818reg.h>
> +#include <dev/ic/mc146818var.h>
>  
> -void	mcclock_init __P((struct device *));
> -void	mcclock_get __P((struct device *, time_t, struct clocktime *));
> -void	mcclock_set __P((struct device *, struct clocktime *));
> -
> -const struct clockfns mcclock_clockfns = {
> -	mcclock_init, mcclock_get, mcclock_set,
> -};
> -
> -#define	mc146818_write(dev, reg, datum)					\
> -	    (*(dev)->sc_busfns->mc_bf_write)(dev, reg, datum)
> -#define	mc146818_read(dev, reg)						\
> -	    (*(dev)->sc_busfns->mc_bf_read)(dev, reg)
> +#include <alpha/alpha/mcclockvar.h>
> +#include <alpha/alpha/clockvar.h>
> +
> +#ifdef CLOCK_COMPAT_OSF1
> +/*
> + * According to OSF/1's /usr/sys/include/arch/alpha/clock.h,
> + * the console adjusts the RTC years 13..19 to 93..99 and
> + * 20..40 to 00..20. (historical reasons?)
> + * DEC Unix uses an offset to the year to stay outside
> + * the dangerous area for the next couple of years.
> + */
> +#define UNIX_YEAR_OFFSET 52 /* 41=>1993, 12=>2064 */
> +#else
> +#define UNIX_YEAR_OFFSET 0
> +#endif
> +
> +
> +void	mcclock_init(void *);
>  
>  void
> -mcclock_attach(sc, busfns)
> -	struct mcclock_softc *sc;
> -	const struct mcclock_busfns *busfns;
> +mcclock_attach(struct mc146818_softc *sc)
>  {
>  
> -	printf(": mc146818 or compatible");
> +	sc->sc_year0 = 1900 + UNIX_YEAR_OFFSET;
> +	sc->sc_flag = 0;	/* BINARY, 24HR */
> +
> +	mc146818_attach(sc);
>  
> -	sc->sc_busfns = busfns;
> +	aprint_normal("\n");
>  
>  	/* Turn interrupts off, just in case. */
> -	mc146818_write(sc, MC_REGB, MC_REGB_BINARY | MC_REGB_24HR);
> +	(*sc->sc_mcwrite)(sc, MC_REGB, MC_REGB_BINARY | MC_REGB_24HR);
>  
> -	clockattach(&sc->sc_dev, &mcclock_clockfns);
> +	todr_attach(&sc->sc_handle);
> +	clockattach(mcclock_init, (void *)sc);
>  }
>  
>  void
> -mcclock_init(dev)
> -	struct device *dev;
> +mcclock_init(void *dev)
>  {
> -	struct mcclock_softc *sc = (struct mcclock_softc *)dev;
> +	struct mc146818_softc *sc = dev;
>  
> -	mc146818_write(sc, MC_REGA, MC_BASE_32_KHz | MC_RATE_1024_Hz);
> -	mc146818_write(sc, MC_REGB,
> +	/* enable interval clock interrupt */
> +	(*sc->sc_mcwrite)(sc, MC_REGA, MC_BASE_32_KHz | MC_RATE_1024_Hz);
> +	(*sc->sc_mcwrite)(sc, MC_REGB,
>  	    MC_REGB_PIE | MC_REGB_SQWE | MC_REGB_BINARY | MC_REGB_24HR);
>  }
> -
> -/*
> - * 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;
> -{
> -	struct mcclock_softc *sc = (struct mcclock_softc *)dev;
> -	mc_todregs regs;
> -	int s;
> -
> -	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];
> -}
> -
> -/*
> - * Reset the TODR based on the time value.
> - */
> -void
> -mcclock_set(dev, ct)
> -	struct device *dev;
> -	struct clocktime *ct;
> -{
> -	struct mcclock_softc *sc = (struct mcclock_softc *)dev;
> -	mc_todregs regs;
> -	int s;
> -
> -	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;
> -
> -	s = splclock();
> -	MC146818_PUTTOD(sc, &regs);
> -	splx(s);
> -}
> Index: conf/files.alpha
> ===================================================================
> RCS file: /cvsroot/src/sys/arch/alpha/conf/files.alpha,v
> retrieving revision 1.170
> diff -u -r1.170 files.alpha
> --- conf/files.alpha	14 Sep 2006 18:08:06 -0000	1.170
> +++ conf/files.alpha	19 Sep 2006 13:31:32 -0000
> @@ -391,7 +391,7 @@
>  # Devices that can live on multiple busses
>  #
>  
> -device	mcclock
> +device	mcclock: mc146818
>  attach	mcclock at ioasic with mcclock_ioasic
>  attach	mcclock at isa with mcclock_isa
>  attach	mcclock at gbus with mcclock_tlsb
> Index: include/types.h
> ===================================================================
> RCS file: /cvsroot/src/sys/arch/alpha/include/types.h,v
> retrieving revision 1.35
> diff -u -r1.35 types.h
> --- include/types.h	3 Sep 2006 13:51:23 -0000	1.35
> +++ include/types.h	19 Sep 2006 13:31:32 -0000
> @@ -61,6 +61,7 @@
>  
>  #define	__HAVE_DEVICE_REGISTER
>  #define	__HAVE_GENERIC_SOFT_INTERRUPTS
> +#define	__HAVE_GENERIC_TODR
>  #define	__HAVE_ATOMIC_OPERATIONS
>  #define	__HAVE_CPU_COUNTER
>  #define	__HAVE_SYSCALL_INTERN
> Index: isa/mcclock_isa.c
> ===================================================================
> RCS file: /cvsroot/src/sys/arch/alpha/isa/mcclock_isa.c,v
> retrieving revision 1.15
> diff -u -r1.15 mcclock_isa.c
> --- isa/mcclock_isa.c	11 Dec 2005 12:16:16 -0000	1.15
> +++ isa/mcclock_isa.c	19 Sep 2006 13:31:32 -0000
> @@ -38,36 +38,25 @@
>  
>  #include <machine/bus.h>
>  
> -#include <dev/dec/clockvar.h>
> -#include <dev/dec/mcclockvar.h>
> +#include <dev/clock_subr.h>
> +
>  #include <dev/ic/mc146818reg.h>
> +#include <dev/ic/mc146818var.h>
>  #include <dev/isa/isavar.h>
>  
> -struct mcclock_isa_softc {
> -	struct mcclock_softc	sc_mcclock;
> -
> -	bus_space_tag_t		sc_iot;
> -	bus_space_handle_t	sc_ioh;
> -};
> +#include <alpha/alpha/mcclockvar.h>
>  
> -int	mcclock_isa_match __P((struct device *, struct cfdata *, void *));
> -void	mcclock_isa_attach __P((struct device *, struct device *, void *));
> +int	mcclock_isa_match(struct device *, struct cfdata *, void *);
> +void	mcclock_isa_attach(struct device *, struct device *, void *);
>  
> -CFATTACH_DECL(mcclock_isa, sizeof (struct mcclock_isa_softc),
> +CFATTACH_DECL(mcclock_isa, sizeof(struct mc146818_softc),
>      mcclock_isa_match, mcclock_isa_attach, NULL, NULL);
>  
> -void	mcclock_isa_write __P((struct mcclock_softc *, u_int, u_int));
> -u_int	mcclock_isa_read __P((struct mcclock_softc *, u_int));
> -
> -const struct mcclock_busfns mcclock_isa_busfns = {
> -	mcclock_isa_write, mcclock_isa_read,
> -};
> +void	mcclock_isa_write(struct mc146818_softc *, u_int, u_int);
> +u_int	mcclock_isa_read(struct mc146818_softc *, u_int);
>  
>  int
> -mcclock_isa_match(parent, match, aux)
> -	struct device *parent;
> -	struct cfdata *match;
> -	void *aux;
> +mcclock_isa_match(struct device *parent, struct cfdata *match, void *aux)
>  {
>  	struct isa_attach_args *ia = aux;
>  	bus_space_handle_t ioh;
> @@ -106,42 +95,37 @@
>  }
>  
>  void
> -mcclock_isa_attach(parent, self, aux)
> -	struct device *parent, *self;
> -	void *aux;
> +mcclock_isa_attach(struct device *parent, struct device *self, void *aux)
>  {
>  	struct isa_attach_args *ia = aux;
> -	struct mcclock_isa_softc *sc = (struct mcclock_isa_softc *)self;
> +	struct mc146818_softc *sc = (void *)self;
>  
> -	sc->sc_iot = ia->ia_iot;
> -	if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr,
> -	    ia->ia_io[0].ir_size, 0, &sc->sc_ioh))
> +	sc->sc_bst = ia->ia_iot;
> +	if (bus_space_map(sc->sc_bst, ia->ia_io[0].ir_addr,
> +	    ia->ia_io[0].ir_size, 0, &sc->sc_bsh))
>  		panic("mcclock_isa_attach: couldn't map clock I/O space");
>  
> -	mcclock_attach(&sc->sc_mcclock, &mcclock_isa_busfns);
> +	sc->sc_mcread  = mcclock_isa_read;
> +	sc->sc_mcwrite = mcclock_isa_write;
> +
> +	mcclock_attach(sc);
>  }
>  
>  void
> -mcclock_isa_write(mcsc, reg, datum)
> -	struct mcclock_softc *mcsc;
> -	u_int reg, datum;
> +mcclock_isa_write(struct mc146818_softc *sc, u_int reg, u_int datum)
>  {
> -	struct mcclock_isa_softc *sc = (struct mcclock_isa_softc *)mcsc;
> -	bus_space_tag_t iot = sc->sc_iot;
> -	bus_space_handle_t ioh = sc->sc_ioh;
> +	bus_space_tag_t iot = sc->sc_bst;
> +	bus_space_handle_t ioh = sc->sc_bsh;
>  
>  	bus_space_write_1(iot, ioh, 0, reg);
>  	bus_space_write_1(iot, ioh, 1, datum);
>  }
>  
>  u_int
> -mcclock_isa_read(mcsc, reg)
> -	struct mcclock_softc *mcsc;
> -	u_int reg;
> +mcclock_isa_read(struct mc146818_softc *sc, u_int reg)
>  {
> -	struct mcclock_isa_softc *sc = (struct mcclock_isa_softc *)mcsc;
> -	bus_space_tag_t iot = sc->sc_iot;
> -	bus_space_handle_t ioh = sc->sc_ioh;
> +	bus_space_tag_t iot = sc->sc_bst;
> +	bus_space_handle_t ioh = sc->sc_bsh;
>  
>  	bus_space_write_1(iot, ioh, 0, reg);
>  	return bus_space_read_1(iot, ioh, 1);
> Index: jensenio/mcclock_jensenio.c
> ===================================================================
> RCS file: /cvsroot/src/sys/arch/alpha/jensenio/mcclock_jensenio.c,v
> retrieving revision 1.4
> diff -u -r1.4 mcclock_jensenio.c
> --- jensenio/mcclock_jensenio.c	2 Oct 2002 04:06:38 -0000	1.4
> +++ jensenio/mcclock_jensenio.c	19 Sep 2006 13:31:32 -0000
> @@ -74,18 +74,17 @@
>  
>  #include <machine/bus.h>
>  
> -#include <dev/dec/clockvar.h>
> -#include <dev/dec/mcclockvar.h>
> +#include <dev/clock_subr.h>
> +
>  #include <dev/ic/mc146818reg.h>
> +#include <dev/ic/mc146818var.h>
>  #include <dev/eisa/eisavar.h>
>  #include <dev/isa/isavar.h>
>  #include <alpha/jensenio/jenseniovar.h>
> +#include <alpha/alpha/mcclockvar.h>
>  
>  struct mcclock_jensenio_softc {
> -	struct mcclock_softc	sc_mcclock;
> -
> -	bus_space_tag_t		sc_iot;
> -	bus_space_handle_t	sc_ioh;
> +	struct mc146818_softc	sc_mc146818;
>  
>  	bus_space_handle_t	sc_std_rtc_ioh;
>  };
> @@ -96,12 +95,9 @@
>  CFATTACH_DECL(mcclock_jensenio, sizeof (struct mcclock_jensenio_softc),
>      mcclock_jensenio_match, mcclock_jensenio_attach, NULL, NULL);
>  
> -void	mcclock_jensenio_write(struct mcclock_softc *, u_int, u_int);
> -u_int	mcclock_jensenio_read(struct mcclock_softc *, u_int);
> +void	mcclock_jensenio_write(struct mc146818_softc *, u_int, u_int);
> +u_int	mcclock_jensenio_read(struct mc146818_softc *, u_int);
>  
> -const struct mcclock_busfns mcclock_jensenio_busfns = {
> -	mcclock_jensenio_write, mcclock_jensenio_read,
> -};
>  
>  int
>  mcclock_jensenio_match(struct device *parent, struct cfdata *match, void *aux)
> @@ -119,40 +115,42 @@
>  mcclock_jensenio_attach(struct device *parent, struct device *self, void *aux)
>  {
>  	struct jensenio_attach_args *ja = aux;
> -	struct mcclock_jensenio_softc *sc = (void *) self;
> +	struct mcclock_jensenio_softc *jsc = (void *)self;
> +	struct mc146818_softc *sc = &jsc->sc_mc146818;
>  
> -	sc->sc_iot = ja->ja_iot;
> -	if (bus_space_map(sc->sc_iot, ja->ja_ioaddr, 0x02, 0,
> -	    &sc->sc_ioh))
> +	sc->sc_bst = ja->ja_iot;
> +	if (bus_space_map(sc->sc_bst, ja->ja_ioaddr, 0x02, 0,
> +	    &sc->sc_bsh))
>  		panic("mcclock_jensenio_attach: couldn't map clock I/O space");
>  
>  	/*
>  	 * Map the I/O space normally used by the ISA RTC (port 0x70) so
>  	 * as to avoid a false match at that address, as well.
>  	 */
> -	(void) bus_space_map(sc->sc_iot, 0x70, 0x02, 0,
> -	    &sc->sc_std_rtc_ioh);
> +	(void)bus_space_map(sc->sc_bst, 0x70, 0x02, 0,
> +	    &jsc->sc_std_rtc_ioh);
> +
> +	sc->sc_mcread  = mcclock_jensenio_read;
> +	sc->sc_mcwrite = mcclock_jensenio_write;
>  
> -	mcclock_attach(&sc->sc_mcclock, &mcclock_jensenio_busfns);
> +	mcclock_attach(sc);
>  }
>  
>  void
> -mcclock_jensenio_write(struct mcclock_softc *mcsc, u_int reg, u_int datum)
> +mcclock_jensenio_write(struct mc146818_softc *sc, u_int reg, u_int datum)
>  {
> -	struct mcclock_jensenio_softc *sc = (void *) mcsc;
> -	bus_space_tag_t iot = sc->sc_iot;
> -	bus_space_handle_t ioh = sc->sc_ioh;
> +	bus_space_tag_t iot = sc->sc_bst;
> +	bus_space_handle_t ioh = sc->sc_bsh;
>  
>  	bus_space_write_1(iot, ioh, 0, reg);
>  	bus_space_write_1(iot, ioh, 1, datum);
>  }
>  
>  u_int
> -mcclock_jensenio_read(struct mcclock_softc *mcsc, u_int reg)
> +mcclock_jensenio_read(struct mc146818_softc *sc, u_int reg)
>  {
> -	struct mcclock_jensenio_softc *sc = (void *) mcsc;
> -	bus_space_tag_t iot = sc->sc_iot;
> -	bus_space_handle_t ioh = sc->sc_ioh;
> +	bus_space_tag_t iot = sc->sc_bst;
> +	bus_space_handle_t ioh = sc->sc_bsh;
>  
>  	bus_space_write_1(iot, ioh, 0, reg);
>  	return bus_space_read_1(iot, ioh, 1);
> Index: pci/a12c.c
> ===================================================================
> RCS file: /cvsroot/src/sys/arch/alpha/pci/a12c.c,v
> retrieving revision 1.16
> diff -u -r1.16 a12c.c
> --- pci/a12c.c	11 Dec 2005 12:16:17 -0000	1.16
> +++ pci/a12c.c	19 Sep 2006 13:31:32 -0000
> @@ -53,10 +53,11 @@
>  
>  #include <dev/isa/isareg.h>
>  #include <dev/isa/isavar.h>
> -#include <dev/dec/clockvar.h>
>  #include <dev/pci/pcireg.h>
>  #include <dev/pci/pcivar.h>
>  
> +#include <alpha/alpha/clockvar.h>
> +
>  #include <alpha/pci/a12creg.h>
>  #include <alpha/pci/a12cvar.h>
>  #include <alpha/pci/pci_a12.h>
> @@ -127,7 +128,6 @@
>  	struct a12c_softc *sc = (struct a12c_softc *)self;
>  	struct a12c_config *ccp;
>  	struct pcibus_attach_args pba;
> -	extern const struct clockfns *clockfns;	/* XXX? */
>  
>  	/* note that we've attached the chipset; can't have 2 A12Cs. */
>  	a12cfound = 1;
> @@ -145,7 +145,7 @@
>  		A12_ALL_EXTRACT(REGVAL(A12_VERS)));
>  
>  	pci_a12_pickintr(ccp);
> -	clockfns = &noclock_fns;	/* XXX? */
> +	clockattach(noclock_init, NULL);	/* XXX? */
>  
>  	memset(&pba, 0, sizeof(pba));
>  	pba.pba_iot = 0;
> @@ -167,19 +167,8 @@
>  	config_found_ia(self, "a12c_a12dc", &pba, NULL);
>  }
>  
> -static void noclock_init(struct device *dev) {
> -	dev = dev;
> -}
> -
> -static void
> -noclock_get(struct device *dev, time_t t, struct clocktime *ct)
> +static void noclock_init(void (*)(void *), void *)
>  {
> -	*ct = zeroct;
> -}
>  
> -static void
> -noclock_set(struct device *dev, struct clocktime *ct)
> -{
> -	if(dev!=NULL)
> -		*ct = *ct;
> +	/* nothing */
>  }
> Index: tc/mcclock_ioasic.c
> ===================================================================
> RCS file: /cvsroot/src/sys/arch/alpha/tc/mcclock_ioasic.c,v
> retrieving revision 1.11
> diff -u -r1.11 mcclock_ioasic.c
> --- tc/mcclock_ioasic.c	2 Oct 2002 04:06:40 -0000	1.11
> +++ tc/mcclock_ioasic.c	19 Sep 2006 13:31:33 -0000
> @@ -36,41 +36,39 @@
>  #include <sys/systm.h>
>  #include <sys/device.h>
>  
> -#include <dev/dec/clockvar.h>
> -#include <dev/dec/mcclockvar.h>
> +#include <machine/bus.h>
> +
> +#include <dev/clock_subr.h>
> +
>  #include <dev/ic/mc146818reg.h>
> +#include <dev/ic/mc146818var.h>
>  #include <dev/tc/tcvar.h> 
>  #include <dev/tc/ioasicvar.h>                   /* XXX */
>  
> +#include <alpha/alpha/mcclockvar.h>
> +
>  struct mcclock_ioasic_clockdatum {
>  	u_char	datum;
>  	char	pad[3];
>  };
>  
>  struct mcclock_ioasic_softc {
> -	struct mcclock_softc	sc_mcclock;
> +	struct mc146818_softc	sc_mc146818;
>  
>  	struct mcclock_ioasic_clockdatum *sc_dp;
>  };
>  
> -int	mcclock_ioasic_match __P((struct device *, struct cfdata *, void *));
> -void	mcclock_ioasic_attach __P((struct device *, struct device *, void *));
> +int	mcclock_ioasic_match(struct device *, struct cfdata *, void *);
> +void	mcclock_ioasic_attach(struct device *, struct device *, void *);
>  
> -CFATTACH_DECL(mcclock_ioasic, sizeof (struct mcclock_ioasic_softc),
> +CFATTACH_DECL(mcclock_ioasic, sizeof(struct mcclock_ioasic_softc),
>      mcclock_ioasic_match, mcclock_ioasic_attach, NULL, NULL);
>  
> -void	mcclock_ioasic_write __P((struct mcclock_softc *, u_int, u_int));
> -u_int	mcclock_ioasic_read __P((struct mcclock_softc *, u_int));
> -
> -const struct mcclock_busfns mcclock_ioasic_busfns = {
> -	mcclock_ioasic_write, mcclock_ioasic_read,
> -};
> +void	mcclock_ioasic_write(struct mc146818_softc *, u_int, u_int);
> +u_int	mcclock_ioasic_read(struct mc146818_softc *, u_int);
>  
>  int
> -mcclock_ioasic_match(parent, match, aux)
> -	struct device *parent;
> -	struct cfdata *match;
> -	void *aux;
> +mcclock_ioasic_match(struct device *parent, struct cfdata *match, void *aux)
>  {
>  	struct ioasicdev_attach_args *d = aux;
>  
> @@ -81,34 +79,34 @@
>  }
>  
>  void
> -mcclock_ioasic_attach(parent, self, aux)
> -	struct device *parent, *self;
> -	void *aux;
> +mcclock_ioasic_attach(struct device *parent, struct device *self, void *aux)
>  {
>  	struct ioasicdev_attach_args *ioasicdev = aux;
> -	struct mcclock_ioasic_softc *sc = (struct mcclock_ioasic_softc *)self;
> +	struct mcclock_ioasic_softc *isc = (void *)self;
> +	struct mc146818_softc *sc = &isc->sc_mc146818;
> +
> +	/* XXX no bus_space(9) for TURBOchannel yet */
> +	isc->sc_dp = (void *)ioasicdev->iada_addr;
>  
> -	sc->sc_dp = (struct mcclock_ioasic_clockdatum *)ioasicdev->iada_addr;
> +	sc->sc_mcread = mcclock_ioasic_read;
> +	sc->sc_mcwrite = mcclock_ioasic_write;
>  
> -	mcclock_attach(&sc->sc_mcclock, &mcclock_ioasic_busfns);
> +	/* call alpha common mcclock attachment */
> +	mcclock_attach(sc);
>  }
>  
>  void
> -mcclock_ioasic_write(dev, reg, datum)
> -	struct mcclock_softc *dev;
> -	u_int reg, datum;
> +mcclock_ioasic_write(struct mc146818_softc *sc, u_int reg, u_int datum)
>  {
> -	struct mcclock_ioasic_softc *sc = (struct mcclock_ioasic_softc *)dev;
> +	struct mcclock_ioasic_softc *isc = (void *)sc;
>  
> -	sc->sc_dp[reg].datum = datum;
> +	isc->sc_dp[reg].datum = datum;
>  }
>  
>  u_int
> -mcclock_ioasic_read(dev, reg)
> -	struct mcclock_softc *dev;
> -	u_int reg;
> +mcclock_ioasic_read(struct mc146818_softc *sc, u_int reg)
>  {
> -	struct mcclock_ioasic_softc *sc = (struct mcclock_ioasic_softc *)dev;
> +	struct mcclock_ioasic_softc *isc = (void *)sc;
>  
> -	return (sc->sc_dp[reg].datum);
> +	return isc->sc_dp[reg].datum;
>  }
> Index: tlsb/mcclock_tlsb.c
> ===================================================================
> RCS file: /cvsroot/src/sys/arch/alpha/tlsb/mcclock_tlsb.c,v
> retrieving revision 1.10
> diff -u -r1.10 mcclock_tlsb.c
> --- tlsb/mcclock_tlsb.c	2 Oct 2002 04:06:40 -0000	1.10
> +++ tlsb/mcclock_tlsb.c	19 Sep 2006 13:31:33 -0000
> @@ -41,14 +41,18 @@
>  
>  #include <machine/bus.h>
>  
> -#include <dev/dec/clockvar.h>
> -#include <dev/dec/mcclockvar.h>
> -
>  #include <alpha/tlsb/gbusvar.h>
>  
>  #include <alpha/tlsb/tlsbreg.h>		/* XXX */
>  
> +#include <dev/clock_subr.h>
> +
>  #include <dev/ic/mc146818reg.h>
> +#include <dev/ic/mc146818var.h>
> +
> +#include <alpha/alpha/mcclockvar.h>
> +
> +#include "ioconf.h"
>  
>  #define	KV(_addr)	((caddr_t)ALPHA_PHYS_TO_K0SEG((_addr)))
>  /*
> @@ -57,69 +61,62 @@
>  #define	REGSHIFT	6
>  
>  struct mcclock_tlsb_softc {
> -	struct mcclock_softc	sc_mcclock;
> +	struct mc146818_softc	sc_mc146818;
>  	unsigned long regbase;
>  };
>  
> -int	mcclock_tlsb_match __P((struct device *, struct cfdata *, void *));
> -void	mcclock_tlsb_attach __P((struct device *, struct device *, void *));
> +int	mcclock_tlsb_match(struct device *, struct cfdata *, void *);
> +void	mcclock_tlsb_attach(struct device *, struct device *, void *);
>  
>  CFATTACH_DECL(mcclock_tlsb, sizeof (struct mcclock_tlsb_softc),
>      mcclock_tlsb_match, mcclock_tlsb_attach, NULL, NULL);
>  
> -extern struct cfdriver mcclock_cd;
> -
> -static void	mcclock_tlsb_write __P((struct mcclock_softc *, u_int, u_int));
> -static u_int	mcclock_tlsb_read __P((struct mcclock_softc *, u_int));
> +static void	mcclock_tlsb_write(struct mc146818_softc *, u_int, u_int);
> +static u_int	mcclock_tlsb_read(struct mc146818_softc *, u_int);
>  
> -const struct mcclock_busfns mcclock_tlsb_busfns = {
> -	mcclock_tlsb_write, mcclock_tlsb_read,
> -};
>  
>  int
> -mcclock_tlsb_match(parent, match, aux)
> -	struct device *parent;
> -	struct cfdata *match;
> -	void *aux;
> +mcclock_tlsb_match(struct device *parent, struct cfdata *match, void *aux)
>  {
>  	struct gbus_attach_args *ga = aux;
> +
>  	if (strcmp(ga->ga_name, mcclock_cd.cd_name))
>  		return (0);
>  	return (1);
>  }
>  
>  void
> -mcclock_tlsb_attach(parent, self, aux)
> -	struct device *parent, *self;
> -	void *aux;
> +mcclock_tlsb_attach(struct device *parent, struct device *self, void *aux)
>  {
> -	struct mcclock_tlsb_softc *sc = (struct mcclock_tlsb_softc *)self;
>  	struct gbus_attach_args *ga = aux;
> +	struct mcclock_tlsb_softc *tsc = (void *)self;
> +	struct mc146818_softc *sc = &tsc->sc_mc146818;
>  
>  	/* XXX Should be bus.h'd, so we can accomodate the kn7aa. */
> -	sc->regbase = TLSB_GBUS_BASE + ga->ga_offset;
> +	tsc->regbase = TLSB_GBUS_BASE + ga->ga_offset;
> +
> +	sc->sc_mcread  = mcclock_tlsb_read;
> +	sc->sc_mcwrite = mcclock_tlsb_write;
>  
> -	mcclock_attach(&sc->sc_mcclock, &mcclock_tlsb_busfns);
> +	mcclock_attach(sc);
>  }
>  
>  static void
> -mcclock_tlsb_write(mcsc, reg, val)
> -	struct mcclock_softc *mcsc;
> -	u_int reg, val;
> +mcclock_tlsb_write(struct mc146818_softc *sc, u_int reg, u_int val)
>  {
> -	struct mcclock_tlsb_softc *sc = (struct mcclock_tlsb_softc *)mcsc;
> +	struct mcclock_tlsb_softc *tsc = (void *)sc;
>  	unsigned char *ptr = (unsigned char *)
> -		KV(sc->regbase + (reg << REGSHIFT));
> +		KV(tsc->regbase + (reg << REGSHIFT));
> +
>  	*ptr = val;
>  }
>  
>  static u_int
> -mcclock_tlsb_read(mcsc, reg)
> -	struct mcclock_softc *mcsc;
> -	u_int reg;
> +mcclock_tlsb_read(struct mc146818_softc *sc, u_int reg)
>  {
> -	struct mcclock_tlsb_softc *sc = (struct mcclock_tlsb_softc *)mcsc;
> +	struct mcclock_tlsb_softc *tsc = (void *)sc;
>  	unsigned char *ptr = (unsigned char *)
> -		KV(sc->regbase + (reg << REGSHIFT));
> +		KV(tsc->regbase + (reg << REGSHIFT));
> +
>  	return *ptr;
>  }
> --- /dev/null	2006-09-19 22:01:53.000000000 +0900
> +++ alpha/clockvar.h	2006-09-19 21:04:38.000000000 +0900
> @@ -0,0 +1,34 @@
> +/* $NetBSD: clockvar.h,v 1.8 2005/12/11 12:21:20 christos 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 
> + */
> +
> +void clockattach(void (*)(void *), void *);
> --- /dev/null	2006-09-19 22:01:53.000000000 +0900
> +++ alpha/mcclockvar.h	2006-09-19 21:06:46.000000000 +0900
> @@ -0,0 +1,30 @@
> +/* $NetBSD: mcclockvar.h,v 1.6 2005/12/11 12:21:20 christos Exp $ */
> +
> +/*
> + * Copyright (c) 1996 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.
> + */
> +
> +void mcclock_attach(struct mc146818_softc *);
>   


-- 
Garrett D'Amore, Principal Software Engineer
Tadpole Computer / Computing Technologies Division,
General Dynamics C4 Systems
http://www.tadpolecomputer.com/
Phone: 951 325-2134  Fax: 951 325-2191