diff options
Diffstat (limited to 'arch/mips/mips-boards/generic/mipsIRQ.S')
-rw-r--r-- | arch/mips/mips-boards/generic/mipsIRQ.S | 110 |
1 files changed, 56 insertions, 54 deletions
diff --git a/arch/mips/mips-boards/generic/mipsIRQ.S b/arch/mips/mips-boards/generic/mipsIRQ.S index 131f49bccb20..a397ecb872d6 100644 --- a/arch/mips/mips-boards/generic/mipsIRQ.S +++ b/arch/mips/mips-boards/generic/mipsIRQ.S | |||
@@ -29,6 +29,20 @@ | |||
29 | #include <asm/regdef.h> | 29 | #include <asm/regdef.h> |
30 | #include <asm/stackframe.h> | 30 | #include <asm/stackframe.h> |
31 | 31 | ||
32 | #ifdef CONFIG_MIPS_ATLAS | ||
33 | #include <asm/mips-boards/atlasint.h> | ||
34 | #define CASCADE_IRQ MIPSCPU_INT_ATLAS | ||
35 | #define CASCADE_DISPATCH atlas_hw0_irqdispatch | ||
36 | #endif | ||
37 | #ifdef CONFIG_MIPS_MALTA | ||
38 | #include <asm/mips-boards/maltaint.h> | ||
39 | #define CASCADE_IRQ MIPSCPU_INT_I8259A | ||
40 | #define CASCADE_DISPATCH malta_hw0_irqdispatch | ||
41 | #endif | ||
42 | #ifdef CONFIG_MIPS_SEAD | ||
43 | #include <asm/mips-boards/seadint.h> | ||
44 | #endif | ||
45 | |||
32 | /* A lot of complication here is taken away because: | 46 | /* A lot of complication here is taken away because: |
33 | * | 47 | * |
34 | * 1) We handle one interrupt and return, sitting in a loop and moving across | 48 | * 1) We handle one interrupt and return, sitting in a loop and moving across |
@@ -80,74 +94,62 @@ | |||
80 | 94 | ||
81 | mfc0 s0, CP0_CAUSE # get irq bits | 95 | mfc0 s0, CP0_CAUSE # get irq bits |
82 | mfc0 s1, CP0_STATUS # get irq mask | 96 | mfc0 s1, CP0_STATUS # get irq mask |
97 | andi s0, ST0_IM # CAUSE.CE may be non-zero! | ||
83 | and s0, s1 | 98 | and s0, s1 |
84 | 99 | ||
85 | /* First we check for r4k counter/timer IRQ. */ | 100 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) |
86 | andi a0, s0, CAUSEF_IP7 | 101 | .set mips32 |
87 | beq a0, zero, 1f | 102 | clz a0, s0 |
88 | andi a0, s0, CAUSEF_IP2 # delay slot, check hw0 interrupt | 103 | .set mips0 |
104 | negu a0 | ||
105 | addu a0, 31-CAUSEB_IP | ||
106 | bltz a0, spurious | ||
107 | #else | ||
108 | beqz s0, spurious | ||
109 | li a0, 7 | ||
89 | 110 | ||
90 | /* Wheee, a timer interrupt. */ | 111 | and t0, s0, 0xf000 |
91 | move a0, sp | 112 | sltiu t0, t0, 1 |
92 | jal mips_timer_interrupt | 113 | sll t0, 2 |
93 | nop | 114 | subu a0, t0 |
115 | sll s0, t0 | ||
94 | 116 | ||
95 | j ret_from_irq | 117 | and t0, s0, 0xc000 |
96 | nop | 118 | sltiu t0, t0, 1 |
119 | sll t0, 1 | ||
120 | subu a0, t0 | ||
121 | sll s0, t0 | ||
97 | 122 | ||
98 | 1: | 123 | and t0, s0, 0x8000 |
99 | #if defined(CONFIG_MIPS_SEAD) | 124 | sltiu t0, t0, 1 |
100 | beq a0, zero, 1f | 125 | # sll t0, 0 |
101 | andi a0, s0, CAUSEF_IP3 # delay slot, check hw1 interrupt | 126 | subu a0, t0 |
102 | #else | 127 | # sll s0, t0 |
103 | beq a0, zero, 1f # delay slot, check hw3 interrupt | ||
104 | andi a0, s0, CAUSEF_IP5 | ||
105 | #endif | 128 | #endif |
106 | 129 | ||
107 | /* Wheee, combined hardware level zero interrupt. */ | 130 | #ifdef CASCADE_IRQ |
108 | #if defined(CONFIG_MIPS_ATLAS) | 131 | li a1, CASCADE_IRQ |
109 | jal atlas_hw0_irqdispatch | 132 | bne a0, a1, 1f |
110 | #elif defined(CONFIG_MIPS_MALTA) | 133 | addu a0, MIPSCPU_INT_BASE |
111 | jal malta_hw0_irqdispatch | ||
112 | #elif defined(CONFIG_MIPS_SEAD) | ||
113 | jal sead_hw0_irqdispatch | ||
114 | #else | ||
115 | #error "MIPS board not supported\n" | ||
116 | #endif | ||
117 | move a0, sp # delay slot | ||
118 | 134 | ||
119 | j ret_from_irq | 135 | jal CASCADE_DISPATCH |
120 | nop # delay slot | 136 | move a0, sp |
121 | 137 | ||
122 | 1: | ||
123 | #if defined(CONFIG_MIPS_SEAD) | ||
124 | beq a0, zero, 1f | ||
125 | andi a0, s0, CAUSEF_IP5 # delay slot, check hw3 interrupt | ||
126 | jal sead_hw1_irqdispatch | ||
127 | move a0, sp # delay slot | ||
128 | j ret_from_irq | ||
129 | nop # delay slot | ||
130 | 1: | ||
131 | #endif | ||
132 | #if defined(CONFIG_MIPS_MALTA) | ||
133 | beq a0, zero, 1f # check hw3 (coreHI) interrupt | ||
134 | nop | ||
135 | jal corehi_irqdispatch | ||
136 | move a0, sp | ||
137 | j ret_from_irq | 138 | j ret_from_irq |
138 | nop | 139 | nop |
139 | 1: | 140 | 1: |
141 | #else | ||
142 | addu a0, MIPSCPU_INT_BASE | ||
140 | #endif | 143 | #endif |
141 | /* | 144 | |
142 | * Here by mistake? This is possible, what can happen is that by the | 145 | jal do_IRQ |
143 | * time we take the exception the IRQ pin goes low, so just leave if | 146 | move a1, sp |
144 | * this is the case. | ||
145 | */ | ||
146 | move a1,s0 | ||
147 | PRINT("Got interrupt: c0_cause = %08x\n") | ||
148 | mfc0 a1, CP0_EPC | ||
149 | PRINT("c0_epc = %08x\n") | ||
150 | 147 | ||
151 | j ret_from_irq | 148 | j ret_from_irq |
152 | nop | 149 | nop |
150 | |||
151 | |||
152 | spurious: | ||
153 | j spurious_interrupt | ||
154 | nop | ||
153 | END(mipsIRQ) | 155 | END(mipsIRQ) |