~kris/9p

9hist

d4546706feed0f9dcb007cec2888edfb0ba54819 — David du Colombier 27 years ago ae831ba
Plan 9 from Bell Labs 1999-05-15
7 files changed, 226 insertions(+), 104 deletions(-)

M alphapc/devether.c
M alphapc/fns.h
M alphapc/l.s
M alphapc/main.c
M alphapc/trap.c
M pc/devlml.c
M pc/devlml.h
M alphapc/devether.c => alphapc/devether.c +1 -1
@@ 356,7 356,7 @@ etherreset(void)
				ether->irq = 9;
			intrenable(VectorPCI+ether->irq, ether->interrupt, ether, ether->tbdf);

			i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX irq %d",
			i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX irq %ld",
				ctlrno, ether->type, ether->mbps, ether->port, ether->irq);
			if(ether->mem)
				i += sprint(buf+i, " addr 0x%luX", PADDR(ether->mem));

M alphapc/fns.h => alphapc/fns.h +2 -2
@@ 71,8 71,8 @@ void	pcisetbme(Pcidev*);
void		prflush(void);
void		printinit(void);
#define	procrestore(p)
#define	procsave(p)
#define	procsetup(p)	((p)->fpstate = FPinit)
void	procsave(Proc*);
void	procsetup(Proc*);
void		restfpregs(FPsave*);
uvlong		rpcc(uvlong*);
void		screeninit(void);

M alphapc/l.s => alphapc/l.s +37 -34
@@ 1,6 1,6 @@
#include "mem.h"

#define SP		R30
#define SP	R30

#define	HI_IPL	6			/* use 7 to disable mchecks */



@@ 23,48 23,45 @@ clrbss:
	MOVL	R0, bootconf(SB)	/* passed in from boot loader */

_fpinit:
	MOVQ	R0, R16
	MOVQ	$1, R16
	CALL_PAL $PALwrfen
	MOVQ	$1, R1
	SLLQ	$59, R1			/* normal rounding mode */

	MOVQ	initfpcr(SB), R1	/* MOVQ	$0x2800800000000000, R1 */
	MOVQ	R1, (R30)
	MOVT	(R30), F1
	EXCB
	MOVT	F1, FPCR
	EXCB

	MOVT	$0.5, F28
	ADDT	F28, F28, F29
	ADDT	F29, F29, F30

	SUBT	F28, F28, F0
	MOVT	F0, F1
	MOVT	F0, F2
	MOVT	F0, F3
	MOVT	F0, F4
	MOVT	F0, F5
	MOVT	F0, F6
	MOVT	F0, F7
	MOVT	F0, F8
	MOVT	F0, F9
	MOVT	F0, F10
	MOVT	F0, F11
	MOVT	F0, F12
	MOVT	F0, F13
	MOVT	F0, F14
	MOVT	F0, F15
	MOVT	F0, F16
	MOVT	F0, F17
	MOVT	F0, F18
	MOVT	F0, F19
	MOVT	F0, F20
	MOVT	F0, F21
	MOVT	F0, F22
	MOVT	F0, F23
	MOVT	F0, F24
	MOVT	F0, F25
	MOVT	F0, F26
	MOVT	F0, F27
	MOVT	F31, F1
	MOVT	F31, F2
	MOVT	F31, F3
	MOVT	F31, F4
	MOVT	F31, F5
	MOVT	F31, F6
	MOVT	F31, F7
	MOVT	F31, F8
	MOVT	F31, F9
	MOVT	F31, F10
	MOVT	F31, F11
	MOVT	F31, F12
	MOVT	F31, F13
	MOVT	F31, F14
	MOVT	F31, F15
	MOVT	F31, F16
	MOVT	F31, F17
	MOVT	F31, F18
	MOVT	F31, F19
	MOVT	F31, F20
	MOVT	F31, F21
	MOVT	F31, F22
	MOVT	F31, F23
	MOVT	F31, F24
	MOVT	F31, F25
	MOVT	F31, F26
	MOVT	F31, F27

	JSR	main(SB)
	MOVQ	$_divq(SB), R31		/* touch _divq etc.; doesn't need to execute */


@@ 380,9 377,15 @@ TEXT	savefpregs(SB), $-8
	MOVT	F31, 0xF8(R0)
	MOVT	FPCR, F0
	MOVT	F0, 0x100(R0)

	MOVQ	$0, R16
	CALL_PAL $PALwrfen		/* disable */
	RET

TEXT	restfpregs(SB), $-8
	MOVQ	$1, R16
	CALL_PAL $PALwrfen		/* enable */

	MOVT	0x100(R0), F0
	MOVT	F0, FPCR
	MOVT	0x00(R0), F0

M alphapc/main.c => alphapc/main.c +44 -7
@@ 15,6 15,7 @@ Hwrpb *hwrpb;
Bootconf *bootconf;
Conf	conf;
FPsave	initfp;
uvlong initfpcr = 0x2800800000000000LL;

void
main(void)


@@ 26,8 27,6 @@ main(void)
	clockinit();
	confinit();
	archinit();
	savefpregs(&initfp);
	fpenab(0);
	mmuinit();
	xinit();
	printinit();


@@ 47,8 46,8 @@ main(void)

#ifdef	NEVER
	percpu = hwrpb + (hwrpb[40]>>2);
//	percpu[32] |= 2;			/* restart capable */
	percpu[32] &= ~1;			/* boot in progress - not */
//	percpu[32] |= 2;		/* restart capable */
	percpu[32] &= ~1;		/* boot in progress - not */
//	percpu[32] |= (3<<16);		/* warm boot requested */
//	percpu[32] |= (2<<16);		/* cold boot requested */
//	percpu[32] |= (4<<16);		/* stay halted */


@@ 61,6 60,8 @@ main(void)
	chandevreset();
	pageinit();
	swapinit();
	savefpregs(&initfp);
initfp.fpstatus = 0x68028000;
	userinit();
	schedinit();
}


@@ 131,9 132,7 @@ userinit(void)
	strcpy(p->text, "*init*");
	strcpy(p->user, eve);

	p->fpstate = FPinit;
	p->fpsave.fpstatus = initfp.fpstatus;
	fpenab(0);
	procsetup(p);

	/*
	 * Kernel Stack


@@ 171,6 170,44 @@ userinit(void)
}

void
procsetup(Proc *p)
{
	p->fpstate = FPinit;
	fpenab(0);
}

void
procsave(Proc *p)
{
	if(p->fpstate == FPactive){
		if(p->state == Moribund)
			fpenab(0);
		else{
			/*
			 * Fpsave() stores without handling pending
			 * unmasked exeptions. Postnote() can't be called
			 * here as sleep() already has up->rlock, so
			 * the handling of pending exceptions is delayed
			 * until the process runs again and generates an
			 * emulation fault to activate the FPU.
			 */
			savefpregs(&up->fpsave);
//print("PS=%lux+", up->fpsave.fpstatus);
		}
		p->fpstate = FPinactive;
	}

	/*
	 * Switch to the prototype page tables for this processor.
	 * While this processor is in the scheduler, the process could run
	 * on another processor and exit, returning the page tables to
	 * the free list where they could be reallocated and overwritten.
	 * When this processor eventually has to get an entry from the
	 * trashed page tables it will crash.
	 */
}

void
exit(int)
{
	canlock(&active);

M alphapc/trap.c => alphapc/trap.c +26 -40
@@ 46,11 46,6 @@ trap(Ureg *ur)
	if(user){
		up = m->proc;
		up->dbgreg = ur;
		if(up && up->fpstate == FPactive) {
			up->fpstate = FPinactive;
			savefpregs(&up->fpsave);
			fpenab(0);
		}
	}
	switch ((int)ur->type) {
	case 1:	/* arith */


@@ 82,15 77,9 @@ trap(Ureg *ur)
		break;
	}

	splhi();
	if(!user)
		return;

	notify(ur);
	if(up->fpstate == FPinactive) {
		fpenab(1);
		restfpregs(&up->fpsave);
		up->fpstate = FPactive;
	if(user && (up->procctl || up->nnote)){
		splhi();
		notify(ur);
	}
}



@@ 500,32 489,32 @@ syscall(Ureg *aur)
	up->dbgreg = aur;
	ur->type = 5;		/* for debugging */

	if(up->fpstate == FPactive) {
		up->fpsave.fpstatus = getfcr();
		up->fpstate = FPinit;
		fpenab(0);
	up->scallnr = ur->r0;

	if(up->scallnr == RFORK && up->fpstate == FPactive){
		savefpregs(&up->fpsave);
		up->fpstate = FPinactive;
//print("SR=%lux+", up->fpsave.fpstatus);
	}
	spllo();

	if(up->procctl)
		procctl(up);

	up->scallnr = ur->r0;
	up->nerrlab = 0;
	sp = ur->sp;
	up->nerrlab = 0;
	ret = -1;
	if(waserror())
		goto error;

	if(up->scallnr >= nsyscall){
		pprint("bad sys call %d pc %lux\n", up->scallnr, (ulong)ur->pc);
		pprint("bad sys call %d pc %lux\n",
			up->scallnr, (ulong)ur->pc);
print("bad sys call %d pc %lux\n", up->scallnr, (ulong)ur->pc);
		postnote(up, 1, "sys: bad sys call", NDebug);
		error(Ebadarg);
	}

	if(sp & (BY2WD-1)){	/* XXX too weak? */
		pprint("odd sp in sys call pc %lux sp %lux\n", (ulong)ur->pc, (ulong)ur->sp);
		pprint("odd sp in sys call pc %lux sp %lux\n",
			(ulong)ur->pc, (ulong)ur->sp);
		postnote(up, 1, "sys: odd stack", NDebug);
		error(Ebadarg);
	}


@@ 543,19 532,15 @@ error:
	up->nerrlab = 0;
	up->psstate = 0;
	up->insyscall = 0;
	if(up->scallnr == NOTED)				/* ugly hack */
	if(up->scallnr == NOTED)			/* ugly hack */
		noted(ur, &aur, *(ulong*)(sp+2*BY2WD));	/* doesn't return */

	splhi();
	if(up->scallnr!=RFORK && (up->procctl || up->nnote)){
		ur->r0 = ret;				/* load up for noted() */
		if(notify(ur))
			return ur->r0;
	}

	if(up->fpstate == FPinactive)		/* due to race with intr */
		up->fpstate = FPinit;

	return ret;
}



@@ 605,7 590,6 @@ execregs(ulong entry, ulong ssize, ulong nargs)
	ur = (Ureg*)up->dbgreg;
	ur->usp = (ulong)sp;
	ur->pc = entry;
	up->fpsave.fpstatus = initfp.fpstatus;
	return USTKTOP-BY2WD;			/* address of user-level clock */
}



@@ 683,18 667,20 @@ illegal(Ureg *ur)
void
fen(Ureg *ur)
{
	ulong fpcr;

	if ((ur->status&UMODE) && up) {
		if(up->fpstate == FPinit) {
	if(up){
		switch(up->fpstate){
		case FPinit:
			restfpregs(&initfp);
			up->fpstate = FPactive;
			fpcr = up->fpsave.fpstatus;
			up->fpsave = initfp;
			up->fpsave.fpstatus = fpcr;
			fpenab(1);
//print("EI=%lux+", initfp.fpstatus);
			return;

		case FPinactive:
			restfpregs(&up->fpsave);
			up->fpstate = FPactive;
//print("EIA=%lux+", up->fpsave.fpstatus);
			return;
		}
	}
	fataltrap(ur, "trap: floating enable");		/* should never happen */
	fataltrap(ur, "trap: floating enable");	/* should never happen */
}

M pc/devlml.c => pc/devlml.c +116 -13
@@ 8,6 8,11 @@

#include	"devlml.h"

#define DBGREGS 0x1
#define DBGREAD 0x2
#define DBGWRIT 0x4
int debug = DBGREAD|DBGWRIT;

// Lml 22 driver

enum{


@@ 15,6 20,7 @@ enum{
	Q819,
	Q856,
	Qreg,
	Qmap,
	Qjvideo,
	Qjframe,
};


@@ 24,6 30,7 @@ static Dirtab lmldir[]={
	"lml819",	{Q819},		0,		0644,
	"lml856",	{Q856},		0,		0644,
	"lmlreg",	{Qreg},		0,		0644,
	"lmlmap",	{Qmap},		0,		0444,
	"jvideo",	{Qjvideo},	0,		0666,
	"jframe",	{Qjframe},	0,		0666,
};


@@ 41,12 48,75 @@ int		hdrPos;
int		nopens;
uchar		q856[3];

struct {
	ulong pci;
	ulong dma;
	ulong codedata;
} lmlmap;

static FrameHeader frameHeader = {
	MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8,
	{ 'L', 'M', 'L', '\0'},
	-1, 0, 0, 0, 0
};

ulong
writel(ulong v, ulong a) {
	if (debug&DBGREGS)
		pprint("writing %.8lux  to  %.8lux (%.4lux)\n",
			v, a, (ulong)a-pciBaseAddr);
	return *(ulong *)a = v;
}

ushort
writew(ushort v, ulong a) {
	if (debug&DBGREGS)
		pprint("writing     %.4ux  to  %.8lux (%.4lux)\n",
			v, a, (ulong)a-pciBaseAddr);
	return *(ushort *)a = v;
}

uchar
writeb(uchar v, ulong a) {
	if (debug&DBGREGS)
		pprint("writing       %.2ux  to  %.8lux (%.4lux)\n",
			v, a, (ulong)a-pciBaseAddr);
	return *(uchar *)a = v;
}

ulong
readl(ulong a) {
	ulong v;

	v = *(ulong*)a;
	if (debug&DBGREGS)
		pprint("reading %.8lux from %.8lux (%.4lux)\n",
			v, a, (ulong)a-pciBaseAddr);
	return v;
}

ushort
readw(ulong a) {
	ushort v;

	v = *(ushort*)a;
	if (debug&DBGREGS)
		pprint("reading     %.4ux from %.8lux (%.4lux)\n",
			v, a, (ulong)a-pciBaseAddr);
	return v;
}

uchar
readb(ulong a) {
	uchar v;

	v = *(uchar*)a;
	if (debug&DBGREGS)
		pprint("reading       %.2ux from %.8lux (%.4lux)\n",
			v, a, (ulong)a-pciBaseAddr);
	return v;
}

static void
i2c_pause(void) {



@@ 222,6 292,7 @@ i2c_rd8(int addr, int sub)

	if (i2c_wrbyte(addr) == 1
	 || i2c_wrbyte(sub) == 1) {
		if (debug&DBGREGS) pprint("i2c_rd8, failure 1\n");
		i2c_stop();
		return -1;
	}


@@ 230,6 301,7 @@ i2c_rd8(int addr, int sub)

	if (i2c_wrbyte(addr+1) == 1
	 || i2c_rdbyte(&msb) == 0){
		if (debug&DBGREGS) pprint("i2c_rd8, failure 2\n");
		i2c_stop();
		return -1;
	}


@@ 303,10 375,13 @@ vread(Chan *, void *va, long count, vlong pos) {
	vlong thetime;
	uchar *buf = va;

	//print("devlml::vread() count=%ld pos=%lld\n", count, pos);
	if(debug&DBGREAD)
		pprint("devlml::vread() count=%ld pos=%lld\n", count, pos);

	// If we just begin reading a file, pos would never be 0 otherwise
	if (pos == 0 && hdrPos == -1) {
		if(debug&DBGREAD)
			pprint("devlml::first read\n");
		 currentBuffer = -1;
		 currentBufferLength = 0;
		 frameNo = -1;


@@ 316,12 391,18 @@ vread(Chan *, void *va, long count, vlong pos) {
	// We get to the end of the current buffer, also covers just
	// open file, since 0 >= -1
	if(hdrPos == -1 && pos >= currentBufferLength) {
		if(debug&DBGREAD)
			pprint("devlml::prepareBuffer\n");
		prepareBuffer(codeData, currentBuffer);
		// if not the first buffer read and single frame mode - return EOF
		if (currentBuffer != -1 && singleFrame)
			return 0;
		if(debug&DBGREAD)
			pprint("devlml::sleep\n");
		while((currentBuffer = getProcessedBuffer(codeData)) == -1)
			sleep(&sleeper, return0, 0);
		if(debug&DBGREAD)
			pprint("devlml::wokeup\n");
		currentBufferLength = getBuffer(codeData, currentBuffer,
			&currentBufferPtr, &frameNo);



@@ 362,7 443,7 @@ vread(Chan *, void *va, long count, vlong pos) {
	memmove(buf + retcount, (char *)currentBufferPtr + pos, cpcount);
	retcount += cpcount;

	//pr_debug("return %d %d\n",cpcount,retcount);
	//pr_debug&DBGREGS("return %d %d\n",cpcount,retcount);
	return retcount;
}



@@ 511,6 592,10 @@ lmlreset(void)
	// Interrupt handler
	intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf);

	lmlmap.pci = pciBaseAddr;
	lmlmap.dma = PADDR(codeData);
	lmlmap.codedata = (ulong)codeData;

	return; 
}



@@ 540,6 625,7 @@ lmlopen(Chan *c, int omode)
	case Q819:
	case Q856:
	case Qreg:
	case Qmap:
		break;
	case Qjvideo:
	case Qjframe:


@@ 566,8 652,12 @@ lmlclose(Chan *c)
	case Q819:
	case Q856:
	case Qreg:
	case Qmap:
		authclose(c);
		break;
	case Qjvideo:
	case Qjframe:
		nopens = 0;
		authclose(c);
	}
}


@@ 577,7 667,6 @@ lmlread(Chan *c, void *va, long n, vlong voff) {
	int i, d;
	uchar *buf = va;
	long off = voff;
	long v;

	switch(c->qid.path & ~CHDIR){



@@ 591,7 680,7 @@ lmlread(Chan *c, void *va, long n, vlong voff) {
			if ((d = i2c_rd8(BT819Addr, off++)) < 0) break;
			*buf++ = d;
		}
		return n - i;
		return i;
	case Q856:
		if (n != 1)
			return 0;


@@ 614,6 703,15 @@ lmlread(Chan *c, void *va, long n, vlong voff) {
			return 0;
		}
		return 1;
	case Qmap:
		if (off < 0)
			return 0;
		for (i = 0; i < n; i++) {
			if (off + i > sizeof lmlmap)
				break;
			buf[i] = ((uchar *)&lmlmap)[off + i];
		}
		return i;
	case Qreg:
		if (off < 0 || off + n > 0x400)
			return 0;


@@ 627,9 725,7 @@ lmlread(Chan *c, void *va, long n, vlong voff) {
			break;
		case 4:
			if (off & (n-1)) return 0;
			v = readl(pciBaseAddr + off);
			*(long *)buf = v;
print("reading %lux at %lux (%lux)\n", v, pciBaseAddr + off, off);
			*(long *)buf = readl(pciBaseAddr + off);
			break;
		default:
			return 0;


@@ 658,7 754,7 @@ lmlwrite(Chan *c, void *va, long n, vlong voff) {
		for (i = n; i > 0; i--)
			if (i2c_wr8(BT819Addr, off++, *buf++) == 0)
				break;
		return n - i;
		return i;
	case Q856:
		if (n != 1 || off < 0xda || off + n > 0xe0)
			return 0;


@@ 677,17 773,20 @@ lmlwrite(Chan *c, void *va, long n, vlong voff) {
		}
		return 1;
	case Qreg:
		if (off < 0 || off + n > 0x200 || (off & 0x3))
		if (off < 0 || off + n > 0x400)
			return 0;
		switch (n) {
		case 1:
			writeb(*buf, pciBaseAddr + off);
			break;
		case 2:
			if (off & 0x1)
				return 0;
			writew(*(short *)buf, pciBaseAddr + off);
			break;
		case 4:
print("writing %lux to %lux (%lux)\n", *(long *)buf, pciBaseAddr + off, off);
			if (off & 0x3)
				return 0;
			writel(*(long *)buf, pciBaseAddr + off);
			break;
		default:


@@ 725,12 824,16 @@ static void
lmlintr(Ureg *, void *) {
	ulong flags = readl(pciBaseAddr+ZR36057_INTR_STAT);
	
//  print("MjpgDrv_intrHandler stat=0x%08x\n", flags);
	if(debug&(DBGREAD|DBGWRIT))
		print("MjpgDrv_intrHandler stat=0x%.8lux\n", flags);

	// Reset all interrupts from 067
	writel(0xff000000, pciBaseAddr + ZR36057_INTR_STAT);

	if(flags & ZR36057_INTR_JPEGREP)
			wakeup(&sleeper);
	if(flags & ZR36057_INTR_JPEGREP) {
		if(debug&(DBGREAD|DBGWRIT))
			print("MjpgDrv_intrHandler wakeup\n");
		wakeup(&sleeper);
	}
	return;
}

M pc/devlml.h => pc/devlml.h +0 -7
@@ 89,13 89,6 @@ typedef struct {
#define FRAGM_FINAL_B 1
#define STAT_BIT 1

#define writel(v, a)	(*(ulong  *)(a) = (v))
#define writew(v, a)	(*(ushort *)(a) = (v))
#define writeb(v, a)	(*(uchar  *)(a) = (v))
#define readl(a)	(*(ulong  *)(a))
#define readw(a)	(*(ushort *)(a))
#define readb(a)	(*(uchar  *)(a))

typedef struct FrameHeader		FrameHeader;
typedef struct MjpgDrv			MjpgDrv;
typedef struct Fragment			Fragment;