[BACK]Return to vector.s CVS log [TXT][DIR] Up to [local] / sys / arch / i386 / i386

Annotation of sys/arch/i386/i386/vector.s, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: vector.s,v 1.10 2007/04/12 20:22:58 art Exp $ */
        !             2: /*     $NetBSD: vector.s,v 1.32 1996/01/07 21:29:47 mycroft Exp $      */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1993, 1994, 1995 Charles M. Hannum.  All rights reserved.
        !             6:  *
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *     notice, this list of conditions and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *     notice, this list of conditions and the following disclaimer in the
        !            14:  *     documentation and/or other materials provided with the distribution.
        !            15:  * 3. All advertising materials mentioning features or use of this software
        !            16:  *     must display the following acknowledgement:
        !            17:  *     This product includes software developed by Charles M. Hannum.
        !            18:  * 4. The name of the author may not be used to endorse or promote products
        !            19:  *     derived from this software without specific prior written permission.
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            22:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            23:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            24:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            25:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            26:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            27:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            28:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            29:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            30:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            31:  */
        !            32:
        !            33: #include <machine/i8259.h>
        !            34: #include <dev/isa/isareg.h>
        !            35:
        !            36: #define MY_COUNT _C_LABEL(uvmexp)
        !            37:
        !            38: /*
        !            39:  * Macros for interrupt entry, call to handler, and exit.
        !            40:  *
        !            41:  * XXX
        !            42:  * The interrupt frame is set up to look like a trap frame.  This may be a
        !            43:  * waste.  The only handler which needs a frame is the clock handler, and it
        !            44:  * only needs a few bits.  Xdoreti() needs a trap frame for handling ASTs, but
        !            45:  * it could easily convert the frame on demand.
        !            46:  *
        !            47:  * The direct costs of setting up a trap frame are two pushl's (error code and
        !            48:  * trap number), an addl to get rid of these, and pushing and popping the
        !            49:  * callee-saved registers %esi, %edi, %ebx, and %ebp twice.
        !            50:  *
        !            51:  * If the interrupt frame is made more flexible,  INTR can push %eax first and
        !            52:  * decide the ipending case with less overhead, e.g., by avoiding loading the
        !            53:  * segment registers.
        !            54:  *
        !            55:  * XXX
        !            56:  * Should we do a cld on every system entry to avoid the requirement for
        !            57:  * scattered cld's?
        !            58:  */
        !            59:
        !            60:        .globl  _C_LABEL(isa_strayintr)
        !            61:
        !            62: #ifdef MULTIPROCESSOR
        !            63: #define LOCK_KERNEL(ipl)       pushl ipl; call _C_LABEL(i386_intlock); addl $4,%esp
        !            64: #define UNLOCK_KERNEL(ipl)     pushl ipl; call _C_LABEL(i386_intunlock); addl $4,%esp
        !            65: #else
        !            66: #define LOCK_KERNEL(ipl)
        !            67: #define UNLOCK_KERNEL(ipl)
        !            68: #endif
        !            69:
        !            70: #define voidop(num)
        !            71:
        !            72: /*
        !            73:  * Normal vectors.
        !            74:  *
        !            75:  * We cdr down the intrhand chain, calling each handler with its appropriate
        !            76:  * argument (0 meaning a pointer to the frame, for clock interrupts).
        !            77:  *
        !            78:  * The handler returns one of three values:
        !            79:  *   0 - This interrupt wasn't for me.
        !            80:  *   1 - This interrupt was for me.
        !            81:  *  -1 - This interrupt might have been for me, but I don't know.
        !            82:  * If there are no handlers, or they all return 0, we flag it as a `stray'
        !            83:  * interrupt.  On a system with level-triggered interrupts, we could terminate
        !            84:  * immediately when one of them returns 1; but this is a PC.
        !            85:  *
        !            86:  * On exit, we jump to Xdoreti(), to process soft interrupts and ASTs.
        !            87:  */
        !            88: #define        INTRSTUB(name, num, early_ack, late_ack, mask, unmask, level_mask) \
        !            89: IDTVEC(resume_/**/name/**/num)                                         ;\
        !            90:        push    %ebx                                                    ;\
        !            91:        cli                                                             ;\
        !            92:        jmp     1f                                                      ;\
        !            93: IDTVEC(recurse_/**/name/**/num)                                                ;\
        !            94:        pushfl                                                          ;\
        !            95:        pushl   %cs                                                     ;\
        !            96:        pushl   %esi                                                    ;\
        !            97:        pushl   $0                      /* dummy error code */          ;\
        !            98:        pushl   $T_ASTFLT               /* trap # for doing ASTs */     ;\
        !            99:        movl    %ebx,%esi                                               ;\
        !           100:        INTRENTRY                                                       ;\
        !           101:        MAKE_FRAME                                                      ;\
        !           102:        push    %esi                                                    ;\
        !           103:        cli                                                             ;\
        !           104:        jmp     1f                                                      ;\
        !           105: _C_LABEL(Xintr_/**/name/**/num):                                       ;\
        !           106:        pushl   $0                      /* dummy error code */          ;\
        !           107:        pushl   $T_ASTFLT               /* trap # for doing ASTs */     ;\
        !           108:        INTRENTRY                                                       ;\
        !           109:        MAKE_FRAME                                                      ;\
        !           110:        mask(num)                       /* mask it in hardware */       ;\
        !           111:        early_ack(num)                  /* and allow other intrs */     ;\
        !           112:        incl    MY_COUNT+V_INTR         /* statistical info */          ;\
        !           113:        movl    _C_LABEL(iminlevel) + (num) * 4, %eax                   ;\
        !           114:        movl    CPL,%ebx                                                ;\
        !           115:        cmpl    %eax,%ebx                                               ;\
        !           116:        jae     _C_LABEL(Xhold_/**/name/**/num)/* currently masked; hold it */;\
        !           117:        pushl   %ebx                    /* cpl to restore on exit */    ;\
        !           118: 1:                                                                     ;\
        !           119:        movl    _C_LABEL(imaxlevel) + (num) * 4,%eax                    ;\
        !           120:        movl    %eax,CPL                /* block enough for this irq */ ;\
        !           121:        sti                             /* safe to take intrs now */    ;\
        !           122:        movl    _C_LABEL(intrhand) + (num) * 4,%ebx     /* head of chain */ ;\
        !           123:        testl   %ebx,%ebx                                               ;\
        !           124:        jz      _C_LABEL(Xstray_/**/name/**/num)        /* no handlers; we're stray */  ;\
        !           125:        STRAY_INITIALIZE                /* nobody claimed it yet */     ;\
        !           126:        LOCK_KERNEL(IF_PPL(%esp))                                       ;\
        !           127: 7:     movl    IH_ARG(%ebx),%eax       /* get handler arg */           ;\
        !           128:        testl   %eax,%eax                                               ;\
        !           129:        jnz     4f                                                      ;\
        !           130:        movl    %esp,%eax               /* 0 means frame pointer */     ;\
        !           131: 4:     pushl   %eax                                                    ;\
        !           132:        call    *IH_FUN(%ebx)           /* call it */                   ;\
        !           133:        addl    $4,%esp                 /* toss the arg */              ;\
        !           134:        STRAY_INTEGRATE                 /* maybe he claimed it */       ;\
        !           135:        orl     %eax,%eax               /* should it be counted? */     ;\
        !           136:        jz      5f                      /* no, skip it */               ;\
        !           137:        addl    $1,IH_COUNT(%ebx)       /* count the intrs */           ;\
        !           138:        adcl    $0,IH_COUNT+4(%ebx)                                     ;\
        !           139: 5:     movl    IH_NEXT(%ebx),%ebx      /* next handler in chain */     ;\
        !           140:        testl   %ebx,%ebx                                               ;\
        !           141:        jnz     7b                                                      ;\
        !           142:        UNLOCK_KERNEL(IF_PPL(%esp))                                     ;\
        !           143:        STRAY_TEST(name,num)            /* see if it's a stray */       ;\
        !           144: 6:     unmask(num)                     /* unmask it in hardware */     ;\
        !           145:        late_ack(num)                                                   ;\
        !           146:        jmp     _C_LABEL(Xdoreti)       /* lower spl and do ASTs */     ;\
        !           147: IDTVEC(stray_/**/name/**/num)                                          ;\
        !           148:        pushl   $num                                                    ;\
        !           149:        call    _C_LABEL(isa_strayintr)                                 ;\
        !           150:        addl    $4,%esp                                                 ;\
        !           151:        jmp     6b                                                      ;\
        !           152: IDTVEC(hold_/**/name/**/num)                                           ;\
        !           153:        orb     $IRQ_BIT(num),_C_LABEL(ipending) + IRQ_BYTE(num)        ;\
        !           154:        INTRFASTEXIT
        !           155:
        !           156: #if defined(DEBUG)
        !           157: #define        STRAY_INITIALIZE \
        !           158:        xorl    %esi,%esi
        !           159: #define        STRAY_INTEGRATE \
        !           160:        orl     %eax,%esi
        !           161: #define        STRAY_TEST(name,num) \
        !           162:        testl   %esi,%esi                                               ;\
        !           163:        jz      _C_LABEL(Xstray_/**/name/**/num)
        !           164: #else /* !DEBUG */
        !           165: #define        STRAY_INITIALIZE
        !           166: #define        STRAY_INTEGRATE
        !           167: #define        STRAY_TEST(name,num)
        !           168: #endif /* DEBUG */
        !           169:
        !           170: #ifdef DDB
        !           171: #define        MAKE_FRAME \
        !           172:        leal    -8(%esp),%ebp
        !           173: #else /* !DDB */
        !           174: #define        MAKE_FRAME
        !           175: #endif /* DDB */
        !           176:
        !           177: #define ICUADDR IO_ICU1
        !           178:
        !           179: INTRSTUB(legacy,0, i8259_asm_ack1, voidop, i8259_asm_mask, i8259_asm_unmask,
        !           180:     voidop)
        !           181: INTRSTUB(legacy,1, i8259_asm_ack1, voidop, i8259_asm_mask, i8259_asm_unmask,
        !           182:     voidop)
        !           183: INTRSTUB(legacy,2, i8259_asm_ack1, voidop, i8259_asm_mask, i8259_asm_unmask,
        !           184:     voidop)
        !           185: INTRSTUB(legacy,3, i8259_asm_ack1, voidop, i8259_asm_mask, i8259_asm_unmask,
        !           186:     voidop)
        !           187: INTRSTUB(legacy,4, i8259_asm_ack1, voidop, i8259_asm_mask, i8259_asm_unmask,
        !           188:     voidop)
        !           189: INTRSTUB(legacy,5, i8259_asm_ack1, voidop, i8259_asm_mask, i8259_asm_unmask,
        !           190:     voidop)
        !           191: INTRSTUB(legacy,6, i8259_asm_ack1, voidop, i8259_asm_mask, i8259_asm_unmask,
        !           192:     voidop)
        !           193: INTRSTUB(legacy,7, i8259_asm_ack1, voidop, i8259_asm_mask, i8259_asm_unmask,
        !           194:     voidop)
        !           195:
        !           196: #undef ICUADDR
        !           197: #define ICUADDR IO_ICU2
        !           198:
        !           199: INTRSTUB(legacy,8, i8259_asm_ack2, voidop, i8259_asm_mask, i8259_asm_unmask,
        !           200:     voidop)
        !           201: INTRSTUB(legacy,9, i8259_asm_ack2, voidop, i8259_asm_mask, i8259_asm_unmask,
        !           202:     voidop)
        !           203: INTRSTUB(legacy,10, i8259_asm_ack2, voidop, i8259_asm_mask, i8259_asm_unmask,
        !           204:     voidop)
        !           205: INTRSTUB(legacy,11, i8259_asm_ack2, voidop, i8259_asm_mask, i8259_asm_unmask,
        !           206:     voidop)
        !           207: INTRSTUB(legacy,12, i8259_asm_ack2, voidop, i8259_asm_mask, i8259_asm_unmask,
        !           208:     voidop)
        !           209: INTRSTUB(legacy,13, i8259_asm_ack2, voidop, i8259_asm_mask, i8259_asm_unmask,
        !           210:     voidop)
        !           211: INTRSTUB(legacy,14, i8259_asm_ack2, voidop, i8259_asm_mask, i8259_asm_unmask,
        !           212:     voidop)
        !           213: INTRSTUB(legacy,15, i8259_asm_ack2, voidop, i8259_asm_mask, i8259_asm_unmask,
        !           214:     voidop)
        !           215:
        !           216: /*
        !           217:  * These tables are used by the ISA configuration code.
        !           218:  */
        !           219: /* interrupt service routine entry points */
        !           220: IDTVEC(intr)
        !           221:        .long   _C_LABEL(Xintr_legacy0), _C_LABEL(Xintr_legacy1)
        !           222:        .long   _C_LABEL(Xintr_legacy2), _C_LABEL(Xintr_legacy3)
        !           223:        .long   _C_LABEL(Xintr_legacy4), _C_LABEL(Xintr_legacy5)
        !           224:        .long   _C_LABEL(Xintr_legacy6), _C_LABEL(Xintr_legacy7)
        !           225:        .long   _C_LABEL(Xintr_legacy8), _C_LABEL(Xintr_legacy9)
        !           226:        .long   _C_LABEL(Xintr_legacy10), _C_LABEL(Xintr_legacy11)
        !           227:        .long   _C_LABEL(Xintr_legacy12), _C_LABEL(Xintr_legacy13)
        !           228:        .long   _C_LABEL(Xintr_legacy14), _C_LABEL(Xintr_legacy15)
        !           229:
        !           230: /*
        !           231:  * These tables are used by Xdoreti() and Xspllower().
        !           232:  */
        !           233: /* resume points for suspended interrupts */
        !           234: IDTVEC(resume)
        !           235:        .long   _C_LABEL(Xresume_legacy0), _C_LABEL(Xresume_legacy1)
        !           236:        .long   _C_LABEL(Xresume_legacy2), _C_LABEL(Xresume_legacy3)
        !           237:        .long   _C_LABEL(Xresume_legacy4), _C_LABEL(Xresume_legacy5)
        !           238:        .long   _C_LABEL(Xresume_legacy6), _C_LABEL(Xresume_legacy7)
        !           239:        .long   _C_LABEL(Xresume_legacy8), _C_LABEL(Xresume_legacy9)
        !           240:        .long   _C_LABEL(Xresume_legacy10), _C_LABEL(Xresume_legacy11)
        !           241:        .long   _C_LABEL(Xresume_legacy12), _C_LABEL(Xresume_legacy13)
        !           242:        .long   _C_LABEL(Xresume_legacy14), _C_LABEL(Xresume_legacy15)
        !           243:        /* for soft interrupts */
        !           244:        .long   0, 0, 0, 0, 0, 0, 0, 0, 0, 0
        !           245:        .long   _C_LABEL(Xsoftast), _C_LABEL(Xsofttty)
        !           246:        .long   _C_LABEL(Xsoftnet), _C_LABEL(Xsoftclock)
        !           247:        .long   0, 0
        !           248: /* fake interrupts to resume from splx() */
        !           249: IDTVEC(recurse)
        !           250:        .long   _C_LABEL(Xrecurse_legacy0), _C_LABEL(Xrecurse_legacy1)
        !           251:        .long   _C_LABEL(Xrecurse_legacy2), _C_LABEL(Xrecurse_legacy3)
        !           252:        .long   _C_LABEL(Xrecurse_legacy4), _C_LABEL(Xrecurse_legacy5)
        !           253:        .long   _C_LABEL(Xrecurse_legacy6), _C_LABEL(Xrecurse_legacy7)
        !           254:        .long   _C_LABEL(Xrecurse_legacy8), _C_LABEL(Xrecurse_legacy9)
        !           255:        .long   _C_LABEL(Xrecurse_legacy10), _C_LABEL(Xrecurse_legacy11)
        !           256:        .long   _C_LABEL(Xrecurse_legacy12), _C_LABEL(Xrecurse_legacy13)
        !           257:        .long   _C_LABEL(Xrecurse_legacy14), _C_LABEL(Xrecurse_legacy15)
        !           258:        /* for soft interrupts */
        !           259:        .long   0, 0, 0, 0, 0, 0, 0, 0, 0, 0
        !           260:        .long   _C_LABEL(Xsoftast), _C_LABEL(Xsofttty)
        !           261:        .long   _C_LABEL(Xsoftnet), _C_LABEL(Xsoftclock)
        !           262:        .long   0, 0

CVSweb