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/interrupt.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  * Mach Operating System
    3  * Copyright (c) 1993,1992,1991,1990 Carnegie Mellon University
    4  * Copyright (c) 1991 IBM Corporation 
    5  * All Rights Reserved.
    6  * 
    7  * Permission to use, copy, modify and distribute this software and its
    8  * documentation is hereby granted, provided that both the copyright
    9  * notice and this permission notice appear in all copies of the
   10  * software, derivative works or modified versions, and any portions
   11  * thereof, and that both notices appear in supporting documentation,
   12  * and that the name IBM not be used in advertising or publicity 
   13  * pertaining to distribution of the software without specific, written
   14  * prior permission.
   15  * 
   16  * CARNEGIE MELLON AND IBM ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   17  * CONDITION.  CARNEGIE MELLON AND IBM DISCLAIM ANY LIABILITY OF ANY KIND FOR
   18  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   19  * 
   20  * Carnegie Mellon requests users of this software to return to
   21  * 
   22  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   23  *  School of Computer Science
   24  *  Carnegie Mellon University
   25  *  Pittsburgh PA 15213-3890
   26  * 
   27  * any improvements or extensions that they make and grant Carnegie Mellon
   28  * the rights to redistribute these changes.
   29  */
   30 
   31 
   32 /*
   33  * HISTORY
   34  * $Log:        interrupt.s,v $
   35  * Revision 2.17  93/11/17  16:36:09  dbg
   36  *      PIC addresses are constants (and known to be <= 0xff), so they
   37  *      can be used as immediate addresses in IN and OUT instructions.
   38  *      [93/10/29            dbg]
   39  * 
   40  *      The reason that the spurious interrupt check has never worked is
   41  *      that the non-specific EOI has already CLEARED the ISR bit that we
   42  *      are checking!
   43  *      [93/10/25            dbg]
   44  * 
   45  *      Changes from ralf@chpc.org: handle spuroius interrupts
   46  *      generated by Adaptec 174x.
   47  *      [93/10/20  13:03:31  af]
   48  * 
   49  * Revision 2.16  93/02/04  07:56:24  danner
   50  *      Convert asm comment "/" over to "/ *" "* /"
   51  *      [93/01/28            rvb]
   52  * 
   53  *      Integrate PS2 code from IBM.
   54  *      [93/01/18            prithvi]
   55  * 
   56  * Revision 2.15  92/04/06  01:15:53  rpd
   57  *      Converted from #-style to /-style comments, for ANSI preprocessors.
   58  *      [92/04/05            rpd]
   59  * 
   60  * Revision 2.14  91/10/07  17:24:48  af
   61  *      From mg32: testing for spurious interrupts is bogus.
   62  *      [91/09/23            rvb]
   63  * 
   64  * Revision 2.13  91/08/28  21:31:06  jsb
   65  *      Check for out-of-range interrupts.
   66  *      [91/08/20            dbg]
   67  * 
   68  * Revision 2.12  91/07/31  17:37:31  dbg
   69  *      Support separate interrupt stack.  Interrupt handler may now be
   70  *      called from different places.
   71  *      [91/07/30  16:52:19  dbg]
   72  * 
   73  * Revision 2.11  91/06/19  11:55:12  rvb
   74  *      cputypes.h->platforms.h
   75  *      [91/06/12  13:44:55  rvb]
   76  * 
   77  * Revision 2.10  91/05/14  16:09:08  mrt
   78  *      Correcting copyright
   79  * 
   80  * Revision 2.9  91/05/08  12:38:18  dbg
   81  *      Put parentheses around substituted immediate expressions, so
   82  *      that they will pass through the GNU preprocessor.
   83  * 
   84  *      Use platforms.h.  Call version of set_spl that leaves interrupts
   85  *      disabled (IF clear) until iret.
   86  *      [91/04/26  14:35:53  dbg]
   87  * 
   88  * Revision 2.8  91/02/05  17:12:22  mrt
   89  *      Changed to new Mach copyright
   90  *      [91/02/01  17:34:58  mrt]
   91  * 
   92  * Revision 2.7  91/01/08  17:32:06  rpd
   93  *      Need special interrupt_return
   94  *      [90/12/21  14:36:12  rvb]
   95  * 
   96  * Revision 2.6  90/12/20  16:35:58  jeffreyh
   97  *      Changes for __STDC__
   98  *      [90/12/07  15:43:38  jeffreyh]
   99  * 
  100  * Revision 2.5  90/12/04  14:46:08  jsb
  101  *      iPSC2 -> iPSC386.
  102  *      [90/12/04  11:16:47  jsb]
  103  * 
  104  * Revision 2.4  90/11/26  14:48:33  rvb
  105  *      Change Prime copyright as per Peter J. Weyman authorization.
  106  *      [90/11/19            rvb]
  107  * 
  108  * Revision 2.3  90/09/23  17:45:14  jsb
  109  *      Added support for iPSC2.
  110  *      [90/09/21  16:40:09  jsb]
  111  * 
  112  * Revision 2.2  90/05/03  15:27:54  dbg
  113  *      Stole from Prime.
  114  *      Pass new parameters to clock_interrupt (no longer called
  115  *      hardclock).  Set curr_ipl correctly around call to clock_interrupt.
  116  *      Moved softclock logic to splx.
  117  *      Added kdb_kintr to find registers for kdb.
  118  *      [90/02/14            dbg]
  119  * 
  120  */
  121 
  122 /*
  123 Copyright (c) 1988,1989 Prime Computer, Inc.  Natick, MA 01760
  124 All Rights Reserved.
  125 
  126 Permission to use, copy, modify, and distribute this
  127 software and its documentation for any purpose and
  128 without fee is hereby granted, provided that the above
  129 copyright notice appears in all copies and that both the
  130 copyright notice and this permission notice appear in
  131 supporting documentation, and that the name of Prime
  132 Computer, Inc. not be used in advertising or publicity
  133 pertaining to distribution of the software without
  134 specific, written prior permission.
  135 
  136 THIS SOFTWARE IS PROVIDED "AS IS", AND PRIME COMPUTER,
  137 INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  138 SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  139 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  IN
  140 NO EVENT SHALL PRIME COMPUTER, INC.  BE LIABLE FOR ANY
  141 SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
  142 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  143 PROFITS, WHETHER IN ACTION OF CONTRACT, NEGLIGENCE, OR
  144 OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION
  145 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  146 */
  147 
  148 #include <platforms.h>
  149 
  150 #include <i386/asm.h>
  151 #include <i386/ipl.h>
  152 #include <i386/pic.h>
  153 #include <assym.s>
  154 
  155 /*
  156  *      Called from locore.s.  The register save area is on top
  157  *      of the stack.  %eax contains the interrupt number.
  158  *      Only %ecx and %edx have been saved.
  159  */
  160 ENTRY(interrupt)
  161 
  162         movl    %eax,%ecx               /* stash interrupt vector number */
  163         subl    $0x40,%ecx              /* interrupt vectors we use */
  164                                         /* start at 0x40, not 0 */
  165         jl      int_range_err           /* and are between 0x40 */
  166         cmpl    $15,%ecx                /* and 0x4f */
  167         jg      int_range_err
  168 
  169 /*
  170  *      Check for spurious interrupt.  A level 7 (for master) or
  171  *      level 15 (slave) interrupt can occur if the INT line is
  172  *      dropped too soon.  We check for this by reading the
  173  *      Interrupt Service Register (BEFORE clearing it with EOI!!)
  174  *      and testing for bit 7.  If it is zero, the interrupt
  175  *      was spurious.
  176  */
  177 
  178         movw    $(MASTER_ICW), %dx      /* point to master PIC */
  179 
  180 #if     defined(AT386) || defined(PS2)
  181         cmpl    $2,%ecx                 /* IRQ 2 is the slave cascade */
  182         je      spurious_interrupt      /* interrupt - ignore it. */
  183 #endif
  184 
  185         cmpl    $7,%ecx                 /* master - level 7? */
  186         je      int_check
  187         cmpl    $15,%ecx                /* slave - level 15? */
  188         jne     int_ok
  189         addw    $(SIZE_PIC),%dx         /* if so, point to slave PIC */
  190 int_check:
  191         movw    $(OCW_TEMPLATE | READ_NEXT_RD | READ_IS_ONRD), %ax
  192         outb    %al,%dx                 /* ask to read ISR */
  193         jmp     0f                      /* delay XXX */
  194 0:
  195         inb     %dx,%al                 /* read ISR */
  196         testb   $0x80, %al              /* if ISR.7 is off, */
  197         jz      spurious_interrupt      /* this is a spurious interrupt */
  198 int_ok:
  199 
  200 #ifndef PS2
  201 /*
  202  *      Now we must acknowledge the interrupt and issue an EOI command to
  203  *      the pics.  We send a NON-SPECIFIC EOI, as we assume that the pic
  204  *      automatically interrupts us with only the highest priority interrupt.
  205  */
  206 
  207         movb    $(NON_SPEC_EOI),%al
  208         outb    %al,$(MASTER_ICW)       /* EOI for master */
  209         nop; nop;                       /* give the bus some breathing room */
  210         outb    %al,$(SLAVE_ICW)        /* EOI for slave */
  211 #endif  /* not PS2 */
  212 
  213 /*
  214  *      Now we must change the interrupt priority level, with interrupts
  215  *      turned off.  First we get the interrupt number and get
  216  *      the interrupt level associated with it, then we call set_spl().
  217  */
  218 
  219         movzbl  _intpri(%ecx),%eax      /* intpri[int#] */
  220         call    _set_spl                /* set SPL */
  221 
  222 /*
  223  *      Interrupts are now enabled.  Call the relevant interrupt
  224  *      handler as per the ivect[] array set up in pic_init.
  225  */
  226 
  227         pushl   %eax                    /*  2   save old IPL */
  228 #ifdef  PS2
  229         pushl   %ecx                    /*  2   save intr # */
  230 #endif
  231         pushl   _iunit(,%ecx,4)         /*  2   push unit# as int handler arg */
  232         call    *_ivect(,%ecx,4)        /*  4   *ivect[int#]() */
  233         addl    $4,%esp                 /* remove interrupt number from stack */
  234 #ifdef  PS2
  235         popl    %ecx                    /*  2   save intr # */
  236 #endif
  237         cli                             /*  3   disable interrupts */
  238 
  239 #ifdef  PS2
  240 /*
  241  *      Now we must acknowledge the interrupt and issue an EOI command to 
  242  *      the pics.  We send a SPECIFIC EOI.
  243  */
  244         mov     %ecx,%eax
  245         cmp     $7,%ecx
  246         jle     do_master
  247         andb    $7,%al
  248         orb     $(SPECIFIC_EOI),%al
  249         outb    %al,$(SLAVE_ICW)
  250         movb    $2,%al
  251 do_master:
  252         orb     $(SPECIFIC_EOI),%al
  253         outb    %al,$(MASTER_ICW)
  254 #endif  /* PS2 */
  255 
  256 /*
  257  *      5. Having dealt with the interrupt now we must return to the previous
  258  *      interrupt priority level.  This is done with interrupts turned off.
  259  */
  260 
  261         popl    %eax                    /* get old IPL from stack */
  262         jmp     _set_spl_noi            /* set old SPL, and return to */
  263                                         /* our caller. */
  264 /*
  265  *      Spurious interrupt.  Send the EOI anyway (XXX),
  266  *      and return.
  267  */
  268 spurious_interrupt:
  269         movb    $(NON_SPEC_EOI),%al
  270         outb    %al,$(MASTER_ICW)       /* EOI for master */
  271         nop; nop;                       /* give the bus some breathing room */
  272         outb    %al,$(SLAVE_ICW)        /* EOI for slave */
  273         ret
  274 
  275 /*
  276  * Interrupt number out of range.
  277  */
  278 int_range_err:
  279         addl    $0x40,%ecx              /* restore original interrupt number */
  280         pushl   %ecx                    /* push number */
  281         pushl   $int_range_message      /* push message */
  282         call    _panic                  /* panic */
  283         addl    $8,%esp                 /* pop stack */
  284         ret                             /* return to caller */
  285 
  286 int_range_message:
  287         .ascii  "Bad interrupt number %#x"
  288         .byte   0
  289 

Cache object: e0fab2af5b547c36950058f8020fa528


[ 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.