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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * arch/mips/dec/int-handler.S
  3.  *
  4.  * Copyright (C) 1995, 1996, 1997 Paul M. Antoine and Harald Koerfgen
  5.  * Copyright (C) 2000, 2001, 2002  Maciej W. Rozycki
  6.  *
  7.  * Written by Ralf Baechle and Andreas Busse, modified for DECStation
  8.  * support by Paul Antoine and Harald Koerfgen.
  9.  *
  10.  * completly rewritten:
  11.  * Copyright (C) 1998 Harald Koerfgen
  12.  *
  13.  * Rewritten extensively for controller-driven IRQ support
  14.  * by Maciej W. Rozycki.
  15.  */
  16. #include <asm/asm.h>
  17. #include <asm/regdef.h>
  18. #include <asm/mipsregs.h>
  19. #include <asm/stackframe.h>
  20. #include <asm/addrspace.h>
  21. #include <asm/dec/interrupts.h>
  22. #include <asm/dec/ioasic_addrs.h>
  23. #include <asm/dec/ioasic_ints.h>
  24. #include <asm/dec/kn01.h>
  25. #include <asm/dec/kn02.h>
  26. #include <asm/dec/kn02xa.h>
  27. #include <asm/dec/kn03.h>
  28. .text
  29. .set noreorder
  30. /*
  31.  * decstation_handle_int: Interrupt handler for DECStations
  32.  *
  33.  * We follow the model in the Indy interrupt code by David Miller, where he
  34.  * says: a lot of complication here is taken away because:
  35.  *
  36.  * 1) We handle one interrupt and return, sitting in a loop
  37.  *    and moving across all the pending IRQ bits in the cause
  38.  *    register is _NOT_ the answer, the common case is one
  39.  *    pending IRQ so optimize in that direction.
  40.  *
  41.  * 2) We need not check against bits in the status register
  42.  *    IRQ mask, that would make this routine slow as hell.
  43.  *
  44.  * 3) Linux only thinks in terms of all IRQs on or all IRQs
  45.  *    off, nothing in between like BSD spl() brain-damage.
  46.  *
  47.  * Furthermore, the IRQs on the DECStations look basically (barring
  48.  * software IRQs which we don't use at all) like...
  49.  *
  50.  * DS2100/3100's, aka kn01, aka Pmax:
  51.  *
  52.  * MIPS IRQ Source
  53.  *      --------        ------
  54.  *             0 Software (ignored)
  55.  *             1        Software (ignored)
  56.  *             2        SCSI
  57.  *             3        Lance Ethernet
  58.  *             4        DZ11 serial
  59.  *             5        RTC
  60.  *             6        Memory Controller
  61.  *             7        FPU
  62.  *
  63.  * DS5000/200, aka kn02, aka 3max:
  64.  *
  65.  * MIPS IRQ Source
  66.  *      --------        ------
  67.  *             0 Software (ignored)
  68.  *             1        Software (ignored)
  69.  *             2        TurboChannel
  70.  *             3        RTC
  71.  *             4        Reserved
  72.  *             5        Memory Controller
  73.  *             6        Reserved
  74.  *             7        FPU
  75.  *
  76.  * DS5000/1xx's, aka kn02ba, aka 3min:
  77.  *
  78.  * MIPS IRQ Source
  79.  *      --------        ------
  80.  *             0 Software (ignored)
  81.  *             1        Software (ignored)
  82.  *             2        TurboChannel Slot 0
  83.  *             3        TurboChannel Slot 1
  84.  *             4        TurboChannel Slot 2
  85.  *             5        TurboChannel Slot 3 (ASIC)
  86.  *             6        Halt button
  87.  *             7        FPU/R4k timer
  88.  *
  89.  * DS5000/2x's, aka kn02ca, aka maxine:
  90.  *
  91.  * MIPS IRQ Source
  92.  *      --------        ------
  93.  *             0 Software (ignored)
  94.  *             1        Software (ignored)
  95.  *             2        Periodic Interrupt (100usec)
  96.  *             3        RTC
  97.  *             4        I/O write timeout
  98.  *             5        TurboChannel (ASIC)
  99.  *             6        Halt Keycode from Access.Bus keyboard (CTRL-ALT-ENTER)
  100.  *             7        FPU/R4k timer
  101.  *
  102.  * DS5000/2xx's, aka kn03, aka 3maxplus:
  103.  *
  104.  * MIPS IRQ Source
  105.  *      --------        ------
  106.  *             0 Software (ignored)
  107.  *             1        Software (ignored)
  108.  *             2        System Board (ASIC)
  109.  *             3        RTC
  110.  *             4        Reserved
  111.  *             5        Memory
  112.  *             6        Halt Button
  113.  *             7        FPU/R4k timer
  114.  *
  115.  * We handle the IRQ according to _our_ priority (see setup.c),
  116.  * then we just return.  If multiple IRQs are pending then we will
  117.  * just take another exception, big deal.
  118.  */
  119. .align 5
  120. NESTED(decstation_handle_int, PT_SIZE, ra)
  121. .set noat
  122. SAVE_ALL
  123. CLI # TEST: interrupts should be off
  124. .set at
  125. .set noreorder
  126. /*
  127.  * Get pending Interrupts
  128.  */
  129. mfc0 t0,CP0_CAUSE # get pending interrupts
  130. mfc0 t1,CP0_STATUS
  131. lw t2,cpu_fpu_mask
  132. andi t0,ST0_IM # CAUSE.CE may be non-zero!
  133. and t0,t1 # isolate allowed ones
  134. beqz t0,spurious
  135.  and t2,t0
  136. bnez t2,fpu # handle FPU immediately
  137. /*
  138.  * Find irq with highest priority
  139.  */
  140.  la t1,cpu_mask_nr_tbl
  141. 1: lw t2,(t1)
  142. nop
  143. and t2,t0
  144. beqz t2,1b
  145.  addu t1,2*PTRSIZE # delay slot
  146. /*
  147.  * Do the low-level stuff
  148.  */
  149. lw a0,(-PTRSIZE)(t1)
  150. nop
  151. bgez a0,handle_it # irq_nr >= 0?
  152. # irq_nr < 0: it is an address
  153.  nop
  154. jr a0
  155. # a trick to save a branch:
  156.  lui t2,KN03_IOASIC_BASE>>16 # upper part of IOASIC Address
  157. /*
  158.  * Handle "IRQ Controller" Interrupts
  159.  * Masked Interrupts are still visible and have to be masked "by hand".
  160.  */
  161. FEXPORT(kn02_io_int) # 3max
  162. lui t0,KN02_CSR_ADDR>>16 # get interrupt status and mask
  163. lw t0,(t0)
  164. nop
  165. andi t1,t0,KN02_IRQ_ALL
  166. b 1f
  167.  srl t0,16 # shift interrupt mask
  168. FEXPORT(kn02xa_io_int) # 3min/maxine
  169. lui t2,KN02XA_IOASIC_BASE>>16 # upper part of IOASIC Address
  170. FEXPORT(kn03_io_int) # 3max+ (t2 loaded earlier)
  171. lw t0,SIR(t2) # get status: IOASIC isr
  172. lw t1,SIMR(t2) # get mask:   IOASIC isrm
  173. nop
  174. 1: and t0,t1 # mask out allowed ones
  175. beqz t0,spurious
  176. /*
  177.  * Find irq with highest priority
  178.  */
  179.  la t1,asic_mask_nr_tbl
  180. 2: lw t2,(t1)
  181. nop
  182. and t2,t0
  183. beq zero,t2,2b
  184.  addu t1,2*PTRSIZE # delay slot
  185. /*
  186.  * Do the low-level stuff
  187.  */
  188. lw a0,%lo(-PTRSIZE)(t1)
  189. nop
  190. bgez a0,handle_it # irq_nr >= 0?
  191. # irq_nr < 0: it is an address
  192.  nop
  193. jr a0
  194.  nop # delay slot
  195. /*
  196.  * Dispatch low-priority interrupts.  We reconsider all status
  197.  * bits again, which looks like a lose, but it makes the code
  198.  * simple and O(log n), so it gets compensated.
  199.  */
  200. FEXPORT(cpu_all_int) # HALT, timers, software junk
  201. li a0,DEC_CPU_IRQ_BASE
  202. srl t0,CAUSEB_IP
  203. li t1,CAUSEF_IP>>CAUSEB_IP # mask
  204. b 1f
  205.  li t2,4 # nr of bits / 2
  206. FEXPORT(kn02_all_int) # impossible ?
  207. li a0,KN02_IRQ_BASE
  208. li t1,KN02_IRQ_ALL # mask
  209. b 1f
  210.  li t2,4 # nr of bits / 2
  211. FEXPORT(asic_all_int) # various I/O ASIC junk
  212. li a0,IO_IRQ_BASE
  213. li t1,IO_IRQ_ALL # mask
  214. b 1f
  215.  li t2,8 # nr of bits / 2
  216. /*
  217.  * Dispatch DMA interrupts -- O(log n).
  218.  */
  219. FEXPORT(asic_dma_int) # I/O ASIC DMA events
  220. li a0,IO_IRQ_BASE+IO_INR_DMA
  221. srl t0,IO_INR_DMA
  222. li t1,IO_IRQ_DMA>>IO_INR_DMA # mask
  223. li t2,8 # nr of bits / 2
  224. /*
  225.  * Find irq with highest priority.
  226.  * Highest irq number takes precedence.
  227.  */
  228. 1: srlv t3,t1,t2
  229. 2: xor t1,t3
  230. and t3,t0,t1
  231. beqz t3,3f
  232.  nop
  233. move t0,t3
  234. addu a0,t2
  235. 3: srl t2,1
  236. bnez t2,2b
  237.  srlv t3,t1,t2
  238. handle_it:
  239. jal do_IRQ
  240.  move a1,sp
  241. j ret_from_irq
  242.  nop
  243. fpu:
  244. j handle_fpe_int
  245.  nop
  246. spurious:
  247. j spurious_interrupt
  248.  nop
  249. END(decstation_handle_int)
  250. /*
  251.  * Generic unimplemented interrupt routines -- cpu_mask_nr_tbl
  252.  * and asic_mask_nr_tbl are initialized to point all interrupts here.
  253.  * The tables are then filled in by machine-specific initialisation
  254.  * in dec_setup().
  255.  */
  256. FEXPORT(dec_intr_unimplemented)
  257. move a1,t0 # cheats way of printing an arg!
  258. PANIC("Unimplemented cpu interrupt! CP0_CAUSE: 0x%08x");
  259. FEXPORT(asic_intr_unimplemented)
  260. move a1,t0 # cheats way of printing an arg!
  261. PANIC("Unimplemented asic interrupt! ASIC ISR: 0x%08x");