Improved delay() implementation with lower overhead,

makes very short delays much more accurate.
This commit is contained in:
gwr 1996-02-16 18:06:11 +00:00
parent bcfac202c8
commit 5404ccfbd7
5 changed files with 55 additions and 62 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: param.h,v 1.31 1996/02/01 22:33:08 mycroft Exp $ */
/* $NetBSD: param.h,v 1.32 1996/02/16 18:08:21 gwr Exp $ */
/*
* Copyright (c) 1994, 1995 Gordon W. Ross
@ -149,17 +149,10 @@
/* XXX - Does this really belong here? -gwr */
#include <machine/psl.h>
#ifdef _KERNEL
#ifndef _LOCORE
#if defined(_KERNEL) && !defined(_LOCORE)
extern void _delay __P((unsigned));
#define delay(us) _delay((us)<<8)
#define DELAY(n) delay(n)
extern int cpuspeed;
static inline void delay2us()
{
register int n = cpuspeed;
__asm __volatile ("0: subql #4,%0; jgt 0b" : "=d" (n) : "0" (n));
}
#endif /* !_LOCORE */
#endif /* _KERNEL */
#endif /* _KERNEL && !_LOCORE */
#endif /* MACHINE */

View File

@ -1,4 +1,4 @@
/* $NetBSD: param3.h,v 1.31 1996/02/01 22:33:08 mycroft Exp $ */
/* $NetBSD: param3.h,v 1.32 1996/02/16 18:08:21 gwr Exp $ */
/*
* Copyright (c) 1994, 1995 Gordon W. Ross
@ -149,17 +149,10 @@
/* XXX - Does this really belong here? -gwr */
#include <machine/psl.h>
#ifdef _KERNEL
#ifndef _LOCORE
#if defined(_KERNEL) && !defined(_LOCORE)
extern void _delay __P((unsigned));
#define delay(us) _delay((us)<<8)
#define DELAY(n) delay(n)
extern int cpuspeed;
static inline void delay2us()
{
register int n = cpuspeed;
__asm __volatile ("0: subql #4,%0; jgt 0b" : "=d" (n) : "0" (n));
}
#endif /* !_LOCORE */
#endif /* _KERNEL */
#endif /* _KERNEL && !_LOCORE */
#endif /* MACHINE */

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.s,v 1.35 1996/02/02 02:37:42 mycroft Exp $ */
/* $NetBSD: locore.s,v 1.36 1996/02/16 18:06:11 gwr Exp $ */
/*
* Copyright (c) 1994, 1995 Gordon W. Ross
@ -1182,26 +1182,23 @@ Lm68881rdone:
frestore a0@ | restore state
rts
| delay(int usecs)
| Delay for "usec" microseconds. Minimum delay is about 5 uS.
|
| This routine depends on the variable "cpuspeed"
| which should be set based on the CPU clock rate.
| XXX - Currently this is set in sun3_startup.c based on the
| CPU model but this should be determined at run time...
|
.globl _delay
_delay:
| d0 = (cpuspeed * usecs)
movel _cpuspeed,d0
mulsl sp@(4),d0
| subtract some overhead
moveq #80,d1
/*
* _delay(unsigned N)
* Delay for at least (N/256) microseconds.
* This routine depends on the variable: delay_divisor
* which should be set based on the CPU clock rate.
* XXX: Currently this is set in sun3_startup.c based on the
* XXX: CPU model but this should be determined at run time...
*/
.globl __delay
__delay:
| d0 = arg = (usecs << 8)
movl sp@(4),d0
| d1 = delay_divisor;
movl _delay_divisor,d1
L_delay:
subl d1,d0
| This loop takes 8 clocks per cycle.
Ldelay:
subql #8,d0
jgt Ldelay
jgt L_delay
rts

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore2.c,v 1.48 1995/10/17 23:16:40 gwr Exp $ */
/* $NetBSD: locore2.c,v 1.49 1996/02/16 18:06:19 gwr Exp $ */
/*
* Copyright (c) 1994 Gordon W. Ross
@ -591,8 +591,13 @@ void sun3_vm_init(kehp)
}
/* XXX - Should just estimate this instead... */
int cpuspeed = 25; /* initial guess */
/*
* XXX - Should empirically estimate the divisor...
* Note that the value of delay_divisor is roughly
* 2048 / cpuclock (where cpuclock is in MHz).
*/
int delay_divisor = 82; /* assume the fastest (3/260) */
void sun3_verify_hardware()
{
unsigned char machtype;
@ -613,33 +618,33 @@ void sun3_verify_hardware()
hole_start = OBMEM_BW50_ADDR;
hole_size = OBMEM_BW2_SIZE;
cpu_string = "50";
cpuspeed = 16; /* MHz */
delay_divisor = 128; /* 16 MHz */
break;
case SUN3_MACH_60 :
cpu_match++;
cpu_string = "60";
cpuspeed = 20; /* MHz */
delay_divisor = 102; /* 20 MHz */
break;
case SUN3_MACH_110:
cpu_match++;
cpu_string = "110";
cpuspeed = 17; /* MHz */
delay_divisor = 120; /* 17 MHz */
cpu_has_vme = TRUE;
break;
case SUN3_MACH_160:
cpu_match++;
cpu_string = "160";
cpuspeed = 17; /* MHz */
delay_divisor = 120; /* 17 MHz */
cpu_has_vme = TRUE;
break;
case SUN3_MACH_260:
cpu_match++;
cpu_string = "260";
cpuspeed = 25; /* MHz */
delay_divisor = 82; /* 25 MHz */
cpu_has_vme = TRUE;
#ifdef HAVECACHE
cache_size = 0x10000; /* 64K */
@ -649,7 +654,7 @@ void sun3_verify_hardware()
case SUN3_MACH_E :
cpu_match++;
cpu_string = "E";
cpuspeed = 20; /* MHz */ /* XXX - Correct? */
delay_divisor = 102; /* 20 MHz XXX: Correct? */
cpu_has_vme = TRUE;
break;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sun3_startup.c,v 1.48 1995/10/17 23:16:40 gwr Exp $ */
/* $NetBSD: sun3_startup.c,v 1.49 1996/02/16 18:06:19 gwr Exp $ */
/*
* Copyright (c) 1994 Gordon W. Ross
@ -591,8 +591,13 @@ void sun3_vm_init(kehp)
}
/* XXX - Should just estimate this instead... */
int cpuspeed = 25; /* initial guess */
/*
* XXX - Should empirically estimate the divisor...
* Note that the value of delay_divisor is roughly
* 2048 / cpuclock (where cpuclock is in MHz).
*/
int delay_divisor = 82; /* assume the fastest (3/260) */
void sun3_verify_hardware()
{
unsigned char machtype;
@ -613,33 +618,33 @@ void sun3_verify_hardware()
hole_start = OBMEM_BW50_ADDR;
hole_size = OBMEM_BW2_SIZE;
cpu_string = "50";
cpuspeed = 16; /* MHz */
delay_divisor = 128; /* 16 MHz */
break;
case SUN3_MACH_60 :
cpu_match++;
cpu_string = "60";
cpuspeed = 20; /* MHz */
delay_divisor = 102; /* 20 MHz */
break;
case SUN3_MACH_110:
cpu_match++;
cpu_string = "110";
cpuspeed = 17; /* MHz */
delay_divisor = 120; /* 17 MHz */
cpu_has_vme = TRUE;
break;
case SUN3_MACH_160:
cpu_match++;
cpu_string = "160";
cpuspeed = 17; /* MHz */
delay_divisor = 120; /* 17 MHz */
cpu_has_vme = TRUE;
break;
case SUN3_MACH_260:
cpu_match++;
cpu_string = "260";
cpuspeed = 25; /* MHz */
delay_divisor = 82; /* 25 MHz */
cpu_has_vme = TRUE;
#ifdef HAVECACHE
cache_size = 0x10000; /* 64K */
@ -649,7 +654,7 @@ void sun3_verify_hardware()
case SUN3_MACH_E :
cpu_match++;
cpu_string = "E";
cpuspeed = 20; /* MHz */ /* XXX - Correct? */
delay_divisor = 102; /* 20 MHz XXX: Correct? */
cpu_has_vme = TRUE;
break;