Annotation of lucent/sys/src/boot/pc/trap.c, revision 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.