ip22-irq.S
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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