|
|
1.1 ! root 1: #include "u.h" ! 2: #include "lib.h" ! 3: #include "mem.h" ! 4: #include "dat.h" ! 5: #include "fns.h" ! 6: #include "io.h" ! 7: #include "ureg.h" ! 8: ! 9: void intr0(void), intr1(void), intr2(void), intr3(void); ! 10: void intr4(void), intr5(void), intr6(void), intr7(void); ! 11: void intr8(void), intr9(void), intr10(void), intr11(void); ! 12: void intr12(void), intr13(void), intr14(void), intr15(void); ! 13: void intr16(void); ! 14: void intr24(void), intr25(void), intr26(void), intr27(void); ! 15: void intr28(void), intr29(void), intr30(void), intr31(void); ! 16: void intr32(void), intr33(void), intr34(void), intr35(void); ! 17: void intr36(void), intr37(void), intr38(void), intr39(void); ! 18: void intr64(void); ! 19: void intrbad(void); ! 20: ! 21: /* ! 22: * 8259 interrupt controllers ! 23: */ ! 24: enum ! 25: { ! 26: Int0ctl= 0x20, /* control port (ICW1, OCW2, OCW3) */ ! 27: Int0aux= 0x21, /* everything else (ICW2, ICW3, ICW4, OCW1) */ ! 28: Int1ctl= 0xA0, /* control port */ ! 29: Int1aux= 0xA1, /* everything else (ICW2, ICW3, ICW4, OCW1) */ ! 30: ! 31: Icw1= 0x10, /* select bit in ctl register */ ! 32: Ocw2= 0x00, ! 33: Ocw3= 0x08, ! 34: ! 35: EOI= 0x20, /* non-specific end of interrupt */ ! 36: }; ! 37: ! 38: int int0mask = 0xff; /* interrupts enabled for first 8259 */ ! 39: int int1mask = 0xff; /* interrupts enabled for second 8259 */ ! 40: ! 41: /* ! 42: * trap/interrupt gates ! 43: */ ! 44: Segdesc ilt[256]; ! 45: ! 46: enum ! 47: { ! 48: Maxhandler= 32, /* max number of interrupt handlers */ ! 49: }; ! 50: ! 51: typedef struct Handler Handler; ! 52: struct Handler ! 53: { ! 54: void (*r)(Ureg*, void*); ! 55: void *arg; ! 56: Handler *next; ! 57: }; ! 58: ! 59: struct ! 60: { ! 61: Handler *ivec[256]; ! 62: Handler h[Maxhandler]; ! 63: int free; ! 64: } halloc; ! 65: ! 66: void ! 67: sethvec(int v, void (*r)(void), int type, int pri) ! 68: { ! 69: ilt[v].d0 = ((ulong)r)&0xFFFF|(KESEL<<16); ! 70: ilt[v].d1 = ((ulong)r)&0xFFFF0000|SEGP|SEGPL(pri)|type; ! 71: } ! 72: ! 73: void ! 74: setvec(int v, void (*r)(Ureg*, void*), void *arg) ! 75: { ! 76: Handler *h; ! 77: ! 78: if(halloc.free >= Maxhandler) ! 79: panic("out of interrupt handlers"); ! 80: h = &halloc.h[halloc.free++]; ! 81: h->next = halloc.ivec[v]; ! 82: h->r = r; ! 83: h->arg = arg; ! 84: halloc.ivec[v] = h; ! 85: ! 86: /* ! 87: * enable corresponding interrupt in 8259 ! 88: */ ! 89: if((v&~0x7) == Int0vec){ ! 90: int0mask &= ~(1<<(v&7)); ! 91: outb(Int0aux, int0mask); ! 92: } else if((v&~0x7) == Int1vec){ ! 93: int1mask &= ~(1<<(v&7)); ! 94: outb(Int1aux, int1mask); ! 95: } ! 96: } ! 97: ! 98: /* ! 99: * set up the interrupt/trap gates ! 100: */ ! 101: void ! 102: trapinit(void) ! 103: { ! 104: int i; ! 105: ! 106: /* ! 107: * set all interrupts to panics ! 108: */ ! 109: for(i = 0; i < 256; i++) ! 110: sethvec(i, intrbad, SEGTG, 0); ! 111: ! 112: /* ! 113: * 80386 processor (and coprocessor) traps ! 114: */ ! 115: sethvec(0, intr0, SEGTG, 0); ! 116: sethvec(1, intr1, SEGTG, 0); ! 117: sethvec(2, intr2, SEGTG, 0); ! 118: sethvec(3, intr3, SEGTG, 0); ! 119: sethvec(4, intr4, SEGTG, 0); ! 120: sethvec(5, intr5, SEGTG, 0); ! 121: sethvec(6, intr6, SEGTG, 0); ! 122: sethvec(7, intr7, SEGTG, 0); ! 123: sethvec(8, intr8, SEGTG, 0); ! 124: sethvec(9, intr9, SEGTG, 0); ! 125: sethvec(10, intr10, SEGTG, 0); ! 126: sethvec(11, intr11, SEGTG, 0); ! 127: sethvec(12, intr12, SEGTG, 0); ! 128: sethvec(13, intr13, SEGTG, 0); ! 129: sethvec(14, intr14, SEGTG, 0); ! 130: sethvec(15, intr15, SEGTG, 0); ! 131: sethvec(16, intr16, SEGTG, 0); ! 132: ! 133: /* ! 134: * device interrupts ! 135: */ ! 136: sethvec(24, intr24, SEGIG, 0); ! 137: sethvec(25, intr25, SEGIG, 0); ! 138: sethvec(26, intr26, SEGIG, 0); ! 139: sethvec(27, intr27, SEGIG, 0); ! 140: sethvec(28, intr28, SEGIG, 0); ! 141: sethvec(29, intr29, SEGIG, 0); ! 142: sethvec(30, intr30, SEGIG, 0); ! 143: sethvec(31, intr31, SEGIG, 0); ! 144: sethvec(32, intr32, SEGIG, 0); ! 145: sethvec(33, intr33, SEGIG, 0); ! 146: sethvec(34, intr34, SEGIG, 0); ! 147: sethvec(35, intr35, SEGIG, 0); ! 148: sethvec(36, intr36, SEGIG, 0); ! 149: sethvec(37, intr37, SEGIG, 0); ! 150: sethvec(38, intr38, SEGIG, 0); ! 151: sethvec(39, intr39, SEGIG, 0); ! 152: ! 153: /* ! 154: * tell the hardware where the table is (and how long) ! 155: */ ! 156: putidt(ilt, sizeof(ilt)); ! 157: ! 158: /* ! 159: * Set up the first 8259 interrupt processor. ! 160: * Make 8259 interrupts start at CPU vector Int0vec. ! 161: * Set the 8259 as master with edge triggered ! 162: * input with fully nested interrupts. ! 163: */ ! 164: outb(Int0ctl, Icw1|0x01); /* ICW1 - edge triggered, master, ! 165: ICW4 will be sent */ ! 166: outb(Int0aux, Int0vec); /* ICW2 - interrupt vector offset */ ! 167: outb(Int0aux, 0x04); /* ICW3 - have slave on level 2 */ ! 168: outb(Int0aux, 0x01); /* ICW4 - 8086 mode, not buffered */ ! 169: ! 170: /* ! 171: * Set up the second 8259 interrupt processor. ! 172: * Make 8259 interrupts start at CPU vector Int0vec. ! 173: * Set the 8259 as master with edge triggered ! 174: * input with fully nested interrupts. ! 175: */ ! 176: outb(Int1ctl, Icw1|0x01); /* ICW1 - edge triggered, master, ! 177: ICW4 will be sent */ ! 178: outb(Int1aux, Int1vec); /* ICW2 - interrupt vector offset */ ! 179: outb(Int1aux, 0x02); /* ICW3 - I am a slave on level 2 */ ! 180: outb(Int1aux, 0x01); /* ICW4 - 8086 mode, not buffered */ ! 181: ! 182: /* ! 183: * pass #2 8259 interrupts to #1 ! 184: */ ! 185: int0mask &= ~0x04; ! 186: outb(Int0aux, int0mask); ! 187: outb(Int1aux, int1mask); ! 188: ! 189: /* ! 190: * Set Ocw3 to return the ISR when ctl read. ! 191: */ ! 192: outb(Int0ctl, Ocw3|0x03); ! 193: outb(Int1ctl, Ocw3|0x03); ! 194: } ! 195: ! 196: /* ! 197: * dump registers ! 198: */ ! 199: static void ! 200: dumpregs(Ureg *ur) ! 201: { ! 202: print("FLAGS=%lux TRAP=%lux ECODE=%lux PC=%lux\n", ! 203: ur->flags, ur->trap, ur->ecode, ur->pc); ! 204: print(" AX %8.8lux BX %8.8lux CX %8.8lux DX %8.8lux\n", ! 205: ur->ax, ur->bx, ur->cx, ur->dx); ! 206: print(" SI %8.8lux DI %8.8lux BP %8.8lux\n", ! 207: ur->si, ur->di, ur->bp); ! 208: print(" CS %4.4ux DS %4.4ux ES %4.4ux FS %4.4ux GS %4.4ux\n", ! 209: ur->cs & 0xFF, ur->ds & 0xFFFF, ur->es & 0xFFFF, ur->fs & 0xFFFF, ur->gs & 0xFFFF); ! 210: print(" CR0 %8.8lux CR2 %8.8lux CR3 %8.8lux\n", ! 211: getcr0(), getcr2(), getcr3()); ! 212: } ! 213: ! 214: /* ! 215: * All traps ! 216: */ ! 217: void ! 218: trap(Ureg *ur) ! 219: { ! 220: int v; ! 221: int c; ! 222: Handler *h; ! 223: ushort isr; ! 224: ! 225: v = ur->trap; ! 226: /* ! 227: * tell the 8259 that we're done with the ! 228: * highest level interrupt (interrupts are still ! 229: * off at this point) ! 230: */ ! 231: c = v&~0x7; ! 232: isr = 0; ! 233: if(c==Int0vec || c==Int1vec){ ! 234: isr = inb(Int0ctl); ! 235: outb(Int0ctl, EOI); ! 236: if(c == Int1vec){ ! 237: isr |= inb(Int1ctl)<<8; ! 238: outb(Int1ctl, EOI); ! 239: } ! 240: } ! 241: ! 242: if(v>=256 || (h = halloc.ivec[v]) == 0){ ! 243: if(v >= Int0vec && v < Int0vec+16){ ! 244: v -= Int0vec; ! 245: /* ! 246: * Check for a default IRQ7. This can happen when ! 247: * the IRQ input goes away before the acknowledge. ! 248: * In this case, a 'default IRQ7' is generated, but ! 249: * the corresponding bit in the ISR isn't set. ! 250: * In fact, just ignore all such interrupts. ! 251: */ ! 252: if(isr & (1<<v)) ! 253: print("unknown interrupt %d pc=0x%lux\n", v, ur->pc); ! 254: return; ! 255: } ! 256: ! 257: switch(v){ ! 258: ! 259: case 0x02: /* NMI */ ! 260: print("NMI: nmisc=0x%2.2ux, nmiertc=0x%2.2ux, nmiesc=0x%2.2ux\n", ! 261: inb(0x61), inb(0x70), inb(0x461)); ! 262: return; ! 263: ! 264: default: ! 265: print("exception/interrupt %d\n", v); ! 266: dumpregs(ur); ! 267: spllo(); ! 268: print("^P to reset\n"); ! 269: for(;;); ! 270: } ! 271: } ! 272: ! 273: /* ! 274: * call the trap routines ! 275: */ ! 276: do { ! 277: (*h->r)(ur, h->arg); ! 278: h = h->next; ! 279: } while(h); ! 280: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.