~kris/9p

9hist

13369d18518a14fb305bfd04834283001d5d0d06 — David du Colombier 35 years ago 536ac6b
Plan 9 from Bell Labs 1991-07-03
10 files changed, 679 insertions(+), 199 deletions(-)

M pc/dat.h
M pc/fns.h
A pc/io.h
M pc/kbd.c
M pc/l.s
M pc/main.c
M pc/mem.h
M pc/mmu.c
M pc/trap.c
M port/queue.c
M pc/dat.h => pc/dat.h +12 -1
@@ 5,6 5,7 @@ typedef struct Lock	Lock;
typedef struct MMU	MMU;
typedef struct Mach	Mach;
typedef struct PMMU	PMMU;
typedef struct Segdesc	Segdesc;
typedef struct Ureg	Ureg;
typedef struct User	User;



@@ 20,7 21,7 @@ extern  void	(*kprofp)(ulong);

struct Lock
{
	char	key;
	ulong	key;
	ulong	pc;
};



@@ 151,6 152,16 @@ struct User
	ushort	svsr;
};

/*
 *  segment descriptor/gate
 */
struct Segdesc
{
	ulong	d0;
	ulong	d1;
};


struct
{
	Lock;

M pc/fns.h => pc/fns.h +30 -0
@@ 1,7 1,37 @@
#include "../port/portfns.h"

void	delay(int);
int	inb(int);
void	intr0(void);
void	intr1(void);
void	intr2(void);
void	intr3(void);
void	intr4(void);
void	intr5(void);
void	intr6(void);
void	intr7(void);
void	intr8(void);
void	intr9(void);
void	intr10(void);
void	intr11(void);
void	intr12(void);
void	intr13(void);
void	intr14(void);
void	intr15(void);
void	intr16(void);
void	intrbad(void);
int	kbdc(void);
void	kbdinit(void);
void	kbdintr(void*);
void	lgdt(Segdesc*, int);
void	lidt(Segdesc*, int);
void	outb(int, int);
void	prhex(ulong);
void	screeninit(void);
void	screenputc(int);
void	screenputs(char*, int);
void	setvec(int, void (*)(void*), int);
void	sti(void);
void	systrap(void);
void	trapinit(void);
int	tas(Lock*);

A pc/io.h => pc/io.h +20 -0
@@ 0,0 1,20 @@
/*
 *  interrupt levels
 */
enum {
	Clockvec=	8,
	Kbdvec=		9,
	Floppyvec=	14,
};

/*
 *  damned 8259, assume DOS sets it up for us
 */
enum {
	Intctlport=	0x20,	/* 8259 control port */
	Intctlmask=	0x21,	/* interrupt mask */

	Intenable=	0x20,	/* written to Intctlport, enables next int */
};

#define	INTENABLE	outb(Intctlport, Intenable)

M pc/kbd.c => pc/kbd.c +351 -103
@@ 2,6 2,8 @@
#include	"lib.h"
#include	"dat.h"
#include	"fns.h"
#include	"io.h"
#include	"mem.h"

enum {
	Data=		0x60,	/* data port */


@@ 16,120 18,366 @@ enum {
	 Rtimeout=	0x40,	/*  receive timeout */
	 Parity=	0x80,	/*  0==odd, 1==even */

	
	Spec=	0x80,

	PF=	Spec|0x20,	/* num pad function key */
	View=	Spec|0x00,	/* view (shift window up) */
	F=	Spec|0x40,	/* function key */
	Shift=	Spec|0x60,
	Break=	Spec|0x61,
	Ctrl=	Spec|0x62,
	Latin=	Spec|0x63,
	Caps=	Spec|0x64,
	Num=	Spec|0x65,
	No=	Spec|0x7F,	/* no mapping */

	Home=	F|13,
	Up=	F|14,
	Pgup=	F|15,
	Print=	F|16,
	Left=	View,
	Right=	View,
	End=	'\r',
	Down=	View,
	Pgdown=	View,
	Ins=	F|20,
	Del=	0x7F,
};

char noshift[256] = 
uchar kbtab[] = 
{
[0x00]	Nokey,	0x1b,	'1',	'2',	'3',	'4',	'5',	'6',
[0x00]	No,	0x1b,	'1',	'2',	'3',	'4',	'5',	'6',
[0x08]	'7',	'8',	'9',	'0',	'-',	'=',	'\b',	'\t',
[0x10]
[0x28]
[0x30]
[0x10]	'q',	'w',	'e',	'r',	't',	'y',	'u',	'i',
[0x18]	'o',	'p',	'[',	']',	'\n',	Ctrl,	'a',	's',
[0x20]	'd',	'f',	'g',	'h',	'j',	'k',	'l',	';',
[0x28]	'\'',	'`',	Shift,	'\\',	'z',	'x',	'c',	'v',
[0x30]	'b',	'n',	'm',	',',	'.',	'/',	Shift,	No,
[0x38]	Latin,	' ',	Caps,	F|1,	F|2,	F|3,	F|4,	F|5,
[0x40]	F|6,	F|7,	F|8,	F|9,	F|10,	Num,	F|12,	Home,
[0x48]	No,	No,	No,	No,	No,	No,	No,	No,
[0x50]	No,	No,	No,	No,	No,	No,	No,	F|11,
[0x58]	F|12,	No,	No,	No,	No,	No,	No,	No,
};

uchar kbtabshift[] =
{
[0x00]	No,	0x1b,	'!',	'@',	'#',	'$',	'%',	'^',
[0x08]	'&',	'*',	'(',	')',	'_',	'+',	'\b',	'\t',
[0x10]	'Q',	'W',	'E',	'R',	'T',	'Y',	'U',	'I',
[0x18]	'O',	'P',	'{',	'}',	'\n',	Ctrl,	'A',	'S',
[0x20]	'D',	'F',	'G',	'H',	'J',	'K',	'L',	':',
[0x28]	'"',	'~',	Shift,	'|',	'Z',	'X',	'C',	'V',
[0x30]	'B',	'N',	'M',	'<',	'>',	'?',	Shift,	No,
[0x38]	Latin,	' ',	Caps,	F|1,	F|2,	F|3,	F|4,	F|5,
[0x40]	F|6,	F|7,	F|8,	F|9,	F|10,	Num,	F|12,	Home,
[0x48]	No,	No,	No,	No,	No,	No,	No,	No,
[0x50]	No,	No,	No,	No,	No,	No,	No,	F|11,
[0x58]	F|12,	No,	No,	No,	No,	No,	No,	No,
};

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

struct latin
{
	uchar	l;
	char	c[2];
}latintab[] = {
	'€',	"!!",	/* spanish initial ! */
	'€',	"c|",	/* cent */
	'€',	"c$",	/* cent */
	'€',	"l$",	/* pound sterling */
	'€',	"g$",	/* general currency */
	'€',	"y$",	/* yen */
	'€',	"j$",	/* yen */
	'€',	"||",	/* broken vertical bar */
	'€',	"SS",	/* section symbol */
	'€',	"\"\"",	/* dieresis */
	'€',	"cr",	/* copyright */
	'€',	"cO",	/* copyright */
	'€',	"sa",	/* super a, feminine ordinal */
	'€',	"<<",	/* left angle quotation */
	'€',	"no",	/* not sign, hooked overbar */
	'€',	"--",	/* soft hyphen */
	'€',	"rg",	/* registered trademark */
	'€',	"__",	/* macron */
	'€',	"s0",	/* degree (sup o) */
	'€',	"+-",	/* plus-minus */
	'€',	"s2",	/* sup 2 */
	'€',	"s3",	/* sup 3 */
	'€',	"''",	/* grave accent */
	'€',	"mu",	/* mu */
	'€',	"pg",	/* paragraph (pilcrow) */
	'€',	"..",	/* centered . */
	'€',	",,",	/* cedilla */
	'€',	"s1",	/* sup 1 */
	'€',	"so",	/* sup o */
	'€',	">>",	/* right angle quotation */
	'€',	"14",	/* 1/4 */
	'€',	"12",	/* 1/2 */
	'€',	"34",	/* 3/4 */
	'€',	"??",	/* spanish initial ? */
	'€',	"A`",	/* A grave */
	'€',	"A'",	/* A acute */
	'€',	"A^",	/* A circumflex */
	'€',	"A~",	/* A tilde */
	'€',	"A\"",	/* A dieresis */
	'€',	"A:",	/* A dieresis */
	'€',	"Ao",	/* A circle */
	'€',	"AO",	/* A circle */
	'€',	"Ae",	/* AE ligature */
	'€',	"AE",	/* AE ligature */
	'€',	"C,",	/* C cedilla */
	'€',	"E`",	/* E grave */
	'€',	"E'",	/* E acute */
	'€',	"E^",	/* E circumflex */
	'€',	"E\"",	/* E dieresis */
	'€',	"E:",	/* E dieresis */
	'€',	"I`",	/* I grave */
	'€',	"I'",	/* I acute */
	'€',	"I^",	/* I circumflex */
	'€',	"I\"",	/* I dieresis */
	'€',	"I:",	/* I dieresis */
	'€',	"D-",	/* Eth */
	'€',	"N~",	/* N tilde */
	'€',	"O`",	/* O grave */
	'€',	"O'",	/* O acute */
	'€',	"O^",	/* O circumflex */
	'€',	"O~",	/* O tilde */
	'€',	"O\"",	/* O dieresis */
	'€',	"O:",	/* O dieresis */
	'€',	"OE",	/* O dieresis */
	'€',	"Oe",	/* O dieresis */
	'€',	"xx",	/* times sign */
	'€',	"O/",	/* O slash */
	'€',	"U`",	/* U grave */
	'€',	"U'",	/* U acute */
	'€',	"U^",	/* U circumflex */
	'€',	"U\"",	/* U dieresis */
	'€',	"U:",	/* U dieresis */
	'€',	"UE",	/* U dieresis */
	'€',	"Ue",	/* U dieresis */
	'€',	"Y'",	/* Y acute */
	'€',	"P|",	/* Thorn */
	'€',	"Th",	/* Thorn */
	'€',	"TH",	/* Thorn */
	'€',	"ss",	/* sharp s */
	'€',	"a`",	/* a grave */
	'€',	"a'",	/* a acute */
	'€',	"a^",	/* a circumflex */
	'€',	"a~",	/* a tilde */
	'€',	"a\"",	/* a dieresis */
	'€',	"a:",	/* a dieresis */
	'€',	"ao",	/* a circle */
	'€',	"ae",	/* ae ligature */
	'€',	"c,",	/* c cedilla */
	'€',	"e`",	/* e grave */
	'€',	"e'",	/* e acute */
	'€',	"e^",	/* e circumflex */
	'€',	"e\"",	/* e dieresis */
	'€',	"e:",	/* e dieresis */
	'€',	"i`",	/* i grave */
	'€',	"i'",	/* i acute */
	'€',	"i^",	/* i circumflex */
	'€',	"i\"",	/* i dieresis */
	'€',	"i:",	/* i dieresis */
	'€',	"d-",	/* eth */
	'€',	"n~",	/* n tilde */
	'€',	"o`",	/* o grave */
	'€',	"o'",	/* o acute */
	'€',	"o^",	/* o circumflex */
	'€',	"o~",	/* o tilde */
	'€',	"o\"",	/* o dieresis */
	'€',	"o:",	/* o dieresis */
	'€',	"oe",	/* o dieresis */
	'€',	"-:",	/* divide sign */
	'€',	"o/",	/* o slash */
	'€',	"u`",	/* u grave */
	'€',	"u'",	/* u acute */
	'€',	"u^",	/* u circumflex */
	'€',	"u\"",	/* u dieresis */
	'€',	"u:",	/* u dieresis */
	'€',	"ue",	/* u dieresis */
	'€',	"y'",	/* y acute */
	'€',	"th",	/* thorn */
	'€',	"p|",	/* thorn */
	'€',	"y\"",	/* y dieresis */
	'€',	"y:",	/* y dieresis */
	0,	0,
};

KIOQ	kbdq;

int
latin1(int k1, int k2)
{
	int i;
	struct latin *l;

	for(l=latintab; l->l; l++)
		if(k1==l->c[0] && k2==l->c[1])
			return l->l;
	return 0;
}

void
kbdinit(void)
{
	initq(&kbdq);
	setvec(Kbdvec, kbdintr, SEGIG);
}

/*
 *  get a byte from the keyboard
 */
int
kbdc(void)
{
	while((inb(Status)&Inready)==0)
		;
	return inb(Data);
	int c;

	for(;;){
		while((inb(Status)&Inready)==0)
			;
		kbdintr(&c);
		c = getc(&kbdq);
		if(c != -1)
			return c;
	}
}

1	0x1b,
3b	F1,
3c	F2,
3d	F3,
3e	F4,
3f	F5,
40	f6,
41	F7,
42	F8,
43	F9,
44	F10,
57	F11,
58	F12,
e0 52	INS,
e0 53	DEL,
2	'1',
3	'2',
4	'3',
5	'4',
6	'5',
7	'6',
8	'7',
9	'8',
A	'9',
B	'0',
C	'-',
D	'=',
E	'\b',
E0 47	Home,
F	'\t',
10	'q',
11	'w',
12	'e',
13	'r',
14	't',
15	'y',
16	'u',
17	'i',
18	'o',
19	'p',
1a	'[',
1b	']',
2b	'\\',
e0 49	Pageup,
3a	Capslock,
1e	'a'
1f	's' 
20	'd'
21	'f'
22	'g'
23	'h'
24	'j'
25	'k'
26	'l'
27	';'
28	'\''
1c	'\r'
2a	Lshift,
2c	'z'
2d	'x'
2e	'c'
2f	'v'
30	'b'
31	'n'
32	'm'
33	','
34	'.'
35	'/'
36	Rshift,
e0 51	Pagedown,
e0 4f	End,
e0 48	Uparrow,
e0 50	Downarrow,
e0 4b	Leftarrow,
e0 4d   Rightarrow,
e0 1d	Rctl,
e0 38	Ralt,
39	Space,
38	Lalt,
1d	Lctl,
29	'`',
1d 38 1 81 b8 9d	F1
1d 38 21 a1 b8 9d	F2
	2e ae		F3
	19 99		F4
	26		F5
	2F		F6

e1 1d 45 e1 9d cf	F7
e0 46 e0 c6		f8
e0 2a e0 37 e0 b7 e0 aa	f9
54			f10
45			f11
46			f12
int
kbdputc(IOQ* q, int c)
{
	screenputc(c);
	putc(q, c);
}

/*
 *  keyboard interrupt
 */
void
kbdintr(void *a)
{
	int c, nc;
	static int esc1, esc2;
	static int shift;
	static int caps;
	static int ctl;
	static int num;
	static int lstate, k1, k2;
	int keyup;

	/*
	 *  get a character to be there
	 */
	c = inb(Data);

	keyup = c&0x80;
	c &= 0x7f;
	if(c > sizeof kbtab){
		print("unknown key %ux\n", c|keyup);
		kbdputc(&kbdq, k1);
		goto out;
	}

	/*
	 *  e0's is the first of a 2 character sequence
	 */
	if(c == 0xe0){
		esc1 = 1;
		goto out;
	} else if(c == 0xe1){
		esc2 = 2;
		goto out;
	}

	if(esc1){
		c = kbtabesc1[c];
		esc1 = 0;
	} else if(esc2){
		esc2--;
		goto out;
	} else if(shift)
		c = kbtabshift[c];
	else
		c = kbtab[c];

	if(caps && c<='z' && c>='a')
		c += 'A' - 'a';

	/*
	 *  keyup only important for shifts
	 */
	if(keyup){
		switch(c){
		case Shift:
			shift = 0;
			break;
		case Ctrl:
			ctl = 0;
			break;
		}
		goto out;
	}

	/*
 	 *  normal character
	 */
	if(!(c & Spec)){
		if(ctl)
			c &= 0x1f;
		switch(lstate){
		case 1:
			k1 = c;
			lstate = 2;
			return;
		case 2:
			k2 = c;
			lstate = 0;
			c = latin1(k1, k2);
			if(c == 0){
				kbdputc(&kbdq, k1);
				c = k2;
			}
			/* fall through */
		default:
			break;
		}
	} else {
		switch(c){
		case Caps:
			caps ^= 1;
			goto out;
		case Num:
			num ^= 1;
			goto out;
		case Shift:
			shift = 1;
			goto out;
		case Latin:
			lstate = 1;
			goto out;
		case Ctrl:
			ctl = 1;
			goto out;
		}
	}
	kbdputc(&kbdq, c);
out:
	INTENABLE;			/* reenable interrupt */
	return;
}

M pc/l.s => pc/l.s +136 -0
@@ 162,3 162,139 @@ TEXT	outb(SB),$0
	MOVL	b+4(FP),AX
	OUTB
	RET

/*
 *  test and set
 */
TEXT	tas(SB),$0
	MOVL	$0xdeadead,AX
	MOVL	l+0(FP),BX
	XCHGL	AX,(BX)
	RET

/*
 *  load the idt
 */
GLOBL	idtptr(SB),$6
TEXT	lidt(SB),$0
	MOVL	t+0(FP),AX
	MOVL	AX,idtptr+2(SB)
	MOVL	l+4(FP),AX
	MOVW	AX,idtptr(SB)
	MOVL	idtptr(SB),IDTR
	RET

/*
 *  load the gdt
 */
GLOBL	gdtptr(SB),$6
TEXT	lgdt(SB),$0
	MOVL	t+0(FP),AX
	MOVL	AX,gdtptr+2(SB)
	MOVL	l+4(FP),AX
	MOVW	AX,gdtptr(SB)
	MOVL	gdtptr(SB),GDTR
	RET

/*
 *  special traps
 */
TEXT	intr0(SB),$0
	PUSHL	$0
	PUSHL	$0
	JMP	intrcommon
TEXT	intr1(SB),$0
	PUSHL	$0
	PUSHL	$1
	JMP	intrcommon
TEXT	intr2(SB),$0
	PUSHL	$0
	PUSHL	$2
	JMP	intrcommon
TEXT	intr3(SB),$0
	PUSHL	$0
	PUSHL	$3
	JMP	intrcommon
TEXT	intr4(SB),$0
	PUSHL	$0
	PUSHL	$4
	JMP	intrcommon
TEXT	intr5(SB),$0
	PUSHL	$0
	PUSHL	$5
	JMP	intrcommon
TEXT	intr6(SB),$0
	PUSHL	$0
	PUSHL	$6
	JMP	intrcommon
TEXT	intr7(SB),$0
	PUSHL	$0
	PUSHL	$7
	JMP	intrcommon
TEXT	intr8(SB),$0
	PUSHL	$8
	JMP	intrscommon
TEXT	intr9(SB),$0
	PUSHL	$0
	PUSHL	$9
	JMP	intrcommon
TEXT	intr10(SB),$0
	PUSHL	$10
	JMP	intrscommon
TEXT	intr11(SB),$0
	PUSHL	$11
	JMP	intrscommon
TEXT	intr12(SB),$0
	PUSHL	$12
	JMP	intrscommon
TEXT	intr13(SB),$0
	PUSHL	$13
	JMP	intrscommon
TEXT	intr14(SB),$0
	PUSHL	$14
	JMP	intrscommon
TEXT	intr15(SB),$0
	PUSHL	$0
	PUSHL	$15
	JMP	intrcommon
TEXT	intr16(SB),$0
	PUSHL	$0
	PUSHL	$16
	JMP	intrcommon
TEXT	intrbad(SB),$0
	PUSHL	$0
	PUSHL	$0x1ff
	JMP	intrcommon

intrcommon:
	PUSHL	DS
	PUSHAL
	LEAL	0(SP),AX
	PUSHL	AX
	CALL	trap(SB)
	POPL	AX
	POPAL
	POPL	DS
	ADDL	$8,SP	/* error code and trap type */
	IRETL
	RET

intrscommon:
	PUSHL	DS
	PUSHAL
	LEAL	0(SP),AX
	PUSHL	AX
	CALL	trap(SB)
	POPL	AX
	POPAL
	POPL	DS
	ADDL	$8,SP	/* error code and trap type */
	IRETL
	RET

/*
 *  turn on interrupts
 */
TEXT	sti(SB),$0
	STI
	RET

M pc/main.c => pc/main.c +20 -3
@@ 5,9 5,14 @@

main(void)
{
	for(;;){
		print("%x ", kbdc());
	}
	screeninit();
	print("screen inited\n");
	trapinit();
	print("traps inited\n");
	kbdinit();
	print("kbd inited\n");
	sti();
	for(;;);
}

void


@@ 37,3 42,15 @@ print(char *fmt, ...)
	screenputs(buf, n);
	return n;
}

void
panic(char *fmt, ...)
{
	char buf[PRINTSIZE];
	int n;

	screenputs("panic: ", 7);
	n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
	screenputs(buf, n);
	for(;;);
}

M pc/mem.h => pc/mem.h +5 -4
@@ 59,10 59,10 @@
 */

#define	NULLSEG	0	/* null segment */
#define	KESEG	1	/* kernel executable */	
#define	KDSEG	2	/* kernel data/stack */
#define	UESEG	3	/* user executable */
#define	UDSEG	4	/* user data/stack */
#define	KDSEG	1	/* kernel data/stack */
#define	KESEG	2	/* kernel executable */	
#define	UDSEG	3	/* user data/stack */
#define	UESEG	4	/* user executable */
#define	SYSGATE	5	/* system call gate */

#define SELGDT	(0<<3)	/* selector is in gdt */


@@ 86,6 86,7 @@
#define SEGCG	(0x0C<<8)	/* call gate */
#define	SEGIG	(0x0E<<8)	/* interrupt gate */
#define SEGTG	(0x0F<<8)	/* task gate */
#define SEGTYPE	(0x1F<<8)

#define SEGP	(1<<15)		/* segment present */
#define SEGPL(x) ((x)<<13)	/* priority level */

M pc/mmu.c => pc/mmu.c +25 -27
@@ 6,29 6,6 @@
#include	"io.h"

/*
 *  segment descriptor/gate
 */
typedef struct Segdesc	Segdesc;
struct Segdesc
{
	ulong	d0;
	ulong	d1;
};

/*
 *  gate initializers
 */
#define TRAPGATE(s,o,p)	{ (o)&0xFFFF0000|SEGP|SEGPL(p)|SEGTG, (o)&0xFFFF|((s)<<16) }
#define INTRGATE(s,o,p)	{ (o)&0xFFFF0000|SEGP|SEGPL(p)|SEGIG, (o)&0xFFFF|((s)<<16) }
#define CALLGATE(s,o,p)	{ (o)&0xFFFF0000|SEGP|SEGPL(p)|SEGCG, (o)&0xFFFF|((s)<<16) }

/*
 *  segment descriptor initializers
 */
#define	DATASEG(p) 	{ SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(p)|SEGDATA|SEGW, 0xFFFF }
#define	EXECSEG(p) 	{ SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(p)|SEGEXEC|SEGR, 0xFFFF }

/*
 *  task state segment.  Plan 9 ignores all the task switching goo and just
 *  uses the tss for esp0 and ss0 on gate's into the kernel, interrupts,
 *  and exceptions.  The rest is completely ignored.


@@ 67,14 44,35 @@ struct Tss
};

/*
 *  segment descriptor initializers
 */
#define	DATASEG(p) 	{ 0xFFFF, SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(p)|SEGDATA|SEGW }
#define	EXECSEG(p) 	{ 0xFFFF, SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(p)|SEGEXEC|SEGR }
#define CALLGATE(s,o,p)	{ (o)&0xFFFF|((s)<<16), (o)&0xFFFF0000|SEGP|SEGPL(p)|SEGCG }

/*
 *  global descriptor table describing all segments
 */
Segdesc gdt[1024] =
Segdesc gdt[6] =
{
[NULLSEG]	{ 0, 0},		/* null descriptor */
[KESEG]		EXECSEG(0),		/* kernel code */
[KDSEG]		DATASEG(0),		/* kernel data/stack */
[UESEG]		EXECSEG(3),		/* user code */
[KESEG]		EXECSEG(0),		/* kernel code */
[UDSEG]		DATASEG(3),		/* user data/stack */
[SYSGATE]	CALLGATE(KESEG, syscall, 3),	/* call gate for system calls */
[UESEG]		EXECSEG(3),		/* user code */
[SYSGATE]	CALLGATE(KESEL,0,3),	/* call gate for system calls */
};

void
mmuinit(void)
{
	gdt[SYSGATE].d0 = ((ulong)systrap)&0xFFFF|(KESEL<<16);
	gdt[SYSGATE].d1 = ((ulong)systrap)&0xFFFF0000|SEGP|SEGPL(3)|SEGCG;
	lgdt(gdt, sizeof gdt);
}

void
systrap(void)
{
	panic("system trap from user");
}

M pc/trap.c => pc/trap.c +80 -60
@@ 4,76 4,96 @@
#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 */
};
#include	"ureg.h"

/*
 *  trap/interrupt gates
 */
Segdesc ilt[256] =
Segdesc ilt[256];
void	(*ivec[256])(void*);

void
sethvec(int v, void (*r)(void), int type)
{
	ilt[v].d0 = ((ulong)r)&0xFFFF|(KESEL<<16);
	ilt[v].d1 = ((ulong)r)&0xFFFF0000|SEGP|SEGPL(3)|type;
}

void
setvec(int v, void (*r)(void*), int type)
{
[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),
};
	ilt[v].d1 &= ~SEGTYPE;
	ilt[v].d1 |= type;
	ivec[v] = r;
}

/*
 *  trap table
 *  set up the interrupt/trap gates
 */
uchar	traptab[4096];
void
trapinit(void)
{
	int i;

	/*
	 *  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));
}


/*
 *  j-random uncaught trap or interrupt
 *  All traps
 */
void
trap(void)
trap(Ureg *ur)
{
	panic("unknown trap");
	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);
}

M port/queue.c => port/queue.c +0 -1
@@ 4,7 4,6 @@
#include	"dat.h"
#include	"fns.h"
#include	"io.h"
#include	"errno.h"

void
initq(IOQ *q)