Basic prep timecounter support. This greatly increases the stability of

ntp on my 7248, however, my 7043-140 is still a bit flaky.  I suspect the
only way to fix the 7043 is going to be writing a timecounter driver for
the 8254 present on these machines.  Either way, this makes some of the
machines better, and the other machines are still about the same as they
were before, so it's a net gain for the port.
This commit is contained in:
garbled 2006-06-20 05:49:09 +00:00
parent 67dcc592dc
commit 1efe96e909
3 changed files with 61 additions and 33 deletions

View File

@ -1,7 +1,8 @@
/* $NetBSD: types.h,v 1.6 2006/05/03 17:47:06 garbled Exp $ */
/* $NetBSD: types.h,v 1.7 2006/06/20 05:49:09 garbled Exp $ */
#define __HAVE_NWSCONS
#define __HAVE_DEVICE_REGISTER
#define __HAVE_GENERIC_SOFT_INTERRUPTS
#define __HAVE_TIMECOUNTER
#include <powerpc/types.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: clock.c,v 1.16 2006/05/09 03:13:00 garbled Exp $ */
/* $NetBSD: clock.c,v 1.17 2006/06/20 05:49:09 garbled Exp $ */
/* $OpenBSD: clock.c,v 1.3 1997/10/13 13:42:53 pefo Exp $ */
/*
@ -33,12 +33,13 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.16 2006/05/09 03:13:00 garbled Exp $");
__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.17 2006/06/20 05:49:09 garbled Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/timetc.h>
#include <uvm/uvm_extern.h>
@ -49,6 +50,8 @@ __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.16 2006/05/09 03:13:00 garbled Exp $");
#define MINYEAR 1990
void decr_intr(struct clockframe *);
void init_prep_tc(void);
static u_int get_prep_timecount(struct timecounter *);
u_long ticks_per_sec;
u_long ns_per_tick;
@ -59,6 +62,15 @@ const struct clockfns *clockfns;
static todr_chip_handle_t todr_handle;
static struct timecounter prep_timecounter = {
get_prep_timecount, /* get_timecount */
0, /* no poll_pps */
0x7fffffff, /* counter_mask */
0, /* frequency */
"prep_mftb", /* name */
0 /* quality */
};
void
todr_attach(todr_chip_handle_t handle)
{
@ -85,6 +97,7 @@ cpu_initclocks(void)
else
__asm volatile ("mftb %0" : "=r"(ci->ci_lasttb));
__asm volatile ("mtdec %0" :: "r"(ticks_per_intr));
init_prep_tc();
}
/*
@ -95,9 +108,13 @@ void
inittodr(time_t base)
{
int badbase, waszero;
struct timeval time;
struct timespec ts;
badbase = 0;
waszero = (base == 0);
time.tv_sec = 0;
time.tv_usec = 0;
if (base < (MINYEAR - 1970) * SECYR) {
if (base != 0)
@ -114,7 +131,10 @@ inittodr(time_t base)
* Believe the time in the file system for lack of
* anything better, resetting the clock.
*/
time.tv_sec = base;
ts.tv_sec = base;
ts.tv_nsec = 0;
tc_setclock(&ts);
if (!badbase)
resettodr();
} else {
@ -123,10 +143,16 @@ inittodr(time_t base)
* if so, assume something is amiss.
*/
int deltat = time.tv_sec - base;
ts.tv_sec = time.tv_sec;
ts.tv_nsec = time.tv_usec * 1000;
tc_setclock(&ts);
if (deltat < 0)
deltat = -deltat;
if (waszero || deltat < 2 * SECDAY)
return;
printf("WARNING: clock %s %d days",
time.tv_sec < base ? "lost" : "gained", deltat / SECDAY);
}
@ -143,6 +169,9 @@ inittodr(time_t base)
void
resettodr(void)
{
struct timeval time;
getmicrotime(&time);
if (time.tv_sec == 0)
return;
@ -228,33 +257,6 @@ decr_intr(struct clockframe *frame)
splx(pri);
}
/*
* Fill in *tvp with current time with microsecond resolution.
*/
void
microtime(struct timeval *tvp)
{
u_long tb;
u_long ticks;
int msr, scratch;
__asm volatile ("mfmsr %0; andi. %1,%0,%2; mtmsr %1"
: "=r"(msr), "=r"(scratch) : "K"((u_short)~PSL_EE));
if ((mfpvr() >> 16) == MPC601)
__asm volatile ("mfspr %0,%1" : "=r"(tb) : "n"(SPR_RTCL_R));
else
__asm volatile ("mftb %0" : "=r"(tb));
ticks = (tb - curcpu()->ci_lasttb) * ns_per_tick;
*tvp = time;
mtmsr(msr);
ticks /= 1000;
tvp->tv_usec += ticks;
while (tvp->tv_usec >= 1000000) {
tvp->tv_usec -= 1000000;
tvp->tv_sec++;
}
}
/*
* Wait for about n microseconds (at least!).
*/
@ -293,3 +295,28 @@ delay(unsigned int n)
: "cr0");
}
}
static u_int
get_prep_timecount(struct timecounter *tc)
{
u_long tb;
int msr, scratch;
__asm volatile ("mfmsr %0; andi. %1,%0,%2; mtmsr %1"
: "=r"(msr), "=r"(scratch) : "K"((u_short)~PSL_EE));
if ((mfpvr() >> 16) == MPC601)
__asm volatile ("mfspr %0,%1" : "=r"(tb) : "n"(SPR_RTCL_R));
else
__asm volatile ("mftb %0" : "=r"(tb));
mtmsr(msr);
return tb;
}
void
init_prep_tc()
{
/* from machdep initialization */
prep_timecounter.tc_frequency = ticks_per_sec;
tc_init(&prep_timecounter);
}

View File

@ -1,6 +1,6 @@
/* $NetBSD: boot.h,v 1.7 2006/04/13 18:46:46 garbled Exp $ */
/* $NetBSD: boot.h,v 1.8 2006/06/20 05:49:09 garbled Exp $ */
#define TICKS_PER_SEC (33000000 / 4) /* 33MHz */
#define TICKS_PER_SEC (66666667 / 4) /* 66MHz */
#define NS_PER_TICK (1000000000 / TICKS_PER_SEC)
/*