linux-old/arch/mips/sgi-ip22/ip22-irq.S
<<
>>
Prefs
   1/*
   2 * ip22-irq.S: Interrupt exception dispatch code for FullHouse and
   3 *             Guiness.
   4 *
   5 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
   6 */
   7
   8#include <asm/asm.h>
   9#include <asm/mipsregs.h>
  10#include <asm/regdef.h>
  11#include <asm/stackframe.h>
  12
  13/* A lot of complication here is taken away because:
  14 *
  15 * 1) We handle one interrupt and return, sitting in a loop and moving across
  16 *    all the pending IRQ bits in the cause register is _NOT_ the answer, the
  17 *    common case is one pending IRQ so optimize in that direction.
  18 *
  19 * 2) We need not check against bits in the status register IRQ mask, that
  20 *    would make this routine slow as hell.
  21 *
  22 * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
  23 *    between like BSD spl() brain-damage.
  24 *
  25 * Furthermore, the IRQs on the INDY look basically (barring software IRQs
  26 * which we don't use at all) like:
  27 *
  28 *      MIPS IRQ        Source
  29 *      --------        ------
  30 *             0        Software (ignored)
  31 *             1        Software (ignored)
  32 *             2        Local IRQ level zero
  33 *             3        Local IRQ level one
  34 *             4        8254 Timer zero
  35 *             5        8254 Timer one
  36 *             6        Bus Error
  37 *             7        R4k timer (what we use)
  38 *
  39 * We handle the IRQ according to _our_ priority which is:
  40 *
  41 * Highest ----     R4k Timer
  42 *                  Local IRQ zero
  43 *                  Local IRQ one
  44 *                  Bus Error
  45 *                  8254 Timer zero
  46 * Lowest  ----     8254 Timer one
  47 *
  48 * then we just return, if multiple IRQs are pending then we will just take
  49 * another exception, big deal.
  50 */
  51
  52        .text
  53        .set    noreorder
  54        .set    noat
  55        .align  5
  56        NESTED(indyIRQ, PT_SIZE, sp)
  57        SAVE_ALL
  58        CLI
  59        .set    at
  60        mfc0    s0, CP0_CAUSE           # get irq mask
  61
  62        /* First we check for r4k counter/timer IRQ. */
  63        andi    a0, s0, CAUSEF_IP7
  64        beq     a0, zero, 1f
  65         andi   a0, s0, CAUSEF_IP2      # delay slot, check local level zero
  66
  67        /* Wheee, a timer interrupt. */
  68        jal     indy_r4k_timer_interrupt
  69         move   a0, sp                  # delay slot
  70        j       ret_from_irq
  71         nop                            # delay slot
  72
  731:
  74        beq     a0, zero, 1f
  75         andi   a0, s0, CAUSEF_IP3      # delay slot, check local level one
  76
  77        /* Wheee, local level zero interrupt. */
  78        jal     indy_local0_irqdispatch
  79         move   a0, sp                  # delay slot
  80
  81        j       ret_from_irq
  82         nop                            # delay slot
  83
  841:
  85        beq     a0, zero, 1f
  86         andi   a0, s0, CAUSEF_IP6      # delay slot, check bus error
  87
  88        /* Wheee, local level one interrupt. */
  89        jal     indy_local1_irqdispatch
  90         move   a0, sp                  # delay slot
  91        j       ret_from_irq
  92         nop                            # delay slot
  93
  941:
  95        beq     a0, zero, 1f
  96         andi   a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)       # delay slot
  97
  98        /* Wheee, an asynchronous bus error... */
  99        jal     indy_buserror_irq
 100         move   a0, sp                  # delay slot
 101        j       ret_from_irq
 102         nop                            # delay slot
 103
 1041:
 105        /* Here by mistake? It is possible, that by the time we take
 106         * the exception the IRQ pin goes low, so just leave if this
 107         * is the case.
 108         */
 109        beq     a0, zero, 1f
 110         nop                            # delay slot
 111
 112        /* Must be one of the 8254 timers... */
 113        jal     indy_8254timer_irq
 114         move   a0, sp                  # delay slot
 1151:
 116        j       ret_from_irq
 117         nop                            # delay slot
 118        END(indyIRQ)
 119
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.