Subject: Re: _delay: and SCSI
To: None <mcr@latour.sandelman.ocunix.on.ca>
From: Gordon W. Ross <gwr@mc.com>
List: port-sun3
Date: 12/05/1995 10:36:34
> Date: Mon, 04 Dec 1995 23:42:12 -0500
> From: Michael Richardson <mcr@latour.sandelman.ocunix.on.ca>

[...]
>  Perhaps we need a dispatch table with a _cpuspeed=16,20,25 Mhz
>  _smalldelay()?

There is already a special function for short delays on the sun3:
machine/param.h provides delay2us().  That could be used in the
ncr5380 driver by defining NCR_DELAY2US() in the machine-dependent
xxxvar.h file (or someplace like that).

Perhaps it would be more useful to have a parametric "short delay"
(i.e. sdelay(n)) but that is a little more effort.  If you want to
play with the delay functions, here are my test programs:

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	Makefile
#	delay.s
#	sdelay.c
#	tdelay.c
# This archive created: Tue Dec  5 10:32:08 1995
export PATH; PATH=/bin:$PATH
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'

CFLAGS= -g -O

sdelay: sdelay.o
	$(CC) -o $@ sdelay.o

tdelay: tdelay.o delay.o
	$(CC) -o $@ tdelay.o delay.o

delay.o : delay.s
	$(CC) -c delay.s
SHAR_EOF
fi # end of overwriting check
if test -f 'delay.s'
then
	echo shar: will not over-write existing file "'delay.s'"
else
cat << \SHAR_EOF > 'delay.s'

| 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...
	.text
| delay(int usecs)
| Delay for "usec" microseconds.  Minimum delay is about 5 uS.
	.globl	_delay
_delay:
	| d0 = (cpuspeed * usecs)
	movel	_cpuspeed,d0
	mulsl	sp@(4),d0
	| subtract some overhead
	moveq	#80,d1
	subl	d1,d0
| This loop takes 8 clocks per cycle.
Ldelay:
	subql	#8,d0
	jgt	Ldelay
	rts
SHAR_EOF
fi # end of overwriting check
if test -f 'sdelay.c'
then
	echo shar: will not over-write existing file "'sdelay.c'"
else
cat << \SHAR_EOF > 'sdelay.c'

#include <sys/time.h>
#include <stdio.h>

int cpuspeed = 25;

static inline void delay2us()
{
	register int n = cpuspeed;

	__asm __volatile ("0: subql #4,%0; jgt 0b" : "=d" (n) : "0" (n));
}

doit(ms)
	int ms;
{
	register int n;

	n = ms * 100;
	do {
		/* 2x5 uS. */
		delay2us();
		delay2us();
		delay2us();
		delay2us();
		delay2us();
	} while (--n > 0);
}

main(argc, argv)
	char **argv;
{
	struct timeval t0, t1;
	int ms=1000;
	register int n;

	if (argc > 1)
		cpuspeed = atoi(argv[1]);

	if (argc > 2)
		ms = atoi(argv[2]);

	printf("cpuspeed=%d, ms=%d\n", cpuspeed, ms);

	gettimeofday(&t0, NULL);
	doit(ms);
	gettimeofday(&t1, NULL);

	t1.tv_sec  -= t0.tv_sec;
	t1.tv_usec -= t0.tv_usec;
	if (t1.tv_usec < 0) {
		t1.tv_usec += 1000000;
		t1.tv_sec -= 1;
	}
	printf("%d.%06d\n", t1.tv_sec, t1.tv_usec);
}

SHAR_EOF
fi # end of overwriting check
if test -f 'tdelay.c'
then
	echo shar: will not over-write existing file "'tdelay.c'"
else
cat << \SHAR_EOF > 'tdelay.c'

#include <sys/time.h>
#include <stdio.h>

int cpuspeed = 25;

main(argc, argv)
	char **argv;
{
	struct timeval t0, t1;
	int ms=1000;
	register int n;

	if (argc > 1)
		cpuspeed = atoi(argv[1]);

	if (argc > 2)
		ms = atoi(argv[2]);

	printf("cpuspeed=%d, ms=%d\n", cpuspeed, ms);

	gettimeofday(&t0, NULL);
	n = ms;
	do delay(1000);
	while (--n > 0);
	gettimeofday(&t1, NULL);

	t1.tv_sec  -= t0.tv_sec;
	t1.tv_usec -= t0.tv_usec;
	if (t1.tv_usec < 0) {
		t1.tv_usec += 1000000;
		t1.tv_sec -= 1;
	}
	printf("%d.%06d\n", t1.tv_sec, t1.tv_usec);
}

SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0