~kris/9p

9hist

3490e974e0b8859b6ac76acb85e4d1e0efda82bb — David du Colombier 34 years ago c29171f
Plan 9 from Bell Labs 1991-12-18
M gnot/fault68020.c => gnot/fault68020.c +2 -2
@@ 90,8 90,8 @@ fault68020(Ureg *ur, FFrame *f)

	if(fault(addr, read) < 0){
		if(user){
			sprint(buf, "sys: fault %s pc=0x%lux addr=0x%lux",
				read? "read" : "write", ur->pc, badvaddr);
			sprint(buf, "sys: trap: fault %s addr=0x%lux",
				read? "read" : "write", badvaddr);
			postnote(u->p, 1, buf, NDebug);
			notify(ur);
			return;

M gnot/trap.c => gnot/trap.c +29 -6
@@ 40,7 40,7 @@ char *trapname[]={
	"illegal instruction",
	"zero divide",
	"chk, chk2 instruction",
	"cptrapcc, trapcc, trapv instruction",
	"trapcc instruction",
	"privilege violation",
	"trace",
	"line 1010 emulator",


@@ 67,6 67,15 @@ char *trapname[]={
	"level 7 autovector",
};

char *fptrapname[]={
[49-49]	"inexact result",
[50-49]	"divide by zero",
[51-49]	"underflow",
[52-49]	"operand error",
[53-49]	"overflow",
[54-49]	"signaling NaN",
};

char*
excname(unsigned vo, ulong pc)
{


@@ 78,7 87,12 @@ excname(unsigned vo, ulong pc)
		/* special case, and pc will be o.k. */
		if(vo==4 && *(ushort*)pc==0x4848)
			return "breakpoint";
		return trapname[vo];
		sprint(buf, "trap: %s", trapname[vo]);
		return buf;
	}
	if(49<=vo && vo<=54){
		sprint(buf, "fp: %s", fptrapname[vo-49]);
		return buf;
	}
	sprint(buf, "offset 0x%ux", vo<<2);
	return buf;


@@ 97,7 111,7 @@ trap(Ureg *ur)
		u->dbgreg = ur;
	}
	if(user){
		sprint(buf, "sys: %s pc=0x%lux", excname(ur->vo, ur->pc), ur->pc);
		sprint(buf, "sys: %s", excname(ur->vo, ur->pc));
		postnote(u->p, 1, buf, NDebug);
	}else{
		print("kernel trap %s pc=0x%lux\n", excname(ur->vo, ur->pc), ur->pc);


@@ 145,7 159,9 @@ dumpregs(Ureg *ur)
void
notify(Ureg *ur)
{
	int l;
	ulong s, sp;
	Note *n;

	if(u->p->procctl)
		procctl(u->p);


@@ 155,12 171,19 @@ notify(Ureg *ur)
	s = spllo();
	qlock(&u->p->debug);
	u->p->notepending = 0;
	if(u->note[0].flag!=NUser && (u->notified || u->notify==0)){
	n = &u->note[0];
	if(strncmp(n->msg, "sys:", 4) == 0){
		l = strlen(n->msg);
		if(l > ERRLEN-15)	/* " pc=0x12345678\0" */
			l = ERRLEN-15;
		sprint(n->msg+l, " pc=0x%.8lux", ur->pc);
	}
	if(n->flag!=NUser && (u->notified || u->notify==0)){
		if(u->note[0].flag == NDebug)
			pprint("suicide: %s\n", u->note[0].msg);
			pprint("suicide: %s\n", n->msg);
    Die:
		qunlock(&u->p->debug);
		pexit(u->note[0].msg, u->note[0].flag!=NDebug);
		pexit(n->msg, n->flag!=NDebug);
	}
	if(!u->notified){
		if(!u->notify)

M pc/fault386.c => pc/fault386.c +2 -2
@@ 26,8 26,8 @@ fault386(Ureg *ur)
	n = fault(addr, read);
	if(n < 0){
		if(user){
			sprint(buf, "sys: fault %s pc=0x%lux addr=0x%lux",
				read? "read" : "write", ur->pc, addr);
			sprint(buf, "sys: trap: fault %s addr=0x%lux",
				read? "read" : "write", addr);
			postnote(u->p, 1, buf, NDebug);
			return;
		}

M pc/trap.c => pc/trap.c +14 -5
@@ 77,7 77,7 @@ debugbpt(Ureg *ur)
		panic("kernel bpt");
	/* restore pc to instruction that caused the trap */
	ur->pc--;
	sprint(buf, "sys: breakpoint pc=0x%lux", ur->pc);
	sprint(buf, "sys: breakpoint");
	postnote(u->p, 1, buf, NDebug);
}



@@ 228,7 228,7 @@ trap(Ureg *ur)
			return;
		if(v <= 16){
			if(user){
				sprint(buf, "sys: %s pc=0x%lux", excname[v], ur->pc);
				sprint(buf, "sys: trap: %s", excname[v]);
				postnote(u->p, 1, buf, NDebug);
				return;
			} else {


@@ 353,7 353,9 @@ syscall(Ureg *ur)
void
notify(Ureg *ur)
{
	int l;
	ulong s, sp;
	Note *n;

	if(u->p->procctl)
		procctl(u->p);


@@ 363,12 365,19 @@ notify(Ureg *ur)
	s = spllo();
	qlock(&u->p->debug);
	u->p->notepending = 0;
	if(u->note[0].flag!=NUser && (u->notified || u->notify==0)){
	n = &u->note[0];
	if(strncmp(n->msg, "sys:", 4) == 0){
		l = strlen(n->msg);
		if(l > ERRLEN-15)	/* " pc=0x12345678\0" */
			l = ERRLEN-15;
		sprint(n->msg+l, " pc=0x%.8lux", ur->pc);
	}
	if(n->flag!=NUser && (u->notified || u->notify==0)){
		if(u->note[0].flag == NDebug)
			pprint("suicide: %s\n", u->note[0].msg);
			pprint("suicide: %s\n", n->msg);
    Die:
		qunlock(&u->p->debug);
		pexit(u->note[0].msg, u->note[0].flag!=NDebug);
		pexit(n->msg, n->flag!=NDebug);
	}
	if(!u->notified){
		if(!u->notify)

M port/devip.c => port/devip.c +29 -29
@@ 16,11 16,11 @@ enum
};

int 	udpsum = 1;
Queue	*Ipoutput;		/* Control message stream for tcp/il */
Ipifc	*ipifc;			/* IP protocol interfaces for stip */
Ipconv	*ipconv[Nrprotocol];	/* Connections for each protocol */
Network	*ipnet[Nrprotocol];	/* User level interface for protocol */
QLock	ipalloc;		/* Protocol port allocation lock */
Queue	*Ipoutput;			/* Control message stream for tcp/il */
Ipifc	*ipifc;				/* IP protocol interfaces for stip */
Ipconv	*ipconv[Nrprotocol];		/* Connections for each protocol */
Network	*ipnet[Nrprotocol];		/* User level interface for protocol */
QLock	ipalloc;			/* Protocol port allocation lock */

/* ARPA User Datagram Protocol */
void	udpstiput(Queue *, Block *);


@@ 157,7 157,7 @@ ipincoming(Ipconv *base, Ipconv *from)
	for(new = base; new < etab; new++) {
		if(new->ref == 0 && canqlock(new)) {
			if(new->ref ||
		          (new->stproto == &tcpinfo && new->tcpctl.state != CLOSED) ||
		          (new->stproto == &tcpinfo && new->tcpctl.state != Closed) ||
			  (new->stproto == &ilinfo && new->ilctl.state != Ilclosed)) {
				qunlock(new);
				continue;


@@ 237,7 237,7 @@ ipwrite(Chan *c, char *a, long n, ulong offset)
		errors("bad ip control");

	if(strcmp(field[0], "connect") == 0) {
		if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) ||
		if((cp->stproto == &tcpinfo && cp->tcpctl.state != Closed) ||
		   (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed))
				error(Edevbusy);



@@ 279,7 279,7 @@ ipwrite(Chan *c, char *a, long n, ulong offset)
		cp->pdst = 0;
	}
	else if(strcmp(field[0], "announce") == 0) {
		if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) ||
		if((cp->stproto == &tcpinfo && cp->tcpctl.state != Closed) ||
		   (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed))
				error(Edevbusy);



@@ 501,15 501,15 @@ tcpstoput(Queue *q, Block *bp)
		error(s->err);

	switch(tcb->state) {
	case LISTEN:
	case Listen:
		tcb->flags |= ACTIVE;
		send_syn(tcb);
		setstate(s, SYN_SENT);
		setstate(s, Syn_sent);
		/* No break */
	case SYN_SENT:
	case SYN_RECEIVED:
	case ESTABLISHED:
	case CLOSE_WAIT:
	case Syn_sent:
	case Syn_received:
	case Established:
	case Close_wait:
		qlock(tcb);
		tcb->sndcnt += blen(bp);
		if(tcb->sndq == 0)


@@ 620,7 620,7 @@ iplisten(Chan *c)
	s = &ipconv[c->dev][connection];
	base = ipconv[c->dev];

	if((s->stproto == &tcpinfo && s->tcpctl.state != LISTEN) ||
	if((s->stproto == &tcpinfo && s->tcpctl.state != Listen) ||
	   (s->stproto == &ilinfo && s->ilctl.state != Illistening))
		errors("not announced");



@@ 659,21 659,21 @@ tcpstclose(Queue *q)
	s->readq = 0;

	switch(tcb->state){
	case CLOSED:
	case LISTEN:
	case SYN_SENT:
	case Closed:
	case Listen:
	case Syn_sent:
		close_self(s, 0);
		break;
	case SYN_RECEIVED:
	case ESTABLISHED:
	case Syn_received:
	case Established:
		tcb->sndcnt++;
		tcb->snd.nxt++;
		setstate(s, FINWAIT1);
		setstate(s, Finwait1);
		goto output;
	case CLOSE_WAIT:
	case Close_wait:
		tcb->sndcnt++;
		tcb->snd.nxt++;
		setstate(s, LAST_ACK);
		setstate(s, Last_ack);
	output:
		qlock(tcb);
		tcp_output(s);


@@ 785,10 785,9 @@ portused(Ipconv *ic, Port port)
	Ipconv *ifc, *etab;

	etab = &ic[conf.ip];
	for(ifc = ic; ifc < etab; ifc++) {
	for(ifc = ic; ifc < etab; ifc++)
		if(ifc->psrc == port) 
			return ifc;
	}

	return 0;
}


@@ 798,10 797,10 @@ nextport(Ipconv *ic, Port base)
{
	Port i;

	for(i = base; i < PORTMAX; i++) {
	for(i = base; i < PORTMAX; i++)
		if(!portused(ic, i))
			return(i);
	}

	return(0);
}



@@ 815,8 814,9 @@ ip_conn(Ipconv *ic, Port dst, Port src, Ipaddr dest, char proto)
	/* Look for a conversation structure for this port */
	etab = &ic[conf.ip];
	for(s = ic; s < etab; s++) {
		if(s->psrc == dst && s->pdst == src &&
		   (s->dst == dest || dest == 0))
		if(s->psrc == dst)
		if(s->pdst == src)
		if(s->dst == dest || dest == 0)
			return s;
	}


M port/ipdat.h => port/ipdat.h +12 -12
@@ 337,19 337,19 @@ struct Ipconv
#define	read_timer(t)	((t)->count)
#define	run_timer(t)	((t)->state == TIMER_RUN)

enum
enum					/* Tcp connection states */
{
	CLOSED = 0,
	LISTEN,
	SYN_SENT,
	SYN_RECEIVED,
	ESTABLISHED,
	FINWAIT1,
	FINWAIT2,
	CLOSE_WAIT,
	CLOSING,
	LAST_ACK,
	TIME_WAIT
	Closed = 0,
	Listen,
	Syn_sent,
	Syn_received,
	Established,
	Finwait1,
	Finwait2,
	Close_wait,
	Closing,
	Last_ack,
	Time_wait
};

/*

M port/proc.c => port/proc.c +5 -3
@@ 506,6 506,7 @@ freebroken(void)
void
pexit(char *exitstr, int freemem)
{
	int n;
	Proc *p, *c;
	Segment **s, **es, *os;
	Waitq *wq, *f, *next;


@@ 526,9 527,10 @@ pexit(char *exitstr, int freemem)
		wq->w.time[TUser] = TK2MS(c->time[TUser]);
		wq->w.time[TSys] = TK2MS(c->time[TSys]);
		wq->w.time[TReal] = TK2MS(MACHP(0)->ticks - c->time[TReal]);
		if(exitstr)
			strncpy(wq->w.msg, exitstr, ERRLEN);
		else
		if(exitstr && exitstr[0]){
			n = sprint(wq->w.msg, "%s %d:", c->text, c->pid);
			strncpy(wq->w.msg+n, exitstr, ERRLEN-n);
		}else
			wq->w.msg[0] = '\0';

		/* Find my parent */

M port/tcpif.c => port/tcpif.c +5 -5
@@ 23,12 23,12 @@ state_upcall(Ipconv *s, char oldstate, char newstate)
		return;

	switch(newstate) {
	case CLOSED:
	case Closed:
		s->psrc = 0;
		s->pdst = 0;
		s->dst = 0;
		/* NO break */
	case CLOSE_WAIT:		/* Remote closes */
	case Close_wait:		/* Remote closes */
		if(s->readq == 0)
			break;



@@ 53,7 53,7 @@ tcpstart(Ipconv *s, int mode, ushort window, char tos)
{
	Tcpctl *tcb = &s->tcpctl;

	if(tcb->state != CLOSED)
	if(tcb->state != Closed)
		return;

	init_tcpctl(s);


@@ 64,14 64,14 @@ tcpstart(Ipconv *s, int mode, ushort window, char tos)
	switch(mode){
	case TCP_PASSIVE:
		tcb->flags |= CLONE;
		setstate(s, LISTEN);
		setstate(s, Listen);
		break;
	case TCP_ACTIVE:
		/* Send SYN, go into SYN_SENT state */
		tcb->flags |= ACTIVE;
		qlock(tcb);
		send_syn(tcb);
		setstate(s, SYN_SENT);
		setstate(s, Syn_sent);
		tcp_output(s);
		qunlock(tcb);
		break;

M port/tcpinput.c => port/tcpinput.c +40 -40
@@ 75,7 75,7 @@ tcp_input(Ipconv *ipc, Block *bp)

		e = &ipc[conf.ip];
		for(s = ipc; s < e; s++) {
			if(s->tcpctl.state == LISTEN)
			if(s->tcpctl.state == Listen)
			if(s->pdst == 0)
			if(s->dst == 0) {
				if(s->curlog >= s->backlog)


@@ 114,11 114,11 @@ process:
	qlock(tcb);

	switch(tcb->state) {
	case CLOSED:
	case Closed:
		freeb(bp);
		reset(source, dest, tos, length, &seg);
		goto done;
	case LISTEN:
	case Listen:
		if(seg.flags & RST) {
			freeb(bp);
			goto done;


@@ 131,7 131,7 @@ process:
		if(seg.flags & SYN) {
			proc_syn(s, tos, &seg);
			send_syn(tcb);
			setstate(s, SYN_RECEIVED);		
			setstate(s, Syn_received);		
			if(length != 0 || (seg.flags & FIN)) 
				break;
			freeb(bp);


@@ 139,7 139,7 @@ process:
		}
		freeb(bp);
		goto done;
	case SYN_SENT:
	case Syn_sent:
		if(seg.flags & ACK) {
			if(!seq_within(seg.ack, tcb->iss+1, tcb->snd.nxt)) {
				freeb(bp);


@@ 163,10 163,10 @@ process:
			proc_syn(s, tos, &seg);
			if(seg.flags & ACK){
				update(s, &seg);
				setstate(s, ESTABLISHED);
				setstate(s, Established);
			}
			else 
				setstate(s, SYN_RECEIVED);
				setstate(s, Syn_received);

			if(length != 0 || (seg.flags & FIN))
				break;


@@ 205,9 205,9 @@ process:

	for(;;) {
		if(seg.flags & RST) {
			if(tcb->state == SYN_RECEIVED
			if(tcb->state == Syn_received
			   && !(tcb->flags & (CLONE|ACTIVE))) 
				setstate(s, LISTEN);
				setstate(s, Listen);
			else
				close_self(s, Econrefused);



@@ 227,10 227,10 @@ process:
		}

		switch(tcb->state) {
		case SYN_RECEIVED:
		case Syn_received:
			if(seq_within(seg.ack, tcb->snd.una+1, tcb->snd.nxt)){
				update(s, &seg);
				setstate(s, ESTABLISHED);
				setstate(s, Established);
			}
			else {
				freeb(bp);


@@ 238,33 238,33 @@ process:
				goto done;
			}
			break;
		case ESTABLISHED:
		case CLOSE_WAIT:
		case Established:
		case Close_wait:
			update(s, &seg);
			break;
		case FINWAIT1:
		case Finwait1:
			update(s, &seg);
			if(tcb->sndcnt == 0)
				setstate(s, FINWAIT2);
				setstate(s, Finwait2);
			break;
		case FINWAIT2:
		case Finwait2:
			update(s, &seg);
			break;
		case CLOSING:
		case Closing:
			update(s, &seg);
			if(tcb->sndcnt == 0){
				setstate(s, TIME_WAIT);
				setstate(s, Time_wait);
				tcb->timer.start = MSL2 * (1000 / MSPTICK);
				start_timer(&tcb->timer);
			}
			break;
		case LAST_ACK:
		case Last_ack:
			update(s, &seg);
			if(tcb->sndcnt == 0) {
				close_self(s, 0);
				goto done;
			}			
		case TIME_WAIT:
		case Time_wait:
			tcb->flags |= FORCE;
			start_timer(&tcb->timer);
		}


@@ 280,10 280,10 @@ process:

		if(length != 0){
			switch(tcb->state){
			case SYN_RECEIVED:
			case ESTABLISHED:
			case FINWAIT1:
			case FINWAIT2:
			case Syn_received:
			case Established:
			case Finwait1:
			case Finwait2:
				/* Place on receive queue */
				tcb->rcvcnt += blen(bp);
				if(s->readq && bp) {


@@ 310,32 310,32 @@ process:
			tcb->flags |= FORCE;

			switch(tcb->state) {
			case SYN_RECEIVED:
			case ESTABLISHED:
			case Syn_received:
			case Established:
				tcb->rcv.nxt++;
				setstate(s, CLOSE_WAIT);
				setstate(s, Close_wait);
				break;
			case FINWAIT1:
			case Finwait1:
				tcb->rcv.nxt++;
				if(tcb->sndcnt == 0) {
					setstate(s, TIME_WAIT);
					setstate(s, Time_wait);
					tcb->timer.start = MSL2 * (1000/MSPTICK);
					start_timer(&tcb->timer);
				}
				else 
					setstate(s, CLOSING);
					setstate(s, Closing);
				break;
			case FINWAIT2:
			case Finwait2:
				tcb->rcv.nxt++;
				setstate(s, TIME_WAIT);
				setstate(s, Time_wait);
				tcb->timer.start = MSL2 * (1000/MSPTICK);
				start_timer(&tcb->timer);
				break;
			case CLOSE_WAIT:
			case CLOSING:
			case LAST_ACK:
			case Close_wait:
			case Closing:
			case Last_ack:
				break;
			case TIME_WAIT:
			case Time_wait:
				start_timer(&tcb->timer);
				break;
			}


@@ 374,13 374,13 @@ tcp_icmp(Ipconv *ipc, Ipaddr source, Ipaddr dest, char type, char code, Block **
	case ICMP_UNREACH:
		tcb->type = type;
		tcb->code = code;
		if(tcb->state == SYN_SENT || tcb->state == SYN_RECEIVED)
		if(tcb->state == Syn_sent || tcb->state == Syn_received)
			close_self(s, Enetunreach);
		break;
	case ICMP_TIMXCEED:
		tcb->type = type;
		tcb->code = code;
		if(tcb->state == SYN_SENT || tcb->state == SYN_RECEIVED)
		if(tcb->state == Syn_sent || tcb->state == Syn_received)
			close_self(s, Etimedout);
		break;
	case ICMP_SOURCEQUENCH:


@@ 492,7 492,7 @@ update(Ipconv *s, Tcp *seg)
			rtt = tcb->rtt_timer.start - tcb->rtt_timer.count;
			rtt *= MSPTICK;	
			if(rtt > tcb->srtt &&
			  (tcb->state == SYN_SENT || tcb->state == SYN_RECEIVED))
			  (tcb->state == Syn_sent || tcb->state == Syn_received))
				tcb->srtt = rtt;
			else {
				abserr = (rtt > tcb->srtt) ? rtt - tcb->srtt : tcb->srtt - rtt;


@@ 861,7 861,7 @@ close_self(Ipconv *s, int reason)

	tcb->reseq = 0;
	s->err = reason;
	setstate(s, CLOSED);
	setstate(s, Closed);
}

int

M port/tcpoutput.c => port/tcpoutput.c +7 -7
@@ 25,8 25,8 @@ tcp_output(Ipconv *s)
	tcb = &s->tcpctl;

	switch(tcb->state) {
	case LISTEN:
	case CLOSED:
	case Listen:
	case Closed:
		return;
	}



@@ 76,10 76,10 @@ tcp_output(Ipconv *s)
		seg.mss = 0;

		switch(tcb->state){
		case SYN_SENT:
		case Syn_sent:
			seg.flags = 0;
			/* No break */
		case SYN_RECEIVED:
		case Syn_received:
			if(tcb->snd.ptr == tcb->iss){
				seg.flags |= SYN;
				dsize--;


@@ 173,12 173,12 @@ tcp_timeout(void *arg)
	DPRINT("Timer %lux state = %d\n", s, tcb->state);

	switch(tcb->state){
	case CLOSED:
	case Closed:
		panic("tcptimeout");
	case TIME_WAIT:
	case Time_wait:
		close_self(s, 0);
		break;
	case ESTABLISHED:
	case Established:
		if(tcb->backoff < MAXBACKOFF)
			tcb->backoff++;
		goto retran;

M power/boot.c => power/boot.c +6 -10
@@ 131,6 131,7 @@ setpasswd(void)
int
bitdial(char *arg)
{
	USED(arg);
	return open("#3/bit3", ORDWR);
}



@@ 189,14 190,12 @@ nonetdial(char *arg)
	cfd = open("#nnonet/2/ctl", ORDWR);
	if(cfd < 0){
		close(fd);
		fd = -1;
		prerror("opening #nnonet/2/ctl");
		return -1;
	}
	if(write(cfd, a->cmd, strlen(a->cmd))<0){
		close(cfd);
		close(fd);
		fd = cfd = -1;
		prerror(a->cmd);
		return -1;
	}


@@ 246,7 245,6 @@ dkdial(char *arg)
	cfd = open("#k/dk/5/ctl", ORDWR);
	if(cfd < 0){
		close(fd);
		fd = -1;
		prerror("opening #k/dk/5/ctl");
		return -1;
	}


@@ 254,7 252,6 @@ dkdial(char *arg)
	if(write(cfd, cmd, strlen(cmd))<0){
		close(cfd);
		close(fd);
		cfd = fd = -1;
		prerror(cmd);
		return -1;
	}


@@ 381,7 378,6 @@ void
boot(int ask)
{
	int n, f, tries;
	char *srvname;

	if(ask)
		outin("server", sys, sizeof(sys));


@@ 389,15 385,15 @@ boot(int ask)
	for(tries = 0; tries < 5; tries++){
		fd = -1;
		if(strncmp(sys, "bit!", 4) == 0)
			fd = bitdial(srvname = &sys[4]);
			fd = bitdial(&sys[4]);
		else if(strncmp(sys, "hot!", 4) == 0)
			fd = hotdial(srvname = &sys[4]);
			fd = hotdial(&sys[4]);
		else if(strncmp(sys, "dk!", 3) == 0)
			fd = dkdial(srvname = &sys[3]);
			fd = dkdial(&sys[3]);
		else if(strncmp(sys, "nonet!", 6) == 0)
			fd = nonetdial(srvname = &sys[6]);
			fd = nonetdial(&sys[6]);
		else
			fd = nonetdial(srvname = sys);
			fd = nonetdial(sys);
		if(fd >= 0)
			break;
		print("can't connect, retrying...\n");

M power/faultmips.c => power/faultmips.c +2 -2
@@ 24,8 24,8 @@ faultmips(Ureg *ur, int user, int code)

	if(fault(addr, read) < 0){
		if(user){
			sprint(buf, "sys: fault %s pc=0x%lux addr=0x%lux",
				read? "read" : "write", ur->pc, ur->badvaddr);
			sprint(buf, "sys: trap: fault %s addr=0x%lux",
				read? "read" : "write", ur->badvaddr);
			postnote(u->p, 1, buf, NDebug);
			return;
		}

M power/trap.c => power/trap.c +14 -5
@@ 152,7 152,7 @@ trap(Ureg *ur)
			if(ecode == FPEXC)
				sprint(buf, "sys: fp: %s FCR31 %lux", fpexcname(x), x);
			else
				sprint(buf, "sys: %s pc=0x%lux", excname[ecode], ur->pc);
				sprint(buf, "sys: trap: %s", excname[ecode]);

			postnote(u->p, 1, buf, NDebug);
		}else{


@@ 367,22 367,31 @@ dumpregs(Ureg *ur)
void
notify(Ureg *ur)
{
	int l;
	ulong s, sp;
	Note *n;

	if(u->p->procctl)
		procctl(u->p);
	if(u->nnote == 0)
	if(u->nnote==0)
		return;

	s = spllo();
	qlock(&u->p->debug);
	u->p->notepending = 0;
	if(u->note[0].flag!=NUser && (u->notified || u->notify==0)){
	n = &u->note[0];
	if(strncmp(n->msg, "sys:", 4) == 0){
		l = strlen(n->msg);
		if(l > ERRLEN-15)	/* " pc=0x12345678\0" */
			l = ERRLEN-15;
		sprint(n->msg+l, " pc=0x%.8lux", ur->pc);
	}
	if(n->flag!=NUser && (u->notified || u->notify==0)){
		if(u->note[0].flag == NDebug)
			pprint("suicide: %s\n", u->note[0].msg);
			pprint("suicide: %s\n", n->msg);
    Die:
		qunlock(&u->p->debug);
		pexit(u->note[0].msg, u->note[0].flag!=NDebug);
		pexit(n->msg, n->flag!=NDebug);
	}
	if(!u->notified){
		if(!u->notify)

M ss/faultsparc.c => ss/faultsparc.c +2 -2
@@ 37,8 37,8 @@ faultsparc(Ureg *ur)

	if(fault(addr, read) < 0){
		if(user){
			sprint(buf, "sys: fault %s pc=0x%lux addr=0x%lux",
				read? "read" : "write", ur->pc, badvaddr);
			sprint(buf, "sys: trap: fault %s addr=0x%lux",
				read? "read" : "write", badvaddr);
			postnote(u->p, 1, buf, NDebug);
			return;
		}

M ss/trap.c => ss/trap.c +36 -24
@@ 21,11 21,11 @@ char *trapname[]={
	"instruction access exception",
	"illegal instruction",
	"privileged instruction",
	"fp disabled",
	"fp: disabled",
	"window overflow",
	"window underflow",
	"unaligned address",
	"fp exception",
	"fp: exception",
	"data access exception",
	"tag overflow",
};


@@ 34,26 34,33 @@ char*
excname(ulong tbr)
{
	static char buf[64];	/* BUG: not reentrant! */
	char xx[64];
	char *t;

	if(tbr < sizeof trapname/sizeof(char*))
		return trapname[tbr];
	if(tbr >= 130)
		sprint(buf, "trap instruction %d", tbr-128);
	else if(17<=tbr && tbr<=31)
		sprint(buf, "interrupt level %d", tbr-16);
	else switch(tbr){
	case 36:
		return "cp disabled";
	switch(tbr){
		return "trap: cp disabled";
	case 40:
		return "cp exception";
		return "trap: cp exception";
	case 128:
		return "syscall";
	case 129:
		return "breakpoint";
	default:
		sprint(buf, "unknown trap %d", tbr);
	}
    Return:
	if(tbr < sizeof trapname/sizeof(char*))
		t = trapname[tbr];
	else{
		if(tbr >= 130)
			sprint(xx, "trap instruction %d", tbr-128);
		else if(17<=tbr && tbr<=31)
			sprint(xx, "interrupt level %d", tbr-16);
		else
			sprint(xx, "unknown trap %d", tbr);
		t = xx;
	}
	if(strncmp(t, "fp: ", 4) == 0)
		strcpy(buf, t);
	else
		sprint(buf, "trap: %s", t);
	return buf;
}



@@ 134,7 141,7 @@ trap(Ureg *ur)
    Error:
		if(user){
			spllo();
			sprint(buf, "sys: %s pc=0x%lux", excname(tbr), ur->pc);
			sprint(buf, "sys: %s", excname(tbr));
			if(tbr == 8)
				sprint(buf+strlen(buf), " FSR %lux", u->fpsave.fsr);
			postnote(u->p, 1, buf, NDebug);


@@ 222,26 229,31 @@ dumpregs(Ureg *ur)
void
notify(Ureg *ur)
{
	int l;
	ulong s, sp;
	Note *n;

	if(u->p->procctl)
		procctl(u->p);
	if(u->nnote == 0)
	if(u->nnote==0)
		return;

	s = spllo();		/* need to go low as may fault */
	s = spllo();
	qlock(&u->p->debug);
	u->p->notepending = 0;
	if(u->nnote==0){
		qunlock(&u->p->debug);
		return;
	n = &u->note[0];
	if(strncmp(n->msg, "sys:", 4) == 0){
		l = strlen(n->msg);
		if(l > ERRLEN-15)	/* " pc=0x12345678\0" */
			l = ERRLEN-15;
		sprint(n->msg+l, " pc=0x%.8lux", ur->pc);
	}
	if(u->note[0].flag!=NUser && (u->notified || u->notify==0)){
	if(n->flag!=NUser && (u->notified || u->notify==0)){
		if(u->note[0].flag == NDebug)
			pprint("suicide: %s\n", u->note[0].msg);
			pprint("suicide: %s\n", n->msg);
    Die:
		qunlock(&u->p->debug);
		pexit(u->note[0].msg, u->note[0].flag!=NDebug);
		pexit(n->msg, n->flag!=NDebug);
	}
	if(!u->notified){
		if(!u->notify)