The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/icu.s

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  * 3. All advertising materials mentioning features or use of this software
   18  *    must display the following acknowledgement:
   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
   22  *    may be used to endorse or promote products derived from this software
   23  *    without specific prior written permission.
   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  *
   37  *      @(#)icu.s       7.2 (Berkeley) 5/21/91
   38  *
   39  * $FreeBSD: src/sys/i386/isa/icu.s,v 1.26.2.4 1999/09/05 08:12:40 peter Exp $
   40  */
   41 
   42 /*
   43  * AT/386
   44  * Vector interrupt control section
   45  */
   46 
   47 /*
   48  * XXX this file should be named ipl.s.  All spls are now soft and the
   49  * only thing related to the hardware icu is that the h/w interrupt
   50  * numbers are used without translation in the masks.
   51  */
   52 
   53         .data
   54         .globl  _cpl
   55 _cpl:   .long   HWI_MASK | SWI_MASK     /* current priority (all off) */
   56         .globl  _imen
   57 _imen:  .long   HWI_MASK        /* interrupt mask enable (all h/w off) */
   58         .globl  _tty_imask
   59 _tty_imask:     .long   0
   60         .globl  _bio_imask
   61 _bio_imask:     .long   SWI_CAMBIO_MASK
   62         .globl  _cam_imask
   63 _cam_imask:     .long   SWI_CAMBIO_MASK | SWI_CAMNET_MASK
   64         .globl  _net_imask
   65 _net_imask:     .long   SWI_CAMNET_MASK
   66         .globl  _ipending
   67 _ipending:      .long   0
   68         .globl  _netisr
   69 _netisr:        .long   0       /* set with bits for which queue to service */
   70         .globl _netisrs
   71 _netisrs:
   72         .long   dummynetisr, dummynetisr, dummynetisr, dummynetisr
   73         .long   dummynetisr, dummynetisr, dummynetisr, dummynetisr
   74         .long   dummynetisr, dummynetisr, dummynetisr, dummynetisr
   75         .long   dummynetisr, dummynetisr, dummynetisr, dummynetisr
   76         .long   dummynetisr, dummynetisr, dummynetisr, dummynetisr
   77         .long   dummynetisr, dummynetisr, dummynetisr, dummynetisr
   78         .long   dummynetisr, dummynetisr, dummynetisr, dummynetisr
   79         .long   dummynetisr, dummynetisr, dummynetisr, dummynetisr
   80 vec:
   81         .long   vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7
   82         .long   vec8, vec9, vec10, vec11, vec12, vec13, vec14, vec15
   83 
   84         .text
   85 
   86 /*
   87  * Handle return from interrupts, traps and syscalls.
   88  */
   89         SUPERALIGN_TEXT
   90 _doreti:
   91         FAKE_MCOUNT(_bintr)             /* init "from" _bintr -> _doreti */
   92         addl    $4,%esp                 /* discard unit number */
   93         popl    %eax                    /* cpl to restore */
   94 doreti_next:
   95         /*
   96          * Check for pending HWIs and SWIs atomically with restoring cpl
   97          * and exiting.  The check has to be atomic with exiting to stop
   98          * (ipending & ~cpl) changing from zero to nonzero while we're
   99          * looking at it (this wouldn't be fatal but it would increase
  100          * interrupt latency).  Restoring cpl has to be atomic with exiting
  101          * so that the stack cannot pile up (the nesting level of interrupt
  102          * handlers is limited by the number of bits in cpl).
  103          */
  104         movl    %eax,%ecx
  105         notl    %ecx
  106         cli
  107         andl    _ipending,%ecx
  108         jne     doreti_unpend
  109 doreti_exit:
  110         movl    %eax,_cpl
  111         decb    _intr_nesting_level
  112         MEXITCOUNT
  113         .globl  doreti_popl_es
  114 doreti_popl_es:
  115         popl    %es
  116         .globl  doreti_popl_ds
  117 doreti_popl_ds:
  118         popl    %ds
  119         popal
  120         addl    $8,%esp
  121         .globl  doreti_iret
  122 doreti_iret:
  123         iret
  124 
  125         ALIGN_TEXT
  126         .globl  doreti_iret_fault
  127 doreti_iret_fault:
  128         subl    $8,%esp
  129         pushal
  130         pushl   %ds
  131         .globl  doreti_popl_ds_fault
  132 doreti_popl_ds_fault:
  133         pushl   %es
  134         .globl  doreti_popl_es_fault
  135 doreti_popl_es_fault:
  136         movl    $0,4+4+32+4(%esp)       /* XXX should be the error code */
  137         movl    $T_PROTFLT,4+4+32+0(%esp)
  138         jmp     alltraps_with_regs_pushed
  139 
  140         ALIGN_TEXT
  141 doreti_unpend:
  142         /*
  143          * Enabling interrupts is safe because we haven't restored cpl yet.
  144          * The locking from the "btrl" test is probably no longer necessary.
  145          * We won't miss any new pending interrupts because we will check
  146          * for them again.
  147          */
  148         sti
  149         bsfl    %ecx,%ecx               /* slow, but not worth optimizing */
  150         btrl    %ecx,_ipending
  151         jnc     doreti_next             /* some intr cleared memory copy */
  152         movl    ihandlers(,%ecx,4),%edx
  153         testl   %edx,%edx
  154         je      doreti_next             /* "can't happen" */
  155         cmpl    $NHWI,%ecx
  156         jae     doreti_swi
  157         cli
  158         movl    %eax,_cpl
  159         MEXITCOUNT
  160         jmp     %edx
  161 
  162         ALIGN_TEXT
  163 doreti_swi:
  164         pushl   %eax
  165         /*
  166          * The SWI_AST handler has to run at cpl = SWI_AST_MASK and the
  167          * SWI_CLOCK handler at cpl = SWI_CLOCK_MASK, so we have to restore
  168          * all the h/w bits in cpl now and have to worry about stack growth.
  169          * The worst case is currently (30 Jan 1994) 2 SWI handlers nested
  170          * in dying interrupt frames and about 12 HWIs nested in active
  171          * interrupt frames.  There are only 4 different SWIs and the HWI
  172          * and SWI masks limit the nesting further.
  173          */
  174         orl     imasks(,%ecx,4),%eax
  175         movl    %eax,_cpl
  176         call    %edx
  177         popl    %eax
  178         jmp     doreti_next
  179 
  180         ALIGN_TEXT
  181 swi_ast:
  182         addl    $8,%esp                 /* discard raddr & cpl to get trap frame */
  183         testb   $SEL_RPL_MASK,TRAPF_CS_OFF(%esp)
  184         je      swi_ast_phantom
  185         movl    $T_ASTFLT,(2+8+0)*4(%esp)
  186         movb    $0,_intr_nesting_level  /* finish becoming a trap handler */
  187         call    _trap
  188         subl    %eax,%eax               /* recover cpl */
  189         movb    $1,_intr_nesting_level  /* for doreti_next to decrement */
  190         jmp     doreti_next
  191 
  192         ALIGN_TEXT
  193 swi_ast_phantom:
  194         /*
  195          * These happen when there is an interrupt in a trap handler before
  196          * ASTs can be masked or in an lcall handler before they can be
  197          * masked or after they are unmasked.  They could be avoided for
  198          * trap entries by using interrupt gates, and for lcall exits by
  199          * using by using cli, but they are unavoidable for lcall entries.
  200          */
  201         cli
  202         orl     $SWI_AST_PENDING,_ipending
  203         subl    %eax,%eax
  204         jmp     doreti_exit     /* SWI_AST is highest so we must be done */
  205 
  206 /*
  207  * Interrupt priority mechanism
  208  *      -- soft splXX masks with group mechanism (cpl)
  209  *      -- h/w masks for currently active or unused interrupts (imen)
  210  *      -- ipending = active interrupts currently masked by cpl
  211  */
  212 
  213 ENTRY(splz)
  214         /*
  215          * The caller has restored cpl and checked that (ipending & ~cpl)
  216          * is nonzero.  We have to repeat the check since if there is an
  217          * interrupt while we're looking, _doreti processing for the
  218          * interrupt will handle all the unmasked pending interrupts
  219          * because we restored early.  We're repeating the calculation
  220          * of (ipending & ~cpl) anyway so that the caller doesn't have
  221          * to pass it, so this only costs one "jne".  "bsfl %ecx,%ecx"
  222          * is undefined when %ecx is 0 so we can't rely on the secondary
  223          * btrl tests.
  224          */
  225         movl    _cpl,%eax
  226 splz_next:
  227         /*
  228          * We don't need any locking here.  (ipending & ~cpl) cannot grow 
  229          * while we're looking at it - any interrupt will shrink it to 0.
  230          */
  231         movl    %eax,%ecx
  232         notl    %ecx
  233         andl    _ipending,%ecx
  234         jne     splz_unpend
  235         ret
  236 
  237         ALIGN_TEXT
  238 splz_unpend:
  239         bsfl    %ecx,%ecx
  240         btrl    %ecx,_ipending
  241         jnc     splz_next
  242         movl    ihandlers(,%ecx,4),%edx
  243         testl   %edx,%edx
  244         je      splz_next               /* "can't happen" */
  245         cmpl    $NHWI,%ecx
  246         jae     splz_swi
  247         /*
  248          * We would prefer to call the intr handler directly here but that
  249          * doesn't work for badly behaved handlers that want the interrupt
  250          * frame.  Also, there's a problem determining the unit number.
  251          * We should change the interface so that the unit number is not
  252          * determined at config time.
  253          */
  254         jmp     *vec(,%ecx,4)
  255 
  256         ALIGN_TEXT
  257 splz_swi:
  258         cmpl    $SWI_AST,%ecx
  259         je      splz_next               /* "can't happen" */
  260         pushl   %eax
  261         orl     imasks(,%ecx,4),%eax
  262         movl    %eax,_cpl
  263         call    %edx
  264         popl    %eax
  265         movl    %eax,_cpl
  266         jmp     splz_next
  267 
  268 /*
  269  * Fake clock interrupt(s) so that they appear to come from our caller instead
  270  * of from here, so that system profiling works.
  271  * XXX do this more generally (for all vectors; look up the C entry point).
  272  * XXX frame bogusness stops us from just jumping to the C entry point.
  273  */
  274         ALIGN_TEXT
  275 vec0:
  276         popl    %eax                    /* return address */
  277         pushfl
  278 #define KCSEL   8
  279         pushl   $KCSEL
  280         pushl   %eax
  281         cli
  282         MEXITCOUNT
  283         jmp     _Xintr0                 /* XXX might need _Xfastintr0 */
  284 
  285 #ifndef PC98
  286         ALIGN_TEXT
  287 vec8:
  288         popl    %eax    
  289         pushfl
  290         pushl   $KCSEL
  291         pushl   %eax
  292         cli
  293         MEXITCOUNT
  294         jmp     _Xintr8                 /* XXX might need _Xfastintr8 */
  295 #endif
  296 
  297 #define BUILD_VEC(irq_num) \
  298         ALIGN_TEXT ; \
  299 __CONCAT(vec,irq_num): ; \
  300         int     $ICU_OFFSET + (irq_num) ; \
  301         ret
  302 
  303         BUILD_VEC(1)
  304         BUILD_VEC(2)
  305         BUILD_VEC(3)
  306         BUILD_VEC(4)
  307         BUILD_VEC(5)
  308         BUILD_VEC(6)
  309         BUILD_VEC(7)
  310 #ifdef PC98
  311         BUILD_VEC(8)
  312 #endif
  313         BUILD_VEC(9)
  314         BUILD_VEC(10)
  315         BUILD_VEC(11)
  316         BUILD_VEC(12)
  317         BUILD_VEC(13)
  318         BUILD_VEC(14)
  319         BUILD_VEC(15)
  320 
  321         ALIGN_TEXT
  322 swi_net:
  323         MCOUNT
  324         bsfl    _netisr,%eax
  325         je      swi_net_done
  326 swi_net_more:
  327         btrl    %eax,_netisr
  328         jnc     swi_net_next
  329         call    *_netisrs(,%eax,4)
  330 swi_net_next:
  331         bsfl    _netisr,%eax
  332         jne     swi_net_more
  333 swi_net_done:
  334         ret
  335 
  336         ALIGN_TEXT
  337 dummynetisr:
  338         MCOUNT
  339         ret
  340 
  341         ALIGN_TEXT
  342 dummycamisr:
  343         MCOUNT  
  344         ret
  345 
  346 /*
  347  * XXX there should be a registration function to put the handler for the
  348  * attached driver directly in ihandlers.  Then this function will go away.
  349  */
  350         ALIGN_TEXT
  351 swi_tty:
  352         MCOUNT
  353 #include "cy.h"
  354 #if NCY > 0
  355         call    _cypoll
  356 #endif
  357 #include "rc.h"
  358 #if NRC > 0
  359         call    _rcpoll
  360 #endif
  361 #include "sio.h"
  362 #if NSIO > 0
  363         jmp     _siopoll
  364 #else
  365         ret
  366 #endif

Cache object: 5d9dd0a2ff5861053a8ea4ab0f49c616


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.