Annotation of Net2/arch/i386/isa/icu.s, revision 1.1.1.4

1.1       root        1: /*-
                      2:  * Copyright (c) 1989, 1990 William F. Jolitz.
                      3:  * Copyright (c) 1990 The Regents of the University of California.
                      4:  * All rights reserved.
                      5:  *
                      6:  * This code is derived from software contributed to Berkeley by
                      7:  * William Jolitz.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
1.1.1.4 ! root       13:  *     notice, this list of conditions and the following disclaimer.
1.1       root       14:  * 2. Redistributions in binary form must reproduce the above copyright
1.1.1.4 ! root       15:  *     notice, this list of conditions and the following disclaimer in the
        !            16:  *     documentation and/or other materials provided with the distribution.
1.1       root       17:  * 3. All advertising materials mentioning features or use of this software
1.1.1.4 ! root       18:  *     must display the following acknowledgement:
1.1       root       19:  *     This product includes software developed by the University of
                     20:  *     California, Berkeley and its contributors.
                     21:  * 4. Neither the name of the University nor the names of its contributors
1.1.1.4 ! root       22:  *     may be used to endorse or promote products derived from this software
        !            23:  *     without specific prior written permission.
1.1       root       24:  *
                     25:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     26:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     27:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     28:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     29:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     30:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     31:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     32:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     33:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     34:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     35:  * SUCH DAMAGE.
                     36:  *
1.1.1.4 ! root       37:  *     from: @(#)icu.s 7.2 (Berkeley) 5/21/91
        !            38:  *     icu.s,v 1.19 1993/07/11 14:12:40 mycroft Exp
1.1       root       39:  */
                     40: 
                     41: /*
                     42:  * AT/386
                     43:  * Vector interrupt control section
                     44:  */
                     45: 
1.1.1.4 ! root       46: /*
        !            47:  * XXX - this file is now misnamed.  All spls are now soft and the only thing
        !            48:  * related to the hardware icu is that the bit numbering is the same in the
        !            49:  * soft priority masks as in the hard ones.
        !            50:  */
        !            51: 
        !            52: #ifdef notyet
        !            53: #include "sio.h"
        !            54: #else
        !            55: #define NSIO 0
        !            56: #endif
        !            57: 
        !            58: #define        HIGHMASK        0xffff
        !            59: #define        SOFTCLOCKMASK   0x8000
        !            60: 
1.1       root       61:        .data
                     62:        .globl  _cpl
1.1.1.4 ! root       63: _cpl:  .long   0xffff                  # current priority (all off)
        !            64:        .globl  _imen
1.1       root       65: _imen: .long   0xffff                  # interrupt mask enable (all off)
                     66:        .globl  _highmask
1.1.1.4 ! root       67: _highmask:     .long   HIGHMASK
1.1       root       68:        .globl  _ttymask
                     69: _ttymask:      .long   0
                     70:        .globl  _biomask
                     71: _biomask:      .long   0
                     72:        .globl  _netmask
                     73: _netmask:      .long   0
1.1.1.4 ! root       74:        .globl  _impmask
        !            75: _impmask:      .long   0
        !            76:        .globl  _ipending
        !            77: _ipending:     .long   0
        !            78: vec:
        !            79:        .long   INTRLOCAL(vec0), INTRLOCAL(vec1), INTRLOCAL(vec2)
        !            80:        .long   INTRLOCAL(vec3), INTRLOCAL(vec4), INTRLOCAL(vec5)
        !            81:        .long   INTRLOCAL(vec6), INTRLOCAL(vec7), INTRLOCAL(vec8)
        !            82:        .long   INTRLOCAL(vec9), INTRLOCAL(vec10), INTRLOCAL(vec11)
        !            83:        .long   INTRLOCAL(vec12), INTRLOCAL(vec13), INTRLOCAL(vec14)
        !            84:        .long   INTRLOCAL(vec15)
        !            85: 
        !            86: #define        GENSPL(name, mask, event) \
        !            87:        .globl  _spl/**/name ; \
        !            88:        ALIGN_TEXT ; \
        !            89: _spl/**/name: ; \
        !            90:        COUNT_EVENT(_intrcnt_spl, event) ; \
        !            91:        movl    _cpl,%eax ; \
        !            92:        movl    %eax,%edx ; \
        !            93:        orl     mask,%edx ; \
        !            94:        movl    %edx,_cpl ; \
        !            95:        SHOW_CPL ; \
        !            96:        ret
        !            97: 
        !            98: #define        FASTSPL(mask) \
        !            99:        movl    mask,_cpl ; \
        !           100:        SHOW_CPL
        !           101: 
        !           102: #define        FASTSPL_VARMASK(varmask) \
        !           103:        movl    varmask,%eax ; \
        !           104:        movl    %eax,_cpl ; \
        !           105:        SHOW_CPL
1.1       root      106: 
                    107:        .text
1.1.1.4 ! root      108: 
        !           109:        ALIGN_TEXT
        !           110: INTRLOCAL(unpend_v):
        !           111:        COUNT_EVENT(_intrcnt_spl, 0)
        !           112:        bsfl    %eax,%eax               # slow, but not worth optimizing
        !           113:        btrl    %eax,_ipending
        !           114:        jnc     INTRLOCAL(unpend_v_next) # some intr cleared the in-memory bit
        !           115:        SHOW_IPENDING
        !           116:        movl    Vresume(,%eax,4),%eax
        !           117:        testl   %eax,%eax
        !           118:        je      INTRLOCAL(noresume)
        !           119:        jmp     %eax
        !           120:   
        !           121:        ALIGN_TEXT
        !           122: /*
        !           123:  * XXX - must be some fastintr, need to register those too.
        !           124:  */
        !           125: INTRLOCAL(noresume):
        !           126: #if NSIO > 0
        !           127:        call    _softsio1
        !           128: #endif
        !           129: INTRLOCAL(unpend_v_next):
        !           130:        movl    _cpl,%eax
        !           131:        movl    %eax,%edx
        !           132:        notl    %eax
        !           133:        andl    _ipending,%eax
        !           134:        je      INTRLOCAL(none_to_unpend)
        !           135:        jmp     INTRLOCAL(unpend_v)
        !           136: 
1.1       root      137: /*
                    138:  * Handle return from interrupt after device handler finishes
                    139:  */
1.1.1.4 ! root      140:        ALIGN_TEXT
1.1       root      141: doreti:
1.1.1.4 ! root      142:        COUNT_EVENT(_intrcnt_spl, 1)
        !           143:        addl    $4,%esp # discard unit arg
        !           144:        popl    %eax    # get previous priority
        !           145: /*
        !           146:  * Now interrupt frame is a trap frame!
        !           147:  *
        !           148:  * XXX - setting up the interrupt frame to be almost a stack frame is mostly
        !           149:  * a waste of time.
        !           150:  */
        !           151:        movl    %eax,_cpl
        !           152:        SHOW_CPL
        !           153:        movl    %eax,%edx
        !           154:        notl    %eax
        !           155:        andl    _ipending,%eax
        !           156:        jne     INTRLOCAL(unpend_v)
        !           157: INTRLOCAL(none_to_unpend):
        !           158:        testl   %edx,%edx       # returning to zero priority?
        !           159:        jne     1f      # nope, going to non-zero priority
        !           160:        movl    _netisr,%eax
        !           161:        testl   %eax,%eax       # check for softint s/traps
        !           162:        jne     2f      # there are some
        !           163:        jmp     test_resched    # XXX - schedule jumps better
        !           164:        COUNT_EVENT(_intrcnt_spl, 2)    # XXX
        !           165: 
        !           166:        ALIGN_TEXT      # XXX
        !           167: 1:     # XXX
        !           168:        COUNT_EVENT(_intrcnt_spl, 3)
        !           169:        popl    %es
        !           170:        popl    %ds
        !           171:        popal
1.1       root      172:        addl    $8,%esp
                    173:        iret
                    174: 
                    175: #include "../net/netisr.h"
                    176: 
1.1.1.4 ! root      177: #define DONET(s, c, event) ; \
        !           178:        .globl  c ; \
        !           179:        btrl    $s,_netisr ; \
        !           180:        jnc     1f ; \
        !           181:        COUNT_EVENT(_intrcnt_spl, event) ; \
1.1       root      182:        call    c ; \
                    183: 1:
                    184: 
1.1.1.4 ! root      185:        ALIGN_TEXT
        !           186: 2:
        !           187:        COUNT_EVENT(_intrcnt_spl, 4)
        !           188: /*
        !           189:  * XXX - might need extra locking while testing reg copy of netisr, but
        !           190:  * interrupt routines setting it would not cause any new problems (since we
        !           191:  * don't loop, fresh bits will not be processed until the next doreti or spl0)
        !           192:  */
        !           193:        testl   $~((1 << NETISR_SCLK) | (1 << NETISR_AST)),%eax
        !           194:        je      test_ASTs       # no net stuff, just temporary AST's
        !           195:        FASTSPL_VARMASK(_netmask)
        !           196:        DONET(NETISR_RAW, _rawintr, 5)
1.1       root      197: #ifdef INET
1.1.1.4 ! root      198:        DONET(NETISR_IP, _ipintr, 6)
1.1       root      199: #endif
                    200: #ifdef IMP
1.1.1.4 ! root      201:        DONET(NETISR_IMP, _impintr, 7)
1.1       root      202: #endif
                    203: #ifdef NS
1.1.1.4 ! root      204:        DONET(NETISR_NS, _nsintr, 8)
1.1       root      205: #endif
1.1.1.4 ! root      206: #ifdef ISO
        !           207:        DONET(NETISR_ISO, _clnlintr, 25)
1.1.1.2   root      208: #endif
1.1.1.4 ! root      209:        FASTSPL($0)
        !           210: test_ASTs:
        !           211:        btrl    $NETISR_SCLK,_netisr
        !           212:        jnc     test_resched
        !           213:        COUNT_EVENT(_intrcnt_spl, 9)
        !           214:        FASTSPL($SOFTCLOCKMASK)
        !           215: /*
        !           216:  * Back to an interrupt frame for a moment.
        !           217:  */
        !           218:        pushl   $0      # previous cpl (probably not used)
        !           219:        pushl   $0x7f   # dummy unit number
1.1       root      220:        call    _softclock
1.1.1.4 ! root      221:        addl    $8,%esp # discard dummies
        !           222:        FASTSPL($0)
        !           223: test_resched:
        !           224: #ifdef notused1
        !           225:        btrl    $NETISR_AST,_netisr
        !           226:        jnc     2f
        !           227: #endif
        !           228: #ifdef notused2
1.1.1.2   root      229:        cmpl    $0,_want_resched
                    230:        je      2f
1.1.1.4 ! root      231: #endif
        !           232:        cmpl    $0,_astpending  # XXX - put it back in netisr to
        !           233:        je      2f      # reduce the number of tests
        !           234:        testb   $SEL_RPL_MASK,TRAPF_CS_OFF(%esp)
        !           235:                                        # to non-kernel (i.e., user)?
        !           236:        je      2f      # nope, leave
        !           237:        COUNT_EVENT(_intrcnt_spl, 10)
        !           238:        movl    $0,_astpending
1.1       root      239:        call    _trap
1.1.1.4 ! root      240: 2:
        !           241:        COUNT_EVENT(_intrcnt_spl, 11)
        !           242:        popl    %es
        !           243:        popl    %ds
1.1       root      244:        popal
                    245:        addl    $8,%esp
                    246:        iret
                    247: 
                    248: /*
                    249:  * Interrupt priority mechanism
1.1.1.4 ! root      250:  *     -- soft splXX masks with group mechanism (cpl)
        !           251:  *     -- h/w masks for currently active or unused interrupts (imen)
        !           252:  *     -- ipending = active interrupts currently masked by cpl
1.1       root      253:  */
                    254: 
1.1.1.4 ! root      255:        GENSPL(bio, _biomask, 12)
        !           256:        GENSPL(clock, $HIGHMASK, 13)    /* splclock == splhigh ex for count */
        !           257:        GENSPL(high, $HIGHMASK, 14)
        !           258:        GENSPL(imp, _impmask, 15)
        !           259:        GENSPL(net, _netmask, 16)
        !           260:        GENSPL(softclock, $SOFTCLOCKMASK, 17)
        !           261:        GENSPL(tty, _ttymask, 18)
1.1       root      262: 
                    263:        .globl _splnone
                    264:        .globl _spl0
1.1.1.4 ! root      265:        ALIGN_TEXT
1.1       root      266: _splnone:
                    267: _spl0:
1.1.1.4 ! root      268:        COUNT_EVENT(_intrcnt_spl, 19)
        !           269: in_spl0:
        !           270:        movl    _cpl,%eax
        !           271:        pushl   %eax    # save old priority
        !           272:        testl   $~((1 << NETISR_SCLK) | (1 << NETISR_AST)),_netisr
        !           273:        jz      INTRLOCAL(over_net_stuff_for_spl0)
        !           274:        movl    _netmask,%eax   # mask off those network devices
        !           275:        movl    %eax,_cpl       # set new priority
        !           276:        SHOW_CPL
        !           277:        DONET(NETISR_RAW, _rawintr, 20)
1.1       root      278: #ifdef INET
1.1.1.4 ! root      279:        DONET(NETISR_IP, _ipintr, 21)
        !           280: #endif
        !           281: #ifdef IMP
        !           282:        DONET(NETISR_IMP, _impintr, 26)
        !           283: #endif
        !           284: #ifdef NS
        !           285:        DONET(NETISR_NS, _nsintr, 27)
1.1       root      286: #endif
1.1.1.4 ! root      287: #ifdef ISO
        !           288:        DONET(NETISR_ISO, _clnlintr, 28)
        !           289: #endif
        !           290: INTRLOCAL(over_net_stuff_for_spl0):
        !           291:        movl    $0,_cpl # set new priority
        !           292:        SHOW_CPL
        !           293:        movl    _ipending,%eax
        !           294:        testl   %eax,%eax
        !           295:        jne     INTRLOCAL(unpend_V)
        !           296:        popl    %eax    # return old priority
1.1       root      297:        ret
1.1.1.4 ! root      298:        
1.1       root      299:        .globl _splx
1.1.1.4 ! root      300:        ALIGN_TEXT
1.1       root      301: _splx:
1.1.1.4 ! root      302:        COUNT_EVENT(_intrcnt_spl, 22)
        !           303:        movl    4(%esp),%eax    # new priority
        !           304:        testl   %eax,%eax
        !           305:        je      in_spl0 # going to "zero level" is special
        !           306:        COUNT_EVENT(_intrcnt_spl, 23)
        !           307:        movl    _cpl,%edx       # save old priority
        !           308:        movl    %eax,_cpl       # set new priority
        !           309:        SHOW_CPL
        !           310:        notl    %eax
        !           311:        andl    _ipending,%eax
        !           312:        jne     INTRLOCAL(unpend_V_result_edx)
        !           313:        movl    %edx,%eax       # return old priority
1.1       root      314:        ret
                    315: 
1.1.1.4 ! root      316:        ALIGN_TEXT
        !           317: INTRLOCAL(unpend_V_result_edx):
        !           318:        pushl   %edx
        !           319: INTRLOCAL(unpend_V):
        !           320:        COUNT_EVENT(_intrcnt_spl, 24)
        !           321:        bsfl    %eax,%eax
        !           322:        btrl    %eax,_ipending
        !           323:        jnc     INTRLOCAL(unpend_V_next)
        !           324:        SHOW_IPENDING
        !           325:        movl    Vresume(,%eax,4),%edx
        !           326:        testl   %edx,%edx
        !           327:        je      INTRLOCAL(noresumeV)
        !           328: /*
        !           329:  * We would prefer to call the intr handler directly here but that doesn't
        !           330:  * work for badly behaved handlers that want the interrupt frame.  Also,
        !           331:  * there's a problem determining the unit number.  We should change the
        !           332:  * interface so that the unit number is not determined at config time.
        !           333:  */
        !           334:        jmp     *vec(,%eax,4)
1.1       root      335: 
1.1.1.4 ! root      336:        ALIGN_TEXT
        !           337: /*
        !           338:  * XXX - must be some fastintr, need to register those too.
        !           339:  */
        !           340: INTRLOCAL(noresumeV):
        !           341: #if NSIO > 0
        !           342:        call    _softsio1
        !           343: #endif
        !           344: INTRLOCAL(unpend_V_next):
        !           345:        movl    _cpl,%eax
        !           346:        notl    %eax
        !           347:        andl    _ipending,%eax
        !           348:        jne     INTRLOCAL(unpend_V)
        !           349:        popl    %eax
        !           350:        ret
1.1       root      351: 
1.1.1.4 ! root      352: #define BUILD_VEC(irq_num) \
        !           353:        ALIGN_TEXT ; \
        !           354: INTRLOCAL(vec/**/irq_num): ; \
        !           355:        int     $ICU_OFFSET + (irq_num) ; \
        !           356:        popl    %eax ; \
        !           357:        ret
1.1       root      358: 
1.1.1.4 ! root      359:        BUILD_VEC(0)
        !           360:        BUILD_VEC(1)
        !           361:        BUILD_VEC(2)
        !           362:        BUILD_VEC(3)
        !           363:        BUILD_VEC(4)
        !           364:        BUILD_VEC(5)
        !           365:        BUILD_VEC(6)
        !           366:        BUILD_VEC(7)
        !           367:        BUILD_VEC(8)
        !           368:        BUILD_VEC(9)
        !           369:        BUILD_VEC(10)
        !           370:        BUILD_VEC(11)
        !           371:        BUILD_VEC(12)
        !           372:        BUILD_VEC(13)
        !           373:        BUILD_VEC(14)
        !           374:        BUILD_VEC(15)
1.1       root      375: 

unix.superglobalmegacorp.com

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