Subject: timecounters and todr for mipsco
To: None <port-mipsco@netbsd.org>
From: Garrett D'Amore <garrett_damore@tadpole.com>
List: port-mipsco
Date: 09/13/2006 15:02:59
This is a multi-part message in MIME format.
--------------090701000303070101050507
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
The following patch provides the MI todr for mipsco.
Additionally it converts the port to timecounters, and if the machine
has a rambo bus, then it will get a timecounter based on the rambo tcount.
Compile tested only. I'd be grateful to anyone who can test this out on
a real kernel.
--
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
--------------090701000303070101050507
Content-Type: text/x-patch;
name="mipsco.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="mipsco.diff"
Index: sys/arch/mipsco/include/sysconf.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mipsco/include/sysconf.h,v
retrieving revision 1.2
diff -d -p -u -r1.2 sysconf.h
--- sys/arch/mipsco/include/sysconf.h 15 Aug 2000 04:56:46 -0000 1.2
+++ sys/arch/mipsco/include/sysconf.h 13 Sep 2006 22:01:18 -0000
@@ -49,17 +49,15 @@ struct platform {
* cons_init - console initialization
* iointr - I/O interrupt handler
* memsize - Size external memory
- * clkread - interporate HZ with hi-resolution timer
* read_todr - Read TOD registers
* write_todr - Write TOD registers
+ * clkinit - Initialize clocks
*/
void (*cons_init) __P((void));
void (*iointr) __P((unsigned, unsigned, unsigned, unsigned));
int (*memsize) __P((caddr_t));
- unsigned (*clkread) __P((void));
- void (*read_todr) __P((struct clock_ymdhms *));
- void (*write_todr) __P((struct clock_ymdhms *));
void (*intr_establish) __P((int, int (*)__P((void *)), void *));
+ void (*clkinit) __P((void));
};
extern struct platform platform;
Index: sys/arch/mipsco/include/types.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mipsco/include/types.h,v
retrieving revision 1.3
diff -d -p -u -r1.3 types.h
--- sys/arch/mipsco/include/types.h 5 Aug 2002 02:13:15 -0000 1.3
+++ sys/arch/mipsco/include/types.h 13 Sep 2006 22:01:18 -0000
@@ -3,6 +3,8 @@
#include <mips/types.h>
#define __HAVE_GENERIC_SOFT_INTERRUPTS
+#define __HAVE_BOOTINFO_H
+#define __HAVE_TIMECOUNTER
+#define __HAVE_GENERIC_TODR
/* MIPS specific options */
-#define __HAVE_BOOTINFO_H
Index: sys/arch/mipsco/mipsco/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mipsco/mipsco/clock.c,v
retrieving revision 1.6
diff -d -p -u -r1.6 clock.c
--- sys/arch/mipsco/mipsco/clock.c 11 Dec 2005 12:18:13 -0000 1.6
+++ sys/arch/mipsco/mipsco/clock.c 13 Sep 2006 22:01:18 -0000
@@ -125,79 +125,6 @@ setstatclockrate(newhz)
void
cpu_initclocks()
{
+ if (platform.clkinit)
+ (*platform.clkinit)();
}
-
-/*
- * 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 clock_ymdhms dt;
-
- int deltat, badbase = 0;
-
- if (base < (MINYEAR-1970)*SECYR) {
- printf("WARNING: preposterous time in file system\n");
- /* read the system clock anyway */
- base = 6*SECYR + 186*SECDAY + SECDAY/2;
- badbase = 1;
- }
-
- (*platform.read_todr)(&dt);
-
- /* simple sanity checks */
- if (dt.dt_mon < 1 || dt.dt_mon > 12 ||
- dt.dt_day < 1 || dt.dt_day > 31 ||
- dt.dt_hour > 23 || dt.dt_min > 59 || dt.dt_sec > 59) {
- printf("WARNING: preposterous clock chip time\n");
- /*
- * Believe the time in the file system for lack of
- * anything better, resetting the TODR.
- */
- time.tv_sec = base;
- if (!badbase)
- resettodr();
- return;
- }
-
- /* now have days since Jan 1, 1970; the rest is easy... */
- time.tv_sec = clock_ymdhms_to_secs(&dt);
-
- 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", deltat / SECDAY);
- 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;
-
- if (time.tv_sec >= (MINYEAR-1970)*SECYR) {
- clock_secs_to_ymdhms(time.tv_sec, &dt);
- (*platform.write_todr)(&dt);
- }
-}
-
Index: sys/arch/mipsco/mipsco/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mipsco/mipsco/machdep.c,v
retrieving revision 1.46
diff -d -p -u -r1.46 machdep.c
--- sys/arch/mipsco/mipsco/machdep.c 9 Apr 2006 01:18:14 -0000 1.46
+++ sys/arch/mipsco/mipsco/machdep.c 13 Sep 2006 22:01:18 -0000
@@ -195,19 +195,15 @@ extern void pizazz_init __P((void));
static void unimpl_cons_init __P((void));
static void unimpl_iointr __P((unsigned, unsigned, unsigned, unsigned));
static int unimpl_memsize __P((caddr_t));
-static unsigned unimpl_clkread __P((void));
-static void unimpl_todr __P((struct clock_ymdhms *));
static void unimpl_intr_establish __P((int, int (*)__P((void *)), void *));
struct platform platform = {
- "iobus not set",
- unimpl_cons_init,
- unimpl_iointr,
- unimpl_memsize,
- unimpl_clkread,
- unimpl_todr,
- unimpl_todr,
- unimpl_intr_establish,
+ .iobus = "iobus not set",
+ .cons_init = unimpl_cons_init,
+ .iointr = unimpl_iointr,
+ .memsize = unimpl_memsize,
+ .intr_establish = unimpl_intr_establish,
+ .clkinit = NULL,
};
struct consdev *cn_tab = NULL;
@@ -550,38 +546,6 @@ haltsys:
/*NOTREACHED*/
}
-/*
- * Return the best possible estimate of the time in the timeval
- * to which tvp points. Unfortunately, we can't read the hardware registers.
- * We guarantee that the time will be greater than the value obtained by a
- * previous call.
- */
-void
-microtime(tvp)
- register struct timeval *tvp;
-{
- static struct timeval lasttime;
- int s = splclock();
-
- *tvp = time;
-
- tvp->tv_usec += (*platform.clkread)();
-
- while (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);
-}
-
int
initcpu()
{
@@ -615,19 +579,6 @@ caddr_t first;
panic("sysconf.init didn't set memsize");
}
-static unsigned
-unimpl_clkread()
-{
- return 0; /* No microtime available */
-}
-
-static void
-unimpl_todr(dt)
- struct clock_ymdhms *dt;
-{
- panic("sysconf.init didn't init TOD");
-}
-
void
unimpl_intr_establish(level, func, arg)
int level;
Index: sys/arch/mipsco/obio/mkclock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mipsco/obio/mkclock.c,v
retrieving revision 1.6
diff -d -p -u -r1.6 mkclock.c
--- sys/arch/mipsco/obio/mkclock.c 11 Dec 2005 12:18:13 -0000 1.6
+++ sys/arch/mipsco/obio/mkclock.c 13 Sep 2006 22:01:18 -0000
@@ -58,6 +58,7 @@ struct mkclock_softc {
struct device dev;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
+ struct todr_chip_handle sc_todr;
};
static int mkclock_match (struct device *, struct cfdata *, void *);
@@ -66,10 +67,8 @@ static void mkclock_attach (struct devic
CFATTACH_DECL(mkclock, sizeof(struct mkclock_softc),
mkclock_match, mkclock_attach, NULL, NULL);
-static struct mkclock_softc *mk0;
-
-void mkclock_read (struct clock_ymdhms *);
-void mkclock_write (struct clock_ymdhms *);
+int mkclock_read (todr_chip_handle_t, struct clock_ymdhms *);
+int mkclock_write (todr_chip_handle_t, struct clock_ymdhms *);
static int mk_read (struct mkclock_softc *, int);
static void mk_write (struct mkclock_softc *, int, int);
@@ -100,9 +99,11 @@ mkclock_attach(parent, self, aux)
return;
}
- platform.write_todr = mkclock_write;
- platform.read_todr = mkclock_read;
- mk0 = sc;
+ sc->sc_todr.todr_settime_ymdhms = mkclock_write;
+ sc->sc_todr.todr_gettime_ymdhms = mkclock_read;
+ sc->sc_todr.cookie = sc;
+ todr_attach(&sc->sc_todr);
+
printf("\n");
}
@@ -126,11 +127,10 @@ mk_write(sc, reg, val)
DATA_PORT + reg*4, TOBCD(val));
}
-void
-mkclock_read(dt)
- struct clock_ymdhms *dt;
+int
+mkclock_read(todr_chip_handle_t tch, struct clock_ymdhms *dt)
{
- struct mkclock_softc *sc = mk0;
+ struct mkclock_softc *sc = tch->cookie;
int s = splclock();
bus_space_write_1(sc->sc_bst, sc->sc_bsh, RTC_PORT, READ_CLOCK);
@@ -145,13 +145,13 @@ mkclock_read(dt)
splx(s);
dt->dt_year = dt->dt_year + (dt->dt_year >= 70 ? 1900 : 2000);
+ return 0;
}
-void
-mkclock_write(dt)
- struct clock_ymdhms *dt;
+int
+mkclock_write(todr_chip_handle_t tch, struct clock_ymdhms *dt)
{
- struct mkclock_softc *sc = mk0;
+ struct mkclock_softc *sc = tch->cookie;
int year, s;
year = dt->dt_year % 100;
@@ -167,4 +167,5 @@ mkclock_write(dt)
mk_write(sc, 6, year);
bus_space_write_1(sc->sc_bst, sc->sc_bsh, RTC_PORT, 0);
splx(s);
+ return 0;
}
Index: sys/arch/mipsco/obio/rambo.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mipsco/obio/rambo.c,v
retrieving revision 1.7
diff -d -p -u -r1.7 rambo.c
--- sys/arch/mipsco/obio/rambo.c 11 Dec 2005 12:18:13 -0000 1.7
+++ sys/arch/mipsco/obio/rambo.c 13 Sep 2006 22:01:19 -0000
@@ -43,6 +43,7 @@ __KERNEL_RCSID(0, "$NetBSD: rambo.c,v 1.
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/systm.h>
+#include <sys/timetc.h>
#include <machine/cpu.h>
#include <machine/mainboard.h>
@@ -58,8 +59,9 @@ __KERNEL_RCSID(0, "$NetBSD: rambo.c,v 1.
static int rambo_match __P((struct device *, struct cfdata *, void *));
static void rambo_attach __P((struct device *, struct device *, void *));
-static unsigned rambo_clkread __P((void));
+static unsigned rambo_get_timecount(struct timecounter *);
void rambo_clkintr __P((struct clockframe *));
+static void rambo_tc_init(void);
struct rambo_softc {
struct device dev;
@@ -115,7 +117,7 @@ rambo_attach(parent, self, aux)
printf(": parity enabled\n");
rambo = sc;
- platform.clkread = rambo_clkread;
+ platform.clkinit = rambo_tc_init;
}
void
@@ -161,10 +163,22 @@ rambo_clkintr(cf)
* Calculate the number of microseconds since the last clock tick
*/
static unsigned
-rambo_clkread()
+rambo_get_timecount(struct timecounter *tc)
{
- register u_int32_t tcount;
-
- tcount = bus_space_read_4(rambo->sc_bst, rambo->sc_bsh, RB_TCOUNT);
- return TICKS_TO_USECS(tcount - rambo->sc_tclast);
+
+ return (bus_space_read_4(rambo->sc_bst, rambo->sc_bsh, RB_TCOUNT));
+}
+
+static void
+rambo_tc_init(void)
+{
+ static struct timecounter tc = {
+ .tc_get_timecount = rambo_get_timecount,
+ .tc_frequency = RB_FREQUENCY,
+ .tc_quality = 100,
+ .tc_name = "rambo_tcount",
+ .tc_counter_mask = ~0
+ };
+
+ tc_init(&tc);
}
Index: sys/arch/mipsco/obio/rambo.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mipsco/obio/rambo.h,v
retrieving revision 1.4
diff -d -p -u -r1.4 rambo.h
--- sys/arch/mipsco/obio/rambo.h 16 Sep 2001 16:34:33 -0000 1.4
+++ sys/arch/mipsco/obio/rambo.h 13 Sep 2006 22:01:19 -0000
@@ -116,6 +116,7 @@ struct rambo_ch {
#define RB_BOUNDRY (1<<RB_BSIZE)
/* Rambo cycle counter is fed by 25MHz clock then divided by 4 */
-#define HZ_TO_TICKS(hz) (6250000L/(hz))
+#define RB_FREQUENCY 625000L
+#define HZ_TO_TICKS(hz) (RB_FREQUENCY/(hz))
#define TICKS_TO_USECS(t) (((t)*4)/25)
#endif
--------------090701000303070101050507--