Add timecounter support and borrow counter-based delay from i386.
From joerg; testing and final tweaks by me.
This commit is contained in:
parent
890508dbe9
commit
c04c9a55d0
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: amiga_init.c,v 1.98 2007/10/17 19:53:12 garbled Exp $ */
|
/* $NetBSD: amiga_init.c,v 1.99 2008/01/06 18:50:29 mhitch Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1994 Michael L. Hitch
|
* Copyright (c) 1994 Michael L. Hitch
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
#include "opt_devreload.h"
|
#include "opt_devreload.h"
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: amiga_init.c,v 1.98 2007/10/17 19:53:12 garbled Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: amiga_init.c,v 1.99 2008/01/06 18:50:29 mhitch Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
|
@ -765,7 +765,6 @@ start_c(id, fphystart, fphysize, cphysize, esym_addr, flags, inh_sync,
|
||||||
void
|
void
|
||||||
start_c_finish()
|
start_c_finish()
|
||||||
{
|
{
|
||||||
extern u_int32_t delaydivisor;
|
|
||||||
#ifdef P5PPC68KBOARD
|
#ifdef P5PPC68KBOARD
|
||||||
struct cfdev *cdp, *ecdp;
|
struct cfdev *cdp, *ecdp;
|
||||||
#endif
|
#endif
|
||||||
|
@ -901,21 +900,6 @@ start_c_finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/*
|
|
||||||
* preliminary delay divisor value
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (machineid & AMIGA_68060)
|
|
||||||
delaydivisor = (1024 * 1) / 80; /* 80 MHz 68060 w. BTC */
|
|
||||||
|
|
||||||
else if (machineid & AMIGA_68040)
|
|
||||||
delaydivisor = (1024 * 3) / 40; /* 40 MHz 68040 */
|
|
||||||
|
|
||||||
else if (machineid & AMIGA_68030)
|
|
||||||
delaydivisor = (1024 * 8) / 50; /* 50 MHz 68030 */
|
|
||||||
|
|
||||||
else
|
|
||||||
delaydivisor = (1024 * 8) / 33; /* 33 MHz 68020 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: locore.s,v 1.144 2007/10/17 19:53:12 garbled Exp $ */
|
/* $NetBSD: locore.s,v 1.145 2008/01/06 18:50:30 mhitch Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1980, 1990 The Regents of the University of California.
|
* Copyright (c) 1980, 1990 The Regents of the University of California.
|
||||||
|
@ -1577,16 +1577,6 @@ Ldorebootend:
|
||||||
.align 2
|
.align 2
|
||||||
#endif
|
#endif
|
||||||
nop
|
nop
|
||||||
ENTRY_NOPROFILE(delay)
|
|
||||||
ENTRY_NOPROFILE(DELAY)
|
|
||||||
movql #10,%d1 | 2 +2
|
|
||||||
movl %sp@(4),%d0 | 4 +4
|
|
||||||
lsll %d1,%d0 | 8 +2
|
|
||||||
movl _C_LABEL(delaydivisor),%d1 | A +6
|
|
||||||
Ldelay: | longword aligned again.
|
|
||||||
subl %d1,%d0
|
|
||||||
jcc Ldelay
|
|
||||||
rts
|
|
||||||
|
|
||||||
#ifdef M68060
|
#ifdef M68060
|
||||||
ENTRY_NOPROFILE(intemu60)
|
ENTRY_NOPROFILE(intemu60)
|
||||||
|
@ -1621,11 +1611,6 @@ GLOBAL(protorp)
|
||||||
GLOBAL(proc0paddr)
|
GLOBAL(proc0paddr)
|
||||||
.long 0 | KVA of proc0 u-area
|
.long 0 | KVA of proc0 u-area
|
||||||
|
|
||||||
GLOBAL(delaydivisor)
|
|
||||||
.long 12 | should be enough for 80 MHz 68060
|
|
||||||
| will be adapted to other CPUs in
|
|
||||||
| start_c_cleanup and calibrated
|
|
||||||
| at clock attach time.
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
ASGLOBAL(fulltflush)
|
ASGLOBAL(fulltflush)
|
||||||
.long 0
|
.long 0
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: machdep.c,v 1.207 2007/12/03 15:33:10 ad Exp $ */
|
/* $NetBSD: machdep.c,v 1.208 2008/01/06 18:50:30 mhitch Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
|
* Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
|
||||||
|
@ -85,7 +85,7 @@
|
||||||
#include "opt_panicbutton.h"
|
#include "opt_panicbutton.h"
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.207 2007/12/03 15:33:10 ad Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.208 2008/01/06 18:50:30 mhitch Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
|
@ -765,39 +765,6 @@ dumpsys()
|
||||||
delay(5000000); /* 5 seconds */
|
delay(5000000); /* 5 seconds */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the best possible estimate of the time in the timeval
|
|
||||||
* to which tvp points. We do this by returning the current time
|
|
||||||
* plus the amount of time since the last clock interrupt (clock.c:clkread).
|
|
||||||
*
|
|
||||||
* Check that this time is no less than any previously-reported time,
|
|
||||||
* which could happen around the time of a clock adjustment. Just for fun,
|
|
||||||
* we guarantee that the time will be greater than the value obtained by a
|
|
||||||
* previous call.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
microtime(tvp)
|
|
||||||
register struct timeval *tvp;
|
|
||||||
{
|
|
||||||
int s = spl7();
|
|
||||||
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;
|
|
||||||
splx(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
initcpu()
|
initcpu()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: clock.c,v 1.46 2007/03/04 05:59:17 christos Exp $ */
|
/* $NetBSD: clock.c,v 1.47 2008/01/06 18:50:31 mhitch Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1982, 1990 The Regents of the University of California.
|
* Copyright (c) 1982, 1990 The Regents of the University of California.
|
||||||
|
@ -77,12 +77,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.46 2007/03/04 05:59:17 christos Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.47 2008/01/06 18:50:31 mhitch Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
#include <sys/device.h>
|
#include <sys/device.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
|
#include <sys/timetc.h>
|
||||||
#include <machine/psl.h>
|
#include <machine/psl.h>
|
||||||
#include <machine/cpu.h>
|
#include <machine/cpu.h>
|
||||||
#include <amiga/amiga/device.h>
|
#include <amiga/amiga/device.h>
|
||||||
|
@ -101,12 +102,24 @@ __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.46 2007/03/04 05:59:17 christos Exp $");
|
||||||
|
|
||||||
/* the clocks run at NTSC: 715.909kHz or PAL: 709.379kHz.
|
/* the clocks run at NTSC: 715.909kHz or PAL: 709.379kHz.
|
||||||
We're using a 100 Hz clock. */
|
We're using a 100 Hz clock. */
|
||||||
|
|
||||||
#define CLK_INTERVAL amiga_clk_interval
|
|
||||||
int amiga_clk_interval;
|
int amiga_clk_interval;
|
||||||
int eclockfreq;
|
int eclockfreq;
|
||||||
|
unsigned int fast_delay_limit;
|
||||||
struct CIA *clockcia;
|
struct CIA *clockcia;
|
||||||
|
|
||||||
|
static u_int clk_getcounter(struct timecounter *);
|
||||||
|
|
||||||
|
static struct timecounter clk_timecounter = {
|
||||||
|
clk_getcounter, /* get_timecount */
|
||||||
|
0, /* no poll_pps */
|
||||||
|
~0u, /* counter_mask */
|
||||||
|
0, /* frequency */
|
||||||
|
"clock", /* name, overriden later */
|
||||||
|
100, /* quality */
|
||||||
|
NULL, /* prev */
|
||||||
|
NULL, /* next */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Machine-dependent clock routines.
|
* Machine-dependent clock routines.
|
||||||
*
|
*
|
||||||
|
@ -119,7 +132,7 @@ struct CIA *clockcia;
|
||||||
* Resettodr restores the time of day hardware after a time change.
|
* 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 amiga_clk_interval-1 instead of amiga_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
|
||||||
* periods where N is the value loaded into the counter.
|
* periods where N is the value loaded into the counter.
|
||||||
*/
|
*/
|
||||||
|
@ -127,7 +140,6 @@ struct CIA *clockcia;
|
||||||
int clockmatch(struct device *, struct cfdata *, void *);
|
int clockmatch(struct device *, struct cfdata *, void *);
|
||||||
void clockattach(struct device *, struct device *, void *);
|
void clockattach(struct device *, struct device *, void *);
|
||||||
void cpu_initclocks(void);
|
void cpu_initclocks(void);
|
||||||
void calibrate_delay(struct device *);
|
|
||||||
|
|
||||||
CFATTACH_DECL(clock, sizeof(struct device),
|
CFATTACH_DECL(clock, sizeof(struct device),
|
||||||
clockmatch, clockattach, NULL, NULL);
|
clockmatch, clockattach, NULL, NULL);
|
||||||
|
@ -152,15 +164,17 @@ clockattach(struct device *pdp, struct device *dp, void *auxp)
|
||||||
u_char dracorev;
|
u_char dracorev;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef DRACO
|
||||||
|
dracorev = is_draco();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (eclockfreq == 0)
|
if (eclockfreq == 0)
|
||||||
eclockfreq = 715909; /* guess NTSC */
|
eclockfreq = 715909; /* guess NTSC */
|
||||||
|
|
||||||
CLK_INTERVAL = (eclockfreq / 100);
|
|
||||||
|
|
||||||
#ifdef DRACO
|
#ifdef DRACO
|
||||||
dracorev = is_draco();
|
|
||||||
if (dracorev >= 4) {
|
if (dracorev >= 4) {
|
||||||
CLK_INTERVAL = (eclockfreq / 700);
|
if (amiga_clk_interval == 0) /* Only do this 1st time */
|
||||||
|
eclockfreq /= 7;
|
||||||
clockchip = "QuickLogic";
|
clockchip = "QuickLogic";
|
||||||
} else if (dracorev) {
|
} else if (dracorev) {
|
||||||
clockcia = (struct CIA *)CIAAbase;
|
clockcia = (struct CIA *)CIAAbase;
|
||||||
|
@ -172,13 +186,18 @@ clockattach(struct device *pdp, struct device *dp, void *auxp)
|
||||||
clockchip = "CIA B";
|
clockchip = "CIA B";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dp)
|
amiga_clk_interval = (eclockfreq / hz);
|
||||||
|
|
||||||
|
clk_timecounter.tc_name = clockchip;
|
||||||
|
clk_timecounter.tc_frequency = eclockfreq;
|
||||||
|
|
||||||
|
fast_delay_limit = UINT_MAX / amiga_clk_interval;
|
||||||
|
|
||||||
|
if (dp != NULL) { /* real autoconfig? */
|
||||||
printf(": %s system hz %d hardware hz %d\n", clockchip, hz,
|
printf(": %s system hz %d hardware hz %d\n", clockchip, hz,
|
||||||
#ifdef DRACO
|
|
||||||
dracorev >= 4 ? eclockfreq / 7 : eclockfreq);
|
|
||||||
#else
|
|
||||||
eclockfreq);
|
eclockfreq);
|
||||||
#endif
|
tc_init(&clk_timecounter);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DRACO
|
#ifdef DRACO
|
||||||
if (dracorev >= 4) {
|
if (dracorev >= 4) {
|
||||||
|
@ -187,10 +206,8 @@ clockattach(struct device *pdp, struct device *dp, void *auxp)
|
||||||
* but need this for delay calibration.
|
* but need this for delay calibration.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
draco_ioct->io_timerlo = CLK_INTERVAL & 0xff;
|
draco_ioct->io_timerlo = amiga_clk_interval & 0xff;
|
||||||
draco_ioct->io_timerhi = CLK_INTERVAL >> 8;
|
draco_ioct->io_timerhi = amiga_clk_interval >> 8;
|
||||||
|
|
||||||
calibrate_delay(dp);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -207,7 +224,7 @@ clockattach(struct device *pdp, struct device *dp, void *auxp)
|
||||||
* the clocks run at NTSC: 715.909kHz or PAL: 709.379kHz
|
* the clocks run at NTSC: 715.909kHz or PAL: 709.379kHz
|
||||||
* supprort for PAL WHEN?!?! XXX
|
* supprort for PAL WHEN?!?! XXX
|
||||||
*/
|
*/
|
||||||
interval = CLK_INTERVAL - 1;
|
interval = amiga_clk_interval - 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* order of setting is important !
|
* order of setting is important !
|
||||||
|
@ -218,67 +235,6 @@ clockattach(struct device *pdp, struct device *dp, void *auxp)
|
||||||
* start timer A in continuous mode
|
* start timer A in continuous mode
|
||||||
*/
|
*/
|
||||||
clockcia->cra = (clockcia->cra & 0xc0) | 1;
|
clockcia->cra = (clockcia->cra & 0xc0) | 1;
|
||||||
|
|
||||||
calibrate_delay(dp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Calibrate delay loop.
|
|
||||||
* We use two iterations because we don't have enough bits to do a factor of
|
|
||||||
* 8 with better than 1%.
|
|
||||||
*
|
|
||||||
* XXX Note that we MUST stay below 1 tick if using clkread(), even for
|
|
||||||
* underestimated values of delaydivisor.
|
|
||||||
*
|
|
||||||
* XXX the "ns" below is only correct for a shift of 10 bits, and even then
|
|
||||||
* off by 2.4%
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
calibrate_delay(struct device *dp)
|
|
||||||
{
|
|
||||||
unsigned long t1, t2;
|
|
||||||
extern u_int32_t delaydivisor;
|
|
||||||
/* XXX this should be defined elsewhere */
|
|
||||||
|
|
||||||
if (dp)
|
|
||||||
printf("Calibrating delay loop... ");
|
|
||||||
|
|
||||||
do {
|
|
||||||
t1 = clkread();
|
|
||||||
delay(1024);
|
|
||||||
t2 = clkread();
|
|
||||||
} while (t2 <= t1);
|
|
||||||
t2 -= t1;
|
|
||||||
delaydivisor = (delaydivisor * t2 + 1023) >> 10;
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (dp)
|
|
||||||
printf("\ndiff %ld us, new divisor %u/1024 us\n", t2,
|
|
||||||
delaydivisor);
|
|
||||||
do {
|
|
||||||
t1 = clkread();
|
|
||||||
delay(1024);
|
|
||||||
t2 = clkread();
|
|
||||||
} while (t2 <= t1);
|
|
||||||
t2 -= t1;
|
|
||||||
delaydivisor = (delaydivisor * t2 + 1023) >> 10;
|
|
||||||
if (dp)
|
|
||||||
printf("diff %ld us, new divisor %u/1024 us\n", t2,
|
|
||||||
delaydivisor);
|
|
||||||
#endif
|
|
||||||
do {
|
|
||||||
t1 = clkread();
|
|
||||||
delay(1024);
|
|
||||||
t2 = clkread();
|
|
||||||
} while (t2 <= t1);
|
|
||||||
t2 -= t1;
|
|
||||||
delaydivisor = (delaydivisor * t2 + 1023) >> 10;
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (dp)
|
|
||||||
printf("diff %ld us, new divisor ", t2);
|
|
||||||
#endif
|
|
||||||
if (dp)
|
|
||||||
printf("%u/1024 us\n", delaydivisor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -288,8 +244,8 @@ cpu_initclocks(void)
|
||||||
unsigned char dracorev;
|
unsigned char dracorev;
|
||||||
dracorev = is_draco();
|
dracorev = is_draco();
|
||||||
if (dracorev >= 4) {
|
if (dracorev >= 4) {
|
||||||
draco_ioct->io_timerlo = CLK_INTERVAL & 0xFF;
|
draco_ioct->io_timerlo = amiga_clk_interval & 0xFF;
|
||||||
draco_ioct->io_timerhi = CLK_INTERVAL >> 8;
|
draco_ioct->io_timerhi = amiga_clk_interval >> 8;
|
||||||
draco_ioct->io_timerrst = 0; /* any value resets */
|
draco_ioct->io_timerrst = 0; /* any value resets */
|
||||||
single_inst_bset_b(draco_ioct->io_status2, DRSTAT2_TMRINTENA);
|
single_inst_bset_b(draco_ioct->io_status2, DRSTAT2_TMRINTENA);
|
||||||
|
|
||||||
|
@ -324,11 +280,11 @@ setstatclockrate(int hertz)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns number of usec since last recorded clock "tick"
|
* Returns ticks since last recorded clock "tick"
|
||||||
* (i.e. clock interrupt).
|
* (i.e. clock interrupt).
|
||||||
*/
|
*/
|
||||||
u_long
|
static u_int
|
||||||
clkread(void)
|
clk_gettick(void)
|
||||||
{
|
{
|
||||||
u_int interval;
|
u_int interval;
|
||||||
u_char hi, hi2, lo;
|
u_char hi, hi2, lo;
|
||||||
|
@ -339,10 +295,10 @@ clkread(void)
|
||||||
hi = draco_ioct->io_timerhi;
|
hi = draco_ioct->io_timerhi;
|
||||||
lo = draco_ioct->io_timerlo;
|
lo = draco_ioct->io_timerlo;
|
||||||
interval = ((hi<<8) | lo);
|
interval = ((hi<<8) | lo);
|
||||||
if (interval > CLK_INTERVAL) /* timer underflow */
|
if (interval > amiga_clk_interval) /* timer underflow */
|
||||||
interval = 65536 + CLK_INTERVAL - interval;
|
interval = 65536 + amiga_clk_interval - interval;
|
||||||
else
|
else
|
||||||
interval = CLK_INTERVAL - interval;
|
interval = amiga_clk_interval - interval;
|
||||||
|
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
|
@ -355,7 +311,7 @@ clkread(void)
|
||||||
hi = hi2;
|
hi = hi2;
|
||||||
}
|
}
|
||||||
|
|
||||||
interval = (CLK_INTERVAL - 1) - ((hi<<8) | lo);
|
interval = (amiga_clk_interval - 1) - ((hi<<8) | lo);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* should read ICR and if there's an int pending, adjust
|
* should read ICR and if there's an int pending, adjust
|
||||||
|
@ -364,7 +320,21 @@ clkread(void)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
return((interval * tick) / CLK_INTERVAL);
|
return interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u_int
|
||||||
|
clk_getcounter(struct timecounter *tc)
|
||||||
|
{
|
||||||
|
int old_hardclock_ticks;
|
||||||
|
u_int clock_tick;
|
||||||
|
|
||||||
|
do {
|
||||||
|
old_hardclock_ticks = hardclock_ticks;
|
||||||
|
clock_tick = clk_gettick();
|
||||||
|
} while (old_hardclock_ticks != hardclock_ticks);
|
||||||
|
|
||||||
|
return old_hardclock_ticks * amiga_clk_interval + clock_tick;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if notyet
|
#if notyet
|
||||||
|
@ -589,12 +559,12 @@ initprofclock(void)
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
* The profile interrupt interval must be an even divisor
|
* The profile interrupt interval must be an even divisor
|
||||||
* of the CLK_INTERVAL so that scaling from a system clock
|
* of the amiga_clk_interval so that scaling from a system clock
|
||||||
* tick to a profile clock tick is possible using integer math.
|
* tick to a profile clock tick is possible using integer math.
|
||||||
*/
|
*/
|
||||||
if (profint > CLK_INTERVAL || (CLK_INTERVAL % profint) != 0)
|
if (profint > amiga_clk_interval || (amiga_clk_interval % profint) != 0)
|
||||||
profint = CLK_INTERVAL;
|
profint = amiga_clk_interval;
|
||||||
profscale = CLK_INTERVAL / profint;
|
profscale = amiga_clk_interval / profint;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -667,3 +637,51 @@ profclock(void *pc, int ps)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
delay(unsigned int n)
|
||||||
|
{
|
||||||
|
unsigned int cur_tick, initial_tick;
|
||||||
|
int remaining;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read the counter first, so that the rest of the setup overhead is
|
||||||
|
* counted.
|
||||||
|
*/
|
||||||
|
initial_tick = clk_gettick();
|
||||||
|
|
||||||
|
if (amiga_clk_interval == 0) {
|
||||||
|
/*
|
||||||
|
* Clock is not initialised yet,
|
||||||
|
* so just do some ad-hoc loop.
|
||||||
|
*/
|
||||||
|
static uint32_t dummy;
|
||||||
|
|
||||||
|
n *= 4;
|
||||||
|
while (n--)
|
||||||
|
dummy *= eclockfreq;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n <= fast_delay_limit) {
|
||||||
|
/*
|
||||||
|
* For unsigned arithmetic, division can be replaced with
|
||||||
|
* multiplication with the inverse and a shift.
|
||||||
|
*/
|
||||||
|
remaining = n * eclockfreq / 1000000;
|
||||||
|
} else {
|
||||||
|
/* This is a very long delay.
|
||||||
|
* Being slow here doesn't matter.
|
||||||
|
*/
|
||||||
|
remaining = (unsigned long long) n * eclockfreq / 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (remaining > 0) {
|
||||||
|
cur_tick = clk_gettick();
|
||||||
|
if (cur_tick > initial_tick)
|
||||||
|
remaining -= amiga_clk_interval - (cur_tick - initial_tick);
|
||||||
|
else
|
||||||
|
remaining -= initial_tick - cur_tick;
|
||||||
|
initial_tick = cur_tick;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: cpu.h,v 1.68 2007/10/17 19:53:25 garbled Exp $ */
|
/* $NetBSD: cpu.h,v 1.69 2008/01/06 18:50:31 mhitch Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1982, 1990 The Regents of the University of California.
|
* Copyright (c) 1982, 1990 The Regents of the University of California.
|
||||||
|
@ -206,11 +206,6 @@ int is_a4000 __P((void));
|
||||||
#define is_draco() ((machineid >> 24) == 0x7d ? (machineid >> 16) & 0xff : 0)
|
#define is_draco() ((machineid >> 24) == 0x7d ? (machineid >> 16) & 0xff : 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* Prototypes from clock.c
|
|
||||||
*/
|
|
||||||
u_long clkread __P((void));
|
|
||||||
|
|
||||||
#ifdef DRACO
|
#ifdef DRACO
|
||||||
/*
|
/*
|
||||||
* Prototypes from kbd.c
|
* Prototypes from kbd.c
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: param.h,v 1.44 2005/12/11 12:16:36 christos Exp $ */
|
/* $NetBSD: param.h,v 1.45 2008/01/06 18:50:32 mhitch Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
|
* Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
|
||||||
|
@ -120,8 +120,8 @@
|
||||||
extern volatile unsigned short *amiga_intena_read, *amiga_intena_write;
|
extern volatile unsigned short *amiga_intena_read, *amiga_intena_write;
|
||||||
|
|
||||||
#ifndef _LOCORE
|
#ifndef _LOCORE
|
||||||
void delay __P((int));
|
void delay(unsigned int);
|
||||||
void DELAY __P((int));
|
#define DELAY(x) delay(x)
|
||||||
#endif /* !_LOCORE */
|
#endif /* !_LOCORE */
|
||||||
#endif /* _KERNEL */
|
#endif /* _KERNEL */
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: types.h,v 1.20 2007/10/17 19:53:26 garbled Exp $ */
|
/* $NetBSD: types.h,v 1.21 2008/01/06 18:50:32 mhitch Exp $ */
|
||||||
|
|
||||||
#ifndef _MACHINE_TYPES_H_
|
#ifndef _MACHINE_TYPES_H_
|
||||||
#define _MACHINE_TYPES_H_
|
#define _MACHINE_TYPES_H_
|
||||||
|
@ -7,5 +7,6 @@
|
||||||
|
|
||||||
#define __GENERIC_SOFT_INTERRUPTS_ALL_LEVELS
|
#define __GENERIC_SOFT_INTERRUPTS_ALL_LEVELS
|
||||||
#define __HAVE_GENERIC_TODR
|
#define __HAVE_GENERIC_TODR
|
||||||
|
#define __HAVE_TIMECOUNTER
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue