Convert x68k to timecounters. This conversion is not tested, due to lack
of available test candidates. It uses the previously unused (as far as I can tell) Timer D, in freerunning mode. It only uses a 1/200 prescaler (20KHz), as anything faster would roll over too fast for the system timer. (Gotta love 8-bit resolution timers!) Approved for untested commit by core@.
This commit is contained in:
parent
fc13afb3a4
commit
b7648fa4c0
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: types.h,v 1.10 2006/09/14 01:18:11 gdamore Exp $ */
|
/* $NetBSD: types.h,v 1.11 2006/09/19 10:13:10 gdamore Exp $ */
|
||||||
|
|
||||||
#ifndef _MACHINE_TYPES_H_
|
#ifndef _MACHINE_TYPES_H_
|
||||||
#define _MACHINE_TYPES_H_
|
#define _MACHINE_TYPES_H_
|
||||||
|
@ -7,5 +7,6 @@
|
||||||
|
|
||||||
#define __HAVE_DEVICE_REGISTER
|
#define __HAVE_DEVICE_REGISTER
|
||||||
#define __HAVE_GENERIC_TODR
|
#define __HAVE_GENERIC_TODR
|
||||||
|
#define __HAVE_TIMECOUNTER
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: clock.c,v 1.23 2006/09/14 01:18:11 gdamore Exp $ */
|
/* $NetBSD: clock.c,v 1.24 2006/09/19 10:13:10 gdamore Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1982, 1990, 1993
|
* Copyright (c) 1982, 1990, 1993
|
||||||
|
@ -77,7 +77,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.23 2006/09/14 01:18:11 gdamore Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.24 2006/09/19 10:13:10 gdamore Exp $");
|
||||||
|
|
||||||
#include "clock.h"
|
#include "clock.h"
|
||||||
|
|
||||||
|
@ -87,6 +87,7 @@ __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.23 2006/09/14 01:18:11 gdamore Exp $");
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
#include <sys/device.h>
|
#include <sys/device.h>
|
||||||
|
#include <sys/timetc.h>
|
||||||
|
|
||||||
#include <machine/psl.h>
|
#include <machine/psl.h>
|
||||||
#include <machine/cpu.h>
|
#include <machine/cpu.h>
|
||||||
|
@ -110,6 +111,8 @@ CFATTACH_DECL(clock, sizeof(struct clock_softc),
|
||||||
|
|
||||||
static int clock_attached;
|
static int clock_attached;
|
||||||
|
|
||||||
|
static unsigned mfp_get_timecount(struct timecounter *);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
clock_match(struct device *parent, struct cfdata *cf, void *aux)
|
clock_match(struct device *parent, struct cfdata *cf, void *aux)
|
||||||
{
|
{
|
||||||
|
@ -135,25 +138,21 @@ clock_attach(struct device *parent, struct device *self, void *aux)
|
||||||
/*
|
/*
|
||||||
* MFP of X68k uses 4MHz clock always and we use 1/200 prescaler here.
|
* MFP of X68k uses 4MHz clock always and we use 1/200 prescaler here.
|
||||||
* Therefore, clock interval is 50 usec.
|
* Therefore, clock interval is 50 usec.
|
||||||
|
*
|
||||||
|
* Note that for timecounters, we'd like to use a finger grained clock, but
|
||||||
|
* since we only have an 8-bit clock, we can't do that without increasing
|
||||||
|
* the system clock rate. (Otherwise the counter would roll in less than
|
||||||
|
* a single system clock.)
|
||||||
*/
|
*/
|
||||||
#define CLK_RESOLUTION (50)
|
#define CLK_RESOLUTION (50)
|
||||||
#define CLOCKS_PER_SEC (1000000 / CLK_RESOLUTION)
|
#define CLOCKS_PER_SEC (1000000 / CLK_RESOLUTION)
|
||||||
|
|
||||||
static int clkint; /* clock interval */
|
|
||||||
|
|
||||||
static int clkread(void);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Machine-dependent clock routines.
|
* Machine-dependent clock routines.
|
||||||
*
|
*
|
||||||
* Startrtclock restarts the real-time clock, which provides
|
* Startrtclock restarts the real-time clock, which provides
|
||||||
* hardclock interrupts to kern_clock.c.
|
* hardclock interrupts to kern_clock.c.
|
||||||
*
|
*
|
||||||
* Inittodr initializes the time of day hardware which provides
|
|
||||||
* date functions.
|
|
||||||
*
|
|
||||||
* Resettodr restores the time of day hardware after a time change.
|
|
||||||
*
|
|
||||||
* A note on the real-time clock:
|
* A note on the real-time clock:
|
||||||
* We actually load the clock with CLK_INTERVAL-1 instead of CLK_INTERVAL.
|
* We actually load the clock with CLK_INTERVAL-1 instead of CLK_INTERVAL.
|
||||||
* This is because the counter decrements to zero after N+1 enabled clock
|
* This is because the counter decrements to zero after N+1 enabled clock
|
||||||
|
@ -168,18 +167,30 @@ static int clkread(void);
|
||||||
void
|
void
|
||||||
cpu_initclocks(void)
|
cpu_initclocks(void)
|
||||||
{
|
{
|
||||||
|
static struct timecounter tc = {
|
||||||
|
.tc_name = "mfp",
|
||||||
|
.tc_frequency = CLOCKS_PER_SEC,
|
||||||
|
.tc_counter_mask = 0xff,
|
||||||
|
.tc_get_timecount = mfp_get_timecount,
|
||||||
|
.tc_quality = 100,
|
||||||
|
};
|
||||||
|
|
||||||
if (CLOCKS_PER_SEC % hz ||
|
if (CLOCKS_PER_SEC % hz ||
|
||||||
hz <= (CLOCKS_PER_SEC / 256) || hz > CLOCKS_PER_SEC) {
|
hz <= (CLOCKS_PER_SEC / 256) || hz > CLOCKS_PER_SEC) {
|
||||||
printf("cannot set %d Hz clock. using 100 Hz\n", hz);
|
printf("cannot set %d Hz clock. using 100 Hz\n", hz);
|
||||||
hz = 100;
|
hz = 100;
|
||||||
}
|
}
|
||||||
clkint = CLOCKS_PER_SEC / hz;
|
|
||||||
|
|
||||||
mfp_set_tcdcr(mfp_get_tcdcr() & 0x0f); /* stop timer C */
|
mfp_set_tcdcr(0); /* stop timers C and D */
|
||||||
mfp_set_tcdcr(mfp_get_tcdcr() | 0x70); /* 1/200 delay mode */
|
mfp_set_tcdcr(mfp_get_tcdcr() | 0x70); /* 1/200 delay mode */
|
||||||
|
|
||||||
mfp_set_tcdr(clkint);
|
mfp_set_tcdr(CLOCKS_PER_SEC / hz);
|
||||||
mfp_bit_set_ierb(MFP_INTR_TIMER_C);
|
mfp_bit_set_ierb(MFP_INTR_TIMER_C);
|
||||||
|
|
||||||
|
mfp_set_tddr(0xff); /* maximum free run -- only 8 bits wide */
|
||||||
|
mfp_set_tcdcr(mfp_get_tcdcr() | 0x07); /* 1/200 prescaler */
|
||||||
|
|
||||||
|
tc_init(&tc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -196,13 +207,14 @@ setstatclockrate(int newhz)
|
||||||
* Returns number of usec since last recorded clock "tick"
|
* Returns number of usec since last recorded clock "tick"
|
||||||
* (i.e. clock interrupt).
|
* (i.e. clock interrupt).
|
||||||
*/
|
*/
|
||||||
int
|
unsigned
|
||||||
clkread(void)
|
mfp_get_timecount(struct timecounter *tc)
|
||||||
{
|
{
|
||||||
return (clkint - mfp_get_tcdr()) * CLK_RESOLUTION;
|
uint8_t val;
|
||||||
|
val = ~(mfp_get_tddr());
|
||||||
|
return (val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
void
|
void
|
||||||
DELAY(mic)
|
DELAY(mic)
|
||||||
|
@ -512,29 +524,6 @@ profclock(caddr_t pc, int ps)
|
||||||
#endif /* PROF */
|
#endif /* PROF */
|
||||||
#endif /* PROFTIMER */
|
#endif /* PROFTIMER */
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the best possible estimate of the current time.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
microtime(struct timeval *tvp)
|
|
||||||
{
|
|
||||||
static struct timeval lasttime;
|
|
||||||
|
|
||||||
*tvp = time;
|
|
||||||
tvp->tv_usec += clkread();
|
|
||||||
while (tvp->tv_usec >= 1000000) {
|
|
||||||
tvp->tv_sec++;
|
|
||||||
tvp->tv_usec -= 1000000;
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* NCLOCK */
|
#else /* NCLOCK */
|
||||||
#error loose.
|
#error loose.
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue