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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  arch/mips/ddb5074/int-handler.S -- NEC DDB Vrc-5074 interrupt handler
  3.  *
  4.  *  Based on arch/mips/sgi/kernel/indyIRQ.S
  5.  *
  6.  *  Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  7.  *
  8.  *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
  9.  *                     Sony Software Development Center Europe (SDCE), Brussels
  10.  */
  11. #include <asm/asm.h>
  12. #include <asm/mipsregs.h>
  13. #include <asm/regdef.h>
  14. #include <asm/stackframe.h>
  15. /*
  16.  * A lot of complication here is taken away because:
  17.  *
  18.  * 1) We handle one interrupt and return, sitting in a loop and moving across
  19.  *    all the pending IRQ bits in the cause register is _NOT_ the answer, the
  20.  *    common case is one pending IRQ so optimize in that direction.
  21.  *
  22.  * 2) We need not check against bits in the status register IRQ mask, that
  23.  *    would make this routine slow as hell.
  24.  *
  25.  * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
  26.  *    between like BSD spl() brain-damage.
  27.  *
  28.  * Furthermore, the IRQs on the INDY look basically (barring software IRQs
  29.  * which we don't use at all) like:
  30.  *
  31.  * MIPS IRQ Source
  32.  *      --------        ------
  33.  *             0 Software (ignored)
  34.  *             1        Software (ignored)
  35.  *             2        Local IRQ level zero
  36.  *             3        Local IRQ level one
  37.  *             4        8254 Timer zero
  38.  *             5        8254 Timer one
  39.  *             6        Bus Error
  40.  *             7        R4k timer (what we use)
  41.  *
  42.  * We handle the IRQ according to _our_ priority which is:
  43.  *
  44.  * Highest ----     R4k Timer
  45.  *                  Local IRQ zero
  46.  *                  Local IRQ one
  47.  *                  Bus Error
  48.  *                  8254 Timer zero
  49.  * Lowest  ----     8254 Timer one
  50.  *
  51.  * then we just return, if multiple IRQs are pending then we will just take
  52.  * another exception, big deal.
  53.  */
  54. .text
  55. .set noreorder
  56. .set noat
  57. .align 5
  58. NESTED(ddbIRQ, PT_SIZE, sp)
  59. SAVE_ALL
  60. CLI
  61. .set at
  62. mfc0 s1, CP0_CAUSE # get irq mask
  63. #if 1
  64. mfc0 t2,CP0_STATUS # get enabled interrupts
  65. and s0, s1, t2 # isolate allowed ones
  66. #endif
  67. /* First we check for r4k counter/timer IRQ. */
  68. andi a0, s0, CAUSEF_IP7 # cpu timer */
  69. bnez a0, cpu_timer_irq
  70. andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero
  71. beq a0, zero, 1f
  72.  andi a0, s0, CAUSEF_IP3 # delay slot, check local level one
  73. /* Wheee, local level zero interrupt. */
  74. jal ddb_local0_irqdispatch
  75.  move a0, sp # delay slot
  76. j ret_from_irq
  77.  nop # delay slot
  78. 1:
  79. beq a0, zero, 1f
  80.  andi a0, s0, CAUSEF_IP6 # delay slot, check bus error
  81. /* Wheee, local level one interrupt. */
  82. move a0, sp
  83. jal ddb_local1_irqdispatch
  84.  nop
  85. j ret_from_irq
  86.  nop
  87. 1:
  88. beq a0, zero, 1f
  89.  nop
  90. /* Wheee, an asynchronous bus error... */
  91. move a0, sp
  92. jal ddb_buserror_irq
  93.  nop
  94. j ret_from_irq
  95.  nop
  96. 1:
  97. /* Here by mistake?  This is possible, what can happen
  98.  * is that by the time we take the exception the IRQ
  99.  * pin goes low, so just leave if this is the case.
  100.  */
  101. andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)
  102. beq a0, zero, 1f
  103. /* Must be one of the 8254 timers... */
  104. move a0, sp
  105. jal ddb_8254timer_irq
  106.  nop
  107. 1:
  108. /* phamtom interrupt */
  109. move  a0, s1
  110. jal ddb_phantom_irq
  111. nop
  112. j ret_from_irq
  113. nop
  114. cpu_timer_irq:
  115. li a0, 0
  116. move a1, sp
  117. jal do_IRQ 
  118. /* jal ll_timer_interrupt */
  119. nop
  120. j ret_from_irq
  121. nop
  122. END(ddbIRQ)