~kris/9p

9hist

6eb3d5e63dceafa17b050c2d9a5592dfc806d65b — David du Colombier 26 years ago 6bbc6be
Plan 9 from Bell Labs 2000-06-27
4 files changed, 118 insertions(+), 33 deletions(-)

M pc/cycintr.c
M pc/fns.h
M pc/i8253.c
M pc/sd53c8xx.c
M pc/cycintr.c => pc/cycintr.c +23 -9
@@ 9,31 9,47 @@
static struct
{
	Lock;
	vlong	when;			/* next scheduled interrupt time */
	Cycintr	*ci;
}cycintrs;

static void
cycsched(void)
/*
 * called by clockintrsched()
 */
vlong
cycintrnext(void)
{
	Cycintr *ci;
	vlong when;

	ilock(&cycintrs);
	when = 0;
	ci = cycintrs.ci;
	if(ci != nil)
		when = ci->when;
	iunlock(&cycintrs);
	return when;
}

void
vlong
checkcycintr(Ureg *u, void*)
{
	Cycintr *ci;
	vlong when;

	ilock(&cycintrs);
	while(ci = cycintrs.ci){
		if(ci->when > fastticks(nil))
			break;
		when = ci->when;
		if(when > fastticks(nil)){
			iunlock(&cycintrs);
			return when;
		}
		cycintrs.ci = ci->next;
		iunlock(&cycintrs);
		(*ci->f)(u, ci);
		ilock(&cycintrs);
	}
	cycsched();
	iunlock(&cycintrs);
	return 0;
}

void


@@ 59,8 75,6 @@ cycintradd(Cycintr *nci)
	}
	nci->next = *last;
	*last = nci;
	if(nci->when < cycintrs.when)
		cycsched();
	iunlock(&cycintrs);
}


M pc/fns.h => pc/fns.h +3 -2
@@ 1,9 1,10 @@
#include "../port/portfns.h"

void	checkcycintr(Ureg*, void*);
vlong	checkcycintr(Ureg*, void*);
void	cycintradd(Cycintr*);
void	cycintrdel(Cycintr*);

void	clockintrsched(void);
vlong	cycintrnext(void);

void	aamloop(int);
void	addconf(char*, char*);

M pc/i8253.c => pc/i8253.c +62 -20
@@ 52,8 52,10 @@ enum

static struct
{
	Lock	lock;
	Lock;
	int	mode;
	vlong	when;		/* next fastticks a clock interrupt should occur */
	vlong	cycwhen;	/* next fastticks a cycintr happens; 0 == infinity */
	long	fastperiod;	/* fastticks/hz */
	long	fast2freq;	/* fastticks*FreqMul/Freq */
}i8253;


@@ 74,6 76,7 @@ i8253init(int aalcycles, int havecycleclock)
		 *  set clock for 1/HZ seconds
		 */
		outb(Tmode, Load0|Square);
		i8253.mode = Square;
		outb(T0cntr, (Freq/HZ));	/* low byte */
		outb(T0cntr, (Freq/HZ)>>8);	/* high byte */



@@ 158,31 161,70 @@ i8253init(int aalcycles, int havecycleclock)
	}
}

#ifdef SETNEXT
set up clock so it is reloaded every interrupt
	outb(Tmode, Load0|Trigger);
	outb(T0cntr, (Freq/HZ));	/* low byte */
	outb(T0cntr, (Freq/HZ)>>8);	/* high byte */
#endif

/*
 * schedule the next interrupt
 * cycwhen is the next time for the cycle counter routines
 */
static void
clockintr0(Ureg* ureg, void *v)
clockintrsched0(vlong next)
{
#ifdef SETNEXT
	vlong now;
	long set;

	i8253.cycwhen = next;
	if(i8253.mode == Square && next == 0)
		return;

	now = fastticks(nil);
	while(i8253.when < now)
		i8253.when += i8253.fastperiod;
	set = (long)(i8253.when - now) * FreqMul / i8253.fast2freq;
	set -= 3;	/* three cycles for the count to take effect: outb, outb, wait */
	outb(T0cntr, set);	/* low byte */
	outb(T0cntr, set>>8);	/* high byte */
#endif

	checkcycintr(ureg, v);
	clockintr(ureg, v);
	if(next || now < i8253.when - i8253.fastperiod || now > i8253.when - ((3*i8253.fastperiod)>>2)){
		if(next > i8253.when)
			next = i8253.when;
		set = (long)(next - now) * FreqMul / i8253.fast2freq;
		set -= 3;	/* three cycles for the count to take effect: outb, outb, wait */
		if(i8253.mode != Trigger){
			outb(Tmode, Load0|Trigger);
			i8253.mode = Trigger;
			set--;
		}
		if(set < 3)
			set = 5;
		outb(T0cntr, set);	/* low byte */
		outb(T0cntr, set>>8);	/* high byte */
	}else if(i8253.mode != Square){
		i8253.mode = Square;
		outb(Tmode, Load0|Square);
		outb(T0cntr, (Freq/HZ));	/* low byte */
		outb(T0cntr, (Freq/HZ)>>8);	/* high byte */
	}
}

void
clockintrsched(void)
{
	vlong next;

	ilock(&i8253);
	next = cycintrnext();
	if(next != i8253.cycwhen)
		clockintrsched0(next);
	iunlock(&i8253);
}

static void
clockintr0(Ureg* ureg, void *v)
{
	vlong now, when;

	now = fastticks(nil);
	when = i8253.when;
	if(now >= i8253.when){
		clockintr(ureg, v);
		do
			i8253.when += i8253.fastperiod;
		while(i8253.when < now);
	}
	if(i8253.cycwhen || i8253.mode != Square)
		clockintrsched0(checkcycintr(ureg, v));
}

void

M pc/sd53c8xx.c => pc/sd53c8xx.c +30 -2
@@ 315,6 315,10 @@ static unsigned char cf2[] = { 6, 2, 3, 4, 6, 8, 12, 16 };

typedef struct Controller {
	Lock;
	struct {
		uchar scntl3;
		uchar stest2;
	} bios;
	uchar synctab[NULTRA2SCF - 1][8];/* table of legal tpfs */
	NegoState s[MAXTARGET];
	uchar scntl3[MAXTARGET];


@@ 359,6 363,7 @@ enum { DataOut, DataIn, Cmd, Status, ReservedOut, ReservedIn, MessageOut, Messag

static void setmovedata(Movedata*, ulong, ulong);
static void advancedata(Movedata*, long);
static int bios_set_differential(Controller *c);

static char *phase[] = {
	"data out", "data in", "command", "status",


@@ 838,8 843,8 @@ softreset(Controller *c)
		n->dmode |= (1 << 1);	/* burst opcode fetch */
	if (c->v->feature & Differential) {
		/* chip capable */
		if ((c->feature & Differential) || (n->gpreg & 0x8) == 0) {
			/* user enabled, or bit 3 of GPREG clear (Symbios cards) */
		if ((c->feature & Differential) || bios_set_differential(c)) {
			/* user enabled, or some evidence bios set differential */
			if (n->sstat2 & (1 << 2))
				print("sd53c8xx: can't go differential; wrong cable\n");
			else {


@@ 1797,6 1802,25 @@ docheck:
	return r->status = status;
}

static void
cribbios(Controller *c)
{
	c->bios.scntl3 = c->n->scntl3;
	c->bios.stest2 = c->n->stest2;
	print("sd53c8xx: bios scntl3(%.2x) stest2(%.2x)\n", c->bios.scntl3, c->bios.stest2);
}

static int
bios_set_differential(Controller *c)
{
	/* Concept lifted from FreeBSD - thanks Gerard */
	/* basically, if clock conversion factors are set, then there is
 	 * evidence the bios had a go at the chip, and if so, it would
	 * have set the differential enable bit in stest2
	 */
	return (c->bios.scntl3 & 7) != 0 && (c->bios.stest2 & 0x20) != 0;
}

#define NCR_VID 	0x1000
#define NCR_810_DID 	0x0001
#define NCR_820_DID	0x0002	/* don't know enough about this one to support it */


@@ 1808,6 1832,7 @@ docheck:
#define SYM_895_DID	0x000c
#define SYM_885_DID	0x000d	/* ditto */
#define SYM_875_DID	0x000f	/* ditto */
#define SYM_1010_DID	0x0020
#define SYM_875J_DID	0x008f

static Variant variant[] = {


@@ 1826,6 1851,7 @@ static Variant variant[] = {
{ SYM_885_DID,   0xff, "SYM53C885",	Burst128, 16, 24, Prefetch|LocalRAM|BigFifo|Wide|Ultra|ClockDouble },
{ SYM_895_DID,   0xff, "SYM53C895",	Burst128, 16, 24, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 },
{ SYM_896_DID,   0xff, "SYM53C896",	Burst128, 16, 64, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 },
{ SYM_896_DID,   0xff, "SYM53C1010",	Burst128, 16, 64, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 },
};

#define offsetof(s, t) ((ulong)&((s *)0)->t)


@@ 2046,6 2072,7 @@ symenable(SDev* sdev)

	ilock(ctlr);
	synctabinit(ctlr);
	cribbios(ctlr);
	reset(ctlr);
	iunlock(ctlr);



@@ 2070,3 2097,4 @@ SDifc sd53c8xxifc = {
	scsibio,			/* bio */
};