Annotation of lucent/sys/src/boot/pc/trap.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.