Timecounter and generic todr support for pmax. From Garret D'Amore.
This commit is contained in:
parent
26ecc8b33a
commit
28b31e738f
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mcclock_ibus.c,v 1.12 2002/10/02 04:15:09 thorpej Exp $ */
|
||||
/* $NetBSD: mcclock_ibus.c,v 1.13 2008/01/03 23:02:24 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
|
||||
@ -28,12 +28,13 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
__KERNEL_RCSID(0, "$NetBSD: mcclock_ibus.c,v 1.12 2002/10/02 04:15:09 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: mcclock_ibus.c,v 1.13 2008/01/03 23:02:24 joerg Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#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>
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sysconf.h,v 1.11 2007/03/04 06:00:33 christos Exp $ */
|
||||
/* $NetBSD: sysconf.h,v 1.12 2008/01/03 23:02:24 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
|
||||
@ -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((void *));
|
||||
unsigned (*clkread) __P((void));
|
||||
void (*tc_init)(void);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: types.h,v 1.23 2007/10/17 19:56:15 garbled Exp $ */
|
||||
/* $NetBSD: types.h,v 1.24 2008/01/03 23:02:24 joerg Exp $ */
|
||||
|
||||
#include <mips/types.h>
|
||||
|
||||
@ -7,3 +7,5 @@
|
||||
/* MIPS specific options */
|
||||
#define __HAVE_BOOTINFO_H
|
||||
#define __HAVE_MIPS_MACHDEP_CACHE_CONFIG
|
||||
#define __HAVE_GENERIC_TODR
|
||||
#define __HAVE_TIMECOUNTER
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: clock.c,v 1.34 2005/12/11 12:18:39 christos Exp $ */
|
||||
/* $NetBSD: clock.c,v 1.35 2008/01/03 23:02:24 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -78,7 +78,7 @@
|
||||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.34 2005/12/11 12:18:39 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.35 2008/01/03 23:02:24 joerg Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
@ -87,11 +87,10 @@ __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.34 2005/12/11 12:18:39 christos Exp $");
|
||||
#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);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dec_3maxplus.c,v 1.57 2007/12/03 15:34:10 ad Exp $ */
|
||||
/* $NetBSD: dec_3maxplus.c,v 1.58 2008/01/03 23:02:24 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Jonathan Stone. All rights reserved.
|
||||
@ -106,11 +106,12 @@
|
||||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: dec_3maxplus.c,v 1.57 2007/12/03 15:34:10 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: dec_3maxplus.c,v 1.58 2008/01/03 23:02:24 joerg Exp $");
|
||||
|
||||
#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 __P((struct device *, void *,
|
||||
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
|
||||
@ -173,8 +175,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;
|
||||
@ -337,7 +339,6 @@ dec_3maxplus_intr(status, cause, pc, ipending)
|
||||
|
||||
__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);
|
||||
@ -455,34 +456,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;
|
||||
|
||||
#ifdef CLOCK_DEBUG
|
||||
if (usec > 3906 +4) {
|
||||
addlog("clkread: usec %d, counter=%lx\n",
|
||||
usec, latched_cycle_cnt);
|
||||
stacktrace();
|
||||
return *(u_int32_t*)(ioasic_base + IOASIC_CTR);
|
||||
}
|
||||
#endif /*CLOCK_DEBUG*/
|
||||
|
||||
return usec;
|
||||
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",
|
||||
};
|
||||
|
||||
tc_init(&tc);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dec_3min.c,v 1.58 2007/12/03 15:34:10 ad Exp $ */
|
||||
/* $NetBSD: dec_3min.c,v 1.59 2008/01/03 23:02:25 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Jonathan Stone. All rights reserved.
|
||||
@ -106,11 +106,12 @@
|
||||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: dec_3min.c,v 1.58 2007/12/03 15:34:10 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: dec_3min.c,v 1.59 2008/01/03 23:02:25 joerg Exp $");
|
||||
|
||||
#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,18 +141,14 @@ static void dec_3min_intr_establish __P((struct device *, void *,
|
||||
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
|
||||
|
||||
static const int dec_3min_ipl2spl_table[] = {
|
||||
[IPL_NONE] = 0,
|
||||
[IPL_SOFTCLOCK] = _SPL_SOFTCLOCK,
|
||||
@ -176,7 +173,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;
|
||||
@ -409,11 +406,7 @@ dec_3min_intr(status, cause, pc, ipending)
|
||||
|
||||
__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);
|
||||
@ -502,18 +495,26 @@ kn02ba_wbflush()
|
||||
"i"(MIPS_PHYS_TO_KSEG1(KMIN_REG_IMSK)));
|
||||
}
|
||||
|
||||
static unsigned
|
||||
kn02ba_clkread()
|
||||
{
|
||||
#ifdef MIPS3
|
||||
if (CPUISMIPS3) {
|
||||
u_int32_t mips3_cycles;
|
||||
/*
|
||||
* Support for using the MIPS 3 clock as a timecounter.
|
||||
*/
|
||||
|
||||
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));
|
||||
void
|
||||
dec_3min_tc_init(void)
|
||||
{
|
||||
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,
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dec_maxine.c,v 1.51 2007/12/03 15:34:11 ad Exp $ */
|
||||
/* $NetBSD: dec_maxine.c,v 1.52 2008/01/03 23:02:25 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Jonathan Stone. All rights reserved.
|
||||
@ -106,11 +106,12 @@
|
||||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: dec_maxine.c,v 1.51 2007/12/03 15:34:11 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: dec_maxine.c,v 1.52 2008/01/03 23:02:25 joerg Exp $");
|
||||
|
||||
#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((unsigned, unsigned, unsigned, unsigned));
|
||||
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;
|
||||
|
||||
static const int dec_maxine_ipl2spl_table[] = {
|
||||
[IPL_NONE] = 0,
|
||||
@ -169,7 +170,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 */
|
||||
@ -331,8 +332,6 @@ dec_maxine_intr(status, cause, pc, ipending)
|
||||
|
||||
__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);
|
||||
@ -408,11 +407,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;
|
||||
|
||||
cycles = *(u_int32_t *)MIPS_PHYS_TO_KSEG1(XINE_REG_FCTR);
|
||||
return cycles - latched_cycle_cnt;
|
||||
return *(u_int32_t *)MIPS_PHYS_TO_KSEG1(XINE_REG_FCTR);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: machdep.c,v 1.221 2007/10/17 19:56:15 garbled Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.222 2008/01/03 23:02:25 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -77,7 +77,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.221 2007/10/17 19:56:15 garbled Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.222 2008/01/03 23:02:25 joerg Exp $");
|
||||
|
||||
#include "fs_mfs.h"
|
||||
#include "opt_ddb.h"
|
||||
@ -704,38 +704,6 @@ nullwork()
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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).
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mcclock_ioasic.c,v 1.18 2002/10/02 04:15:10 thorpej Exp $ */
|
||||
/* $NetBSD: mcclock_ioasic.c,v 1.19 2008/01/03 23:02:25 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
|
||||
@ -28,11 +28,12 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: mcclock_ioasic.c,v 1.18 2002/10/02 04:15:10 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: mcclock_ioasic.c,v 1.19 2008/01/03 23:02:25 joerg Exp $");
|
||||
|
||||
#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>
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: clockvar.h,v 1.8 2005/12/11 12:21:20 christos Exp $ */
|
||||
/* $NetBSD: clockvar.h,v 1.9 2008/01/03 23:02:25 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
|
||||
@ -31,22 +31,6 @@
|
||||
* Definitions for CPU-independent clock handling for the alpha and pmax.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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:
|
||||
*
|
||||
@ -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 *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mcclock.c,v 1.17 2005/12/11 12:21:20 christos Exp $ */
|
||||
/* $NetBSD: mcclock.c,v 1.18 2008/01/03 23:02:25 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
|
||||
@ -28,12 +28,13 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: mcclock.c,v 1.17 2005/12/11 12:21:20 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: mcclock.c,v 1.18 2008/01/03 23:02:25 joerg Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#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 1.17 2005/12/11 12:21:20 christos Exp $"
|
||||
|
||||
|
||||
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
|
||||
@ -132,57 +138,108 @@ again:
|
||||
MC_REGB_PIE | MC_REGB_SQWE | MC_REGB_BINARY | MC_REGB_24HR);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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, ®s)
|
||||
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, ®s);
|
||||
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, ®s);
|
||||
splx(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mcclock_pad32.c,v 1.13 2005/12/11 12:21:20 christos Exp $ */
|
||||
/* $NetBSD: mcclock_pad32.c,v 1.14 2008/01/03 23:02:25 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
|
||||
@ -28,7 +28,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: mcclock_pad32.c,v 1.13 2005/12/11 12:21:20 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: mcclock_pad32.c,v 1.14 2008/01/03 23:02:25 joerg Exp $");
|
||||
|
||||
|
||||
/*
|
||||
@ -49,6 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: mcclock_pad32.c,v 1.13 2005/12/11 12:21:20 christos
|
||||
#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>
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mcclockvar.h,v 1.6 2005/12/11 12:21:20 christos Exp $ */
|
||||
/* $NetBSD: mcclockvar.h,v 1.7 2008/01/03 23:02:25 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Carnegie-Mellon University.
|
||||
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user