From 13369d18518a14fb305bfd04834283001d5d0d06 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 3 Jul 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-07-03 --- pc/dat.h | 13 +- pc/fns.h | 30 ++++ pc/io.h | 20 +++ pc/kbd.c | 454 +++++++++++++++++++++++++++++++++++++++------------ pc/l.s | 136 +++++++++++++++ pc/main.c | 23 ++- pc/mem.h | 9 +- pc/mmu.c | 52 +++--- pc/trap.c | 140 +++++++++------- port/queue.c | 1 - 10 files changed, 679 insertions(+), 199 deletions(-) create mode 100644 pc/io.h diff --git a/pc/dat.h b/pc/dat.h index b5bbb2165003dbdc9d1f3733bf54dff56549210d..c133d25c5d929dcacfce05d0c81aca0a764145e1 100644 --- a/pc/dat.h +++ b/pc/dat.h @@ -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; diff --git a/pc/fns.h b/pc/fns.h index a13bfb1aa8d51159dbe1dbaa938175d2edf30050..0018860c70d5928dd13d11a55232242289e8dad2 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -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*); diff --git a/pc/io.h b/pc/io.h new file mode 100644 index 0000000000000000000000000000000000000000..5edb6dfdafba17ad10820c29a9f0496b6ac01880 --- /dev/null +++ b/pc/io.h @@ -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) diff --git a/pc/kbd.c b/pc/kbd.c index db500d81a001bf85e049fc47362b489a3a6337c3..716604b71626848644e719723e00d8e27b29ca9b 100644 --- a/pc/kbd.c +++ b/pc/kbd.c @@ -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; +} diff --git a/pc/l.s b/pc/l.s index 15e86e5bf6382c713a6eda35619f83ea8a4b428e..51dff8ec73b774c667e3883cff35ef4df627006e 100644 --- a/pc/l.s +++ b/pc/l.s @@ -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 diff --git a/pc/main.c b/pc/main.c index d5d62370740a7d116f1e4e8b1963deee6c4f9b23..0eafae752e0e2bc398d11e23686701b874c9cdf2 100644 --- a/pc/main.c +++ b/pc/main.c @@ -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(;;); +} diff --git a/pc/mem.h b/pc/mem.h index f66a8fb83cf74b889eaa2d07f114cd3868ba391d..dec719ac87d5307bdd3877a9fc78c65aeef47734 100644 --- a/pc/mem.h +++ b/pc/mem.h @@ -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 */ diff --git a/pc/mmu.c b/pc/mmu.c index 7f2fdcd12d078aa97e1ff9e278643255b1fe0f88..10c6898440d354860bc9706d656e12d883068fb7 100644 --- a/pc/mmu.c +++ b/pc/mmu.c @@ -5,29 +5,6 @@ #include "fns.h" #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, @@ -66,15 +43,36 @@ struct Tss ulong iomap; /* io map base */ }; +/* + * 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"); +} diff --git a/pc/trap.c b/pc/trap.c index 52f4f002c26693deb3228ab72a26c8ef112d70ae..2f2aea91e7b4042f12b25c40e87d570b3e2734ba 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -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); } diff --git a/port/queue.c b/port/queue.c index db545ac915c32d99d8cae668fbfc9e84aa13c005..d15e29ea5bd937e9514dc404ea9b180406fda362 100644 --- a/port/queue.c +++ b/port/queue.c @@ -4,7 +4,6 @@ #include "dat.h" #include "fns.h" #include "io.h" -#include "errno.h" void initq(IOQ *q)