Subject: timecounters and todr for hpcmips
To: None <port-hpcmips@NetBSD.org>
From: Garrett D'Amore <garrett_damore@tadpole.com>
List: port-hpcmips
Date: 09/13/2006 12:48:42
This is a multi-part message in MIME format.
--------------070809010906060003050600
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Attached find a patch which converts the hpcmips port to timecounters
and todr. I've not tested it, so I'm looking for people to do so. (It
does build, at least.)
The following things are noteworthy:
1) tx39 systems do not appear to have a battery backed clock (or at
least the old code didn't assume one), so they will not see the standard
warning about "no TOD clock present", and will use the filesystem time
(which they always did before).
2) tx39 systems get a 32kHz timecounter, hopefully giving a much
better estimate for microtime(). The tc is called "tx39rtc", and is
based of the 32kHz RTC.
3) vrXX systems have an RTC, but appear to have used weird rules for
it -- e.g. an EPOCH starting in 1850. I've rewritten most of that code
to be simpler, but I'd REALLY appreciate if folks could test. One side
benefit of these changes is that the RTC will be retrieved and updated
with 1/32 sec accuracy. (The old code was pretty hairy.) Note that the
epoch base for some systems (LROUTER as an example) is 1/1/1970, whereas
for others it is 1/1/1850 (Windows CE legacy, I guess).
4) vrXX get a 32kHz timecounter as well, called "vrrtc", also based
of the 32kHz RTC.
Again, please test it. src/regress/sys/kern/time is an excellent test.
So is date; /usr/bin/time sleep 10; date.
To test TODR, make sure the system gets a good time-of-day on boot, and
that it is retained properly across a reboot. (Ideally without NTP
correction.)
Thanks again!
--
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
--------------070809010906060003050600
Content-Type: text/x-patch;
name="hpcmips.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="hpcmips.diff"
Index: sys/arch/hpcmips/conf/LROUTER
===================================================================
RCS file: /cvsroot/src/sys/arch/hpcmips/conf/LROUTER,v
retrieving revision 1.34
diff -d -p -u -r1.34 LROUTER
--- sys/arch/hpcmips/conf/LROUTER 26 Aug 2006 20:26:45 -0000 1.34
+++ sys/arch/hpcmips/conf/LROUTER 13 Sep 2006 19:48:33 -0000
@@ -39,7 +39,6 @@ options USERCONF # userconf(4) support
#options SCSIVERBOSE # human readable SCSI error messages
-options YBASE=2000
options EPOCHYEAR=1970
#options RTC_OFFSET=0 # hardware clock is this many mins. west of GMT
Index: sys/arch/hpcmips/conf/std.lcard
===================================================================
RCS file: /cvsroot/src/sys/arch/hpcmips/conf/std.lcard,v
retrieving revision 1.6
diff -d -p -u -r1.6 std.lcard
--- sys/arch/hpcmips/conf/std.lcard 11 Dec 2005 12:17:33 -0000 1.6
+++ sys/arch/hpcmips/conf/std.lcard 13 Sep 2006 19:48:33 -0000
@@ -17,7 +17,6 @@ options NO_SYMBOLSZ_ENTRY
options VR4181 # NEC VR4181
-options YBASE=2000
options EPOCHYEAR=1970
mainbus0 at root
Index: sys/arch/hpcmips/hpcmips/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hpcmips/hpcmips/clock.c,v
retrieving revision 1.18
diff -d -p -u -r1.18 clock.c
--- sys/arch/hpcmips/hpcmips/clock.c 11 Dec 2005 12:17:33 -0000 1.18
+++ sys/arch/hpcmips/hpcmips/clock.c 13 Sep 2006 19:48:33 -0000
@@ -115,9 +115,6 @@ __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.
#include <dev/clock_subr.h>
#include <machine/sysconf.h> /* platform */
-#define MINYEAR 2002 /* "today" */
-#define UNIX_YEAR_OFFSET 0
-
/*
* platform_clock_attach:
*
@@ -150,15 +147,6 @@ cpu_initclocks()
hz = clock->hz;
tick = 1000000 / hz;
- /* number of microseconds between interrupts */
- tickfix = 1000000 - (hz * tick);
- if (tickfix) {
- int ftp;
-
- ftp = min(ffs(tickfix), ffs(hz));
- tickfix >>= (ftp - 1);
- tickfixinterval = hz >> (ftp - 1);
- }
/* start periodic timer */
(*clock->init)(clock->self);
@@ -179,152 +167,6 @@ setstatclockrate(int newhz)
}
/*
- * 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.
- *
- * 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(time_t base)
-{
- struct platform_clock *clock = platform.clock;
- struct clock_ymdhms dt;
- int year, badbase;
- time_t deltat;
-
- if (clock == NULL)
- panic("inittodr: no clock attached");
-
- 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;
-
- (*clock->rtc_get)(clock->self, base, &dt);
-#ifdef DEBUG
- printf("readclock: %d/%d/%d/%d/%d/%d", dt.dt_year, dt.dt_mon, dt.dt_day,
- dt.dt_hour, dt.dt_min, dt.dt_sec);
-#endif
- clock->start = 1;
-
- year = 1900 + UNIX_YEAR_OFFSET + dt.dt_year;
- if (year < 1970)
- year += 100;
- /* simple sanity checks (2037 = time_t overflow) */
- if (year < MINYEAR || year > 2037 ||
- 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) {
- /*
- * 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;
- time.tv_sec = clock_ymdhms_to_secs(&dt);
-#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 %ld days",
- time.tv_sec < base ? "lost" : "gained",
- (long)deltat / SECDAY);
- }
- bad:
- printf(" -- CHECK AND RESET THE DATE!\n");
-}
-
-/*
- * resettodr:
- *
- * restores the time of day hardware after a time change.
- *
- * 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 platform_clock *clock = platform.clock;
- struct clock_ymdhms dt;
-
- if (clock == NULL)
- panic("inittodr: no clock attached");
-
- if (!clock->start)
- return;
-
- clock_secs_to_ymdhms(time.tv_sec, &dt);
-
- /* rt clock wants 2 digits XXX */
- dt.dt_year = (dt.dt_year - UNIX_YEAR_OFFSET) % 100;
-#ifdef DEBUG
- printf("setclock: %d/%d/%d/%d/%d/%d\n", dt.dt_year, dt.dt_mon,
- dt.dt_day, dt.dt_hour, dt.dt_min, dt.dt_sec);
-#endif
-
- (*clock->rtc_set)(clock->self, &dt);
-}
-
-/*
- * microtime:
- *
- * 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.
- */
-void
-microtime(struct timeval *tvp)
-{
- int s = splclock();
- static struct timeval lasttime;
-
- *tvp = time;
-
- 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);
-}
-
-/*
* delay:
*
* Wait at least "n" microseconds.
Index: sys/arch/hpcmips/include/sysconf.h
===================================================================
RCS file: /cvsroot/src/sys/arch/hpcmips/include/sysconf.h,v
retrieving revision 1.11
diff -d -p -u -r1.11 sysconf.h
--- sys/arch/hpcmips/include/sysconf.h 23 Sep 2001 14:32:52 -0000 1.11
+++ sys/arch/hpcmips/include/sysconf.h 13 Sep 2006 19:48:33 -0000
@@ -74,8 +74,6 @@ extern struct platform {
struct platform_clock {
int hz;
void (*init)(struct device *);
- void (*rtc_get)(struct device *, time_t, struct clock_ymdhms *);
- void (*rtc_set)(struct device *, struct clock_ymdhms *);
void *self;
int start;
};
Index: sys/arch/hpcmips/include/types.h
===================================================================
RCS file: /cvsroot/src/sys/arch/hpcmips/include/types.h,v
retrieving revision 1.5
diff -d -p -u -r1.5 types.h
--- sys/arch/hpcmips/include/types.h 23 Mar 2002 03:14:54 -0000 1.5
+++ sys/arch/hpcmips/include/types.h 13 Sep 2006 19:48:33 -0000
@@ -4,3 +4,5 @@
#define __HAVE_GENERIC_SOFT_INTERRUPTS
#define __HAVE_OLD_DISKLABEL
+#define __HAVE_GENERIC_TODR
+#define __HAVE_TIMECOUNTER
Index: sys/arch/hpcmips/tx/tx39clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hpcmips/tx/tx39clock.c,v
retrieving revision 1.20
diff -d -p -u -r1.20 tx39clock.c
--- sys/arch/hpcmips/tx/tx39clock.c 16 Jun 2006 00:08:28 -0000 1.20
+++ sys/arch/hpcmips/tx/tx39clock.c 13 Sep 2006 19:48:34 -0000
@@ -43,6 +43,7 @@ __KERNEL_RCSID(0, "$NetBSD: tx39clock.c,
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/timetc.h>
#include <dev/clock_subr.h>
@@ -65,12 +66,10 @@ __KERNEL_RCSID(0, "$NetBSD: tx39clock.c,
dbg_bitmask_print(r, TX39_CLOCK_EN ## m ## CLK, #m)
void tx39clock_init(struct device *);
-void tx39clock_get(struct device *, time_t, struct clock_ymdhms *);
-void tx39clock_set(struct device *, struct clock_ymdhms *);
struct platform_clock tx39_clock = {
#define CLOCK_RATE 100
- CLOCK_RATE, tx39clock_init, tx39clock_get, tx39clock_set,
+ CLOCK_RATE, tx39clock_init,
};
struct txtime {
@@ -86,6 +85,7 @@ struct tx39clock_softc {
int sc_enabled;
int sc_year;
struct clock_ymdhms sc_epoch;
+ struct timecounter sc_tcounter;
};
int tx39clock_match(struct device *, struct cfdata *, void *);
@@ -100,6 +100,7 @@ void __tx39timer_rtcfreeze(tx_chipset_ta
void __tx39timer_rtcreset(tx_chipset_tag_t);
inline void __tx39timer_rtcget(struct txtime *);
inline time_t __tx39timer_rtc2sec(struct txtime *);
+uint32_t tx39_timecount(struct timecounter *);
CFATTACH_DECL(tx39clock, sizeof(struct tx39clock_softc),
tx39clock_match, tx39clock_attach, NULL, NULL);
@@ -195,13 +196,6 @@ __tx39timer_rtcfreeze(tx_chipset_tag_t t
tx_conf_write(tc, TX39_TIMERCONTROL_REG, reg);
}
-inline time_t
-__tx39timer_rtc2sec(struct txtime *t)
-{
- /* This rely on RTC is 32.768kHz */
- return ((t->t_lo >> 15) | (t->t_hi << 17));
-}
-
inline void
__tx39timer_rtcget(struct txtime *t)
{
@@ -245,6 +239,20 @@ __tx39timer_rtcreset(tx_chipset_tag_t tc
tx_conf_write(tc, TX39_TIMERCONTROL_REG, reg);
}
+uint32_t
+tx39_timecount(struct timecounter *tch)
+{
+ tx_chipset_tag_t tc = tch->tc_priv;
+
+ /*
+ * since we're only reading the low register, we don't care about
+ * if the chip increments it. we assume that the single read will
+ * always be consistent. This is much faster than the routine which
+ * has to get both values, improving the quality.
+ */
+ return (tx_conf_read(tc, TX39_TIMERRTCLO_REG));
+}
+
void
tx39clock_init(struct device *dev)
{
@@ -268,61 +276,14 @@ tx39clock_init(struct device *dev)
reg = tx_conf_read(tc, TX39_INTRENABLE6_REG);
reg |= TX39_INTRPRI13_TIMER_PERIODIC_BIT;
tx_conf_write(tc, TX39_INTRENABLE6_REG, reg);
-}
-
-void
-tx39clock_get(struct device *dev, time_t base, struct clock_ymdhms *t)
-{
- struct tx39clock_softc *sc = (void *)dev;
- struct clock_ymdhms dt;
- struct txtime tt;
- time_t sec;
-
- __tx39timer_rtcget(&tt);
- sec = __tx39timer_rtc2sec(&tt);
- if (!sc->sc_enabled) {
- DPRINTF(("bootstrap: %d sec from previous reboot\n",
- (int)sec));
-
- sc->sc_enabled = 1;
- clock_secs_to_ymdhms(base, &dt);
- sc->sc_epoch = dt;
- base += sec;
- } else {
- dt.dt_year = sc->sc_year;
- dt.dt_mon = sc->sc_epoch.dt_mon;
- dt.dt_day = sc->sc_epoch.dt_day;
- dt.dt_hour = sc->sc_epoch.dt_hour;
- dt.dt_min = sc->sc_epoch.dt_min;
- dt.dt_sec = sc->sc_epoch.dt_sec;
- dt.dt_wday = sc->sc_epoch.dt_wday;
- base = sec + clock_ymdhms_to_secs(&dt);
- }
-
- clock_secs_to_ymdhms(base, &dt);
-
- t->dt_year = dt.dt_year % 100;
- t->dt_mon = dt.dt_mon;
- t->dt_day = dt.dt_day;
- t->dt_hour = dt.dt_hour;
- t->dt_min = dt.dt_min;
- t->dt_sec = dt.dt_sec;
- t->dt_wday = dt.dt_wday;
-
- sc->sc_year = dt.dt_year;
-}
-
-void
-tx39clock_set(struct device *dev, struct clock_ymdhms *dt)
-{
- struct tx39clock_softc *sc = (void *)dev;
-
- if (sc->sc_enabled) {
- sc->sc_epoch = *dt;
- __tx39timer_rtcreset(sc->sc_tc);
- tx39clock_alarm_refill(sc->sc_tc);
- }
+ sc->sc_tcounter.tc_name = "tx39rtc";
+ sc->sc_tcounter.tc_get_timecount = tx39_timecount;
+ sc->sc_tcounter.tc_priv = tc;
+ sc->sc_tcounter.tc_counter_mask = 0xffffffff;
+ sc->sc_tcounter.tc_frequency = TX39_RTCLOCK;
+ sc->sc_tcounter.tc_quality = 100;
+ tc_init(&sc->sc_tcounter);
}
int
Index: sys/arch/hpcmips/vr/rtc.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hpcmips/vr/rtc.c,v
retrieving revision 1.23
diff -d -p -u -r1.23 rtc.c
--- sys/arch/hpcmips/vr/rtc.c 24 Dec 2005 23:24:00 -0000 1.23
+++ sys/arch/hpcmips/vr/rtc.c 13 Sep 2006 19:48:34 -0000
@@ -42,6 +42,7 @@ __KERNEL_RCSID(0, "$NetBSD: rtc.c,v 1.23
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/timetc.h>
#include <machine/sysconf.h>
#include <machine/bus.h>
@@ -80,15 +81,19 @@ struct vrrtc_softc {
int sc_tclk_h_reg, sc_tclk_l_reg;
int sc_tclk_cnt_h_reg, sc_tclk_cnt_l_reg;
#endif /* SINGLE_VRIP_BASE */
+ int64_t sc_epoch;
+ struct todr_chip_handle sc_todr;
+ struct timecounter sc_tc;
};
-void clock_init(struct device *);
-void clock_get(struct device *, time_t, struct clock_ymdhms *);
-void clock_set(struct device *, struct clock_ymdhms *);
+void vrrtc_init(struct device *);
+int vrrtc_get(todr_chip_handle_t, volatile struct timeval *);
+int vrrtc_set(todr_chip_handle_t, volatile struct timeval *);
+uint32_t vrrtc_get_timecount(struct timecounter *);
struct platform_clock vr_clock = {
#define CLOCK_RATE 128
- CLOCK_RATE, clock_init, clock_get, clock_set,
+ CLOCK_RATE, vrrtc_init,
};
int vrrtc_match(struct device *, struct cfdata *, void *);
@@ -99,27 +104,6 @@ void vrrtc_dump_regs(struct vrrtc_softc
CFATTACH_DECL(vrrtc, sizeof(struct vrrtc_softc),
vrrtc_match, vrrtc_attach, NULL, NULL);
-static inline void vrrtc_write(struct vrrtc_softc *, int, u_int16_t);
-static inline u_int16_t vrrtc_read(struct vrrtc_softc *, int);
-void cvt_timehl_ymdhms(u_int32_t, u_int32_t, struct clock_ymdhms *);
-
-extern int rtc_offset;
-static int m2d[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-
-static inline void
-vrrtc_write(struct vrrtc_softc *sc, int port, u_int16_t val)
-{
-
- bus_space_write_2(sc->sc_iot, sc->sc_ioh, port, val);
-}
-
-static inline u_int16_t
-vrrtc_read(struct vrrtc_softc *sc, int port)
-{
-
- return (bus_space_read_2(sc->sc_iot, sc->sc_ioh, port));
-}
-
int
vrrtc_match(struct device *parent, struct cfdata *cf, void *aux)
{
@@ -140,6 +124,7 @@ vrrtc_attach(struct device *parent, stru
{
struct vrip_attach_args *va = aux;
struct vrrtc_softc *sc = (void *)self;
+ int year;
#ifndef SINGLE_VRIP_BASE
if (va->va_addr == VR4102_RTC_ADDR) {
@@ -212,6 +197,26 @@ vrrtc_attach(struct device *parent, stru
*/
bus_space_write_2(sc->sc_iot, sc->sc_ioh, RTCINT_REG_W, RTCINT_ALL);
+ /*
+ * Figure out the epoch, which could be either forward or
+ * backwards in time. We assume that the start date will always
+ * be on Jan 1.
+ */
+ for (year = EPOCHYEAR; year < POSIX_BASE_YEAR; year++) {
+ sc->sc_epoch += LEAPYEAR4(year) ? SECYR + SECDAY : SECYR;
+ }
+ for (year = POSIX_BASE_YEAR; year < EPOCHYEAR; year++) {
+ sc->sc_epoch -= LEAPYEAR4(year) ? SECYR + SECDAY : SECYR;
+ }
+
+ /*
+ * Initialize MI todr(9)
+ */
+ sc->sc_todr.todr_settime = vrrtc_set;
+ sc->sc_todr.todr_gettime = vrrtc_get;
+ sc->sc_todr.cookie = sc;
+ todr_attach(&sc->sc_todr);
+
platform_clock_attach(sc, &vr_clock);
}
@@ -230,7 +235,7 @@ vrrtc_intr(void *arg, u_int32_t pc, u_in
}
void
-clock_init(struct device *dev)
+vrrtc_init(struct device *dev)
{
struct vrrtc_softc *sc = (struct vrrtc_softc *)dev;
@@ -241,17 +246,39 @@ clock_init(struct device *dev)
bus_space_write_2(sc->sc_iot, sc->sc_ioh, RTCL1_H_REG_W, 0);
bus_space_write_2(sc->sc_iot, sc->sc_ioh, RTCL1_L_REG_W,
RTCL1_L_HZ/CLOCK_RATE);
+
+ /*
+ * Initialize timecounter.
+ */
+ sc->sc_tc.tc_get_timecount = vrrtc_get_timecount;
+ sc->sc_tc.tc_name = "vrrtc";
+ sc->sc_tc.tc_counter_mask = 0xffff;
+ sc->sc_tc.tc_frequency = ETIME_L_HZ;
+ sc->sc_tc.tc_priv = sc;
+ sc->sc_tc.tc_quality = 100;
+ tc_init(&sc->sc_tc);
}
-void
-clock_get(struct device *dev, time_t base, struct clock_ymdhms *dt)
+uint32_t
+vrrtc_get_timecount(struct timecounter *tc)
{
+ struct vrrtc_softc *sc = (struct vrrtc_softc *)tc->tc_priv;
+ bus_space_tag_t iot = sc->sc_iot;
+ bus_space_handle_t ioh = sc->sc_ioh;
- struct vrrtc_softc *sc = (struct vrrtc_softc *)dev;
+ return (bus_space_read_2(iot, ioh, ETIME_L_REG_W));
+}
+
+int
+vrrtc_get(todr_chip_handle_t tch, volatile struct timeval *tvp)
+{
+
+ struct vrrtc_softc *sc = (struct vrrtc_softc *)tch->cookie;
bus_space_tag_t iot = sc->sc_iot;
bus_space_handle_t ioh = sc->sc_ioh;
u_int32_t timeh; /* elapse time (2*timeh sec) */
u_int32_t timel; /* timel/32768 sec */
+ int64_t sec, usec;
timeh = bus_space_read_2(iot, ioh, ETIME_H_REG_W);
timeh = (timeh << 16) | bus_space_read_2(iot, ioh, ETIME_M_REG_W);
@@ -259,135 +286,47 @@ clock_get(struct device *dev, time_t bas
DPRINTF(("clock_get: timeh %08x timel %08x\n", timeh, timel));
- cvt_timehl_ymdhms(timeh, timel, dt);
+ timeh -= EPOCHOFF;
+ sec = timeh * 2;
+ sec -= sc->sc_epoch;
+ tvp->tv_sec = sec;
+ tvp->tv_sec += timel / ETIME_L_HZ;
- DPRINTF(("clock_get: %d/%d/%d/%d/%d/%d\n", dt->dt_year, dt->dt_mon,
- dt->dt_day, dt->dt_hour, dt->dt_min, dt->dt_sec));
+ /* scale from 32kHz to 1MHz */
+ usec = (timel % ETIME_L_HZ);
+ usec *= 1000000;
+ usec /= ETIME_L_HZ;
+ tvp->tv_usec = (uint32_t)usec;
+
+ return 0;
}
-void
-clock_set(struct device *dev, struct clock_ymdhms *dt)
+int
+vrrtc_set(todr_chip_handle_t tch, volatile struct timeval *tvp)
{
- struct vrrtc_softc *sc = (struct vrrtc_softc *)dev;
+ struct vrrtc_softc *sc = (struct vrrtc_softc *)tch->cookie;
bus_space_tag_t iot = sc->sc_iot;
bus_space_handle_t ioh = sc->sc_ioh;
u_int32_t timeh; /* elapse time (2*timeh sec) */
u_int32_t timel; /* timel/32768 sec */
- int year, month, sec2;
-
- timeh = 0;
- timel = 0;
-
- DPRINTF(("clock_set: %d/%d/%d/%d/%d/%d\n", dt->dt_year, dt->dt_mon,
- dt->dt_day, dt->dt_hour, dt->dt_min, dt->dt_sec));
-
- dt->dt_year += YBASE;
-
- DPRINTF(("clock_set: %d/%d/%d/%d/%d/%d\n", dt->dt_year, dt->dt_mon,
- dt->dt_day, dt->dt_hour, dt->dt_min, dt->dt_sec));
-
- year = EPOCHYEAR;
- sec2 = LEAPYEAR4(year)?SEC2YR+SEC2DAY:SEC2YR;
- while (year < dt->dt_year) {
- year++;
- timeh += sec2;
- sec2 = LEAPYEAR4(year)?SEC2YR+SEC2DAY:SEC2YR;
- }
- month = 1; /* now month is 1..12 */
- sec2 = SEC2DAY * m2d[month-1];
- while (month < dt->dt_mon) {
- month++;
- timeh += sec2;
- sec2 = SEC2DAY * m2d[month-1];
- if (month == 2 && LEAPYEAR4(year)) /* feb. and leapyear */
- sec2 += SEC2DAY;
- }
-
- timeh += (dt->dt_day - 1)*SEC2DAY;
-
- timeh += dt->dt_hour*SEC2HOUR;
-
- timeh += dt->dt_min*SEC2MIN;
-
- timeh += dt->dt_sec/2;
- timel += (dt->dt_sec%2)*ETIME_L_HZ;
+ int64_t sec, cnt;
- timeh += EPOCHOFF;
- timeh -= (rtc_offset*SEC2MIN);
+ sec = tvp->tv_sec + sc->sc_epoch;
+ sec += sc->sc_epoch;
+ timeh = EPOCHOFF + (sec / 2);
+ timel = sec % 2;
-#ifdef VRRTCDEBUG
- cvt_timehl_ymdhms(timeh, timel, NULL);
-#endif /* RTCDEBUG */
+ cnt = tvp->tv_usec;
+ /* scale from 1MHz to 32kHz */
+ cnt *= ETIME_L_HZ;
+ cnt /= 1000000;
+ timel += (uint32_t)cnt;
bus_space_write_2(iot, ioh, ETIME_H_REG_W, (timeh >> 16) & 0xffff);
bus_space_write_2(iot, ioh, ETIME_M_REG_W, timeh & 0xffff);
bus_space_write_2(iot, ioh, ETIME_L_REG_W, timel);
-}
-
-void
-cvt_timehl_ymdhms(
- u_int32_t timeh, /* 2 sec */
- u_int32_t timel, /* 1/32768 sec */
- struct clock_ymdhms *dt)
-{
- u_int32_t year, month, date, hour, mins, sec, sec2;
-
- timeh -= EPOCHOFF;
-
- timeh += (rtc_offset*SEC2MIN);
-
- year = EPOCHYEAR;
- sec2 = LEAPYEAR4(year)?SEC2YR+SEC2DAY:SEC2YR;
- while (timeh > sec2) {
- year++;
- timeh -= sec2;
- sec2 = LEAPYEAR4(year)?SEC2YR+SEC2DAY:SEC2YR;
- }
-
- DPRINTF(("cvt_timehl_ymdhms: timeh %08x year %d yrref %d\n",
- timeh, year, sec2));
-
- month = 0; /* now month is 0..11 */
- sec2 = SEC2DAY * m2d[month];
- while (timeh > sec2) {
- timeh -= sec2;
- month++;
- sec2 = SEC2DAY * m2d[month];
- if (month == 1 && LEAPYEAR4(year)) /* feb. and leapyear */
- sec2 += SEC2DAY;
- }
- month +=1; /* now month is 1..12 */
-
- DPRINTF(("cvt_timehl_ymdhms: timeh %08x month %d mref %d\n",
- timeh, month, sec2));
- sec2 = SEC2DAY;
- date = timeh/sec2+1; /* date is 1..31 */
- timeh -= (date-1)*sec2;
-
- DPRINTF(("cvt_timehl_ymdhms: timeh %08x date %d dref %d\n",
- timeh, date, sec2));
-
- sec2 = SEC2HOUR;
- hour = timeh/sec2;
- timeh -= hour*sec2;
-
- sec2 = SEC2MIN;
- mins = timeh/sec2;
- timeh -= mins*sec2;
-
- sec = timeh*2 + timel/ETIME_L_HZ;
-
- DPRINTF(("cvt_timehl_ymdhms: hour %d min %d sec %d\n", hour, mins, sec));
-
- if (dt) {
- dt->dt_year = year - YBASE; /* base 1900 */
- dt->dt_mon = month;
- dt->dt_day = date;
- dt->dt_hour = hour;
- dt->dt_min = mins;
- dt->dt_sec = sec;
- }
+ return 0;
}
void
Index: sys/arch/hpcmips/vr/rtcreg.h
===================================================================
RCS file: /cvsroot/src/sys/arch/hpcmips/vr/rtcreg.h,v
retrieving revision 1.8
diff -d -p -u -r1.8 rtcreg.h
--- sys/arch/hpcmips/vr/rtcreg.h 10 Feb 2002 14:36:52 -0000 1.8
+++ sys/arch/hpcmips/vr/rtcreg.h 13 Sep 2006 19:48:34 -0000
@@ -35,22 +35,6 @@
*
*/
-#define SECMIN ((unsigned)60) /* seconds per minute */
-#define SECHOUR ((unsigned)(60*SECMIN)) /* seconds per hour */
-
-#define SEC2MIN ((unsigned)60/2) /* 2seconds per minute */
-#define SEC2HOUR ((unsigned)(60*SECMIN)/2) /* 2seconds per hour */
-#define SEC2DAY ((unsigned)(24*SECHOUR)/2) /* 2seconds per day */
-#define SEC2YR ((unsigned)(365*SECDAY)/2) /* 2seconds per common year */
-
-#define YRREF 1999
-#define MREF 1
-#define DREF 1
-
-#ifndef YBASE
-#define YBASE 1900
-#endif
-
#define EPOCHOFF 0 /* epoch offset */
#ifndef EPOCHYEAR
#define EPOCHYEAR 1850 /* XXX */ /* WINCE epoch year */
--------------070809010906060003050600--