diff options
Diffstat (limited to 'arch/mips/kernel/genex.S')
-rw-r--r-- | arch/mips/kernel/genex.S | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 13f22d1d0e8b..ff7af369f286 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | 13 | ||
14 | #include <asm/asm.h> | 14 | #include <asm/asm.h> |
15 | #include <asm/asmmacro.h> | ||
15 | #include <asm/cacheops.h> | 16 | #include <asm/cacheops.h> |
16 | #include <asm/regdef.h> | 17 | #include <asm/regdef.h> |
17 | #include <asm/fpregdef.h> | 18 | #include <asm/fpregdef.h> |
@@ -122,6 +123,20 @@ handle_vcei: | |||
122 | .set pop | 123 | .set pop |
123 | END(except_vec3_r4000) | 124 | END(except_vec3_r4000) |
124 | 125 | ||
126 | __FINIT | ||
127 | |||
128 | .align 5 | ||
129 | NESTED(handle_int, PT_SIZE, sp) | ||
130 | SAVE_ALL | ||
131 | CLI | ||
132 | |||
133 | PTR_LA ra, ret_from_irq | ||
134 | move a0, sp | ||
135 | j plat_irq_dispatch | ||
136 | END(handle_int) | ||
137 | |||
138 | __INIT | ||
139 | |||
125 | /* | 140 | /* |
126 | * Special interrupt vector for MIPS64 ISA & embedded MIPS processors. | 141 | * Special interrupt vector for MIPS64 ISA & embedded MIPS processors. |
127 | * This is a dedicated interrupt exception vector which reduces the | 142 | * This is a dedicated interrupt exception vector which reduces the |
@@ -157,6 +172,15 @@ NESTED(except_vec_vi, 0, sp) | |||
157 | SAVE_AT | 172 | SAVE_AT |
158 | .set push | 173 | .set push |
159 | .set noreorder | 174 | .set noreorder |
175 | #ifdef CONFIG_MIPS_MT_SMTC | ||
176 | /* | ||
177 | * To keep from blindly blocking *all* interrupts | ||
178 | * during service by SMTC kernel, we also want to | ||
179 | * pass the IM value to be cleared. | ||
180 | */ | ||
181 | EXPORT(except_vec_vi_mori) | ||
182 | ori a0, $0, 0 | ||
183 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
160 | EXPORT(except_vec_vi_lui) | 184 | EXPORT(except_vec_vi_lui) |
161 | lui v0, 0 /* Patched */ | 185 | lui v0, 0 /* Patched */ |
162 | j except_vec_vi_handler | 186 | j except_vec_vi_handler |
@@ -173,6 +197,25 @@ EXPORT(except_vec_vi_end) | |||
173 | NESTED(except_vec_vi_handler, 0, sp) | 197 | NESTED(except_vec_vi_handler, 0, sp) |
174 | SAVE_TEMP | 198 | SAVE_TEMP |
175 | SAVE_STATIC | 199 | SAVE_STATIC |
200 | #ifdef CONFIG_MIPS_MT_SMTC | ||
201 | /* | ||
202 | * SMTC has an interesting problem that interrupts are level-triggered, | ||
203 | * and the CLI macro will clear EXL, potentially causing a duplicate | ||
204 | * interrupt service invocation. So we need to clear the associated | ||
205 | * IM bit of Status prior to doing CLI, and restore it after the | ||
206 | * service routine has been invoked - we must assume that the | ||
207 | * service routine will have cleared the state, and any active | ||
208 | * level represents a new or otherwised unserviced event... | ||
209 | */ | ||
210 | mfc0 t1, CP0_STATUS | ||
211 | and t0, a0, t1 | ||
212 | mfc0 t2, CP0_TCCONTEXT | ||
213 | or t0, t0, t2 | ||
214 | mtc0 t0, CP0_TCCONTEXT | ||
215 | xor t1, t1, t0 | ||
216 | mtc0 t1, CP0_STATUS | ||
217 | ehb | ||
218 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
176 | CLI | 219 | CLI |
177 | move a0, sp | 220 | move a0, sp |
178 | jalr v0 | 221 | jalr v0 |