[MIPS] Fix the crime against humanity that mipsIRQ.S is.
[linux-2.6.git] / arch / mips / mips-boards / malta / malta-irq.S
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
27 #include <asm/asm.h>
28 #include <asm/mipsregs.h>
29 #include <asm/regdef.h>
30 #include <asm/stackframe.h>
31 #include <asm/mips-boards/maltaint.h>
32
33 /*
34  * IRQs on the Malta board look basically (barring software IRQs which we
35  * don't use at all and all external interrupt sources are combined together
36  * on hardware interrupt 0 (MIPS IRQ 2)) like:
37  *
38  *      MIPS IRQ        Source
39  *      --------        ------
40  *             0        Software (ignored)
41  *             1        Software (ignored)
42  *             2        Combined hardware interrupt (hw0)
43  *             3        Hardware (ignored)
44  *             4        Hardware (ignored)
45  *             5        Hardware (ignored)
46  *             6        Hardware (ignored)
47  *             7        R4k timer (what we use)
48  *
49  * We handle the IRQ according to _our_ priority which is:
50  *
51  * Highest ----     R4k Timer
52  * Lowest  ----     Combined hardware interrupt
53  *
54  * then we just return, if multiple IRQs are pending then we will just take
55  * another exception, big deal.
56  */
57
58         .text
59         .set    noreorder
60         .set    noat
61         .align  5
62         NESTED(mipsIRQ, PT_SIZE, sp)
63         SAVE_ALL
64         CLI
65         .set    at
66
67         mfc0    s0, CP0_CAUSE           # get irq bits
68         mfc0    s1, CP0_STATUS          # get irq mask
69         andi    s0, ST0_IM              # CAUSE.CE may be non-zero!
70         and     s0, s1
71
72 #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
73         .set    mips32
74         clz     a0, s0
75         .set    mips0
76         negu    a0
77         addu    a0, 31-CAUSEB_IP
78         bltz    a0, spurious
79 #else
80         beqz    s0, spurious
81          li     a0, 7
82
83         and     t0, s0, 0xf000
84         sltiu   t0, t0, 1
85         sll     t0, 2
86         subu    a0, t0
87         sll     s0, t0
88
89         and     t0, s0, 0xc000
90         sltiu   t0, t0, 1
91         sll     t0, 1
92         subu    a0, t0
93         sll     s0, t0
94
95         and     t0, s0, 0x8000
96         sltiu   t0, t0, 1
97         # sll   t0, 0
98         subu    a0, t0
99         # sll   s0, t0
100 #endif
101
102          li     a1, MIPSCPU_INT_I8259A
103         bne     a0, a1, 1f
104          addu   a0, MIPSCPU_INT_BASE
105
106         jal     malta_hw0_irqdispatch
107          move    a0, sp
108
109         j       ret_from_irq
110          nop
111 1:
112
113         jal     do_IRQ
114          move   a1, sp
115
116         j       ret_from_irq
117          nop
118
119 spurious:
120         j       spurious_interrupt
121          nop
122         END(mipsIRQ)