Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/pc/trap.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname pc/trap.c 1991/0613
## diff -e /dev/null /n/bootesdump/1991/0613/sys/src/9/safari/trap.c
0a
#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"io.h"

void	ediv(void);
void	edebug(void);
void	enmi(void);
void	ebp(void);
void	eover(void);
void	ebound(void);
void	ebadop(void);
void	enoco(void);
void	edfault(void);
void	enoway(void);
void	etss(void);
void	enoseg(void);
void	estack(void);
void	eprot(void);
void	efault(void);

/*
 *  exception types
 */
enum {
	Ediv=	0,	/* divide error */
	Edebug=	1,	/* debug exceptions */
	Enmi=	2,	/* non-maskable interrupt */
	Ebp=	3,	/* INT 3 */
	Eover=	4,	/* overflow */
	Ebound=	5,	/* bounds check */
	Ebadop=	6,	/* invalid opcode */
	Enoco=	7,	/* coprocessor not available */
	Edfault=8,	/* double fault */
	Etss=	10,	/* invalid tss */
	Enoseg=	11,	/* segment not present */
	Estack=	12,	/* stack exception */
	Eprot=	13,	/* general protection */
	Efault=	14,	/* page fault */
	Eco=	16,	/* coprocessor error */
};

/*
 *  exception/trap gates
 */
Segdesc ilt[256] =
{
[Ediv]		TRAPGATE(KESEL, ediv, 3),
[Edebug]	TRAPGATE(KESEL, edebug, 3),
[Enmi]		INTRGATE(KESEL, enmi, 3),
[Ebp]		TRAPGATE(KESEL, ebp, 3),
[Eover]		TRAPGATE(KESEL, eover, 3),
[Ebound]	TRAPGATE(KESEL, ebound, 3),
[Ebadop]	TRAPGATE(KESEL, ebadop, 3),
[Enoco]		TRAPGATE(KESEL, enoco, 3),
[Edfault]	TRAPGATE(KESEL, edfault, 3),
[Etss]		TRAPGATE(KESEL, etss, 3),
[Enoseg]	TRAPGATE(KESEL, enoseg, 3),
[Estack]	TRAPGATE(KESEL, estack, 3),
[Eprot]		TRAPGATE(KESEL, eprot, 3),
[Efault]	TRAPGATE(KESEL, efault, 3),
[Eco]		TRAPGATE(KESEL, eco, 3),
};
.
## diffname pc/trap.c 1991/0614
## diff -e /n/bootesdump/1991/0613/sys/src/9/safari/trap.c /n/bootesdump/1991/0614/sys/src/9/safari/trap.c
65a

/*
 *  trap table
 */
uchar	traptab[4096];

/*
 *  set up some basic vectored interrupts
 */
trapinit(

/*
 *  j-random uncaught trap or interrupt
 */
void
trap(void)
{
	panic("unknown trap");
}
.
46c
 *  trap/interrupt gates
.
## diffname pc/trap.c 1991/0625
## diff -e /n/bootesdump/1991/0614/sys/src/9/safari/trap.c /n/bootesdump/1991/0625/sys/src/9/safari/trap.c
73,77d
## diffname pc/trap.c 1991/0703
## diff -e /n/bootesdump/1991/0625/sys/src/9/safari/trap.c /n/bootesdump/1991/0703/sys/src/9/safari/trap.c
78c
	print("trap %lux\n", ur->trap);
	print(" edi %lux\n", ur->edi);
	print(" esi %lux\n", ur->esi);
	print(" ebp %lux\n", ur->ebp);
	print(" esp %lux\n", ur->esp);
	print(" ebx %lux\n", ur->ebx);
	print(" edx %lux\n", ur->edx);
	print(" ecx %lux\n", ur->ecx);
	print(" eax %lux\n", ur->eax);
	print(" ds %lux\n", ur->ds);
	print(" trap %lux\n", ur->trap);
	print(" ecode %lux\n", ur->ecode);
	print(" eip %lux\n", ur->eip);
	print(" cs %lux\n", ur->cs);
	print(" eflags %lux\n", ur->eflags);
	print(" oesp %lux\n", ur->oesp);
	print(" ss %lux\n", ur->ss);
	delay(500);
	if(ur->trap>=256 || ivec[ur->trap] == 0)
		panic("bad trap type %d\n", ur->trap);

	(*ivec[ur->trap])(ur);
.
75,76c
trap(Ureg *ur)
.
73c
 *  All traps
.
71a
	/*
	 *  set the standard traps
	 */
	sethvec(0, intr0, SEGTG);
	sethvec(1, intr1, SEGTG);
	sethvec(2, intr2, SEGTG);
	sethvec(3, intr3, SEGTG);
	sethvec(4, intr4, SEGTG);
	sethvec(5, intr5, SEGTG);
	sethvec(6, intr6, SEGTG);
	sethvec(7, intr7, SEGTG);
	sethvec(8, intr8, SEGTG);
	sethvec(9, intr9, SEGTG);
	sethvec(10, intr10, SEGTG);
	sethvec(11, intr11, SEGTG);
	sethvec(12, intr12, SEGTG);
	sethvec(13, intr13, SEGTG);
	sethvec(14, intr14, SEGTG);
	sethvec(15, intr15, SEGTG);
	sethvec(16, intr16, SEGTG);

	/*
	 *  set all others to unknown
	 */
	for(i = 17; i < 256; i++)
		sethvec(i, intrbad, SEGIG);

	/*
	 *  tell the hardware where the table is (and how long)
	 */
	lidt(ilt, sizeof(ilt));
}


.
70c
void
trapinit(void)
{
	int i;
.
68c
 *  set up the interrupt/trap gates
.
66a
void
setvec(int v, void (*r)(void*), int type)
{
	ilt[v].d1 &= ~SEGTYPE;
	ilt[v].d1 |= type;
	ivec[v] = r;
}

.
50,65c
	ilt[v].d0 = ((ulong)r)&0xFFFF|(KESEL<<16);
	ilt[v].d1 = ((ulong)r)&0xFFFF0000|SEGP|SEGPL(3)|type;
}
.
48c
Segdesc ilt[256];
void	(*ivec[256])(void*);

void
sethvec(int v, void (*r)(void), int type)
.
25,45d
8,23d
6a
#include	"ureg.h"
.
## diffname pc/trap.c 1991/0704
## diff -e /n/bootesdump/1991/0703/sys/src/9/safari/trap.c /n/bootesdump/1991/0704/sys/src/9/safari/trap.c
68a

	/*
	 *  Set up the 8259 interrupt processor #1.
	 *  Make 8259 interrupts starting at vector I8259vec.
	 *
	 *  N.B. This is all magic to me.  It comes from the 
	 *	 IBM technical reference manual.  I just
	 *	 changed the vector.
	 */
	outb(I8259ctl, 0x11);		/* ICW1 - edge, master, ICW4 */
	outb(I8259aux, I8259vec);	/* ICW2 - interrupt vector */
	outb(I8259aux, 0x04);		/* ICW3 - master level 2 */
	outb(I8259aux, 0x01);		/* ICW4 - master, 8086 mode */
	outb(I8259aux, 0x00);		/* mask - all enabled */
.
## diffname pc/trap.c 1991/0705
## diff -e /n/bootesdump/1991/0704/sys/src/9/safari/trap.c /n/bootesdump/1991/0705/sys/src/9/safari/trap.c
78,82c
	outb(Int0ctl, 0x11);		/* ICW1 - edge, master, ICW4 */
	outb(Int0aux, Int0vec);		/* ICW2 - interrupt vector */
	outb(Int0aux, 0x04);		/* ICW3 - master level 2 */
	outb(Int0aux, 0x01);		/* ICW4 - master, 8086 mode */
	outb(Int0aux, 0x00);		/* mask - all enabled */
.
## diffname pc/trap.c 1991/0706
## diff -e /n/bootesdump/1991/0705/sys/src/9/safari/trap.c /n/bootesdump/1991/0706/sys/src/9/safari/trap.c
112a
	INT0ENABLE;
.
91,108d
62c
	for(i = 24; i < 256; i++)
.
57a
	sethvec(17, intr17, SEGTG);
	sethvec(18, intr18, SEGTG);
	sethvec(19, intr19, SEGTG);
	sethvec(20, intr20, SEGTG);
	sethvec(21, intr21, SEGTG);
	sethvec(22, intr22, SEGTG);
	sethvec(23, intr23, SEGTG);
.
23c
setvec(int v, void (*r)(Ureg*), int type)
.
## diffname pc/trap.c 1991/0709
## diff -e /n/bootesdump/1991/0706/sys/src/9/safari/trap.c /n/bootesdump/1991/0709/sys/src/9/safari/trap.c
102c

	/*
	 *  tell the 8259 that we're done with the
	 *  highest level interrupt
	 */
	outb(Int0ctl, EOI);
.
100a
	/*
	 *  call the trap routine
	 */
.
92d
88,89c
	outb(Int0aux, 0x01);		/* ICW4 - 8086 mode, not buffered */
.
85,86c
	outb(Int0ctl, 0x11);		/* ICW1 - edge triggered, master,
					   ICW4 will be sent */
	outb(Int0aux, Int0vec);		/* ICW2 - interrupt vector offset */
.
78,83c
	 *  Set up the first 8259 interrupt processor.
	 *  Make 8259 interrupts start at CPU vector Int0vec.
	 *  Set the 8259 as master with edge triggered
	 *  input with fully nested interrupts.
.
27a

	/*
	 *  enable corresponding interrupt in 8259
	 */
	if((v&~0x7) == Int0vec){
		int0mask &= ~(1<<(v&7));
		outb(Int0aux, int0mask);
	}
.
9a
 *  8259 interrupt controllers
 */
enum
{
	Int0ctl=	0x20,		/* control port (ICW1, OCW2, OCW3) */
	Int0aux=	0x21,		/* everything else (ICW2, ICW3, ICW4, OCW1) */
	Int1ctl=	0xA0,		/* control port */
	Int1aux=	0xA1,		/* everything else (ICW2, ICW3, ICW4, OCW1) */

	EOI=		0x20,		/* non-specific end of interrupt */
};

int	int0mask = 7;		/* interrupts enabled for first 8259 */
int	int1mask = 7;		/* interrupts enabled for second 8259 */

/*
.
## diffname pc/trap.c 1991/0710
## diff -e /n/bootesdump/1991/0709/sys/src/9/safari/trap.c /n/bootesdump/1991/0710/sys/src/9/safari/trap.c
131a
}

/*
 *  system calls
 */
long
syscall(Ureg *ur)
{
	panic("syscall");
}

#include "errstr.h"

void
error(int code)
{
	strncpy(u->error, errstrtab[code], ERRLEN);
	nexterror();
}

void
errors(char *err)
{
	strncpy(u->error, err, ERRLEN);
	nexterror();
}


void
nexterror(void)
{
	gotolabel(&u->errlab[--u->nerrlab]);
.
116a
void
.
96a
	 *  system calls
	 */
	sethvec(64, intr64, SEGTG, 3);
/*	setvec(64, syscall, SEGTG);	/**/

	/*
.
94c
		sethvec(i, intrbad, SEGIG, 0);
.
65,88c
	sethvec(0, intr0, SEGTG, 0);
	sethvec(1, intr1, SEGTG, 0);
	sethvec(2, intr2, SEGTG, 0);
	sethvec(3, intr3, SEGTG, 0);
	sethvec(4, intr4, SEGTG, 0);
	sethvec(5, intr5, SEGTG, 0);
	sethvec(6, intr6, SEGTG, 0);
	sethvec(7, intr7, SEGTG, 0);
	sethvec(8, intr8, SEGTG, 0);
	sethvec(9, intr9, SEGTG, 0);
	sethvec(10, intr10, SEGTG, 0);
	sethvec(11, intr11, SEGTG, 0);
	sethvec(12, intr12, SEGTG, 0);
	sethvec(13, intr13, SEGTG, 0);
	sethvec(14, intr14, SEGTG, 0);
	sethvec(15, intr15, SEGTG, 0);
	sethvec(16, intr16, SEGTG, 0);
	sethvec(17, intr17, SEGTG, 0);
	sethvec(18, intr18, SEGTG, 0);
	sethvec(19, intr19, SEGTG, 0);
	sethvec(20, intr20, SEGTG, 0);
	sethvec(21, intr21, SEGTG, 0);
	sethvec(22, intr22, SEGTG, 0);
	sethvec(23, intr23, SEGTG, 0);
.
35c
	ilt[v].d1 = ((ulong)r)&0xFFFF0000|SEGP|SEGPL(pri)|type;
.
32c
sethvec(int v, void (*r)(void), int type, int pri)
.
## diffname pc/trap.c 1991/0711
## diff -e /n/bootesdump/1991/0710/sys/src/9/safari/trap.c /n/bootesdump/1991/0711/sys/src/9/safari/trap.c
162,170c
	((Ureg*)UREGADDR)->pc = entry;
.
160c
execpc(ulong entry)
.
155,156d
153c
dumpstack(void)
.
150,151d
127c
		panic("bad trap type %d %lux\n", ur->trap, ur->pc);
.
## diffname pc/trap.c 1991/0716
## diff -e /n/bootesdump/1991/0711/sys/src/9/safari/trap.c /n/bootesdump/1991/0716/sys/src/9/safari/trap.c
100c
	setvec(64, (void (*)(Ureg*))syscall);
.
41,42d
39c
setvec(int v, void (*r)(Ureg*))
.
## diffname pc/trap.c 1991/0718
## diff -e /n/bootesdump/1991/0716/sys/src/9/safari/trap.c /n/bootesdump/1991/0718/sys/src/9/safari/trap.c
144a
	u->p->insyscall = 1;
	u->p->pc = ur->pc;

.
139a
 *  dump registers
 */
void
dumpregs(Ureg *ur)
{
	if(u)
		print("registers for %s %d\n", u->p->text, u->p->pid);
	else
		print("registers for kernel\n");
	print("FLAGS=%lux ECODE=%lux CS=%lux PC=%lux SS=%lux USP=%lux\n", ur->flags,
		ur->ecode, ur->cs, ur->pc, ur->ss, ur->usp);

	print("  AX %8.8lux  BX %8.8lux  CX %8.8lux  DX %8.8lux\n",
		ur->ax, ur->bx, ur->cx, ur->dx);
	print("  SI %8.8lux  DI %8.8lux  BP %8.8lux  DS %8.8lux\n",
		ur->si, ur->di, ur->bp, ur->ds);
}

/*
.
103c
	putidt(ilt, sizeof(ilt));
.
89c
	 *  set all others to unknown interrupts
.
## diffname pc/trap.c 1991/0719
## diff -e /n/bootesdump/1991/0718/sys/src/9/safari/trap.c /n/bootesdump/1991/0719/sys/src/9/safari/trap.c
63,86c
	sethvec(0, intr0, SEGIG, 0);
	sethvec(1, intr1, SEGIG, 0);
	sethvec(2, intr2, SEGIG, 0);
	sethvec(3, intr3, SEGIG, 0);
	sethvec(4, intr4, SEGIG, 0);
	sethvec(5, intr5, SEGIG, 0);
	sethvec(6, intr6, SEGIG, 0);
	sethvec(7, intr7, SEGIG, 0);
	sethvec(8, intr8, SEGIG, 0);
	sethvec(9, intr9, SEGIG, 0);
	sethvec(10, intr10, SEGIG, 0);
	sethvec(11, intr11, SEGIG, 0);
	sethvec(12, intr12, SEGIG, 0);
	sethvec(13, intr13, SEGIG, 0);
	sethvec(14, intr14, SEGIG, 0);
	sethvec(15, intr15, SEGIG, 0);
	sethvec(16, intr16, SEGIG, 0);
	sethvec(17, intr17, SEGIG, 0);
	sethvec(18, intr18, SEGIG, 0);
	sethvec(19, intr19, SEGIG, 0);
	sethvec(20, intr20, SEGIG, 0);
	sethvec(21, intr21, SEGIG, 0);
	sethvec(22, intr22, SEGIG, 0);
	sethvec(23, intr23, SEGIG, 0);
.
## diffname pc/trap.c 1991/0720
## diff -e /n/bootesdump/1991/0719/sys/src/9/safari/trap.c /n/bootesdump/1991/0720/sys/src/9/safari/trap.c
178c
	Ureg *nur;

	nur = u->ureg;
	validaddr(nur->pc, 1, 0);
	validaddr(nur->usp, BY2WD, 0);
	if(nur->cs!=u->svcs || nur->ss!=u->svss
	|| (nur->flags&0xff)!=(u->svflags&0xff)){
		pprint("bad noted ureg cs %ux ss %ux flags %ux\n", nur->cs, nur->ss,
			nur->flags);
		pexit("Suicide", 0);
	}
	lock(&u->p->debug);
	if(!u->notified){
		unlock(&u->p->debug);
		return;
	}
	u->notified = 0;
	nur->flags = (u->svflags&0xffffff00) | (ur->flags&0xff);
	memmove(ur, u->ureg, sizeof(Ureg));
	ur->ax = -1;	/* return error from the interrupted call */
	switch(arg0){
	case NCONT:
		splhi();
		unlock(&u->p->debug);
		rfnote(ur);
		break;
		/* never returns */

	default:
		pprint("unknown noted arg 0x%lux\n", arg0);
		u->lastnote.flag = NDebug;
		/* fall through */
		
	case NDFLT:
		if(u->lastnote.flag == NDebug)
			pprint("suicide: %s\n", u->lastnote.msg);
		unlock(&u->p->debug);
		pexit(u->lastnote.msg, u->lastnote.flag!=NDebug);
	}
.
176c
noted(Ureg *ur, ulong arg0)
.
174a
/*
 *   Return user to state before notify()
 */
.
172a
	ulong sp;

	lock(&u->p->debug);
	if(u->nnote==0){
		unlock(&u->p->debug);
		return;
	}
	if(u->note[0].flag!=NUser && (u->notified || u->notify==0)){
		if(u->note[0].flag == NDebug)
			pprint("suicide: %s\n", u->note[0].msg);
    Die:
		unlock(&u->p->debug);
		pexit(u->note[0].msg, u->note[0].flag!=NDebug);
	}
	if(!u->notified){
		if(!u->notify)
			goto Die;
		u->svcs = ur->cs;
		u->svss = ur->ss;
		u->svflags = ur->flags;
		sp = ur->usp;
		sp -= sizeof(Ureg);
		u->ureg = (void*)sp;
		memmove((Ureg*)sp, ur, sizeof(Ureg));
		sp -= ERRLEN;
		memmove((char*)sp, u->note[0].msg, ERRLEN);
		sp -= 3*BY2WD;
		*(ulong*)(sp+2*BY2WD) = sp+3*BY2WD;	/* arg 2 is string */
		*(ulong*)(sp+1*BY2WD) = (ulong)u->ureg;	/* arg 1 is ureg* */
		*(ulong*)(sp+0*BY2WD) = 0;		/* arg 0 is pc */
		ur->usp = sp;
		ur->pc = (ulong)u->notify;
		u->notified = 1;
		u->nnote--;
		memmove(&u->lastnote, &u->note[0], sizeof(Note));
		memmove(&u->note[0], &u->note[1], u->nnote*sizeof(Note));
	}
	unlock(&u->p->debug);
.
171c
notify(Ureg *ur)
.
169a
/*
 *  Call user, if necessary, with note.
 *  Pass user the Ureg struct and the note on his stack.
 */
.
167c
	/*
	 *  do something about floating point!!!
	 */

	ax = ur->ax;
	sp = ur->usp;
	u->nerrlab = 0;
	ret = -1;
z = (ulong *)sp;
print("syscall %lux %lux %lux %lux\n", *z, *(z+1), *(z+2), *(z+3));
dumpregs(ur);
if(++times==3)
	panic("3rd time in syscall");
	if(!waserror()){
		if(ax >= sizeof systab/BY2WD){
			pprint("bad sys call number %d pc %lux\n", ax, ur->pc);
			postnote(u->p, 1, "sys: bad sys call", NDebug);
			error(Ebadarg);
		}
		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(1+MAXSYSARG)*BY2WD))
			validaddr(sp, (1+MAXSYSARG)*BY2WD, 0);
		ret = (*systab[ax])((ulong*)(sp+BY2WD));
		poperror();
	}
print("return from syscall\n");
	if(u->nerrlab){
		print("bad errstack [%d]: %d extra\n", ax, u->nerrlab);
		for(i = 0; i < NERR; i++)
			print("sp=%lux pc=%lux\n", u->errlab[i].sp, u->errlab[i].pc);
		panic("error stack");
	}
	u->p->insyscall = 0;
	if(ax == NOTED){
		noted(ur, *(ulong*)(sp+BY2WD));
		ret = -1;
	} else if(u->nnote){
		ur->ax = ret;
		notify(ur);
	}
	return ret;
.
165a
	if((ur->cs)&0xffff == KESEL)
		panic("recursive system call");
	u->p->insyscall = 0;
.
163a
	ulong	ax;
	ulong	sp;
	long	ret;
	int	i;
	static int times;
ulong	*z;

.
160a
#undef	CHDIR	/* BUG */
#include "/sys/src/libc/9syscall/sys.h"

typedef long Syscall(ulong*);
Syscall	sysr1, sysfork, sysexec, sysgetpid, syssleep, sysexits, sysdeath, syswait;
Syscall	sysopen, sysclose, sysread, syswrite, sysseek, syserrstr, sysaccess, sysstat, sysfstat;
Syscall sysdup, syschdir, sysforkpgrp, sysbind, sysmount, syspipe, syscreate;
Syscall	sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted, sysalarm;

Syscall *systab[]={
	sysr1,
	syserrstr,
	sysbind,
	syschdir,
	sysclose,
	sysdup,
	sysalarm,
	sysexec,
	sysexits,
	sysfork,
	sysforkpgrp,
	sysfstat,
	sysdeath,
	sysmount,
	sysopen,
	sysread,
	sysseek,
	syssleep,
	sysstat,
	syswait,
	syswrite,
	syspipe,
	syscreate,
	sysdeath,
	sysbrk_,
	sysremove,
	syswstat,
	sysfwstat,
	sysnotify,
	sysnoted,
	sysdeath,	/* sysfilsys */
};

.
157a
void
dumpstack(void)
{
}

void
execpc(ulong entry)
{
	((Ureg*)UREGADDR)->pc = entry;
}

.
8a
void	noted(Ureg*, ulong);
void	notify(Ureg*);

.
7a
#include	"errno.h"
.
## diffname pc/trap.c 1991/0722
## diff -e /n/bootesdump/1991/0720/sys/src/9/safari/trap.c /n/bootesdump/1991/0722/sys/src/9/safari/trap.c
354,356c
		return;
.
305a
		if(waserror()){
			pprint("suicide: trap in notify\n");
			unlock(&u->p->debug);
			pexit("Suicide", 0);
		}
		validaddr((ulong)u->notify, 1, 0);
		validaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN-3*BY2WD, 0);
		poperror();
.
## diffname pc/trap.c 1991/0723
## diff -e /n/bootesdump/1991/0722/sys/src/9/safari/trap.c /n/bootesdump/1991/0723/sys/src/9/safari/trap.c
259d
243,247d
226,227d
## diffname pc/trap.c 1991/0724
## diff -e /n/bootesdump/1991/0723/sys/src/9/safari/trap.c /n/bootesdump/1991/0724/sys/src/9/safari/trap.c
349c
	ur->ax = -1;	/* return error from the interrupted syscall */
.
262c
	} else if(u->nnote && ax!=FORK){
.
## diffname pc/trap.c 1991/0725
## diff -e /n/bootesdump/1991/0724/sys/src/9/safari/trap.c /n/bootesdump/1991/0725/sys/src/9/safari/trap.c
349c
/*	ur->ax = -1;	/* return error from the interrupted syscall */
.
261,262c
	else if(u->nnote && ax!=FORK){
.
259c
	if(ax == NOTED)
.
## diffname pc/trap.c 1991/0727
## diff -e /n/bootesdump/1991/0725/sys/src/9/safari/trap.c /n/bootesdump/1991/0727/sys/src/9/safari/trap.c
281a
	u->p->notepending = 0;
.
## diffname pc/trap.c 1991/0731
## diff -e /n/bootesdump/1991/0727/sys/src/9/safari/trap.c /n/bootesdump/1991/0731/sys/src/9/safari/trap.c
176,217c
#include "../port/systab.h"
.
140c
	c = v&~0x7;
	if(c==Int0vec || c==Int1vec){
		outb(Int0ctl, EOI);
		if(c == Int1vec)
			outb(Int1ctl, EOI);
	}
.
134c
	(*ivec[v])(ur);
.
130a
	v = ur->trap;
	if(v>=256 || ivec[v] == 0)
		panic("bad trap type %d %lux\n", v, ur->pc);

.
128,129c
	int v;
	int c;
.
119a

	/*
	 *  Set up the second 8259 interrupt processor.
	 *  Make 8259 interrupts start at CPU vector Int0vec.
	 *  Set the 8259 as master with edge triggered
	 *  input with fully nested interrupts.
	 */
	outb(Int1ctl, 0x11);		/* ICW1 - edge triggered, master,
					   ICW4 will be sent */
	outb(Int1aux, Int1vec);		/* ICW2 - interrupt vector offset */
	outb(Int1aux, 0x02);		/* ICW3 - I am a slave on level 2 */
	outb(Int1aux, 0x01);		/* ICW4 - 8086 mode, not buffered */

	/*
	 *  pass #2 8259 interrupts to #1
	 */
	int0mask &= ~0x04;
	outb(Int0aux, int0mask);
.
118c
	outb(Int0aux, 0x04);		/* ICW3 - have slave on level 2 */
.
93,98d
90a
	sethvec(24, intr24, SEGIG, 0);
	sethvec(25, intr25, SEGIG, 0);
	sethvec(26, intr26, SEGIG, 0);
	sethvec(27, intr27, SEGIG, 0);
	sethvec(28, intr28, SEGIG, 0);
	sethvec(29, intr29, SEGIG, 0);
	sethvec(30, intr30, SEGIG, 0);
	sethvec(31, intr31, SEGIG, 0);
.
82a

	/*
	 *  set the standard devices
	 */
.
64a
	 *  set all interrupts to panics
	 */
	for(i = 32; i < 256; i++)
		sethvec(i, intrbad, SEGIG, 0);

	/*
.
52a
	} else if((v&~0x7) == Int1vec){
		int1mask &= ~(1<<(v&7));
		outb(Int1aux, int1mask);
.
26,27c
int	int0mask = 0xff;	/* interrupts enabled for first 8259 */
int	int1mask = 0xff;		/* interrupts enabled for second 8259 */
.
12a
void	intr0(void), intr1(void), intr2(void), intr3(void);
void	intr4(void), intr5(void), intr6(void), intr7(void);
void	intr8(void), intr9(void), intr10(void), intr11(void);
void	intr12(void), intr13(void), intr14(void), intr15(void);
void	intr16(void), intr17(void), intr18(void), intr19(void);
void	intr20(void), intr21(void), intr22(void), intr23(void);
void	intr24(void), intr25(void), intr26(void), intr27(void);
void	intr28(void), intr29(void), intr30(void), intr31(void);
void	intr64(void);
void	intrbad(void);

.
## diffname pc/trap.c 1991/0801
## diff -e /n/bootesdump/1991/0731/sys/src/9/safari/trap.c /n/bootesdump/1991/0801/sys/src/9/safari/trap.c
274d
270a
	ur->ax = ret;
.
193a

	/*
	 *  call the trap routine
	 */
	(*ivec[v])(ur);
.
186c
	 *  highest level interrupt (interrupts are still
	 *  off at this point)
.
180,184d
## diffname pc/trap.c 1991/0802
## diff -e /n/bootesdump/1991/0801/sys/src/9/safari/trap.c /n/bootesdump/1991/0802/sys/src/9/safari/trap.c
365d
362d
349c
	|| (nur->flags&0xff00)!=(u->svflags&0xff00)){
.
275c
	} else if(u->nnote && ax!=FORK){
.
273c
	if(ax == NOTED){
.
253a
	spllo();
.
## diffname pc/trap.c 1991/0803
## diff -e /n/bootesdump/1991/0802/sys/src/9/safari/trap.c /n/bootesdump/1991/0803/sys/src/9/safari/trap.c
38c
int	int1mask = 0xff;	/* interrupts enabled for second 8259 */
.
## diffname pc/trap.c 1991/0806
## diff -e /n/bootesdump/1991/0803/sys/src/9/safari/trap.c /n/bootesdump/1991/0806/sys/src/9/safari/trap.c
194a
}

/*
 *  print 8259 status
 */
void
dump8259(void)
{
	int c;

	outb(Int0ctl, 0x0a);	/* read ir */
	print("ir0 %lux\n", inb(Int0ctl));
	outb(Int0ctl, 0x0b);	/* read is */
	print("is0 %lux\n", inb(Int0ctl));
	print("im0 %lux\n", inb(Int0aux));

	outb(Int1ctl, 0x0a);	/* read ir */
	print("ir1 %lux\n", inb(Int1ctl));
	outb(Int1ctl, 0x0b);	/* read is */
	print("is1 %lux\n", inb(Int1ctl));
	print("im1 %lux\n", inb(Int1aux));
.
188a
		outb(Int0ctl, EOI);
.
186d
178a
	if(v==19 || v==20)
		print("trap = %d\n", v);

.
## diffname pc/trap.c 1991/0807
## diff -e /n/bootesdump/1991/0806/sys/src/9/safari/trap.c /n/bootesdump/1991/0807/sys/src/9/safari/trap.c
176,177c
	if(v>=256 || ivec[v] == 0){
		print("bad trap type %d %lux %lux %lux\n", v, ur->pc, int0mask, int1mask);
		return;
	}
.
## diffname pc/trap.c 1991/0808
## diff -e /n/bootesdump/1991/0807/sys/src/9/safari/trap.c /n/bootesdump/1991/0808/sys/src/9/safari/trap.c
289a
		if(ax == EXITS)
			print("%d returned from sysexits!\n", u->p->pid);
.
288a
		if(ax == EXITS)
			print("%d exiting\n", u->p->pid);
.
234c
		ur->ecode, ur->cs&0xff, ur->pc, ur->ss&0xff, ur->usp);
.
37,38c
int	int0mask = 0x00;	/* interrupts enabled for first 8259 */
int	int1mask = 0x00;	/* interrupts enabled for second 8259 */
.
## diffname pc/trap.c 1991/0809
## diff -e /n/bootesdump/1991/0808/sys/src/9/safari/trap.c /n/bootesdump/1991/0809/sys/src/9/safari/trap.c
292,293d
289,290d
## diffname pc/trap.c 1991/0810
## diff -e /n/bootesdump/1991/0809/sys/src/9/safari/trap.c /n/bootesdump/1991/0810/sys/src/9/safari/trap.c
181,183d
## diffname pc/trap.c 1991/0814
## diff -e /n/bootesdump/1991/0810/sys/src/9/safari/trap.c /n/bootesdump/1991/0814/sys/src/9/safari/trap.c
387a
		if(waserror()){
			pprint("suicide: trap in noted\n");
			unlock(&u->p->debug);
			goto Die;
		}
		validaddr(nur->pc, 1, 0);
		validaddr(nur->usp, BY2WD, 0);
		poperror();
.
379a
		pprint("call to noted() when not notified\n");
.
375a
    Die:
.
## diffname pc/trap.c 1991/0822
## diff -e /n/bootesdump/1991/0814/sys/src/9/safari/trap.c /n/bootesdump/1991/0822/sys/src/9/safari/trap.c
277d
267c
	spllo();
.
193a
	 *  check for a waiting character, the uart is at too low
	 *  a priority level to work correctly at 9600 baud.
	 */
	uartintr0(ur);

	/*
.
## diffname pc/trap.c 1991/0823
## diff -e /n/bootesdump/1991/0822/sys/src/9/safari/trap.c /n/bootesdump/1991/0823/sys/src/9/safari/trap.c
273d
194,199d
190a
		if(v != Uart0vec)
			uartintr0(ur);
.
87,102c
	sethvec(0, intr0, SEGTG, 0);
	sethvec(1, intr1, SEGTG, 0);
	sethvec(2, intr2, SEGTG, 0);
	sethvec(3, intr3, SEGTG, 0);
	sethvec(4, intr4, SEGTG, 0);
	sethvec(5, intr5, SEGTG, 0);
	sethvec(6, intr6, SEGTG, 0);
	sethvec(7, intr7, SEGTG, 0);
	sethvec(8, intr8, SEGTG, 0);
	sethvec(9, intr9, SEGTG, 0);
	sethvec(10, intr10, SEGTG, 0);
	sethvec(11, intr11, SEGTG, 0);
	sethvec(12, intr12, SEGTG, 0);
	sethvec(13, intr13, SEGTG, 0);
	sethvec(14, intr14, SEGTG, 0);
	sethvec(15, intr15, SEGTG, 0);
.
82c
		sethvec(i, intrbad, SEGTG, 0);
.
## diffname pc/trap.c 1991/0827
## diff -e /n/bootesdump/1991/0823/sys/src/9/safari/trap.c /n/bootesdump/1991/0827/sys/src/9/safari/trap.c
177c
		panic("bad trap type %d %lux %lux %lux\n", v, ur->pc, int0mask, int1mask);
.
## diffname pc/trap.c 1991/0904
## diff -e /n/bootesdump/1991/0827/sys/src/9/safari/trap.c /n/bootesdump/1991/0904/sys/src/9/safari/trap.c
107,122c
	sethvec(24, intr24, SEGIG, 0);
	sethvec(25, intr25, SEGIG, 0);
	sethvec(26, intr26, SEGIG, 0);
	sethvec(27, intr27, SEGIG, 0);
	sethvec(28, intr28, SEGIG, 0);
	sethvec(29, intr29, SEGIG, 0);
	sethvec(30, intr30, SEGIG, 0);
	sethvec(31, intr31, SEGIG, 0);
	sethvec(32, intr32, SEGIG, 0);
	sethvec(33, intr33, SEGIG, 0);
	sethvec(34, intr34, SEGIG, 0);
	sethvec(35, intr35, SEGIG, 0);
	sethvec(36, intr36, SEGIG, 0);
	sethvec(37, intr37, SEGIG, 0);
	sethvec(38, intr38, SEGIG, 0);
	sethvec(39, intr39, SEGIG, 0);
.
105c
	 *  device interrupts
.
102a
	sethvec(16, intr16, SEGTG, 0);
.
85c
	 *  80386 processor (and coprocessor) traps
.
81c
	for(i = 0; i < 256; i++)
.
20a
void	intr32(void), intr33(void), intr34(void), intr35(void);
void	intr36(void), intr37(void), intr38(void), intr39(void);
.
17,18c
void	intr16(void);
.
## diffname pc/trap.c 1991/0910
## diff -e /n/bootesdump/1991/0904/sys/src/9/safari/trap.c /n/bootesdump/1991/0910/sys/src/9/safari/trap.c
200a

	if(((ur->cs)&0xffff)!=KESEL && u->nnote && v!=Syscallvec)
		notify(ur);
.
197,199d
129,130c
	sethvec(Syscallvec, intr64, SEGTG, 3);
	setvec(Syscallvec, (void (*)(Ureg*))syscall);
.
## diffname pc/trap.c 1991/0912
## diff -e /n/bootesdump/1991/0910/sys/src/9/safari/trap.c /n/bootesdump/1991/0912/sys/src/9/safari/trap.c
196a
if(v==16) print("vec thru 16\n");
.
122c
	sethvec(37, intr37, SEGTG, 0);
.
## diffname pc/trap.c 1991/0913
## diff -e /n/bootesdump/1991/0912/sys/src/9/safari/trap.c /n/bootesdump/1991/0913/sys/src/9/safari/trap.c
199a
	/*
	 *  syscall does it's own notifying
	 */
.
197d
122c
	sethvec(37, intr37, SEGIG, 0);
.
## diffname pc/trap.c 1991/0926
## diff -e /n/bootesdump/1991/0913/sys/src/9/safari/trap.c /n/bootesdump/1991/0926/sys/src/9/safari/trap.c
300a
	u->p->psstate = 0;
.
290a
		u->p->psstate = sysctab[ax];
.
## diffname pc/trap.c 1991/1001
## diff -e /n/bootesdump/1991/0926/sys/src/9/safari/trap.c /n/bootesdump/1991/1001/sys/src/9/safari/trap.c
38,39c
int	int0mask = 0xff;	/* interrupts enabled for first 8259 */
int	int1mask = 0xff;	/* interrupts enabled for second 8259 */
.
## diffname pc/trap.c 1991/1005
## diff -e /n/bootesdump/1991/1001/sys/src/9/safari/trap.c /n/bootesdump/1991/1005/sys/src/9/safari/trap.c
179,180c
		if(v == 10 && spuriousfloppy == 0){
			v = Floppyvec;
			spuriousfloppy = 1;
		}else
			panic("bad trap type %d %lux %lux %lux\n", v, ur->pc, int0mask, int1mask);
.
175a
	static int spuriousfloppy;
.
## diffname pc/trap.c 1991/1112
## diff -e /n/bootesdump/1991/1005/sys/src/9/safari/trap.c /n/bootesdump/1991/1112/sys/src/9/safari/trap.c
422a
}

/* This routine must save the values of registers the user is not permitted to write
 * from devproc and the restore the saved values before returning
 */
void
setregisters(Ureg *xp, char *pureg, char *uva, int n)
{
	ulong flags;
	ulong cs;
	ulong ss;

	flags = xp->flags;
	cs = xp->cs;
	ss = xp->ss;
	memmove(pureg, uva, n);
	xp->flags = (xp->flags & 0xff) | (flags & 0xff00);
	xp->cs = cs;
	xp->ss = ss;
.
329c
	lock(&u->p->debug);
.
325,327c
	if(u->p->procctl)
		procctl(u->p);
	if(u->nnote==0)
.
310c
	} else if(u->p->procctl || (u->nnote && ax!=FORK)){
.
275a
	u->dbgreg = ur;
.
206c
	if(user)
.
186a
	user = ((ur->cs)&0xffff)!=KESEL && v!=Syscallvec;
	if(user)
		u->dbgreg = ur;

	if(v>=256 || ivec[v] == 0)
		panic("bad trap type %d %lux %lux %lux\n", v, ur->pc, int0mask, int1mask);

.
179,185d
174c
	int v, user;
.
130a
	sethvec(Bptvec, intr3, SEGTG, 3);
	setvec(Bptvec, debugbpt);
.
91d
70a
void
debugbpt(Ureg *ur)
{
	char buf[ERRLEN];

	if(u == 0)
		panic("kernel bpt");
	/* restore pc to instruction that caused the trap */
	ur->pc--;
	sprint(buf, "sys: breakpoint pc=0x%lux", ur->pc);
	postnote(u->p, 1, buf, NDebug);
}

.
## diffname pc/trap.c 1991/1113
## diff -e /n/bootesdump/1991/1112/sys/src/9/safari/trap.c /n/bootesdump/1991/1113/sys/src/9/safari/trap.c
212a
	}

	if(v>=256 || ivec[v] == 0){
		if(v <= 16){
			if(user){
				sprint(buf, "sys: %s pc=0x%lux", excname[v], ur->pc);
				postnote(u->p, 1, buf, NDebug);
				return;
			} else {
				dumpregs(ur);
				panic("%s pc=0x%lux", excname[v], ur->pc);
			}
		}
		panic("bad trap type %d pc=0x%lux\n", v, ur->pc);
.
198,200d
190c
	char buf[ERRLEN];
.
181a
char *excname[] =
{
[0]	"divide error",
[1]	"debug exception",
[4]	"overflow",
[5]	"bounds check",
[6]	"invalid opcode",
[8]	"double fault",
[10]	"invalid TSS",
[11]	"segment not present",
[12]	"stack exception",
[13]	"general protection violation",
};

.
## diffname pc/trap.c 1991/1114
## diff -e /n/bootesdump/1991/1113/sys/src/9/safari/trap.c /n/bootesdump/1991/1114/sys/src/9/safari/trap.c
409a
	splx(s);
.
368a

	s = spllo();
.
363c
	ulong s, sp;
.
352d
350c

	splhi();
	if(ax!=FORK && (u->p->procctl || u->nnote))
.
348c
	if(ax == NOTED)
.
344a

.
## diffname pc/trap.c 1991/1214
## diff -e /n/bootesdump/1991/1114/sys/src/9/safari/trap.c /n/bootesdump/1991/1214/sys/src/9/safari/trap.c
315d
297a
	return USTKTOP-BY2WD;			/* address of user-level clock */
.
296a
	ulong *sp;

	sp = (ulong*)(USTKTOP - ssize);
	*--sp = nargs;
	((Ureg*)UREGADDR)->usp = (ulong)sp;
.
294,295c
long
execregs(ulong entry, ulong ssize, ulong nargs)
.
285,286c
	print("  SI %8.8lux  DI %8.8lux  BP %8.8lux\n",
		ur->si, ur->di, ur->bp);
	print("  DS %4.4ux  ES %4.4ux  FS %4.4ux  GS %4.4ux\n",
		ur->ds&0xffff, ur->es&0xffff, ur->fs&0xffff, ur->gs&0xffff);
.
280,282c
	print("FLAGS=%lux ECODE=%lux CS=%lux PC=%lux", ur->flags,
		ur->ecode, ur->cs&0xff, ur->pc);
	if(ur == (Ureg*)UREGADDR)
		print(" SS=%lux USP=%lux\n", ur->ss&0xff, ur->usp);
	else
		print("\n");
.
250,270d
226a
		if(v == 13)
			return;
.
139c
	 *  system calls and break points
.
## diffname pc/trap.c 1991/1216
## diff -e /n/bootesdump/1991/1214/sys/src/9/safari/trap.c /n/bootesdump/1991/1216/sys/src/9/safari/trap.c
456c
		qunlock(&u->p->debug);
.
445c
		qunlock(&u->p->debug);
.
439c
			qunlock(&u->p->debug);
.
429c
		qunlock(&u->p->debug);
.
426c
	qlock(&u->p->debug);
.
404c
	qunlock(&u->p->debug);
.
383c
			qunlock(&u->p->debug);
.
370c
		qunlock(&u->p->debug);
.
364c
	qlock(&u->p->debug);
.
## diffname pc/trap.c 1991/1218
## diff -e /n/bootesdump/1991/1216/sys/src/9/safari/trap.c /n/bootesdump/1991/1218/sys/src/9/safari/trap.c
371c
		pexit(n->msg, n->flag!=NDebug);
.
368c
			pprint("suicide: %s\n", n->msg);
.
366c
	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)){
.
356a
	Note *n;
.
355a
	int l;
.
231c
				sprint(buf, "sys: trap: %s", excname[v]);
.
80c
	sprint(buf, "sys: breakpoint");
.
## diffname pc/trap.c 1992/0103
## diff -e /n/bootesdump/1991/1218/sys/src/9/safari/trap.c /n/bootesdump/1992/0103/sys/src/9/safari/trap.c
343c
	splhi(); /* avoid interrupts during the iret */
.
313d
296a
/*
 *  syscall is called spllo()
 */
.
## diffname pc/trap.c 1992/0104
## diff -e /n/bootesdump/1992/0103/sys/src/9/safari/trap.c /n/bootesdump/1992/0104/sys/src/9/safari/trap.c
247c
	if(user && (u->p->procctl || u->nnote))
.
245c
	 *  check user since syscall does it's own notifying
.
## diffname pc/trap.c 1992/0108
## diff -e /n/bootesdump/1992/0104/sys/src/9/safari/trap.c /n/bootesdump/1992/0108/sys/src/9/safari/trap.c
416a
	return 1;
.
364,365c
	if(u->nnote == 0)
		return 0;
.
355c
int
.
245c
	 *  check user since syscall does its own notifying
.
11d
## diffname pc/trap.c 1992/0111
## diff -e /n/bootesdump/1992/0108/sys/src/9/safari/trap.c /n/bootesdump/1992/0111/sys/src/9/safari/trap.c
8c
#include	"../port/error.h"
.
## diffname pc/trap.c 1992/0120
## diff -e /n/bootesdump/1992/0111/sys/src/9/safari/trap.c /n/bootesdump/1992/0120/sys/src/9/safari/trap.c
290a
ulong
userpc(void)
{
	return ((Ureg*)UREGADDR)->pc;
}

.
## diffname pc/trap.c 1992/0124
## diff -e /n/bootesdump/1992/0120/sys/src/9/safari/trap.c /n/bootesdump/1992/0124/sys/src/9/safari/trap.c
422c
	return sent;
.
391a
		sent = 1;
.
388a
	sent = 0;
.
363c
	int l, sent;
.
## diffname pc/trap.c 1992/0321
## diff -e /n/bootesdump/1992/0124/sys/src/9/safari/trap.c /n/bootesdump/1992/0321/sys/src/9/safari/trap.c
2c
#include	"../port/lib.h"
.
## diffname pc/trap.c 1992/0408
## diff -e /n/bootesdump/1992/0321/sys/src/9/safari/trap.c /n/bootesdump/1992/0408/sys/src/9/safari/trap.c
255a
splhi();
.
## diffname pc/trap.c 1992/0409
## diff -e /n/bootesdump/1992/0408/sys/src/9/safari/trap.c /n/bootesdump/1992/0409/sys/src/9/safari/trap.c
256d
## diffname pc/trap.c 1992/0430
## diff -e /n/bootesdump/1992/0409/sys/src/9/safari/trap.c /n/bootesdump/1992/0430/sys/src/9/safari/trap.c
351c
	if(ax!=RFORK && (u->p->procctl || u->nnote))
.
## diffname pc/trap.c 1992/0609
## diff -e /n/bootesdump/1992/0430/sys/src/9/safari/trap.c /n/bootesdump/1992/0609/sys/src/9/safari/trap.c
461c
		validaddr(nur->pc, 1, 0);	/* check for valid pc & usp */
.
452,453c
	nur->flags = (u->svflags&0xffffff00) | (nur->flags&0xff);
	memmove(ur, nur, sizeof(Ureg));
.
435,437c
	nur = u->ureg;		/* pointer to user returned Ureg struct */
.
346a

.
345a

	/*
	 *  Put return value in frame.  On the safari the syscall is
	 *  just another trap and the return value from syscall is
	 *  ignored.  On other machines the return value is put into
	 *  the results register by caller of syscall.
	 */
.
## diffname pc/trap.c 1992/0616
## diff -e /n/bootesdump/1992/0609/sys/src/9/safari/trap.c /n/bootesdump/1992/0616/sys/src/9/safari/trap.c
467,469d
462c
		if(!okaddr(nur->pc, 1, 0) || !okaddr(nur->usp, BY2WD, 0)){
.
412,414d
407,408c
		if(!okaddr((ulong)u->notify, 1, 0)
		|| !okaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN-3*BY2WD, 0)){
			pprint("suicide: bad address in notify\n");
.
## diffname pc/trap.c 1992/0625
## diff -e /n/bootesdump/1992/0616/sys/src/9/safari/trap.c /n/bootesdump/1992/0625/sys/src/9/safari/trap.c
334c

		ret = (*systab[ax])(u->s.args);
.
332a

		u->s = *((Sargs*)(sp+1*BY2WD));
.
330a

.
## diffname pc/trap.c 1992/06271
## diff -e /n/bootesdump/1992/0625/sys/src/9/safari/trap.c /n/bootesdump/1992/06271/sys/src/9/safari/trap.c
363c
	if(u->scallnr!=RFORK && (u->p->procctl || u->nnote))
.
359c
	if(u->scallnr == NOTED)
.
342c
		print("bad errstack [%d]: %d extra\n", u->scallnr, u->nerrlab);
.
338c
		ret = (*systab[u->scallnr])(u->s.args);
.
336c
		u->p->psstate = sysctab[u->scallnr];
.
326,327c
		if(u->scallnr >= sizeof systab/BY2WD){
			pprint("bad sys call number %d pc %lux\n", u->scallnr, ur->pc);
.
321c
	u->scallnr = ur->ax;
.
308d
## diffname pc/trap.c 1992/0714
## diff -e /n/bootesdump/1992/06271/sys/src/9/safari/trap.c /n/bootesdump/1992/0714/sys/src/9/safari/trap.c
394c
		if(n->flag == NDebug)
.
## diffname pc/trap.c 1992/0804
## diff -e /n/bootesdump/1992/0714/sys/src/9/safari/trap.c /n/bootesdump/1992/0804/sys/src/9/safari/trap.c
363a

.
338a
if(u->p->fgrp->ref <= 0) print("after syscall %s\n", u->p->psstate);
.
336a
if(u->p->fgrp->ref <= 0) print("before syscall %s\n", u->p->psstate);
.
276a
	ulong l, v, i;
	extern ulong etext;

	if(u == 0)
		return;

	i = 0;
	for(l=(ulong)&l; l<USERADDR+BY2PG; l+=4){
		v = *(ulong*)l;
		if(KTZERO < v && v < (ulong)&etext){
			print("%lux ", v);
			i++;
		}
		if(i == 4){
			i = 0;
			print("\n");
		}
	}

.
## diffname pc/trap.c 1992/0805
## diff -e /n/bootesdump/1992/0804/sys/src/9/safari/trap.c /n/bootesdump/1992/0805/sys/src/9/safari/trap.c
359d
356d
339a
	if(u->scallnr == RFORK && u->p->fpstate == FPactive){
		/*
		 *  so that the child starts out with the
		 *  same registers as the parent
		 */
		splhi();
		if(u->p->fpstate == FPactive){
			fpsave(&u->fpsave);
			u->p->fpstate = FPinactive;
		}
		spllo();
	}
.
336,338d
113c
	sethvec(14, intr14, SEGIG, 0);
.
## diffname pc/trap.c 1992/0806
## diff -e /n/bootesdump/1992/0805/sys/src/9/safari/trap.c /n/bootesdump/1992/0806/sys/src/9/safari/trap.c
115c
	sethvec(16, intr16, SEGIG, 0);	/* math coprocessor, interrupts off */
.
113c
	sethvec(14, intr14, SEGIG, 0);	/* page fault, interrupts off */
.
## diffname pc/trap.c 1992/0918
## diff -e /n/bootesdump/1992/0808/sys/src/9/safari/trap.c /n/bootesdump/1992/0918/sys/src/9/pc/trap.c
238c
		print("bad trap type %d pc=0x%lux\n", v, ur->pc);
		return;
.
## diffname pc/trap.c 1992/1203
## diff -e /n/bootesdump/1992/0918/sys/src/9/pc/trap.c /n/bootesdump/1992/1203/sys/src/9/pc/trap.c
432,433c
		if(!u->notify){
			qunlock(&u->p->debug);
			pexit(n->msg, n->flag!=NDebug);
		}
.
426d
## diffname pc/trap.c 1993/0216
## diff -e /n/bootesdump/1992/1203/sys/src/9/pc/trap.c /n/bootesdump/1993/0216/sys/src/9/pc/trap.c
220d
217a
		outb(Int0ctl, EOI);
.
## diffname pc/trap.c 1993/0217
## diff -e /n/bootesdump/1993/0216/sys/src/9/pc/trap.c /n/bootesdump/1993/0217/sys/src/9/pc/trap.c
242c
	do {
		(*h->r)(ur);
		h = h->next;
	} while(h);
.
225c
	if(v>=256 || (h = halloc.ivec[v]) == 0){
.
203a
	Handler *h;
.
57a
	lock(&halloc);
	if(halloc.free >= Maxhandler)
		panic("out of interrupt handlers");
	h = &halloc.h[halloc.free++];
	h->next = halloc.ivec[v];
	h->r = r;
	halloc.ivec[v] = h;
	unlock(&halloc);

.
56c
	Handler *h;
.
45a
typedef struct Handler	Handler;
struct Handler
{
	void	(*r)(void*);
	Handler	*next;
};

struct
{
	Lock;
	Handler	*ivec[256];
	Handler	h[Maxhandler];
	int	free;
} halloc;

.
44d
34a

	Maxhandler=	128,		/* max number of interrupt handlers */
.
## diffname pc/trap.c 1993/0219
## diff -e /n/bootesdump/1993/0217/sys/src/9/pc/trap.c /n/bootesdump/1993/0219/sys/src/9/pc/trap.c
246a
		outb(Int0ctl, EOI);
.
244d
## diffname pc/trap.c 1993/0220
## diff -e /n/bootesdump/1993/0219/sys/src/9/pc/trap.c /n/bootesdump/1993/0220/sys/src/9/pc/trap.c
264c
		if(badtrap[v]++ < 10 || (badtrap[v]%1000) == 0)
			print("bad trap type %d pc=0x%lux: total %d\n", v, ur->pc,
				badtrap[v]);
.
45a
int	badtrap[256];
.
## diffname pc/trap.c 1993/0224
## diff -e /n/bootesdump/1993/0220/sys/src/9/pc/trap.c /n/bootesdump/1993/0224/sys/src/9/pc/trap.c
276,278c
	/* check user since syscall does its own notifying */
.
270a
	/* there may be multiple handlers on one interrupt level */
.
265,267c

		if(v >= Int0vec || v < Int0vec+16){
			/* an unknown interrupts */
			v -= Int0vec;
			if(badintr[v]++ == 0 || (badintr[v]%1000) == 0)
				print("unknown interrupt %d pc=0x%lux: total %d\n", v,
					ur->pc, badintr[v]);
		} else {
			/* unimplemented traps */
			print("illegal trap %d pc=0x%lux\n", v, ur->pc);
		}
.
254a

		/* a processor or coprocessor error */
.
252a
		/* an old 386 generates these fairly often, no idea why */
.
248,249d
46c
int badintr[16];
.
## diffname pc/trap.c 1993/0225
## diff -e /n/bootesdump/1993/0224/sys/src/9/pc/trap.c /n/bootesdump/1993/0225/sys/src/9/pc/trap.c
247d
244a
		outb(Int0ctl, EOI);
.
## diffname pc/trap.c 1993/0915
## diff -e /n/bootesdump/1993/0225/sys/src/9/pc/trap.c /n/fornaxdump/1993/0915/sys/src/brazil/pc/trap.c
548,551c
		if(up->lastnote.flag == NDebug)
			pprint("suicide: %s\n", up->lastnote.msg);
		qunlock(&up->debug);
		pexit(up->lastnote.msg, up->lastnote.flag!=NDebug);
.
544c
		up->lastnote.flag = NDebug;
.
539c
		qunlock(&up->debug);
.
536c
			qunlock(&up->debug);
.
529,530c
	up->notified = 0;
	nur->flags = (up->svflags&0xffffff00) | (nur->flags&0xff);
.
526c
		qunlock(&up->debug);
.
523,524c
	qlock(&up->debug);
	if(!up->notified){
.
515,517c
	nur = up->ureg;		/* pointer to user returned Ureg struct */
	if(nur->cs!=up->svcs || nur->ss!=up->svss
	|| (nur->flags&0xff00)!=(up->svflags&0xff00)){
.
502c
	qunlock(&up->debug);
.
496,500c
		ur->pc = (ulong)up->notify;
		up->notified = 1;
		up->nnote--;
		memmove(&up->lastnote, &up->note[0], sizeof(Note));
		memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
.
493c
		*(ulong*)(sp+1*BY2WD) = (ulong)up->ureg;	/* arg 1 is ureg* */
.
490c
		memmove((char*)sp, up->note[0].msg, ERRLEN);
.
487c
		up->ureg = (void*)sp;
.
484d
482a
			qunlock(&up->debug);
.
481c
		if(!okaddr((ulong)up->notify, 1, 0)
.
476,478c
		up->svcs = ur->cs;
		up->svss = ur->ss;
		up->svflags = ur->flags;
.
470,472c
	if(!up->notified){
		if(!up->notify){
			qunlock(&up->debug);
.
466d
463c
	if(n->flag!=NUser && (up->notified || up->notify==0)){
		qunlock(&up->debug);
.
454,456c
	qlock(&up->debug);
	up->notepending = 0;
	n = &up->note[0];
.
448,450c
	if(up->procctl)
		procctl(up->p);
	if(up->nnote == 0)
.
431c
	if(up->scallnr!=RFORK && (up->procctl || up->nnote))
.
427c
	if(up->scallnr == NOTED)
.
416,417c
	up->insyscall = 0;
	up->psstate = 0;
.
412c
			print("sp=%lux pc=%lux\n", up->errlab[i].sp, up->errlab[i].pc);
.
409,410c
	if(up->nerrlab){
		print("bad errstack [%d]: %d extra\n", up->scallnr, up->nerrlab);
.
406c
		ret = (*systab[up->scallnr])(up->s.args);
.
403,404c
		up->s = *((Sargs*)(sp+1*BY2WD));
		up->psstate = sysctab[up->scallnr];
.
394,396c
		if(up->scallnr >= sizeof systab/BY2WD){
			pprint("bad sys call number %d pc %lux\n", up->scallnr, ur->pc);
			postnote(up->p, 1, "sys: bad sys call", NDebug);
.
391c
	up->nerrlab = 0;
.
384,386c
		if(up->fpstate == FPactive){
			fpsave(&up->fpsave);
			up->fpstate = FPinactive;
.
377,378c
	up->scallnr = ur->ax;
	if(up->scallnr == RFORK && up->fpstate == FPactive){
.
372,373c
	up->insyscall = 1;
	up->pc = ur->pc;
.
325c
	for(l=(ulong)&l; l<up->kstack+BY2PG; l+=4){
.
321c
	if(up == 0)
.
315a
dumpregs(Ureg *ur)
{
	dumpregs2(ur);
	print("  ur %lux\n", ur);
	dumpregs2(&lasttrap);
	print("  lastur %lux\n", lastur);
}

void
.
312a

.
301c
	print("FLAGS=%lux TRAP=%lux ECODE=%lux CS=%lux PC=%lux", ur->flags, ur->trap,
.
297,298c
	if(up)
		print("registers for %s %d\n", up->text, up->pid);
.
295c
dumpregs2(Ureg *ur)
.
288a
lasttrap = *ur;
lastur = ur;
.
287c
	splhi();
	if(user && (up->procctl || up->nnote))
.
270c
			if(badintr[v]++ == 0 || (badintr[v]%100000) == 0)
.
259c
				postnote(up->p, 1, buf, NDebug);
.
250a
lasttrap = *ur;
lastur = ur;
.
236c
		up->dbgreg = ur;
.
220a
Ureg lasttrap, *lastur;


.
106c
	postnote(up->p, 1, buf, NDebug);
.
101c
	if(up == 0)
.
## diffname pc/trap.c 1993/1013
## diff -e /n/fornaxdump/1993/0915/sys/src/brazil/pc/trap.c /n/fornaxdump/1993/1013/sys/src/brazil/pc/trap.c
467c
		procctl(up);
.
414c
			postnote(up, 1, "sys: bad sys call", NDebug);
.
372c
	Ureg *ur;

	ur = (Ureg*)up->dbgreg;
	return ur->pc;
.
364,365c

	ur = up->dbgreg;
	ur->usp = (ulong)sp;
	ur->pc = entry;
.
360a
	Ureg *ur;
.
343c
	for(l=(ulong)&l; l<(ulong)(up->kstack+BY2PG); l+=4){
.
311,314c
	print(" SS=%lux USP=%lux\n", ur->ss&0xff, ur->usp);
.
264c
				postnote(up, 1, buf, NDebug);
.
106c
	postnote(up, 1, buf, NDebug);
.
## diffname pc/trap.c 1993/1022
## diff -e /n/fornaxdump/1993/1013/sys/src/brazil/pc/trap.c /n/fornaxdump/1993/1022/sys/src/brazil/pc/trap.c
593a

/* Give enough context in the ureg to produce a kernel stack for
 * a sleeping process
 */
void
setkernur(Ureg *xp, Proc *p)
{
	xp->pc = p->sched.pc;
	xp->sp = p->sched.sp;
}
.
## diffname pc/trap.c 1993/1113
## diff -e /n/fornaxdump/1993/1022/sys/src/brazil/pc/trap.c /n/fornaxdump/1993/1113/sys/src/brazil/pc/trap.c
592a
}

static void
linkproc(void)
{
	spllo();
	(*up->kpfun)(up->kparg);
}

void
kprocchild(Proc *p, void (*func)(void*), void *arg)
{
	p->sched.pc = (ulong)linkproc;
	p->sched.sp = (ulong)p->kstack+KSTACK;

	p->kpfun = func;
	p->kparg = arg;
}

void
forkchild(Proc *p, Ureg *ur)
{
	Ureg *cur;

	/*
	 * We add 2*BY2Wd to the stack because we have to account for
	 *  - the return PC
	 *  - trap's argument (ur)
	 */
	p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Ureg)+2*BY2WD);
	p->sched.pc = (ulong)forkret;

	cur = (Ureg*)(p->sched.sp+2*BY2WD);
	memmove(cur, ur, sizeof(Ureg));
	cur->ax = 0;				/* return value of syscall in child */

	/* Things from bottom of syscall we never got to execute */
	p->psstate = 0;
	p->insyscall = 0;
.
575a
long
execregs(ulong entry, ulong ssize, ulong nargs)
{
	ulong *sp;
	Ureg *ur;

	sp = (ulong*)(USTKTOP - ssize);
	*--sp = nargs;

	ur = up->dbgreg;
	ur->usp = (ulong)sp;
	ur->pc = entry;
	return USTKTOP-BY2WD;			/* address of user-level clock */
}

ulong
userpc(void)
{
	Ureg *ur;

	ur = (Ureg*)up->dbgreg;
	return ur->pc;
}

.
354,377d
348a
			lim--;
.
346c
		if(i == 8){
.
340c
	lim = 3;
	for(l=(ulong)&l; l<(ulong)(up->kstack+BY2PG) && lim; l+=4){
.
334a
	int lim;
.
327c
	print("  lastur %lux lastup %lux\n", lastur);
splhi();
dumpstack();
for(;;);
.
325c
	print("  magic %lux %lux %lux\n", x[0], x[1], x[2]);
	print("  ur %lux up %lux\n", ur, up);
.
323a
	ulong *x;

	x = (ulong*)(ur+1);
.
316,317c
	print("  DS %4.4lux  ES %4.4lux  FS %4.4lux  GS %4.4lux\n",
		ur->ds, ur->es, ur->fs, ur->gs);
.
310,311c
		ur->ecode, ur->cs, ur->pc);
	print(" SS=%lux USP=%lux\n", ur->ss, ur->usp);
.
294a

lastup = up;
.
255a
lastup = up;
.
240a
ur->cs &= 0xffff;
ur->ds &= 0xffff;
ur->es &= 0xffff;
ur->fs &= 0xffff;
ur->gs &= 0xffff;
if(user) ur->ss &= 0xffff;

.
237c
	user = (ur->cs&0xffff) == UESEL;
.
221a
Proc *lastup;
.
## diffname pc/trap.c 1993/1114
## diff -e /n/fornaxdump/1993/1113/sys/src/brazil/pc/trap.c /n/fornaxdump/1993/1114/sys/src/brazil/pc/trap.c
168c
	sethvec(Bptvec, intr3, SEGIG, 3);
.
166c
	sethvec(Syscallvec, intr64, SEGIG, 3);
.
140c
	sethvec(15, intr15, SEGIG, 0);
.
126,138c
	sethvec(0, intr0, SEGIG, 0);
	sethvec(1, intr1, SEGIG, 0);
	sethvec(2, intr2, SEGIG, 0);
	sethvec(4, intr4, SEGIG, 0);
	sethvec(5, intr5, SEGIG, 0);
	sethvec(6, intr6, SEGIG, 0);
	sethvec(7, intr7, SEGIG, 0);
	sethvec(8, intr8, SEGIG, 0);
	sethvec(9, intr9, SEGIG, 0);
	sethvec(10, intr10, SEGIG, 0);
	sethvec(11, intr11, SEGIG, 0);
	sethvec(12, intr12, SEGIG, 0);
	sethvec(13, intr13, SEGIG, 0);
.
121c
		sethvec(i, intrbad, SEGIG, 0);
.
## diffname pc/trap.c 1993/1115
## diff -e /n/fornaxdump/1993/1114/sys/src/brazil/pc/trap.c /n/fornaxdump/1993/1115/sys/src/brazil/pc/trap.c
329d
322c
	print(" SS=%4.4lux USP=%lux\n", ur->ss&0xffff, ur->usp);
.
320c
	print("FLAGS=%lux TRAP=%lux ECODE=%lux CS=%4.4lux PC=%lux", ur->flags, ur->trap,
.
315a
	ur->cs &= 0xffff;
	ur->ds &= 0xffff;
	ur->es &= 0xffff;
	ur->fs &= 0xffff;
	ur->gs &= 0xffff;

.
242,248d
226c
 *  All trapscome here.  It is slower to have all traps call trap() rather than
 *  directly vectoring the handler.  However, this avoids a lot of code duplication
 *  and possible bugs.
.
141c
	sethvec(16, intr16, SEGIG, 0);	/* math coprocessor */
.
139c
	sethvec(14, intr14, SEGIG, 0);	/* page fault */
.
## diffname pc/trap.c 1993/1116
## diff -e /n/fornaxdump/1993/1115/sys/src/brazil/pc/trap.c /n/fornaxdump/1993/1116/sys/src/brazil/pc/trap.c
242a
	else if(ur->pc <= (ulong)end && *(uchar*)ur->pc == 0xCF) {
		if(iret_traps++ > 10)
			panic("iret trap");
		return;
	}
	iret_traps = 0;
.
236a
	static int iret_traps;
.
## diffname pc/trap.c 1993/1124
## diff -e /n/fornaxdump/1993/1116/sys/src/brazil/pc/trap.c /n/fornaxdump/1993/1124/sys/src/brazil/pc/trap.c
458,459d
396a
	USED(arg);

.
390,391c
void
syscall(Ureg *ur, void *arg)
.
298c
		(*h->r)(ur, h->arg);
.
226c
 *  All traps come here.  It is slower to have all traps call trap() rather than
.
169c
	setvec(Bptvec, debugbpt, 0);
.
167c
	setvec(Syscallvec, syscall, 0);
.
100a
	USED(arg);

.
97c
debugbpt(Ureg *ur, void *arg)
.
80a
	h->arg = arg;
.
71c
setvec(int v, void (*r)(Ureg*, void*), void *arg)
.
51c
	void	(*r)(Ureg*, void*);
	void	*arg;
.
## diffname pc/trap.c 1993/1225
## diff -e /n/fornaxdump/1993/1124/sys/src/brazil/pc/trap.c /n/fornaxdump/1993/1225/sys/src/brazil/pc/trap.c
404a
	up->dbgreg = ur;

.
## diffname pc/trap.c 1994/0219
## diff -e /n/fornaxdump/1993/1225/sys/src/brazil/pc/trap.c /n/fornaxdump/1994/0219/sys/src/brazil/pc/trap.c
675c
	xp->sp = p->sched.sp+4;
.
## diffname pc/trap.c 1994/0407
## diff -e /n/fornaxdump/1994/0219/sys/src/brazil/pc/trap.c /n/fornaxdump/1994/0407/sys/src/brazil/pc/trap.c
431a
		up->syscall[up->scallnr]++;
.
427c
		if(up->scallnr >= nsyscall){
.
## diffname pc/trap.c 1994/0512
## diff -e /n/fornaxdump/1994/0407/sys/src/brazil/pc/trap.c /n/fornaxdump/1994/0512/sys/src/brazil/pc/trap.c
352,356d
310,313d
268,270d
228d
225,226d
198,199c
	outb(Int1ctl, (1<<4)|(1<<3)|(1<<0));	/* ICW1 - master, level triggered,
					  	 ICW4 will be sent */
.
186,187c
	outb(Int0ctl, (1<<4)|(1<<3)|(1<<0));	/* ICW1 - master, level triggered,
					  	 ICW4 will be sent */
.
## diffname pc/trap.c 1994/0513
## diff -e /n/fornaxdump/1994/0512/sys/src/brazil/pc/trap.c /n/fornaxdump/1994/0513/sys/src/brazil/pc/trap.c
584c
	return USTKTOP-BY2WD;		/* address of user-level clock */
.
554c
			pexit("Suicide", 0);
.
546a

	nur = up->ureg;		/* pointer to user returned Ureg struct */
	if(nur->cs!=up->svcs || nur->ss!=up->svss ||
	  (nur->flags&0xff00)!=(up->svflags&0xff00)) {
		qunlock(&up->debug);
		pprint("bad noted ureg cs %ux ss %ux flags %ux\n",
				nur->cs, nur->ss, nur->flags);
			pexit("Suicide", 0);
	}

.
543a
		pprint("call to noted() when not notified\n");
.
541,542c
	if(!up->notified) {
.
532,539d
195c
	 *  Set the 8259 as master with level triggered
.
186c
	outb(Int0ctl, (1<<4)|(0<<3)|(1<<0));	/* ICW1 - master, level triggered,
.
## diffname pc/trap.c 1994/0603
## diff -e /n/fornaxdump/1994/0513/sys/src/brazil/pc/trap.c /n/fornaxdump/1994/0603/sys/src/brazil/pc/trap.c
186c
	outb(Int0ctl, (1<<4)|(0<<3)|(1<<0));	/* ICW1 - master, edge triggered,
.
## diffname pc/trap.c 1994/0612
## diff -e /n/fornaxdump/1994/0603/sys/src/brazil/pc/trap.c /n/fornaxdump/1994/0612/sys/src/brazil/pc/trap.c
417d
## diffname pc/trap.c 1994/0623
## diff -e /n/fornaxdump/1994/0612/sys/src/brazil/pc/trap.c /n/fornaxdump/1994/0623/sys/src/brazil/pc/trap.c
447a
	if(up->nerrlab != 0)
		panic("nerrlab = %d syscall = %d\n", up->nerrlab, up->scallnr);

.
## diffname pc/trap.c 1994/0715
## diff -e /n/fornaxdump/1994/0623/sys/src/brazil/pc/trap.c /n/fornaxdump/1994/0715/sys/src/brazil/pc/trap.c
448,451d
444a
	splhi();
.
407a
	spllo();

.
406d
401d
399c
		 *  same registers as the parent.
		 *  this must be atomic relative to this CPU, hence
		 *  the spl's.
.
387a

.
377c
 *  syscall is called splhi()
.
302c
	if(v != Syscallvec && user && (up->procctl || up->nnote))
.
300c
	/*
	 *  check user since syscall does its own notifying
	 */
.
229c
 *  and possible bugs.  trap is called splhi().
.
225d
## diffname pc/trap.c 1994/0722
## diff -e /n/fornaxdump/1994/0715/sys/src/brazil/pc/trap.c /n/fornaxdump/1994/0722/sys/src/brazil/pc/trap.c
281c
			/* an unknown interrupt */
.
211,222c
char *excname[] = {
	[0]	"divide error",
	[1]	"debug exception",
	[2]	" nonmaskable interrupt",
	[3]	"breakpoint",
	[4]	"overflow",
	[5]	"bounds check",
	[6]	"invalid opcode",
	[7]	"coprocessor not available",
	[8]	"double fault",
	[9]	"9 (reserved)",
	[10]	"invalid TSS",
	[11]	"segment not present",
	[12]	"stack exception",
	[13]	"general protection violation",
	[14]	"page fault",
	[15]	"15 (reserved)",
	[16]	"coprocessor error",
.
## diffname pc/trap.c 1994/0812
## diff -e /n/fornaxdump/1994/0722/sys/src/brazil/pc/trap.c /n/fornaxdump/1994/0812/sys/src/brazil/pc/trap.c
362c
	lim = 6;
.
## diffname pc/trap.c 1994/0813
## diff -e /n/fornaxdump/1994/0812/sys/src/brazil/pc/trap.c /n/fornaxdump/1994/0813/sys/src/brazil/pc/trap.c
375a
	/* save crash info */
	print("crasharea 0x%lux\n", crasharea);
	cs = (Crashstate*)crasharea;
	memmove(cs->kstack, up->kstack, KSTACK);
	cs->kbot = up->kstack;
	memmove(cs->text, up->text, NAMELEN);
	cs->magic = 0xdeaddead;
	cs->ksp = &l;
.
363c
	for(l=(ulong)&l; l<(ulong)(up->kstack+KSTACK) && lim; l+=4){
.
356a
	Crashstate *cs;
.
348a

	/* save crash info */
	print("crasharea 0x%lux\n", crasharea);
	cs = (Crashstate*)crasharea;
	memmove(&cs->ureg, ur, sizeof(Ureg));
.
344a

.
342a
	Crashstate *cs;
	extern ulong etext;
.
63a
/*
 *  somewhere to drop crash info
 */
typedef struct
{
	ulong	magic;
	void	*kbot;
	void	*ksp;
	char	text[NAMELEN];
	Ureg	ureg;
	uchar	kstack[KSTACK];
} Crashstate;

.
## diffname pc/trap.c 1994/0814
## diff -e /n/fornaxdump/1994/0813/sys/src/brazil/pc/trap.c /n/fornaxdump/1994/0814/sys/src/brazil/pc/trap.c
398a
	if(crasharea == 0)
		return;
.
366a
	if(crasharea == 0)
		return;
.
## diffname pc/trap.c 1994/0816
## diff -e /n/fornaxdump/1994/0814/sys/src/brazil/pc/trap.c /n/fornaxdump/1994/0816/sys/src/brazil/pc/trap.c
396d
386,387c
	for(l=(ulong)&l; l<(ulong)(up->kstack+KSTACK); l+=4){
.
379d
## diffname pc/trap.c 1994/0817
## diff -e /n/fornaxdump/1994/0816/sys/src/brazil/pc/trap.c /n/fornaxdump/1994/0817/sys/src/brazil/pc/trap.c
396,406d
379d
365,371d
356d
64,76d
## diffname pc/trap.c 1994/0824
## diff -e /n/fornaxdump/1994/0817/sys/src/brazil/pc/trap.c /n/fornaxdump/1994/0824/sys/src/brazil/pc/trap.c
194c
	 *  Make 8259 interrupts start at CPU vector Int1vec.
.
## diffname pc/trap.c 1994/0902
## diff -e /n/fornaxdump/1994/0824/sys/src/brazil/pc/trap.c /n/fornaxdump/1994/0902/sys/src/brazil/pc/trap.c
348a
	print("  CR0 %8.8lux CR2 %8.8lux\n", getcr0(), getcr2());
.
## diffname pc/trap.c 1994/1007
## diff -e /n/fornaxdump/1994/0902/sys/src/brazil/pc/trap.c /n/fornaxdump/1994/1007/sys/src/brazil/pc/trap.c
174a

.
## diffname pc/trap.c 1994/1029
## diff -e /n/fornaxdump/1994/1007/sys/src/brazil/pc/trap.c /n/fornaxdump/1994/1029/sys/src/brazil/pc/trap.c
348a
	dumpregs2(&scndlastur);
	dumpregs2(&lastur);
.
311a
out:
	scndlastur = lastur;
	lastur = *ur;
.
297c
		goto out;
.
282a
print("%s pc=0x%lux", excname[v], ur->pc);
for(;;);
.
280c
				goto out;
.
273c
			goto out;
.
254c
		goto out;
.
231a
Ureg lastur;
Ureg scndlastur;

.
229a
	[17]	"alignment check",
	[18]	"something bad happened",
.
145a
	sethvec(17, intr17, SEGIG, 0);
	sethvec(18, intr18, SEGIG, 0);
.
16c
void	intr16(void), intr17(void), intr18(void);
.
## diffname pc/trap.c 1995/0105
## diff -e /n/fornaxdump/1994/1029/sys/src/brazil/pc/trap.c /n/fornaxdump/1995/0105/sys/src/brazil/pc/trap.c
592d
581,582c
		break;
.
578d
573a
	qunlock(&up->debug);

.
559c
		pexit("Suicide", 0);
.
471a
	splhi();
.
469d
## diffname pc/trap.c 1995/0115
## diff -e /n/fornaxdump/1995/0105/sys/src/brazil/pc/trap.c /n/fornaxdump/1995/0115/sys/src/brazil/pc/trap.c
474a

.
## diffname pc/trap.c 1995/0202
## diff -e /n/fornaxdump/1995/0115/sys/src/brazil/pc/trap.c /n/fornaxdump/1995/0202/sys/src/brazil/pc/trap.c
592a
		qunlock(&up->debug);
.
584a
	case NSAVE:
		if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->usp, BY2WD, 0)){
			pprint("suicide: trap in noted\n");
			qunlock(&up->debug);
			pexit("Suicide", 0);
		}
		qunlock(&up->debug);
		sp = oureg-4*BY2WD-ERRLEN;
		splhi();
		ur->sp = sp;
		((ulong*)sp)[1] = oureg;	/* arg 1 0(FP) is ureg* */
		((ulong*)sp)[0] = 0;		/* arg 0 is pc */
		break;

.
582a
		up->ureg = (Ureg*)(*(ulong*)(oureg-BY2WD));
		qunlock(&up->debug);
.
580a
			qunlock(&up->debug);
.
578a
	case NRSTR:
.
575d
573c
	/* don't let user change text or stack segments */
	nur->cs = ur->cs;
	nur->ss = ur->ss;

	/* don't let user change system flags */
	nur->flags = (ur->flags & ~0xCD5) | (nur->flags & 0xCD5);

.
568,570c
		pexit("Suicide", 0);
.
565,566c

	/* sanity clause */
	oureg = (ulong)nur;
	if(oureg>=USTKTOP || oureg<USTKTOP-USTKSIZE
	|| !okaddr((ulong)oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){
		pprint("bad ureg in noted or call to noted() when not notified\n");
.
557c
	if(arg0!=NRSTR && !up->notified) {
.
554a
	ulong oureg, sp;
.
545c
	return 1;
.
542a
		
	if(!up->notify){
		qunlock(&up->debug);
		pexit(n->msg, n->flag!=NDebug);
	}
	sp = ur->usp;
	sp -= sizeof(Ureg);

	if(!okaddr((ulong)up->notify, 1, 0)
	|| !okaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN-3*BY2WD, 0)){
		pprint("suicide: bad address in notify\n");
		qunlock(&up->debug);
		pexit("Suicide", 0);
	}

	up->ureg = (void*)sp;
	memmove((Ureg*)sp, ur, sizeof(Ureg));
	*(Ureg**)(sp-BY2WD) = up->ureg;	/* word under Ureg is old up->ureg */
	up->ureg = (void*)sp;
	sp -= BY2WD+ERRLEN;
	memmove((char*)sp, up->note[0].msg, ERRLEN);
	sp -= 3*BY2WD;
	*(ulong*)(sp+2*BY2WD) = sp+3*BY2WD;	/* arg 2 is string */
	*(ulong*)(sp+1*BY2WD) = (ulong)up->ureg;	/* arg 1 is ureg* */
	*(ulong*)(sp+0*BY2WD) = 0;		/* arg 0 is pc */
	ur->usp = sp;
	ur->pc = (ulong)up->notify;
	up->notified = 1;
	up->nnote--;
	memmove(&up->lastnote, &up->note[0], sizeof(Note));
	memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note));

.
510,541c

	if(up->notified) {
		qunlock(&up->debug);
		splhi();
		return 0;
.
503a

.
485c
	int l;
.
## diffname pc/trap.c 1995/02021
## diff -e /n/fornaxdump/1995/0202/sys/src/brazil/pc/trap.c /n/fornaxdump/1995/02021/sys/src/brazil/pc/trap.c
575,576c
	if(!okaddr((ulong)oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){
.
526c
	|| !okaddr(sp-ERRLEN-4*BY2WD, sizeof(Ureg)+ERRLEN+4*BY2WD, 1)){
.
## diffname pc/trap.c 1995/0222
## diff -e /n/fornaxdump/1995/02021/sys/src/brazil/pc/trap.c /n/fornaxdump/1995/0222/sys/src/brazil/pc/trap.c
301a
				print("isr0 = 0x%2.2ux, isr1 = 0x%2.2ux\n", isr0, isr1);
			}
.
299c
			/*
			 * Check for a default IRQ7. This can happen when
			 * the IRQ input goes away before the acknowledge.
			 * In this case, a 'default IRQ7' is generated, but
			 * the corresponding bit in the ISR isn't set.
			 */
			if(v == 7 && (isr0 & 0x80) == 0)
				goto out;
			if(badintr[v]++ == 0 || (badintr[v]%100000) == 0){
.
274a
		}
.
273c
		if(c == Int1vec){
			isr1 = inb(Int1ctl);
.
271a
		isr0 = inb(Int0ctl);
.
270a
	isr0 = isr1 = 0x00;
.
251a
	uchar isr0, isr1;
.
211a

	/*
	 * Set Ocw3 to return the ISR when ctl read.
	 */
	outb(Int0ctl, Ocw3|0x03);
	outb(Int1ctl, Ocw3|0x03);
.
33a
	Icw1=		0x10,		/* select bit in ctl register */
	Ocw2=		0x00,
	Ocw3=		0x08,

.
## diffname pc/trap.c 1995/0223
## diff -e /n/fornaxdump/1995/0222/sys/src/brazil/pc/trap.c /n/fornaxdump/1995/0223/sys/src/brazil/pc/trap.c
325c
				print("isr = 0x%4.4ux\n", isr);
.
320c
			if((isr & (1<<v)) == 0)
.
318a
			 * In fact, just ignore all such interrupts.
.
311c
		if(v >= Int0vec && v < Int0vec+16){
.
287c
			isr |= inb(Int1ctl)<<8;
.
284c
		isr = inb(Int0ctl);
.
282c
	isr = 0;
.
262c
	ushort isr;
.
## diffname pc/trap.c 1995/0329
## diff -e /n/fornaxdump/1995/0223/sys/src/brazil/pc/trap.c /n/fornaxdump/1995/0329/sys/src/brazil/pc/trap.c
202c
	 *  Set the 8259 as master with edge triggered
.
## diffname pc/trap.c 1995/0331
## diff -e /n/fornaxdump/1995/0329/sys/src/brazil/pc/trap.c /n/fornaxdump/1995/0331/sys/src/brazil/pc/trap.c
202c
	 *  Set the 8259 as master with level triggered
.
## diffname pc/trap.c 1995/0502
## diff -e /n/fornaxdump/1995/0331/sys/src/brazil/pc/trap.c /n/fornaxdump/1995/0502/sys/src/brazil/pc/trap.c
205c
	outb(Int1ctl, (1<<4)|(0<<3)|(1<<0));	/* ICW1 - master, level triggered,
.
## diffname pc/trap.c 1995/1024
## diff -e /n/fornaxdump/1995/0502/sys/src/brazil/pc/trap.c /n/fornaxdump/1995/1024/sys/src/brazil/pc/trap.c
745a

ulong
dbgpc(Proc *p)
{
	Ureg *ur;

	ur = p->dbgreg;
	if(ur == 0)
		return 0;

	return ur->pc;
}
.
## diffname pc/trap.c 1996/0514
## diff -e /n/fornaxdump/1995/1024/sys/src/brazil/pc/trap.c /n/fornaxdump/1996/0514/sys/src/brazil/pc/trap.c
293,295d
## diffname pc/trap.c 1996/0626
## diff -e /n/fornaxdump/1996/0514/sys/src/brazil/pc/trap.c /n/fornaxdump/1996/0626/sys/src/brazil/pc/trap.c
531a
		qunlock(&up->debug);
.
529d
344c
saveout:
.
340a
out:
.
329c
		goto saveout;
.
319c
				goto saveout;
.
302,303d
296a
				spllo();
.
272c
		goto saveout;
.
## diffname pc/trap.c 1996/0802
## diff -e /n/fornaxdump/1996/0626/sys/src/brazil/pc/trap.c /n/fornaxdump/1996/0802/sys/src/brazil/pc/trap.c
385a
*/
.
383a
/*
.
## diffname pc/trap.c 1997/0327
## diff -e /n/fornaxdump/1996/0802/sys/src/brazil/pc/trap.c /n/emeliedump/1997/0327/sys/src/brazil/pc/trap.c
755c
	return ureg->pc;
.
751,752c
	ureg = p->dbgreg;
	if(ureg == 0)
.
749c
	Ureg *ureg;
.
742,743c
	ureg->pc = p->sched.pc;
	ureg->sp = p->sched.sp+4;
.
740c
setkernur(Ureg* ureg, Proc* p)
.
731c
	/* Things from bottom of syscall which were never executed */
.
727,729c
	cureg = (Ureg*)(p->sched.sp+2*BY2WD);
	memmove(cureg, ureg, sizeof(Ureg));
	cureg->ax = 0;				/* return value of syscall in child */
.
720c
	 * Add 2*BY2WD to the stack to account for
.
717c
	Ureg *cureg;
.
715c
forkchild(Proc *p, Ureg *ureg)
.
705c
kprocchild(Proc* p, void (*func)(void*), void* arg)
.
701c
	up->kpfun(up->kparg);
.
692,694c
	ureg->flags = (ureg->flags & 0x00FF) | (flags & 0xFF00);
	ureg->cs = cs;
	ureg->ss = ss;
.
688,690c
	flags = ureg->flags;
	cs = ureg->cs;
	ss = ureg->ss;
.
682c
setregisters(Ureg* ureg, char* pureg, char* uva, int n)
.
679c
 * from devproc and then restore the saved values before returning
.
674,675c
	ureg = (Ureg*)up->dbgreg;
	return ureg->pc;
.
672c
	Ureg *ureg;
.
663,665c
	ureg = up->dbgreg;
	ureg->usp = (ulong)sp;
	ureg->pc = entry;
.
658c
	Ureg *ureg;
.
636c
		ureg->sp = sp;
.
628c
		if(!okaddr(nureg->pc, BY2WD, 0) || !okaddr(nureg->usp, BY2WD, 0)){
.
618c
		if(!okaddr(nureg->pc, 1, 0) || !okaddr(nureg->usp, BY2WD, 0)){
.
613c
	memmove(ureg, nureg, sizeof(Ureg));
.
611c
	nureg->flags = (ureg->flags & ~0xCD5) | (nureg->flags & 0xCD5);
.
607,608c
	nureg->cs = ureg->cs;
	nureg->ss = ureg->ss;
.
599c
	oureg = (ulong)nureg;
.
596c
	nureg = up->ureg;		/* pointer to user returned Ureg struct */
.
585c
	Ureg *nureg;
.
583c
noted(Ureg* ureg, ulong arg0)
.
567,568c
	ureg->usp = sp;
	ureg->pc = (ulong)up->notify;
.
558c
	memmove((Ureg*)sp, ureg, sizeof(Ureg));
.
547c
	sp = ureg->usp;
.
527c
		sprint(n->msg+l, " pc=0x%.8lux", ureg->pc);
.
508c
notify(Ureg* ureg)
.
499c
		notify(ureg);
.
495c
		noted(ureg, *(ulong*)(sp+BY2WD));
.
492c
	ureg->ax = ret;
.
473c
		ret = systab[up->scallnr](up->s.args);
.
462c
			pprint("bad sys call number %d pc %lux\n", up->scallnr, ureg->pc);
.
457c
	sp = ureg->usp;
.
442c
	up->scallnr = ureg->ax;
.
439c
	if((ureg->cs)&0xffff == KESEL)
.
436,437c
	up->pc = ureg->pc;
	up->dbgreg = ureg;
.
432,434c
	m->syscall++;
.
425,426c
static void
syscall(Ureg* ureg, void*)
.
416a
static void
debugbpt(Ureg* ureg, void*)
{
	char buf[ERRLEN];

	if(up == 0)
		panic("kernel bpt");
	/* restore pc to instruction that caused the trap */
	ureg->pc--;
	sprint(buf, "sys: breakpoint");
	postnote(up, 1, buf, NDebug);
}

static void
fault386(Ureg* ureg, void*)
{
	ulong addr;
	int read, user, n, insyscall;
	char buf[ERRLEN];

	insyscall = up->insyscall;
	up->insyscall = 1;
	addr = getcr2();
	read = !(ureg->ecode & 2);
	user = (ureg->cs&0xffff) == UESEL;
	spllo();
	n = fault(addr, read);
	if(n < 0){
		if(user){
			sprint(buf, "sys: trap: fault %s addr=0x%lux",
				read? "read" : "write", addr);
			postnote(up, 1, buf, NDebug);
			return;
		}
		dumpregs(ureg);
		panic("fault: 0x%lux\n", addr);
	}
	up->insyscall = insyscall;
}

.
407,408c
			p = (uchar*)v;
			if(*(p-5) == 0xE8){
				print("%lux ", p-5);
				i++;
			}
.
397a
	uchar *p;
.
383,391c
	/*
	 * Processor control registers.
	 * If machine check exception, time stamp counter, page size extensions or
	 * enhanced virtual 8086 mode extensions are supported, there is a CR4.
	 * If there is a CR4 and machine check extensions, read the machine check
	 * address and machine check type registers if RDMSR supported.
	 */
	print("  CR0 %8.8lux CR2 %8.8lux CR3 %8.8lux", getcr0(), getcr2(), getcr3());
	if(m->cpuiddx & 0x9A){
		print(" CR4 %8.8luX", getcr4());
		if((m->cpuiddx & 0xA0) == 0xA0){
			rdmsr(0x00, &mca[1], &mca[0]);
			rdmsr(0x01, &mct[1], &mct[0]);
			print("\n  MCA %8.8luX:%8.8luX MCT %8.8luX",
				mca[1], mca[0], mct[0]);
		}
	}
	print("\n  ur %luX up %luX\n", ureg, up);
.
381a
	dumpregs2(ureg);
.
380c
	ulong mca[2], mct[2];
.
377c
dumpregs(Ureg* ureg)
.
364,373c
		print("cpu%d: registers for kernel\n", m->machno);
	print("FLAGS=%luX TRAP=%luX ECODE=%luX PC=%luX", ureg->flags, ureg->trap,
		ureg->ecode, ureg->pc);
	print(" SS=%4.4luX USP=%luX\n", ureg->ss & 0xFFFF, ureg->usp);
	print("  AX %8.8luX  BX %8.8luX  CX %8.8luX  DX %8.8luX\n",
		ureg->ax, ureg->bx, ureg->cx, ureg->dx);
	print("  SI %8.8luX  DI %8.8luX  BP %8.8luX\n",
		ureg->si, ureg->di, ureg->bp);
	print("  CS %4.4uX  DS %4.4uX  ES %4.4uX  FS %4.4uX  GS %4.4uX\n",
		ureg->cs, ureg->ds, ureg->es, ureg->fs, ureg->gs);
.
362c
		print("cpu%d: registers for %s %d\n", m->machno, up->text, up->pid);
.
355,359c
	ureg->cs &= 0xFFFF;
	ureg->ds &= 0xFFFF;
	ureg->es &= 0xFFFF;
	ureg->fs &= 0xFFFF;
	ureg->gs &= 0xFFFF;
.
353c
dumpregs2(Ureg* ureg)
.
342,346c
	if(v != VectorSYSCALL && user && (up->procctl || up->nnote))
		notify(ureg);
.
340d
331,336d
329a
	else if(v <= 16 && user){
		spllo();
		sprint(buf, "sys: trap: %s", excname[v]);
		postnote(up, 1, buf, NDebug);
	}
	else if(v >= VectorPIC && v <= MaxVectorPIC){
		/*
		 * An unknown interrupt.
		 * Check for a default IRQ7. This can happen when
		 * the IRQ input goes away before the acknowledge.
		 * In this case, a 'default IRQ7' is generated, but
		 * the corresponding bit in the ISR isn't set.
		 * In fact, just ignore all such interrupts.
		 */
		if(nspuriousintr < 2)
			print("spurious interrupt %d\n", v-VectorPIC);
		nspuriousintr++;
		return;
	}
	else{
		dumpregs(ureg);
		if(v < nelem(excname))
			panic("%s", excname[v]);
		panic("unknown trap/intr: %d\n", v);
	}
.
294,328c
		if(ctl->eoi)
			ctl->eoi(v);
.
292c
		for(irq = ctl->irq; irq; irq = irq->next)
			irq->f(ureg, irq->a);
.
276,290c
	v = ureg->trap;
	if(ctl = irqctl[v]){
		if(ctl->isintr)
			m->intr++;
		if(ctl->isr)
			ctl->isr(v);
.
268,274c
		up->dbgreg = ureg;
.
264,266c
	user = (ureg->cs & 0xFFFF) == UESEL;
.
260,262c
	Irqctl *ctl;
	Irq *irq;
.
258d
255c
trap(Ureg* ureg)
.
246,247c
static int nspuriousintr;
.
243c
	[18]	"machine check",
.
234c
	[9]	"coprocessor segment overrun",
.
227c
	[2]	"nonmaskable interrupt",
.
131,221c
	intrenable(VectorBPT, debugbpt, 0, BUSUNKNOWN);
	intrenable(VectorPF, fault386, 0, BUSUNKNOWN);
	intrenable(VectorSYSCALL, syscall, 0, BUSUNKNOWN);
.
125,129c
	idt = (Segdesc*)IDTADDR;
	vaddr = (ulong)vectortable;
	for(v = 0; v < 256; v++){
		if(v == VectorBPT || v == VectorSYSCALL)
			pri = 3;
		else
			pri = 0;
		idt[v].d0 = (vaddr & 0xFFFF)|(KESEL<<16);
		idt[v].d1 = (vaddr & 0xFFFF0000)|SEGP|SEGPL(pri)|SEGIG;
		vaddr += 6;
	}
.
123c
	int v, pri;
	ulong vaddr;
	Segdesc *idt;
.
103,120d
99a
	ctl = irqctl[v];
	irq = xalloc(sizeof(Irq));
	irq->f = f;
	irq->a = a;
	irq->next = ctl->irq;
	ctl->irq = irq;
	unlock(&irqctllock);
.
75,98c
	lock(&irqctllock);
	if(irqctl[v] == 0){
		ctl = xalloc(sizeof(Irqctl));
		if(arch->intrenable(v, tbdf, ctl) == -1){
			unlock(&irqctllock);
			/*
			print("intrenable: didn't find v %d, tbdf 0x%uX\n", v, tbdf);
			 */
			xfree(ctl);
			return;
		}
		irqctl[v] = ctl;
.
71,73c
	Irq * irq;
	Irqctl *ctl;
.
69c
intrenable(int v, void (*f)(Ureg*, void*), void* a, int tbdf)
.
34,67d
24,32c
static Lock irqctllock;
static Irqctl *irqctl[256];
.
12,22c
static void debugbpt(Ureg*, void*);
static void fault386(Ureg*, void*);
static void syscall(Ureg*, void*);
.
## diffname pc/trap.c 1997/0405
## diff -e /n/emeliedump/1997/0327/sys/src/brazil/pc/trap.c /n/emeliedump/1997/0405/sys/src/brazil/pc/trap.c
144a
		if(v == 2){
			if(m->machno != 0)
				for(;;);
			nmienable();
		}
.
68a

	nmienable();
.
46a
static void
nmienable(void)
{
	int x;

	/*
	 * Hack: should be locked with NVRAM access.
	 */
	outb(0x70, 0x80);
	outb(0x70, 0);

	x = inb(0x61);
	outb(0x61, 0x08|x);
	outb(0x61, x & ~0x08);
}

.
## diffname pc/trap.c 1997/0520
## diff -e /n/emeliedump/1997/0405/sys/src/brazil/pc/trap.c /n/emeliedump/1997/0520/sys/src/brazil/pc/trap.c
491,493c
	/*
	 * Check the segment selectors are all valid, otherwise
	 * a fault will be taken on attempting to return to the
	 * user process.
	 */
	if(nureg->cs != UESEL || nureg->ss != UDSEL || nureg->ds != UDSEL
	  || nureg->es != UDSEL || nureg->fs != UDSEL || nureg->gs != UDSEL){
		pprint("bad segement selector in noted\n");
		qunlock(&up->debug);
		pexit("Suicide", 0);
	}
.
486c
		pprint("bad ureg in noted or call to noted when not notified\n");
.
## diffname pc/trap.c 1997/1003
## diff -e /n/emeliedump/1997/0520/sys/src/brazil/pc/trap.c /n/emeliedump/1997/1003/sys/src/brazil/pc/trap.c
496,498c
	if((nureg->cs & 0xFFFF) != UESEL || (nureg->ss & 0xFFFF) != UDSEL
	  || (nureg->ds & 0xFFFF) != UDSEL || (nureg->es & 0xFFFF) != UDSEL
	  || (nureg->fs & 0xFFFF) != UDSEL || (nureg->gs & 0xFFFF) != UDSEL){
		pprint("bad segment selector in noted\n");
.
494a
	 * Take care with the comparisons as different processor
	 * generations push segment descriptors in different ways.
.
## diffname pc/trap.c 1997/1011
## diff -e /n/emeliedump/1997/1003/sys/src/brazil/pc/trap.c /n/emeliedump/1997/1011/sys/src/brazil/pc/trap.c
298,299c
		if(mmukmapsync(addr) == 0){	
			dumpregs(ureg);
			panic("fault: 0x%lux\n", addr);
		}
.
## diffname pc/trap.c 1997/1101
## diff -e /n/emeliedump/1997/1011/sys/src/brazil/pc/trap.c /n/emeliedump/1997/1101/sys/src/brazil/pc/trap.c
387c
	}
.
385c
	if(scallnr!=RFORK && (up->procctl || up->nnote)){
		splhi();
.
383d
381c
	if(scallnr == NOTED)
.
374c
	 *  Put return value in frame.  On the x86 the syscall is
.
364c
		print("bad errstack [%d]: %d extra\n", scallnr, up->nerrlab);
.
360c
		ret = systab[scallnr](up->s.args);
.
357,358c
		up->s = *((Sargs*)(sp+BY2WD));
		up->psstate = sysctab[scallnr];
.
354,355c
		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs)-BY2WD))
			validaddr(sp, sizeof(Sargs)+BY2WD, 0);
.
348,349c
		if(scallnr >= nsyscall){
			pprint("bad sys call number %d pc %lux\n", scallnr, ureg->pc);
.
342d
326,340c
	scallnr = ureg->ax;
	up->scallnr = scallnr;
	if(scallnr == RFORK && up->fpstate == FPactive){
		splhi();
		fpsave(&up->fpsave);
		up->fpstate = FPinactive;
		spllo();
.
320a
	if((ureg->cs & 0xFFFF) != UESEL)
		panic("syscall: cs 0x%4.4uX\n", ureg->cs);

.
319c
	int	i, scallnr;
.
314,315c
void
syscall(Ureg* ureg)
.
312c
 *  Syscall is called directly from assembler without going through trap().
.
252c
			if(*(p-5) == 0xE8 || (*(p-2) == 0xFF && *(p-1) == 0xD0)){
.
250a
			/*
			 * Pick off general CALL (0xE8) and CALL indirect
			 * through AX (0xFFD0).
			 */
.
206c
		ureg->cs & 0xFFFF, ureg->ds & 0xFFFF, ureg->es & 0xFFFF,
		ureg->fs & 0xFFFF, ureg->gs & 0xFFFF);
.
188,193d
179a
	}
.
174,178c
	if(user && (up->procctl || up->nnote)){
		splhi();
.
134,135c
			if(ctl->isr)
				ctl->isr(v);
		}
.
132c
		if(ctl->isintr){
.
128a
	}
.
126,127c
	user = 0;
	if((ureg->cs & 0xFFFF) == UESEL){
		user = 1;
.
116c
 *  and possible bugs.  The only exception is VectorSYSCALL.
 *  Trap is called with interrupts disabled via interrupt-gates.
.
84d
81a
	/*
	 * Special traps.
	 * Syscall() is called directly without going through trap().
	 */
.
78c
		idt[v].d1 = d1;
.
73,76c
		d1 = (vaddr & 0xFFFF0000)|SEGP;
		switch(v){

		case VectorBPT:
			d1 |= SEGPL(3)|SEGIG;
			break;

		case VectorSYSCALL:
			d1 |= SEGPL(3)|SEGTG;
			break;

		default:
			d1 |= SEGPL(0)|SEGIG;
			break;
		}
.
66c
	int d1, v;
.
14d
## diffname pc/trap.c 1998/0115
## diff -e /n/emeliedump/1997/1101/sys/src/brazil/pc/trap.c /n/emeliedump/1998/0115/sys/src/brazil/pc/trap.c
174,176c
		print("cpu%d: spurious interrupt %d, last %d",
			m->machno, v-VectorPIC, m->lastintr);
		for(i = 0; i < 32; i++){
			if(!(active.machs & (1<<i)))
				continue;
			mach = MACHP(i);
			if(m->machno == mach->machno)
				continue;
			print(": cpu%d: last %d", mach->machno, mach->lastintr);
		}
		print("\n");
		m->spuriousintr++;
.
151a
			if(v >= VectorPIC && v <= MaxVectorPIC)
				m->lastintr = v-VectorPIC;
.
138a
	Mach *mach;
.
135c
	int i, v, user;
.
124,125d
## diffname pc/trap.c 1998/0320
## diff -e /n/emeliedump/1998/0115/sys/src/brazil/pc/trap.c /n/emeliedump/1998/0320/sys/src/brazil/pc/trap.c
193c
			//nmienable();
.
190c
		if(v == VectorNMI){
.
102c
static char *excname[] = {
.
59c
	outb(0x61, x);
.
57c
	x = inb(0x61) & 0x07;		/* Enable NMI */
.
54c
	outb(0x70, 0x80);		/* NMI latch clear */
.
27c
		if(v >= VectorINTR && arch->intrenable(v, tbdf, ctl) == -1){
.
## diffname pc/trap.c 1998/0401
## diff -e /n/emeliedump/1998/0320/sys/src/brazil/pc/trap.c /n/emeliedump/1998/0401/sys/src/brazil/pc/trap.c
360a
	spllo();
.
359d
356d
248,251c
			rdmsr(0x00, &mca);
			rdmsr(0x01, &mct);
			print("\n  MCA %8.8lluX MCT %8.8lluX", mca, mct);
.
233c
	vlong mca, mct;
.
193c
			}
.
191c
			nmienable();
			if(m->machno != 0){
				print("cpu%d: PC %8.8uX\n", m->machno, ureg->pc);
.
159a

		/* preemptive scheduling */
		if(ctl->isintr && v != VectorTIMER && v != VectorCLOCK)
			if(up && up->state == Running && anyhigher())
				sched();
.
80c
			d1 |= SEGPL(3)|SEGIG;
.
29,31c
			//print("intrenable: didn't find v %d, tbdf 0x%uX\n", v, tbdf);
.
## diffname pc/trap.c 1998/0512
## diff -e /n/emeliedump/1998/0401/sys/src/brazil/pc/trap.c /n/emeliedump/1998/0512/sys/src/brazil/pc/trap.c
161,162c
		if(up && up->state == Running)
		if(anyhigher())
		if(!active.exiting)
			sched();
.
142a
{
ulong x, y;

x = (ulong)&(m->stack[512]);
y = (ulong)&mach;
if(y < x) panic("trap: kstack %lux %lux", m->stack, y);
}

.
## diffname pc/trap.c 1998/0514
## diff -e /n/emeliedump/1998/0512/sys/src/brazil/pc/trap.c /n/emeliedump/1998/0514/sys/src/brazil/pc/trap.c
148c
if(y < x+512) panic("cpu%d: trap: kstack %lux %lux", m->machno, x, y);
.
146c
if(up)
  x = (ulong)(up->kstack);
else
  x = (ulong)(m->stack);
.
## diffname pc/trap.c 1998/0516
## diff -e /n/emeliedump/1998/0514/sys/src/brazil/pc/trap.c /n/emeliedump/1998/0516/sys/src/brazil/pc/trap.c
175a
			splhi();
			up->preempted = 0;
		}
.
174c
		if(up->preempted == 0)
		if(!active.exiting){
			up->preempted = 1;
.
170c
		/* 
		 *  preemptive scheduling.  to limit stack depth,
		 *  make sure process has a chance to return from
		 *  the current interrupt before being preempted a
		 *  second time.
		 */
.
143,153d
## diffname pc/trap.c 1998/0605
## diff -e /n/emeliedump/1998/0516/sys/src/brazil/pc/trap.c /n/emeliedump/1998/0605/sys/src/brazil/pc/trap.c
419a
	}
	if (up->nlocks != 0) {
		print("nlock = %d\n", up->nlocks);
		up->nlocks = 0;
.
173a
			return;
.
## diffname pc/trap.c 1998/0606
## diff -e /n/emeliedump/1998/0605/sys/src/brazil/pc/trap.c /n/emeliedump/1998/0606/sys/src/brazil/pc/trap.c
422,425d
## diffname pc/trap.c 1998/0731
## diff -e /n/emeliedump/1998/0606/sys/src/brazil/pc/trap.c /n/emeliedump/1998/0731/sys/src/brazil/pc/trap.c
339,342c
		dumpregs(ureg);
		panic("fault: 0x%lux\n", addr);
.
329c
	insyscall = up->insyscall;
	up->insyscall = 1;
.
327a
	user = (ureg->cs & 0xFFFF) == UESEL;
	if(!user && mmukmapsync(addr))
		return;
.
325,326d
## diffname pc/trap.c 1998/0806
## diff -e /n/emeliedump/1998/0731/sys/src/brazil/pc/trap.c /n/emeliedump/1998/0806/sys/src/brazil/pc/trap.c
35c

.
33c
		unlock(&irqctllock);
		print("intrenable: didn't find v %d, tbdf 0x%uX\n", v, tbdf);
		return;
.
31d
25,29c
	if(irqctl[v] == 0)
		irqctl[v] = xalloc(sizeof(Irqctl));
	ctl = irqctl[v];

	if(v >= VectorINTR && arch->intrenable(v, tbdf, ctl) == -1){
		if(ctl->irq == nil){
			irqctl[v] = nil;
.
21c
	Irq *irq;
.
## diffname pc/trap.c 1998/0811
## diff -e /n/emeliedump/1998/0806/sys/src/brazil/pc/trap.c /n/emeliedump/1998/0811/sys/src/brazil/pc/trap.c
274c
	print("\n  ur %lux up %lux\n", ureg, up);
.
271c
			print("\n  MCA %8.8llux MCT %8.8llux", mca, mct);
.
267c
		print(" CR4 %8.8lux", getcr4());
.
243c
	print("  SI %8.8lux  DI %8.8lux  BP %8.8lux\n",
.
240,241c
	print(" SS=%4.4lux USP=%lux\n", ureg->ss & 0xFFFF, ureg->usp);
	print("  AX %8.8lux  BX %8.8lux  CX %8.8lux  DX %8.8lux\n",
.
238c
	print("FLAGS=%lux TRAP=%lux ECODE=%lux PC=%lux", ureg->flags, ureg->trap,
.
## diffname pc/trap.c 1998/0825
## diff -e /n/emeliedump/1998/0811/sys/src/brazil/pc/trap.c /n/emeliedump/1998/0825/sys/src/brazil/pc/trap.c
245c
	print("  CS %4.4luX  DS %4.4luX  ES %4.4luX  FS %4.4luX  GS %4.4luX\n",
.
243c
	print("  SI %8.8luX  DI %8.8luX  BP %8.8luX\n",
.
240,241c
	print(" SS=%4.4luX USP=%luX\n", ureg->ss & 0xFFFF, ureg->usp);
	print("  AX %8.8luX  BX %8.8luX  CX %8.8luX  DX %8.8luX\n",
.
238c
	print("FLAGS=%luX TRAP=%luX ECODE=%luX PC=%luX", ureg->flags, ureg->trap,
.
235c
		print("cpu%d: registers for %s %lud\n", m->machno, up->text, up->pid);
.
212c
				print("cpu%d: PC %8.8luX\n", m->machno, ureg->pc);
.
## diffname pc/trap.c 1998/0910
## diff -e /n/emeliedump/1998/0825/sys/src/brazil/pc/trap.c /n/emeliedump/1998/0910/sys/src/brazil/pc/trap.c
344,345c
		sprint(buf, "sys: trap: fault %s addr=0x%lux",
			read? "read" : "write", addr);
		postnote(up, 1, buf, NDebug);
.
338,342c
		if(!user){
			dumpregs(ureg);
			panic("fault: 0x%lux\n", addr);
.
217,219c
		if(vno < nelem(excname))
			panic("%s", excname[vno]);
		panic("unknown trap/intr: %d\n", vno);
.
209c
		if(vno == VectorNMI){
.
195c
			m->machno, vno, m->lastintr);
.
185c
	else if(vno >= VectorPIC && vno != VectorSYSCALL){
.
182c
		sprint(buf, "sys: trap: %s", excname[vno]);
.
180c
	else if(vno <= nelem(excname) && user){
.
168c
		if(ctl->isintr && ctl->irq != IrqTIMER && ctl->irq != IrqCLOCK)
.
160c
			ctl->eoi(vno);
.
156,158c
		if(ctl->isr)
			ctl->isr(vno);
		for(v = ctl; v != nil; v = v->next){
			if(v->f)
				v->f(ureg, v->a);
		}
.
150,153c
			if(vno >= VectorPIC && vno != VectorSYSCALL)
				m->lastintr = ctl->irq;
.
146,147c
	vno = ureg->trap;
	if(ctl = vctl[vno]){
.
136,137c
	Vctl *ctl, *v;
.
134c
	int i, vno, user;
.
103,122c
static char* excname[32] = {
	"divide error",
	"debug exception",
	"nonmaskable interrupt",
	"breakpoint",
	"overflow",
	"bounds check",
	"invalid opcode",
	"coprocessor not available",
	"double fault",
	"coprocessor segment overrun",
	"invalid TSS",
	"segment not present",
	"stack exception",
	"general protection violation",
	"page fault",
	"15 (reserved)",
	"coprocessor error",
	"alignment check",
	"machine check",
	"19 (reserved)",
	"20 (reserved)",
	"21 (reserved)",
	"22 (reserved)",
	"23 (reserved)",
	"24 (reserved)",
	"25 (reserved)",
	"26 (reserved)",
	"27 (reserved)",
	"28 (reserved)",
	"29 (reserved)",
	"30 (reserved)",
	"31 (reserved)",
.
97,98c
	trapenable(VectorBPT, debugbpt, 0);
	trapenable(VectorPF, fault386, 0);
.
39,44c
void
trapenable(int vno, void (*f)(Ureg*, void*), void* a)
{
	Vctl *v;

	if(vno < 0 || vno >= VectorPIC)
		panic("trapenable: vno %d\n", vno);
	v = xalloc(sizeof(Vctl));
	v->tbdf = BUSUNKNOWN;
	v->f = f;
	v->a = a;

	lock(&vctllock);
	if(vctl[vno])
		v->next = vctl[vno]->next;
	vctl[vno] = v;
	unlock(&vctllock);
.
37a
	if(vctl[vno]){
		if(vctl[vno]->isr != v->isr || vctl[vno]->eoi != v->eoi)
			panic("intrenable: irq handler botch: %luX %luX %luX %luX\n",
				vctl[vno]->isr, v->isr, vctl[vno]->eoi, v->eoi);
		v->next = vctl[vno]->next;
	}
	vctl[vno] = v;
	iunlock(&vctllock);
}
.
29,35c
	ilock(&vctllock);
	vno = arch->intrenable(v);
	//print("irq%d, vno %d\n", irq, vno);
	if(vno == -1){
		iunlock(&vctllock);
		print("intrenable: couldn't enable irq %d, tbdf 0x%uX\n", irq, tbdf);
		xfree(v);
.
24,27c
	v = xalloc(sizeof(Vctl));
	v->isintr = 1;
	v->irq = irq;
	v->tbdf = tbdf;
	v->f = f;
	v->a = a;
.
21,22c
	int vno;
	Vctl *v;
.
19c
intrenable(int irq, void (*f)(Ureg*, void*), void* a, int tbdf)
.
15,16c
static Lock vctllock;
static Vctl *vctl[256];
.
## diffname pc/trap.c 1998/1218
## diff -e /n/emeliedump/1998/0910/sys/src/brazil/pc/trap.c /n/emeliedump/1998/1218/sys/src/brazil/pc/trap.c
44c
		v->next = vctl[vno];
.
## diffname pc/trap.c 1999/0301
## diff -e /n/emeliedump/1998/1218/sys/src/brazil/pc/trap.c /n/emeliedump/1999/0301/sys/src/brazil/pc/trap.c
698c
	/* return value of syscall in child */
	cureg->ax = 0;
.
647,648c
/* This routine must save the values of registers the user is not permitted
 * to write from devproc and then restore the saved values before returning.
.
597c
		if(!okaddr(nureg->pc, BY2WD, 0)
		|| !okaddr(nureg->usp, BY2WD, 0)){
.
554c
	nureg = up->ureg;	/* pointer to user returned Ureg struct */
.
437c
			print("sp=%lux pc=%lux\n",
				up->errlab[i].sp, up->errlab[i].pc);
.
420c
			pprint("bad sys call number %d pc %lux\n",
				scallnr, ureg->pc);
.
331c
			if(*(p-5) == 0xE8
			|| (*(p-2) == 0xFF && *(p-1) == 0xD0)){
.
300c
	print("  CR0 %8.8lux CR2 %8.8lux CR3 %8.8lux",
		getcr0(), getcr2(), getcr3());
.
295,298c
	 * If machine check exception, time stamp counter, page size extensions
	 * or enhanced virtual 8086 mode extensions are supported, there is a
	 * CR4. If there is a CR4 and machine check extensions, read the machine
	 * check address and machine check type registers if RDMSR supported.
.
273,274c
	print("FLAGS=%luX TRAP=%luX ECODE=%luX PC=%luX",
		ureg->flags, ureg->trap, ureg->ecode, ureg->pc);
.
270c
		print("cpu%d: registers for %s %lud\n",
			m->machno, up->text, up->pid);
.
247c
				print("cpu%d: PC %8.8luX\n",
					m->machno, ureg->pc);
.
161,163c
 *  All traps come here.  It is slower to have all traps call trap()
 *  rather than directly vectoring the handler.  However, this avoids a
 *  lot of code duplication and possible bugs.  The only exception is
 *  VectorSYSCALL.
.
42c
			panic("intrenable: handler: %luX %luX %luX %luX\n",
.
36c
		print("intrenable: couldn't enable irq %d, tbdf 0x%uX\n",
			irq, tbdf);
.
33d
## diffname pc/trap.c 1999/0319
## diff -e /n/emeliedump/1999/0301/sys/src/brazil/pc/trap.c /n/emeliedump/1999/0319/sys/src/brazil/pc/trap.c
378a
print("fault pc %luX addr %luX\n", ureg->pc, addr);
.
## diffname pc/trap.c 1999/0514
## diff -e /n/emeliedump/1999/0319/sys/src/brazil/pc/trap.c /n/emeliedump/1999/0514/sys/src/brazil/pc/trap.c
379d
## diffname pc/trap.c 1999/0517
## diff -e /n/emeliedump/1999/0514/sys/src/brazil/pc/trap.c /n/emeliedump/1999/0517/sys/src/brazil/pc/trap.c
685c
	p->sched.sp = (ulong)p->kstack+KSTACK-BY2WD;
.
683a
	/*
	 * gotolabel() needs a word on the stack in
	 * which to place the return PC used to jump
	 * to linkproc().
	 */
.
## diffname pc/trap.c 1999/0528
## diff -e /n/emeliedump/1999/0517/sys/src/brazil/pc/trap.c /n/emeliedump/1999/0528/sys/src/brazil/pc/trap.c
17a
uvlong	intrts;

.
## diffname pc/trap.c 1999/0529
## diff -e /n/emeliedump/1999/0528/sys/src/brazil/pc/trap.c /n/emeliedump/1999/0529/sys/src/brazil/pc/trap.c
740a
}

/* called with interrupts off */
static void
savets(void)
{
	lock(&tsalloc);
	if(tsalloc.n < nelem(tsalloc.ts))
		tsalloc.ts[tsalloc.n++] = intrts;
	unlock(&tsalloc);
}

/* read interrupt timestamps */
long
readintrts(void *buf, int n)
{
	n /= sizeof(uvlong);
	if(n <= 0)
		return 0;
	ilock(&tsalloc);
	if(n > tsalloc.n)
		n = tsalloc.n;
	memmove(buf, tsalloc.ts, n*sizeof(uvlong));
	tsalloc.n = 0;
	iunlock(&tsalloc);
	return n*sizeof(uvlong);
.
183a
	if(vno == tsalloc.vno)
		savets();
.
34a
	if(irq == IrqUART0)
		tsalloc.vno = vno;
.
19a
static void	savets(void);

.
18c
/* interrupt timestamps, l.s knows fills intrts each interupt */
	uvlong	intrts;
static	struct {
	Lock;
	int	vno;		/* vector to save timestamps for */
	int	n;		/* number of valid timestamps in ts[] */
	uvlong	ts[128];	/* time stamps */
} tsalloc;
.
## diffname pc/trap.c 1999/0601
## diff -e /n/emeliedump/1999/0529/sys/src/brazil/pc/trap.c /n/emeliedump/1999/0601/sys/src/brazil/pc/trap.c
754,779d
195,196d
44,45d
27,28d
18,25c
/* interrupt timestamps, l.s fills intrts each interupt */
uvlong	intrts;
.
## diffname pc/trap.c 1999/0604
## diff -e /n/emeliedump/1999/0601/sys/src/brazil/pc/trap.c /n/emeliedump/1999/0604/sys/src/brazil/pc/trap.c
629c
		} else
			qunlock(&up->debug);
.
627c
		if(up->lastnote.flag == NDebug){ 
			qunlock(&up->debug);
.
610a
			pprint("suicide: trap in noted\n");
.
609d
599a
			pprint("suicide: trap in noted\n");
.
598d
## diffname pc/trap.c 1999/0701
## diff -e /n/emeliedump/1999/0604/sys/src/brazil/pc/trap.c /n/emeliedump/1999/0701/sys/src/brazil/pc/trap.c
378d
177a
	m->intrts = fastticks(nil);
.
18,20d
## diffname pc/trap.c 1999/0717
## diff -e /n/emeliedump/1999/0701/sys/src/brazil/pc/trap.c /n/emeliedump/1999/0717/sys/src/brazil/pc/trap.c
338c
				print("%p ", p-5);
.
## diffname pc/trap.c 1999/0720
## diff -e /n/emeliedump/1999/0717/sys/src/brazil/pc/trap.c /n/emeliedump/1999/0720/sys/src/brazil/pc/trap.c
346a
	if(i)
		print("\n");
.
342c
		if(i == 4){
.
338c
				print("%.8lux=%.8lux ", l, v);
.
326a
	getpcsp(&pc, &sp);
	print("ktrace /kernel/path %.8lux %.8lux\n", pc, sp);
.
320a
	ulong sp, pc;
.
317a
getpcsp(ulong *pc, ulong *sp)
{
	*pc = getcallerpc(&pc);
	*sp = (ulong)&pc;
}

void
.
## diffname pc/trap.c 1999/0721
## diff -e /n/emeliedump/1999/0720/sys/src/brazil/pc/trap.c /n/emeliedump/1999/0721/sys/src/brazil/pc/trap.c
358a
}

void
dumpstack(void)
{
	callwithureg(_dumpstack);
.
335,336c
	print("ktrace /kernel/path %.8lux %.8lux\n", ureg->pc, ureg->sp);
.
328d
324,325c
static void
_dumpstack(Ureg *ureg)
.
320,321c
	Ureg ureg;
	ureg.pc = getcallerpc(&fn);
	ureg.sp = (ulong)&fn;
	fn(&ureg);
.
318c
callwithureg(void (*fn)(Ureg*))
.
316a

/*
 * Fill in enough of Ureg to get a stack trace, and call a function.
 * Used by debugging interface rdb.
 */
.
## diffname pc/trap.c 1999/0819
## diff -e /n/emeliedump/1999/0721/sys/src/brazil/pc/trap.c /n/emeliedump/1999/0819/sys/src/brazil/pc/trap.c
119,120c
	trapenable(VectorBPT, debugbpt, 0, "debugpt");
	trapenable(VectorPF, fault386, 0, "fault386");
.
60a
	strncpy(v->name, name, NAMELEN);
	v->name[NAMELEN-1] = 0;
.
51c
trapenable(int vno, void (*f)(Ureg*, void*), void* a, char *name)
.
49a
int
irqallocread(char *buf, long n, vlong offset)
{
	int vno;
	Vctl *v;
	long oldn;
	char str[11+1+NAMELEN+1], *p;
	int m;

	if(n < 0 || offset < 0)
		error(Ebadarg);

	oldn = n;
	for(vno=0; vno<nelem(vctl); vno++){
		for(v=vctl[vno]; v; v=v->next){
			m = snprint(str, sizeof str, "%11d %11d %.*s\n", vno, v->irq, NAMELEN, v->name);
			if(m <= offset)	/* if do not want this, skip entry */
				offset -= m;
			else{
				/* skip offset bytes */
				m -= offset;
				p = str+offset;
				offset = 0;

				/* write at most max(n,m) bytes */
				if(m > n)
					m = n;
				memmove(buf, p, m);
				n -= m;
				buf += m;

				if(n == 0)
					return oldn;
			}	
		}
	}
	return oldn - n;
}

.
42c
			panic("intrenable: handler: %s %s %luX %luX %luX %luX\n",
				vctl[vno]->name, v->name,
.
35,36c
		print("intrenable: couldn't enable irq %d, tbdf 0x%uX for %s\n",
			irq, tbdf, v->name);
		if(p=vctl[vno]){
			print("intrenable: irq %d is already used by", irq);
			for(; p; p=p->next)
				print(" %s", p->name);
			print("\n");
		}
.
29a
	strncpy(v->name, name, NAMELEN-1);
	v->name[NAMELEN-1] = 0;
.
22c
	Vctl *v, *p;
.
19c
intrenable(int irq, void (*f)(Ureg*, void*), void* a, int tbdf, char *name)
.
## diffname pc/trap.c 2000/0626
## diff -e /n/emeliedump/1999/0819/sys/src/brazil/pc/trap.c /n/emeliedump/2000/0626/sys/src/9/pc/trap.c
39,44d
22c
	Vctl *v;
.
## diffname pc/trap.c 2000/0902
## diff -e /n/emeliedump/2000/0626/sys/src/9/pc/trap.c /n/emeliedump/2000/0902/sys/src/9/pc/trap.c
714a
/*
 *  return the userpc the last exception happened at
 */
.
## diffname pc/trap.c 2000/1018
## diff -e /n/emeliedump/2000/0902/sys/src/9/pc/trap.c /n/emeliedump/2000/1018/sys/src/9/pc/trap.c
166a

	addarchfile("irqalloc", 0444, irqallocread, nil);
.
65a
	buf = vbuf;
.
59,60c
	Vctl *v;
.
56,57c
	char *buf, *p, str[11+1+NAMELEN+1];
	int m, vno;
.
53,54c
static long
irqallocread(Chan*, void *vbuf, long n, vlong offset)
.
## diffname pc/trap.c 2001/0217
## diff -e /n/emeliedump/2000/1018/sys/src/9/pc/trap.c /n/emeliedump/2001/0217/sys/src/9/pc/trap.c
279c
		for(i = 0; i < 0; i++){
.
## diffname pc/trap.c 2001/0219
## diff -e /n/emeliedump/2001/0217/sys/src/9/pc/trap.c /n/emeliedump/2001/0219/sys/src/9/pc/trap.c
279c
		for(i = 0; i < conf.nmach; i++){
.
## diffname pc/trap.c 2001/0405
## diff -e /n/emeliedump/2001/0219/sys/src/9/pc/trap.c /n/emeliedump/2001/0405/sys/src/9/pc/trap.c
396,401c
			print("%.8lux=%.8lux ", l, v);
			i++;
.
393,394c
			 * we could Pick off general CALL (((uchar*)v)[-5] == 0xE8)
			 * and CALL indirect through AX (((uchar*)v)[-2] == 0xFF && ((uchar*)v)[-2] == 0xD0),
			 * but this is too clever and misses faulting address.
.
## diffname pc/trap.c 2001/0411
## diff -e /n/emeliedump/2001/0405/sys/src/9/pc/trap.c /n/emeliedump/2001/0411/sys/src/9/pc/trap.c
490c
		if(scallnr >= nsyscall || systab[scallnr] == 0){
.
381d
## diffname pc/trap.c 2001/0527
## diff -e /n/emeliedump/2001/0411/sys/src/9/pc/trap.c /n/emeliedump/2001/0527/sys/src/9/pc/trap.c
676c
		sp = oureg-4*BY2WD-ERRMAX;
.
591,592c
	sp -= BY2WD+ERRMAX;
	memmove((char*)sp, up->note[0].msg, ERRMAX);
.
581c
	|| !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)){
.
555,556c
		if(l > ERRMAX-15)	/* " pc=0x12345678\0" */
			l = ERRMAX-15;
.
438a
if(up == nil) {print("what? up is zero pc %8lux\n", ureg->pc); for(;;);}
.
432c
	char buf[ERRMAX];
.
417c
	char buf[ERRMAX];
.
279c
		for(i = 0; i < 32; i++){
.
217c
	char buf[ERRMAX];
.
103,104c
	strncpy(v->name, name, KNAMELEN);
	v->name[KNAMELEN-1] = 0;
.
68c
			m = snprint(str, sizeof str, "%11d %11d %.*s\n", vno, v->irq, KNAMELEN, v->name);
.
56c
	char *buf, *p, str[11+1+KNAMELEN+1];
.
30,31c
	strncpy(v->name, name, KNAMELEN-1);
	v->name[KNAMELEN-1] = 0;
.
## diffname pc/trap.c 2001/0822
## diff -e /n/emeliedump/2001/0527/sys/src/9/pc/trap.c /n/emeliedump/2001/0822/sys/src/9/pc/trap.c
504a
	}else{
		/* failure: save the error buffer for errstr */
		kstrcpy(up->syserror, up->error, sizeof up->syserror);
.
## diffname pc/trap.c 2001/0905
## diff -e /n/emeliedump/2001/0822/sys/src/9/pc/trap.c /n/emeliedump/2001/0905/sys/src/9/pc/trap.c
52a
void
intrdisable(int irq, void (*f)(Ureg *, void *), void *a, int tbdf, char *name)
{
	Vctl **pv, *v;
	int vno;

	vno = arch->intrvecno(irq);
	ilock(&vctllock);
	pv = &vctl[vno];
	while (*pv && 
		  ((*pv)->irq != irq || (*pv)->tbdf != tbdf || (*pv)->f != f || (*pv)->a != a ||
		   strcmp((*pv)->name, name)))
		pv = &((*pv)->next);
	assert(*pv);

	v = *pv;
	*pv = (*pv)->next;	/* Link out the entry */
	
	if (vctl[vno] == nil)
		arch->intrdisable(irq);
	iunlock(&vctllock);
	xfree(v);
}

.
## diffname pc/trap.c 2001/0914
## diff -e /n/emeliedump/2001/0905/sys/src/9/pc/trap.c /n/emeliedump/2001/0914/sys/src/9/pc/trap.c
71c
	if (vctl[vno] == nil && arch->intrdisable != nil)
.
58a
	/*
	 * For now, none of this will work with the APIC code,
	 * there is no mapping between irq and vector as the IRQ
	 * is pretty meaningless.
	 */
	if(arch->intrvecno == nil)
		return;
.
## diffname pc/trap.c 2001/0924
## diff -e /n/emeliedump/2001/0914/sys/src/9/pc/trap.c /n/emeliedump/2001/0924/sys/src/9/pc/trap.c
538c
		e = up->syserrstr;
		up->syserrstr = up->errstr;
		up->errstr = e;
.
496a
	char *e;
.
## diffname pc/trap.c 2001/1130
## diff -e /n/emeliedump/2001/0924/sys/src/9/pc/trap.c /n/emeliedump/2001/1130/sys/src/9/pc/trap.c
23a
	if(f == nil){
		print("intrenable: nil handler for %d, tbdf 0x%uX for %s\n",
			irq, tbdf, name);
		return;
	}

.
## diffname pc/trap.c 2002/0114
## diff -e /n/emeliedump/2001/1130/sys/src/9/pc/trap.c /n/emeliedump/2002/0114/sys/src/9/pc/trap.c
509c
		panic("syscall: cs 0x%4.4luX\n", ureg->cs);
.
## diffname pc/trap.c 2002/0220
## diff -e /n/emeliedump/2002/0114/sys/src/9/pc/trap.c /n/emeliedump/2002/0220/sys/src/9/pc/trap.c
476c
	if(up == nil)
		panic("what? up is zero pc 0x%8.8lux\n", ureg->pc);
.
## diffname pc/trap.c 2002/0327
## diff -e /n/emeliedump/2002/0220/sys/src/9/pc/trap.c /n/emeliedump/2002/0327/sys/src/9/pc/trap.c
305a
		/* call all interrupt routines, just in case */
		for(i = VectorPIC; i <= MaxIrqLAPIC; i++){
			ctl = vctl[i];
			if(ctl == nil)
				continue;
			if(!ctl->isintr)
				continue;
			for(v = ctl; v != nil; v = v->next){
				if(v->f)
					v->f(ureg, v->a);
			}
			/* should we do this? */
			if(ctl->eoi)
				ctl->eoi(i);
		}
			
.
## diffname pc/trap.c 2002/0329
## diff -e /n/emeliedump/2002/0327/sys/src/9/pc/trap.c /n/emeliedump/2002/0329/sys/src/9/pc/trap.c
306,320c
		i8259isr(vno);
.
## diffname pc/trap.c 2002/0402
## diff -e /n/emeliedump/2002/0329/sys/src/9/pc/trap.c /n/emeliedump/2002/0402/sys/src/9/pc/trap.c
315a

		/* call all interrupt routines, just in case */
		for(i = VectorPIC; i <= MaxIrqLAPIC; i++){
			ctl = vctl[i];
			if(ctl == nil)
				continue;
			if(!ctl->isintr)
				continue;
			for(v = ctl; v != nil; v = v->next){
				if(v->f)
					v->f(ureg, v->a);
			}
			/* should we do this? */
			if(ctl->eoi)
				ctl->eoi(i);
		}

		/* clear the interrupt */
		i8259isr(vno);
			
.
306,307d
## diffname pc/trap.c 2002/0404
## diff -e /n/emeliedump/2002/0402/sys/src/9/pc/trap.c /n/emeliedump/2002/0404/sys/src/9/pc/trap.c
445c
	if(up)
		estack = (ulong)up->kstack+KSTACK;
	else
		estack = (ulong)m+MACHSIZE;

	for(l=(ulong)&l; l<estack; l+=4){
.
440,442d
437c
	ulong l, v, i, estack;
.
## diffname pc/trap.c 2002/0412
## diff -e /n/emeliedump/2002/0404/sys/src/9/pc/trap.c /n/emeliedump/2002/0412/sys/src/9/pc/trap.c
445a
	else
		return;
.
444c
	else if((ulong)&l >= (ulong)m->stack
	&& (ulong)&l <= (ulong)m+BY2PG)
.
442c
	if(up
	&& (ulong)&l >= (ulong)up->kstack
	&& (ulong)&l <= (ulong)up->kstack+KSTACK)
.
## diffname pc/trap.c 2002/0417
## diff -e /n/emeliedump/2002/0412/sys/src/9/pc/trap.c /n/emeliedump/2002/0417/sys/src/9/pc/trap.c
534c
	int	i;
	ulong scallnr;
.
## diffname pc/trap.c 2002/0419
## diff -e /n/emeliedump/2002/0417/sys/src/9/pc/trap.c /n/emeliedump/2002/0419/sys/src/9/pc/trap.c
579c
		print("bad errstack [%uld]: %d extra\n", scallnr, up->nerrlab);
.
334c
		if(0)print("cpu%d: spurious interrupt %d, last %d",
.
## diffname pc/trap.c 2002/0420
## diff -e /n/emeliedump/2002/0419/sys/src/9/pc/trap.c /n/emeliedump/2002/0420/sys/src/9/pc/trap.c
289a
		if(up->nlocks == 0)
.
## diffname pc/trap.c 2002/0423
## diff -e /n/emeliedump/2002/0420/sys/src/9/pc/trap.c /n/emeliedump/2002/0423/sys/src/9/pc/trap.c
290d
## diffname pc/trap.c 2002/0425
## diff -e /n/emeliedump/2002/0423/sys/src/9/pc/trap.c /n/emeliedump/2002/0425/sys/src/9/pc/trap.c
539a
	/* check syscall has an empty kernel stack */
	if(up->kstack + KSTACK - (char*)ureg > 512)
		panic("syscall: stack %ld\n", up->kstack + KSTACK - (char*)ureg);

.
## diffname pc/trap.c 2002/0426
## diff -e /n/emeliedump/2002/0425/sys/src/9/pc/trap.c /n/emeliedump/2002/0426/sys/src/9/pc/trap.c
540,543d
## diffname pc/trap.c 2002/0524
## diff -e /n/emeliedump/2002/0426/sys/src/9/pc/trap.c /n/emeliedump/2002/0524/sys/src/9/pc/trap.c
93c
	char *buf, *p, str[2*(11+1)+KNAMELEN+1+1];
.
## diffname pc/trap.c 2002/0615
## diff -e /n/emeliedump/2002/0524/sys/src/9/pc/trap.c /n/emeliedump/2002/0615/sys/src/9/pc/trap.c
821a
	pexit("kproc dying", 0);
.
## diffname pc/trap.c 2002/0820
## diff -e /n/emeliedump/2002/0615/sys/src/9/pc/trap.c /n/emeliedump/2002/0820/sys/src/9/pc/trap.c
280a
		if(ctl->isintr && m->havetsc)
			intrtime(m, vno);
.
258c
	if(m->havetsc)
		 rdtsc(&m->intrts);
.
243a
 *  keep histogram of interrupt service times (tops off at 1/100 second)
 */
void
intrtime(Mach *m, int vno)
{
	uvlong now;
	ulong diff;

	rdtsc(&now);
	diff = now - m->intrts;
	diff /= m->cpumhz;
	if(diff >= 1000)
		diff = 999;
	if(intrtimes[vno] == nil)
		intrtimes[vno] = xalloc(Ntimevec*sizeof(ulong));
	intrtimes[vno][diff]++;
}

/*
.
17a
enum
{
	Ntimevec = 1000		/* number of time buckets for each intr */
};

.
16a
ulong *intrtimes[256];
.
## diffname pc/trap.c 2002/0821
## diff -e /n/emeliedump/2002/0820/sys/src/9/pc/trap.c /n/emeliedump/2002/0821/sys/src/9/pc/trap.c
263,264d
60a
	if(intrtimes[vno] == nil)
		intrtimes[vno] = xalloc(Ntimevec*sizeof(ulong));
.
## diffname pc/trap.c 2002/0822
## diff -e /n/emeliedump/2002/0821/sys/src/9/pc/trap.c /n/emeliedump/2002/0822/sys/src/9/pc/trap.c
326a
		if(ctl->isintr)
			intrtime(m, vno);
.
321a
			intrtime(m, vno);
.
307,308d
283,284c
	m->perf.intrts = perfticks();
.
263,264c
	if(diff >= Ntimevec)
		diff = Ntimevec-1;
.
260,261c
	diff = x - m->perf.intrts;
	m->perf.intrts = x;

	m->perf.inintr += diff;
	if(up == nil && m->perf.inidle > diff)
		m->perf.inidle -= diff;

.
258a
	ulong x = perfticks();
.
257d
255c
intrtime(Mach*, int vno)
.
252c
 *  keep histogram of interrupt service times
.
## diffname pc/trap.c 2002/0824
## diff -e /n/emeliedump/2002/0822/sys/src/9/pc/trap.c /n/emeliedump/2002/0824/sys/src/9/pc/trap.c
808a

	up->fpstate = FPinit;
	fpoff();
.
733a
	up->fpstate &= ~FPillegal;

.
702c
	*(ulong*)(sp+0*BY2WD) = 0;			/* arg 0 is pc */
.
700c
	*(ulong*)(sp+2*BY2WD) = sp+3*BY2WD;		/* arg 2 is string */
.
654a
	if(user && up->fpstate == FPactive){
		fpsave(&up->fpsave);
		up->fpstate = FPinactive;
	}
	up->fpstate |= FPillegal;

.
## diffname pc/trap.c 2002/0829
## diff -e /n/emeliedump/2002/0824/sys/src/9/pc/trap.c /n/emeliedump/2002/0829/sys/src/9/pc/trap.c
655c
	if(up->fpstate == FPactive){
.
## diffname pc/trap.c 2002/0924
## diff -e /n/emeliedump/2002/0829/sys/src/9/pc/trap.c /n/emeliedump/2002/0924/sys/src/9/pc/trap.c
537c
		panic("fault but up is zero; pc 0x%8.8lux addr 0x%8.8lux\n", ureg->pc, addr);
.
## diffname pc/trap.c 2002/1216
## diff -e /n/emeliedump/2002/0924/sys/src/9/pc/trap.c /n/emeliedump/2002/1216/sys/src/9/pc/trap.c
609a
		if(0 && up->pid == 1)
			print("syscall %lud error %s\n", scallnr, up->syserrstr);
.
## diffname pc/trap.c 2002/1218
## diff -e /n/emeliedump/2002/1216/sys/src/9/pc/trap.c /n/emeliedump/2002/1218/sys/src/9/pc/trap.c
269a
	}
.
268c
	if(diff >= Ntimevec){
		if (vno == 32) print("timer took %d µs\n", diff);
.
## diffname pc/trap.c 2002/1219
## diff -e /n/emeliedump/2002/1218/sys/src/9/pc/trap.c /n/emeliedump/2002/1219/sys/src/9/pc/trap.c
269d
## diffname pc/trap.c 2003/0228
## diff -e /n/emeliedump/2002/1219/sys/src/9/pc/trap.c /n/emeliedump/2003/0228/sys/src/9/pc/trap.c
331,332d
326,329c
			if(up && ctl->irq != IrqTIMER && ctl->irq != IrqCLOCK)
				preempted();
.
313,324c
		if(ctl->isintr){
.

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].