~kris/9p

9hist

362308540b5cf580593f0a82d073a4de5fe41c2e — David du Colombier 34 years ago fd21a50
Plan 9 from Bell Labs 1992-08-06
17 files changed, 300 insertions(+), 274 deletions(-)

M gnot/fns.h
M gnot/l.s
M gnot/trap.c
M pc/dat.h
M pc/fns.h
M pc/kbd.c
M pc/l.s
M pc/main.c
M pc/trap.c
M power/fptrap.c
M power/trap.c
M ss/faultsparc.c
M ss/fns.h
M ss/l.s
M ss/mmu.c
M ss/trap.c
M ss/u.h
M gnot/fns.h => gnot/fns.h +1 -0
@@ 14,6 14,7 @@ void	firmware(void);
void	flushcpucache(void);
#define	flushpage(x) if(x)
int	fpcr(int);
ulong	fpiar(void);
void	fpregrestore(char*);
void	fpregsave(char*);
void	fprestore(FPsave*);

M gnot/l.s => gnot/l.s +0 -1
@@ 170,7 170,6 @@ TEXT	fpcr(SB), $0
	MOVL	R1, FPCR
	RTS


TEXT	rfnote(SB), $0

	MOVL	uregp+0(FP), A7

M gnot/trap.c => gnot/trap.c +9 -2
@@ 79,6 79,7 @@ char*
excname(unsigned vo, ulong pc)
{
	static char buf[32];	/* BUG: not reentrant! */
	ulong fppc;

	vo &= 0x0FFF;
	vo >>= 2;


@@ 90,7 91,10 @@ excname(unsigned vo, ulong pc)
		return buf;
	}
	if(49<=vo && vo<=54){
		sprint(buf, "fp: %s", fptrapname[vo-49]);
		fppc = 0;
		if(u)
			fppc = *(ulong*)(u->fpsave.reg+8);
		sprint(buf, "fp: %s fppc=0x%lux", fptrapname[vo-49], fppc);
		return buf;
	}
	sprint(buf, "offset 0x%ux", vo<<2);


@@ 109,6 113,9 @@ trap(Ureg *ur)
		u->dbgreg = ur;

	if(user){
		splhi();
		procsave(u->p);
		spllo();
		sprint(buf, "sys: %s", excname(ur->vo, ur->pc));
		postnote(u->p, 1, buf, NDebug);
	}else{


@@ 174,7 181,7 @@ notify(Ureg *ur)
		l = strlen(n->msg);
		if(l > ERRLEN-15)	/* " pc=0x12345678\0" */
			l = ERRLEN-15;
		sprint(n->msg+l, " pc=0x%.8lux", ur->pc);
		sprint(n->msg+l, " pc=0x%lux", ur->pc);
	}
	if(n->flag!=NUser && (u->notified || u->notify==0)){
		if(n->flag == NDebug)

M pc/dat.h => pc/dat.h +13 -1
@@ 45,7 45,19 @@ enum

struct	FPsave
{
	uchar	regs[108];
	ushort	control;
	ushort	r1;
	ushort	status;
	ushort	r2;
	ushort	tag;
	ushort	r3;
	ulong	pc;
	ushort	selector;
	ushort	r4;
	ulong	operand;
	ushort	oselector;
	ushort	r5;
	uchar	regs[80];	/* floating point registers */
};

struct Conf

M pc/fns.h => pc/fns.h +1 -0
@@ 16,6 16,7 @@ void	fault386(Ureg*);
void	faultinit(void);
void	fclock(Ureg*);
void	fclockinit(void);
void	fpenv(FPsave*);
void	fpinit(void);
void	fpoff(void);
void	fprestore(FPsave*);

M pc/kbd.c => pc/kbd.c +14 -18
@@ 36,7 36,7 @@ enum {
	Caps=	Spec|0x64,
	Num=	Spec|0x65,
	Middle=	Spec|0x66,
	No=	Spec|0x7F,	/* no mapping */
	No=	0x00,		/* peter */

	Home=	KF|13,
	Up=	KF|14,


@@ 59,11 59,11 @@ uchar kbtab[] =
[0x18]	'o',	'p',	'[',	']',	'\n',	Ctrl,	'a',	's',
[0x20]	'd',	'f',	'g',	'h',	'j',	'k',	'l',	';',
[0x28]	'\'',	'`',	Shift,	'\\',	'z',	'x',	'c',	'v',
[0x30]	'b',	'n',	'm',	',',	'.',	'/',	Shift,	No,
[0x30]	'b',	'n',	'm',	',',	'.',	'/',	Shift,	'*',
[0x38]	Latin,	' ',	Ctrl,	KF|1,	KF|2,	KF|3,	KF|4,	KF|5,
[0x40]	KF|6,	KF|7,	KF|8,	KF|9,	KF|10,	Num,	KF|12,	Home,
[0x48]	No,	No,	No,	No,	No,	No,	No,	No,
[0x50]	No,	No,	No,	No,	No,	No,	No,	KF|11,
[0x40]	KF|6,	KF|7,	KF|8,	KF|9,	KF|10,	Num,	KF|12,	'7',
[0x48]	'8',	'9',	'-',	'4',	'5',	'6',	'+',	'1',
[0x50]	'2',	'3',	'0',	'.',	No,	No,	No,	KF|11,
[0x58]	KF|12,	No,	No,	No,	No,	No,	No,	No,
};



@@ 75,11 75,11 @@ uchar kbtabshift[] =
[0x18]	'O',	'P',	'{',	'}',	'\n',	Ctrl,	'A',	'S',
[0x20]	'D',	'F',	'G',	'H',	'J',	'K',	'L',	':',
[0x28]	'"',	'~',	Shift,	'|',	'Z',	'X',	'C',	'V',
[0x30]	'B',	'N',	'M',	'<',	'>',	'?',	Shift,	No,
[0x30]	'B',	'N',	'M',	'<',	'>',	'?',	Shift,	'*',
[0x38]	Latin,	' ',	Ctrl,	KF|1,	KF|2,	KF|3,	KF|4,	KF|5,
[0x40]	KF|6,	KF|7,	KF|8,	KF|9,	KF|10,	Num,	KF|12,	Home,
[0x48]	No,	No,	No,	No,	No,	No,	No,	No,
[0x50]	No,	No,	No,	No,	No,	No,	No,	KF|11,
[0x40]	KF|6,	KF|7,	KF|8,	KF|9,	KF|10,	Num,	KF|12,	'7',
[0x48]	'8',	'9',	'-',	'4',	'5',	'6',	'+',	'1',
[0x50]	'2',	'3',	'0',	'.',	No,	No,	No,	KF|11,
[0x58]	KF|12,	No,	No,	No,	No,	No,	No,	No,
};



@@ 88,14 88,14 @@ uchar kbtabesc1[] =
[0x00]	No,	No,	No,	No,	No,	No,	No,	No,
[0x08]	No,	No,	No,	No,	No,	No,	No,	No,
[0x10]	No,	No,	No,	No,	No,	No,	No,	No,
[0x18]	No,	No,	No,	No,	No,	Ctrl,	No,	No,
[0x18]	No,	No,	No,	No,	'\n',	Ctrl,	No,	No,
[0x20]	No,	No,	No,	No,	No,	No,	No,	No,
[0x28]	No,	No,	No,	No,	No,	No,	No,	No,
[0x30]	No,	No,	No,	No,	No,	No,	No,	Print,
[0x28]	No,	No,	Shift,	No,	No,	No,	No,	No,
[0x30]	No,	No,	No,	No,	No,	'/',	No,	Print,
[0x38]	Latin,	No,	No,	No,	No,	No,	No,	No,
[0x40]	No,	No,	No,	No,	No,	No,	Break,	Home,
[0x48]	Up,	Pgup,	No,	Down,	No,	Right,	No,	End,
[0x50]	Left,	Pgdown,	Ins,	Del,	No,	No,	No,	No,
[0x48]	Up,	Pgup,	No,	Left,	No,	Right,	No,	End,
[0x50]	Down,	Pgdown,	Ins,	Del,	No,	No,	No,	No,
[0x58]	No,	No,	No,	No,	No,	No,	No,	No,
};



@@ 338,9 338,6 @@ kbdintr0(void)
	if(esc1){
		c = kbtabesc1[c];
		esc1 = 0;
		if(!keyup)
			goto dochar;
		return 0;
	} else if(esc2){
		esc2--;
		return 0;


@@ 373,7 370,6 @@ kbdintr0(void)
	/*
 	 *  normal character
	 */
dochar:
	if(!(c & Spec)){
		if(ctl)
			c &= 0x1f;

M pc/l.s => pc/l.s +5 -0
@@ 330,6 330,11 @@ TEXT	fpstatus(SB),$0		/* get floating point status */
	FSTSW	AX
	RET

TEXT	fpenv(SB),$0		/* save floating point environment without waiting */
	MOVL	p+0(FP),AX
	FSTENV	0(AX)
	RET

/*
 *  special traps
 */

M pc/main.c => pc/main.c +16 -5
@@ 287,16 287,27 @@ matherror(Ureg *ur)
	 */
	outb(0xF0, 0xFF);

	status = fpstatus() & 0xffff;
	msg = "unknown";
	/*
	 *  save floating point state to check out error
	 */
	fpenv(&u->fpsave);
	status = u->fpsave.status;

	msg = 0;
	for(i = 0; i < 8; i++)
		if((1<<i) & status){
			msg = mathmsg[i];
			sprint(note, "sys: fp: %s fppc=0x%lux", msg, u->fpsave.pc);
			postnote(u->p, 1, note, NDebug);
			break;
		}
	sprint(note, "sys: fp: %s, status 0x%ux, pc 0x%lux", msg, status, ur->pc);
print("%s cr0 %lux\n", note, getcr0());
	postnote(u->p, 1, note, NDebug);
	if(msg == 0){
		sprint(note, "sys: fp: unknown fppc=0x%lux", u->fpsave.pc);
		postnote(u->p, 1, note, NDebug);
	}
	if(ur->pc & KZERO)
		panic("fp: status %lux fppc=0x%lux pc=0x%lux", status,
			u->fpsave.pc, ur->pc);
}

/*

M pc/trap.c => pc/trap.c +2 -2
@@ 110,9 110,9 @@ trapinit(void)
	sethvec(11, intr11, SEGTG, 0);
	sethvec(12, intr12, SEGTG, 0);
	sethvec(13, intr13, SEGTG, 0);
	sethvec(14, intr14, SEGIG, 0);
	sethvec(14, intr14, SEGIG, 0);	/* page fault, interrupts off */
	sethvec(15, intr15, SEGTG, 0);
	sethvec(16, intr16, SEGTG, 0);
	sethvec(16, intr16, SEGIG, 0);	/* math coprocessor, interrupts off */

	/*
	 *  device interrupts

M power/fptrap.c => power/fptrap.c +2 -1
@@ 30,6 30,7 @@ fptrap(Ureg *ur, ulong fcr31)
	ulong iw, npc;

	savefpregs(&u->fpsave);
	u->p->fpstate = FPinactive;	/* will get turned on again in trap() */
	if((fcr31&(1<<17)) == 0)
		return 0;
	if(ur->cause & (1<<31))


@@ 45,7 46,7 @@ fptrap(Ureg *ur, ulong fcr31)
				return 0;
		}else
			ur->pc += 4;
		restfpregs(&u->fpsave, fcr31);
		u->fpsave.fpstatus = fcr31 & ~(1<<17);
	}
	return 1;
}

M power/trap.c => power/trap.c +24 -13
@@ 45,7 45,7 @@ char *excname[] =
	/* the following is made up */
	"trap: floating point exception"	/* FPEXC */
};
char	*fpexcname(ulong);
char	*fpexcname(Ureg*, ulong, char*);

char *regname[]={
	"STATUS",	"PC",


@@ 77,7 77,7 @@ trap(Ureg *ur)
	int ecode;
	int user, x;
	ulong fcr31;
	char buf[ERRLEN];
	char buf[2*ERRLEN], buf1[ERRLEN];

	SET(fcr31);
	ecode = EXCCODE(ur->cause);


@@ 151,7 151,7 @@ trap(Ureg *ur)
		if(user){
			spllo();
			if(ecode == FPEXC)
				sprint(buf, "sys: fp: %s FCR31 %lux", fpexcname(fcr31), fcr31);
				sprint(buf, "sys: fp: %s", fpexcname(ur, fcr31, buf1));
			else
				sprint(buf, "sys: %s", excname[ecode]);



@@ 159,7 159,7 @@ trap(Ureg *ur)
		}else{
			print("%s %s pc=%lux\n", user? "user": "kernel", excname[ecode], ur->pc);
			if(ecode == FPEXC)
				print("fp: %s FCR31 %lux\n", fpexcname(fcr31), fcr31);
				print("fp: %s\n", fpexcname(ur, fcr31, buf1));
			dumpregs(ur);
			if(m->machno == 0)
				spllo();


@@ 319,7 319,7 @@ intr(Ureg *ur)
}

char*
fpexcname(ulong fcr31)
fpexcname(Ureg *ur, ulong fcr31, char *buf)
{
	static char *str[]={
		"inexact operation",


@@ 329,15 329,26 @@ fpexcname(ulong fcr31)
		"invalid operation",
	};
	int i;
	char *s;
	ulong fppc;

	fppc = ur->pc;
	if(ur->cause & (1<<31))	/* branch delay */
		fppc += 4;
	s = 0;
	if(fcr31 & (1<<17))
		return "unimplemented operation";
	fcr31 >>= 7;		/* trap enable bits */
	fcr31 &= (fcr31>>5);	/* anded with exceptions */
	for(i=0; i<5; i++)
		if(fcr31 & (1<<i))
			return str[i];
	return "no floating point exception";
		s = "unimplemented operation";
	else{
		fcr31 >>= 7;		/* trap enable bits */
		fcr31 &= (fcr31>>5);	/* anded with exceptions */
		for(i=0; i<5; i++)
			if(fcr31 & (1<<i))
				s = str[i];
	}
	if(s == 0)
		return "no floating point exception";
	sprint(buf, "%s fppc=0x%lux", s, fppc);
	return buf;
}

void


@@ 396,7 407,7 @@ notify(Ureg *ur)
		l = strlen(n->msg);
		if(l > ERRLEN-15)	/* " pc=0x12345678\0" */
			l = ERRLEN-15;
		sprint(n->msg+l, " pc=0x%.8lux", ur->pc);
		sprint(n->msg+l, " pc=0x%lux", ur->pc);
	}
	if(n->flag!=NUser && (u->notified || u->notify==0)){
		if(n->flag == NDebug)

M ss/faultsparc.c => ss/faultsparc.c +3 -3
@@ 28,8 28,8 @@ faultsparc(Ureg *ur)
		/*
		 * According to the book, this isn't good enough.  We'll see.
		 */
		addr = getw2(SEVAR);
		ser = getw2(SER);
		addr = getsysspace(SEVAR);
		ser = getsysspace(SER);
		if(ser&(SE_WRITE|SE_PROT))
			read = 0;
	}


@@ 62,7 62,7 @@ faultasync(Ureg *ur)
{
	int user;

	print("interrupt 15 ASER %lux ASEVAR %lux SER %lux\n", getw2(ASER), getw2(ASEVAR), getw2(SER));
	print("interrupt 15 ASER %lux ASEVAR %lux SER %lux\n", getsysspace(ASER), getsysspace(ASEVAR), getsysspace(SER));
	dumpregs(ur);
	/*
	 * Clear interrupt by toggling low bit of interrupt register

M ss/fns.h => ss/fns.h +3 -12
@@ 19,10 19,9 @@ void	fpregsave(char*);
void	fprestore(FPsave*);
void	fpsave(FPsave*);
int	fptrap(void);
int	getb2(ulong);
int	getfpq(ulong*);
ulong	getfsr(void);
int	getw2(ulong);
ulong	(*getsysspace)(ulong);
void	intrinit(void);
void	ioinit(void);
int	kbdstate(IOQ*, int);


@@ 46,22 45,14 @@ void	printinit(void);
#define	procrestore(p)
#define	procsave(p)
#define	procsetup(x)	((p)->fpstate = FPinit)
void	putb2(ulong, int);
void	putcontext(int);
void	putcxreg(int);
void	putcxsegm(int, ulong, int);
void	(*putenab)(ulong);
void	putpmeg(ulong, ulong);
void	putsegm(ulong, int);
void	(*putsysspace)(ulong, ulong);
void	putstr(char*);
void	putstrn(char*, long);
void	puttbr(ulong);
void	putw2(ulong, ulong);
void	putw4(ulong, ulong);
void	putwC(ulong, ulong);
void	putwD16(ulong, ulong);
void	putwD(ulong, ulong);
void	putwE16(ulong, ulong);
void	putwE(ulong, ulong);
void	systemreset(void);
void	restfpregs(FPsave*, ulong);
void	screeninit(void);

M ss/l.s => ss/l.s +2 -179
@@ 11,8 11,8 @@ TEXT	start(SB), $-4
	MOVW	$KZERO, R7
	MOVB	R0, (R7, 3)
	MOVW	$(KZERO+BY2SEGM), R7
	MOVW	$1, R8
	MOVB	R8, (R7, 3)
	MOVW	$1, R9
	MOVB	R9, (R7, 3)
	/* now mapped correctly.  jmpl to where we want to be */
	MOVW	$setSB(SB), R2
	MOVW	$startvirt(SB), R7


@@ 333,183 333,6 @@ TEXT	getpsr(SB), $0
	MOVW	PSR, R7
	RETURN

TEXT	putcxreg(SB), $0

	MOVW	$CONTEXT, R8
	MOVB	R7, (R8, 2)
	RETURN

TEXT	putb2(SB), $0

	MOVW	4(FP), R8
	MOVB	R8, (R7, 2)
	RETURN

TEXT	getb2(SB), $0

	MOVB	(R7, 2), R7
	RETURN

TEXT	getw2(SB), $0

	MOVW	(R7, 2), R7
	RETURN

TEXT	putw2(SB), $0

	MOVW	4(FP), R8
	MOVW	R8, (R7, 2)
	RETURN

TEXT	putw4(SB), $0

	MOVW	4(FP), R8
	MOVW	R8, (R7, 4)
	RETURN

TEXT	putw6(SB), $0

	MOVW	4(FP), R8
	MOVW	R8, (R7, 6)
	RETURN

TEXT	putw8(SB), $0

	MOVW	4(FP), R8
	MOVW	R8, (R7, 8)
	RETURN

TEXT	getw4(SB), $0

	MOVW	(R7, 4), R7
	RETURN

TEXT	putwC(SB), $0

	MOVW	4(FP), R8
	MOVW	R8, (R7, 0xC)
	RETURN

TEXT	putwD(SB), $0

	MOVW	4(FP), R8
	MOVW	R8, (R7, 0xD)
	RETURN

TEXT	putw716(SB), $0

	MOVW	4(FP), R8
	MOVW	R8, (R7, 0x7)
	ADD	$BY2PG, R7
	MOVW	R8, (R7, 0x7)
	ADD	$BY2PG, R7
	MOVW	R8, (R7, 0x7)
	ADD	$BY2PG, R7
	MOVW	R8, (R7, 0x7)
	ADD	$BY2PG, R7
	MOVW	R8, (R7, 0x7)
	ADD	$BY2PG, R7
	MOVW	R8, (R7, 0x7)
	ADD	$BY2PG, R7
	MOVW	R8, (R7, 0x7)
	ADD	$BY2PG, R7
	MOVW	R8, (R7, 0x7)
	ADD	$BY2PG, R7
	MOVW	R8, (R7, 0x7)
	ADD	$BY2PG, R7
	MOVW	R8, (R7, 0x7)
	ADD	$BY2PG, R7
	MOVW	R8, (R7, 0x7)
	ADD	$BY2PG, R7
	MOVW	R8, (R7, 0x7)
	ADD	$BY2PG, R7
	MOVW	R8, (R7, 0x7)
	ADD	$BY2PG, R7
	MOVW	R8, (R7, 0x7)
	ADD	$BY2PG, R7
	MOVW	R8, (R7, 0x7)
	ADD	$BY2PG, R7
	MOVW	R8, (R7, 0x7)
	RETURN

TEXT	putwD16(SB), $0

	MOVW	4(FP), R8
	MOVW	R8, (R7, 0xD)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xD)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xD)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xD)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xD)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xD)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xD)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xD)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xD)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xD)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xD)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xD)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xD)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xD)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xD)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xD)
	RETURN

TEXT	putwE(SB), $0

	MOVW	4(FP), R8
	MOVW	R8, (R7, 0xE)
	RETURN

TEXT	putwE16(SB), $0

	MOVW	4(FP), R8
	MOVW	R8, (R7, 0xE)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xE)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xE)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xE)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xE)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xE)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xE)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xE)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xE)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xE)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xE)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xE)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xE)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xE)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xE)
	ADD	$VACLINESZ, R7
	MOVW	R8, (R7, 0xE)
	RETURN

TEXT	putsegm(SB), $0

	MOVW	4(FP), R8

M ss/mmu.c => ss/mmu.c +200 -33
@@ 5,16 5,29 @@
#include	"fns.h"
#include	"io.h"

void	compile(void);
#define	NCODE	1024
static	ulong	code[NCODE];
static	ulong	*codep = code;

void	(*putcontext)(ulong);
void	(*putenab)(ulong);
ulong	(*getenab)(void);
void	(*putpmegspace)(ulong, ulong);
void	(*putsysspace)(ulong, ulong);
ulong	(*getsysspace)(ulong);
ulong	(*flushcx)(ulong);
ulong	(*flushpg)(ulong);

struct
{
	Lock;
	int	init;
	int	lowpmeg;
	KMap	*free;
	KMap	arena[(IOEND-IOSEGM)/BY2PG];
}kmapalloc;

#define	NKLUDGE	12
#define	NKLUDGE	11		/* <= ((TOPPMEG-kmap.lowpmeg)/NCONTEXT) */

/*
 * On SPARC, tlbpid i == context i-1 so that 0 means unallocated


@@ 112,21 125,14 @@ newpid(Proc *p)
}

void
putcontext(int c)
{
	putcxreg(c);
}

void
flushcontext(void)
{
	int i;
	ulong a;

	/*
	 * Clear context from cache
	 */
	for(i=0; i<VACSIZE; i+=16*VACLINESZ)
		putwE16(i, 0);
	a = 0;
	do
		a = flushcx(a);
	while(a < VACSIZE);
}

void


@@ 141,10 147,11 @@ mmuinit(void)
{
	ulong ktop, l, i, j, c, pte;

	compile();
	/*
	 * TEMP: just map the first 4M of bank 0 for the kernel - philw
	 * xinit sets conf.npage0 to maximum kernel address
	 */
	ktop = 4*1024*1024;
	ktop = PADDR(conf.npage0);
	/*
	 * First map lots of memory as kernel addressable in all contexts
	 */


@@ 263,16 270,26 @@ print("putmmu %lux %d %s\n", tlbvirt, seg, p->text);
void
putpmeg(ulong virt, ulong phys)
{
	int i;
	ulong a, evirt;

	virt &= VAMASK;
	virt &= ~(BY2PG-1);
#ifdef asdf
	if(conf.ss2)
		putw6(virt, 0);
	else
		for(i=0; i<BY2PG; i+=16*VACLINESZ)
			putwD16(virt+i, 0);
#endif
	/*
	 * Flush old entries from cache
	 */
	for(i=0; i<BY2PG; i+=16*VACLINESZ)
		putwD16(virt+i, 0);
	putw4(virt, phys);
	a = virt;
	evirt = virt+BY2PG;
	do
		a = flushpg(a);
	while(a < evirt);
	putpmegspace(virt, phys);
}

void


@@ 280,14 297,12 @@ putpmegnf(ulong virt, ulong phys)	/* no need to flush */
{
	virt &= VAMASK;
	virt &= ~(BY2PG-1);
	putw4(virt, phys);
	putpmegspace(virt, phys);
}

int nflushmmu;
void
flushmmu(void)
{
nflushmmu++;
	splhi();
	u->p->newtlb = 1;
	mapstack(u->p);


@@ 297,23 312,20 @@ nflushmmu++;
void
cacheinit(void)
{
	int c, i;
	int i;

	putcontext(0);
	/*
	 * Initialize cache by clearing the valid bit
	 * (along with the others) in all cache entries
	 */
	for(c=0; c<NCONTEXT; c++){	/* necessary? */
		putcontext(c);
		for(i=0; i<VACSIZE; i+=VACLINESZ)
			putw2(CACHETAGS+i, 0);
	}
	putcontext(0);
	for(i=0; i<VACSIZE; i+=VACLINESZ)
		putsysspace(CACHETAGS+i, 0);

	/*
	 * Turn cache on
	 */
	putb2(ENAB, getb2(ENAB)|ENABCACHE); /**/
	putenab(getenab()|ENABCACHE); /**/
}

void


@@ 322,8 334,6 @@ kmapinit(void)
	KMap *k;
	int i;

	print("low pmeg %d high pmeg %d\n", kmapalloc.lowpmeg, TOPPMEG);

	kmapalloc.free = 0;
	k = kmapalloc.arena;
	for(i=0; i<(IOEND-IOSEGM)/BY2PG; i++,k++){


@@ 389,3 399,160 @@ invalidateu(void)
{
	putpmeg(USERADDR, INVALIDPTE);
}

/*
 * Compile MMU code for this machine, since the MMU can only
 * be addressed from parameterless machine instructions.
 * What's wrong with MMUs you can talk to from C?
 */

/* op3 */
#define	LD	0
#define	ADD	0
#define	OR	2
#define	LDA	16
#define	LDUBA	17
#define	STA	20
#define	STBA	21
#define	JMPL	56
/* op2 */
#define	SETHI	4

void	*compileconst(int, ulong, int);	/* value to/from constant address */
void	*compileldaddr(int, int);	/* value from parameter address */
void	*compilestaddr(int, int);	/* value to parameter address */
void	*compile16(ulong, int);		/* 16 stores of zero */
void	*compile1(ulong, int);		/* 1 stores of zero */

#define	ret()	{*codep++ = (2<<30)|(0<<25)|(JMPL<<19)|(15<<14)|(1<<13)|8;}
#define	nop()	{*codep++ = (0<<30)|(0<<25)|(SETHI<<22)|(0>>10);}

void
compile(void)
{
	putcontext = compileconst(STBA, CONTEXT, 2);
	getenab = compileconst(LDUBA, ENAB, 2);
	putenab = compileconst(STBA, ENAB, 2);
	putpmegspace = compilestaddr(STA, 4);
	putsysspace = compilestaddr(STA, 2);
	getsysspace = compileldaddr(LDA, 2);
	if(conf.ss2){
		flushpg = compile1(BY2PG, 6);
		flushcx = compile16(VACLINESZ, 7);
	}else{
		flushpg = compile16(VACLINESZ, 0xD);
		flushcx = compile16(VACLINESZ, 0xE);
	}
}

void
parameter(int param, int reg)
{
	param += 1;	/* 0th parameter is 1st word on stack */
	param *= 4;
	/* LD #param(R1), Rreg */
	*codep++ = (3<<30)|(reg<<25)|(LD<<19)|(1<<14)|(1<<13)|param;
}

void
constant(ulong c, int reg)
{
	*codep++ = (0<<30)|(reg<<25)|(SETHI<<22)|(c>>10);
	if(c & 0x3FF)
		*codep++ = (2<<30)|(reg<<25)|(OR<<19)|(reg<<14)|(1<<13)|(c&0x3FF);
}

/*
 * void f(int c) { *(word*,asi)addr = c } for stores
 * ulong f(void)  { return *(word*,asi)addr } for loads
 */
void*
compileconst(int op3, ulong addr, int asi)
{
	void *a;

	a = codep;
	constant(addr, 8);	/* MOVW $CONSTANT, R8 */
	ret();			/* JMPL 8(R15), R0 */
	/* in delay slot 	   st or ld R7, (R8+R0, asi)	*/
	*codep++ = (3<<30)|(7<<25)|(op3<<19)|(8<<14)|(asi<<5);
	return a;
}

/*
 * ulong f(ulong addr)  { return *(word*,asi)addr }
 */
void*
compileldaddr(int op3, int asi)
{
	void *a;

	a = codep;
	ret();			/* JMPL 8(R15), R0 */
	/* in delay slot 	   ld (R7+R0, asi), R7	*/
	*codep++ = (3<<30)|(7<<25)|(op3<<19)|(7<<14)|(asi<<5);
	return a;
}

/*
 * void f(ulong addr, int c) { *(word*,asi)addr = c }
 */
void*
compilestaddr(int op3, int asi)
{
	void *a;

	a = codep;
	parameter(1, 8);	/* MOVW (4*1)(FP), R8 */
	ret();			/* JMPL 8(R15), R0 */
	/* in delay slot 	   st R8, (R7+R0, asi)	*/
	*codep++ = (3<<30)|(8<<25)|(op3<<19)|(7<<14)|(asi<<5);
	return a;
}

/*
 * ulong f(ulong addr) { *addr=0; addr+=offset; return addr}
 * offset can be anything
 */
void*
compile1(ulong offset, int asi)
{
	void *a;

	a = codep;
	/* ST R0, (R7+R0, asi)	*/
	*codep++ = (3<<30)|(0<<25)|(STA<<19)|(7<<14)|(asi<<5);
	if(offset < (1<<12)){
		ret();			/* JMPL 8(R15), R0 */
		/* in delay slot ADD $offset, R7 */
		*codep++ = (2<<30)|(7<<25)|(ADD<<19)|(7<<14)|(1<<13)|offset;
	}else{
		constant(offset, 8);
		ret();			/* JMPL 8(R15), R0 */
		/* in delay slot ADD R8, R7 */
		*codep++ = (2<<30)|(7<<25)|(ADD<<19)|(7<<14)|(0<<13)|8;
	}
	return a;
}

/*
 * ulong f(ulong addr) { for(i=0;i<16;i++) {*addr=0; addr+=offset}; return addr}
 * offset must be less than 1<<12
 */
void*
compile16(ulong offset, int asi)
{
	void *a;
	int i;

	a = codep;
	for(i=0; i<16; i++){
		/* ST R0, (R7+R0, asi)	*/
		*codep++ = (3<<30)|(0<<25)|(STA<<19)|(7<<14)|(asi<<5);
		/* ADD $offset, R7 */
		*codep++ = (2<<30)|(7<<25)|(ADD<<19)|(7<<14)|(1<<13)|offset;
	}
	ret();			/* JMPL 8(R15), R0 */
	nop();
	return a;
}

M ss/trap.c => ss/trap.c +4 -4
@@ 58,7 58,7 @@ excname(ulong tbr)
			if(m->fpunsafe==0 && u->p->fpstate!=FPactive)
				panic("fptrap not active\n");
			fsr = u->fpsave.fsr;
			sprint(excbuf, "fp: %s FQpc=0x%lux",
			sprint(excbuf, "fp: %s fppc=0x%lux",
				fptrapname[(fsr>>14)&7],
				u->fpsave.q[0].a, fsr);
		}


@@ 110,7 110,7 @@ trap(Ureg *ur)
	tbr = (ur->tbr&0xFFF)>>4;
	/* SS2 bug: flush cache line holding trap entry in table */
	if(conf.ss2)
		putw2(CACHETAGS+((TRAPS+16*tbr)&(VACSIZE-1)), 0);
		putsysspace(CACHETAGS+((TRAPS+16*tbr)&(VACSIZE-1)), 0);
	if(tbr > 16){			/* interrupt */
		if(u && u->p->state==Running){
			/* if active, FPop at head of Q is probably an excep */


@@ 407,7 407,7 @@ notify(Ureg *ur)
		l = strlen(n->msg);
		if(l > ERRLEN-15)	/* " pc=0x12345678\0" */
			l = ERRLEN-15;
		sprint(n->msg+l, " pc=0x%.8lux", ur->pc);
		sprint(n->msg+l, " pc=0x%lux", ur->pc);
	}
	if(n->flag!=NUser && (u->notified || u->notify==0)){
		if(n->flag == NDebug)


@@ 521,7 521,7 @@ syscall(Ureg *aur)

	/* SS2 bug: flush cache line holding trap entry in table */
	if(conf.ss2)
		putw2(CACHETAGS+((TRAPS+16*128)&(VACSIZE-1)), 0);
		putsysspace(CACHETAGS+((TRAPS+16*128)&(VACSIZE-1)), 0);

	if(u->p->fpstate == FPactive) {
		fpquiet();

M ss/u.h => ss/u.h +1 -0
@@ 1,3 1,4 @@
typedef	unsigned int	uint;
typedef	unsigned short	ushort;
typedef	unsigned char	uchar;
typedef unsigned long	ulong;