31bc99a52383415959325fd55813c178d341b4f7
[linux-2.6.git] / arch / mips / mips-boards / atlas / atlas-irq.S
1 /*
2  * Carsten Langgaard, carstenl@mips.com
3  * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
4  *
5  *  This program is free software; you can distribute it and/or modify it
6  *  under the terms of the GNU General Public License (Version 2) as
7  *  published by the Free Software Foundation.
8  *
9  *  This program is distributed in the hope it will be useful, but WITHOUT
10  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  *  for more details.
13  *
14  *  You should have received a copy of the GNU General Public License along
15  *  with this program; if not, write to the Free Software Foundation, Inc.,
16  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
17  *
18  * Interrupt exception dispatch code.
19  */
20 #include <linux/config.h>
21
22 #include <asm/asm.h>
23 #include <asm/mipsregs.h>
24 #include <asm/regdef.h>
25 #include <asm/stackframe.h>
26 #include <asm/mips-boards/atlasint.h>
27
28 /*
29  * Furthermore, the IRQs on the MIPS board look basically (barring software
30  * IRQs which we don't use at all and all external interrupt sources are
31  * combined together on hardware interrupt 0 (MIPS IRQ 2)) like:
32  *
33  *      MIPS IRQ        Source
34  *      --------        ------
35  *             0        Software (ignored)
36  *             1        Software (ignored)
37  *             2        Combined hardware interrupt (hw0)
38  *             3        Hardware (ignored)
39  *             4        Hardware (ignored)
40  *             5        Hardware (ignored)
41  *             6        Hardware (ignored)
42  *             7        R4k timer (what we use)
43  *
44  * Note: On the SEAD board thing are a little bit different.
45  *       Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired
46  *       wired to UART1.
47  *
48  * We handle the IRQ according to _our_ priority which is:
49  *
50  * Highest ----     R4k Timer
51  * Lowest  ----     Combined hardware interrupt
52  *
53  * then we just return, if multiple IRQs are pending then we will just take
54  * another exception, big deal.
55  */
56
57         .text
58         .set    noreorder
59         .set    noat
60         .align  5
61         NESTED(mipsIRQ, PT_SIZE, sp)
62         SAVE_ALL
63         CLI
64         .set    at
65
66         mfc0    s0, CP0_CAUSE           # get irq bits
67         mfc0    s1, CP0_STATUS          # get irq mask
68         andi    s0, ST0_IM              # CAUSE.CE may be non-zero!
69         and     s0, s1
70
71 #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
72         .set    mips32
73         clz     a0, s0
74         .set    mips0
75         negu    a0
76         addu    a0, 31-CAUSEB_IP
77         bltz    a0, spurious
78 #else
79         beqz    s0, spurious
80          li     a0, 7
81
82         and     t0, s0, 0xf000
83         sltiu   t0, t0, 1
84         sll     t0, 2
85         subu    a0, t0
86         sll     s0, t0
87
88         and     t0, s0, 0xc000
89         sltiu   t0, t0, 1
90         sll     t0, 1
91         subu    a0, t0
92         sll     s0, t0
93
94         and     t0, s0, 0x8000
95         sltiu   t0, t0, 1
96         # sll   t0, 0
97         subu    a0, t0
98         # sll   s0, t0
99 #endif
100
101          li     a1, MIPSCPU_INT_ATLAS
102         bne     a0, a1, 1f
103          addu   a0, MIPSCPU_INT_BASE
104
105         jal     atlas_hw0_irqdispatch
106          move    a0, sp
107
108         j       ret_from_irq
109          nop
110
111 1:      jal     do_IRQ
112          move   a1, sp
113
114         j       ret_from_irq
115          nop
116
117 spurious:
118         j       spurious_interrupt
119          nop
120         END(mipsIRQ)