mipsIRQ.S
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:4k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Carsten Langgaard, carstenl@mips.com
  3.  * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
  4.  *
  5.  * ########################################################################
  6.  *
  7.  *  This program is free software; you can distribute it and/or modify it
  8.  *  under the terms of the GNU General Public License (Version 2) as
  9.  *  published by the Free Software Foundation.
  10.  *
  11.  *  This program is distributed in the hope it will be useful, but WITHOUT
  12.  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13.  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14.  *  for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License along
  17.  *  with this program; if not, write to the Free Software Foundation, Inc.,
  18.  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  19.  *
  20.  * ########################################################################
  21.  *
  22.  * Interrupt exception dispatch code.
  23.  *
  24.  */
  25. #include <linux/config.h>
  26. #include <asm/asm.h>
  27. #include <asm/mipsregs.h>
  28. #include <asm/regdef.h>
  29. #include <asm/stackframe.h>
  30. /* A lot of complication here is taken away because:
  31.  *
  32.  * 1) We handle one interrupt and return, sitting in a loop and moving across
  33.  *    all the pending IRQ bits in the cause register is _NOT_ the answer, the
  34.  *    common case is one pending IRQ so optimize in that direction.
  35.  *
  36.  * 2) We need not check against bits in the status register IRQ mask, that
  37.  *    would make this routine slow as hell.
  38.  *
  39.  * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
  40.  *    between like BSD spl() brain-damage.
  41.  *
  42.  * Furthermore, the IRQs on the MIPS board look basically (barring software
  43.  * IRQs which we don't use at all and all external interrupt sources are
  44.  * combined together on hardware interrupt 0 (MIPS IRQ 2)) like:
  45.  *
  46.  * MIPS IRQ Source
  47.  *      --------        ------
  48.  *             0 Software (ignored)
  49.  *             1        Software (ignored)
  50.  *             2        Combined hardware interrupt (hw0)
  51.  *             3        Hardware (ignored)
  52.  *             4        Hardware (ignored)
  53.  *             5        Hardware (ignored)
  54.  *             6        Hardware (ignored)
  55.  *             7        R4k timer (what we use)
  56.  *
  57.  * Note: On the SEAD board thing are a little bit different.
  58.  *       Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired
  59.  *       wired to UART1.
  60.  *
  61.  * We handle the IRQ according to _our_ priority which is:
  62.  *
  63.  * Highest ----     R4k Timer
  64.  * Lowest  ----     Combined hardware interrupt
  65.  *
  66.  * then we just return, if multiple IRQs are pending then we will just take
  67.  * another exception, big deal.
  68.  */
  69. .text
  70. .set noreorder
  71. .set noat
  72. .align 5
  73. NESTED(mipsIRQ, PT_SIZE, sp)
  74. SAVE_ALL
  75. CLI
  76. .set at
  77. mfc0 s0, CP0_CAUSE # get irq bits
  78. mfc0 s1, CP0_STATUS # get irq mask
  79. and s0, s1
  80. /* First we check for r4k counter/timer IRQ. */
  81. andi a0, s0, CAUSEF_IP7
  82. beq a0, zero, 1f
  83.  andi a0, s0, CAUSEF_IP2 # delay slot, check hw0 interrupt
  84. /* Wheee, a timer interrupt. */
  85. move a0, sp
  86. jal mips_timer_interrupt
  87.  nop
  88. j ret_from_irq
  89.  nop
  90. 1:
  91. #if defined(CONFIG_MIPS_SEAD)
  92. beq a0, zero, 1f
  93.  andi a0, s0, CAUSEF_IP3 # delay slot, check hw1 interrupt
  94. #else
  95. beq a0, zero, 1f # delay slot, check hw3 interrupt
  96.    andi a0, s0, CAUSEF_IP5
  97. #endif
  98. /* Wheee, combined hardware level zero interrupt. */
  99. #if defined(CONFIG_MIPS_ATLAS)
  100. jal atlas_hw0_irqdispatch
  101. #elif defined(CONFIG_MIPS_MALTA)
  102. jal malta_hw0_irqdispatch
  103. #elif defined(CONFIG_MIPS_SEAD)
  104. jal sead_hw0_irqdispatch
  105. #else
  106. #error "MIPS board not supportedn"
  107. #endif
  108.  move a0, sp # delay slot
  109. j ret_from_irq
  110.  nop # delay slot
  111. 1:
  112. #if defined(CONFIG_MIPS_SEAD)
  113. beq a0, zero, 1f
  114.  andi a0, s0, CAUSEF_IP5 # delay slot, check hw3 interrupt
  115. jal sead_hw1_irqdispatch
  116.  move a0, sp # delay slot
  117. j ret_from_irq
  118.  nop # delay slot
  119. 1:
  120. #endif
  121. #if defined(CONFIG_MIPS_MALTA)
  122. beq a0, zero, 1f            # check hw3 (coreHI) interrupt
  123.  nop
  124. jal corehi_irqdispatch
  125.  move a0, sp
  126. j ret_from_irq
  127.  nop
  128. 1:
  129. #endif
  130. /*
  131.  * Here by mistake?  This is possible, what can happen is that by the
  132.  * time we take the exception the IRQ pin goes low, so just leave if
  133.  * this is the case.
  134.  */
  135. move a1,s0
  136. PRINT("Got interrupt: c0_cause = %08xn")
  137. mfc0 a1, CP0_EPC
  138. PRINT("c0_epc = %08xn")
  139. j ret_from_irq
  140.  nop
  141. END(mipsIRQ)