diff options
Diffstat (limited to 'arch/mips/kernel/process.c')
-rw-r--r-- | arch/mips/kernel/process.c | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 636b0745d7c7..eb76434828e8 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <asm/isadep.h> | 42 | #include <asm/isadep.h> |
43 | #include <asm/inst.h> | 43 | #include <asm/inst.h> |
44 | #include <asm/stacktrace.h> | 44 | #include <asm/stacktrace.h> |
45 | #include <asm/irq_regs.h> | ||
45 | 46 | ||
46 | #ifdef CONFIG_HOTPLUG_CPU | 47 | #ifdef CONFIG_HOTPLUG_CPU |
47 | void arch_cpu_idle_dead(void) | 48 | void arch_cpu_idle_dead(void) |
@@ -187,21 +188,21 @@ static inline int is_ra_save_ins(union mips_instruction *ip) | |||
187 | */ | 188 | */ |
188 | if (mm_insn_16bit(ip->halfword[0])) { | 189 | if (mm_insn_16bit(ip->halfword[0])) { |
189 | mmi.word = (ip->halfword[0] << 16); | 190 | mmi.word = (ip->halfword[0] << 16); |
190 | return ((mmi.mm16_r5_format.opcode == mm_swsp16_op && | 191 | return (mmi.mm16_r5_format.opcode == mm_swsp16_op && |
191 | mmi.mm16_r5_format.rt == 31) || | 192 | mmi.mm16_r5_format.rt == 31) || |
192 | (mmi.mm16_m_format.opcode == mm_pool16c_op && | 193 | (mmi.mm16_m_format.opcode == mm_pool16c_op && |
193 | mmi.mm16_m_format.func == mm_swm16_op)); | 194 | mmi.mm16_m_format.func == mm_swm16_op); |
194 | } | 195 | } |
195 | else { | 196 | else { |
196 | mmi.halfword[0] = ip->halfword[1]; | 197 | mmi.halfword[0] = ip->halfword[1]; |
197 | mmi.halfword[1] = ip->halfword[0]; | 198 | mmi.halfword[1] = ip->halfword[0]; |
198 | return ((mmi.mm_m_format.opcode == mm_pool32b_op && | 199 | return (mmi.mm_m_format.opcode == mm_pool32b_op && |
199 | mmi.mm_m_format.rd > 9 && | 200 | mmi.mm_m_format.rd > 9 && |
200 | mmi.mm_m_format.base == 29 && | 201 | mmi.mm_m_format.base == 29 && |
201 | mmi.mm_m_format.func == mm_swm32_func) || | 202 | mmi.mm_m_format.func == mm_swm32_func) || |
202 | (mmi.i_format.opcode == mm_sw32_op && | 203 | (mmi.i_format.opcode == mm_sw32_op && |
203 | mmi.i_format.rs == 29 && | 204 | mmi.i_format.rs == 29 && |
204 | mmi.i_format.rt == 31)); | 205 | mmi.i_format.rt == 31); |
205 | } | 206 | } |
206 | #else | 207 | #else |
207 | /* sw / sd $ra, offset($sp) */ | 208 | /* sw / sd $ra, offset($sp) */ |
@@ -233,7 +234,7 @@ static inline int is_jump_ins(union mips_instruction *ip) | |||
233 | if (ip->r_format.opcode != mm_pool32a_op || | 234 | if (ip->r_format.opcode != mm_pool32a_op || |
234 | ip->r_format.func != mm_pool32axf_op) | 235 | ip->r_format.func != mm_pool32axf_op) |
235 | return 0; | 236 | return 0; |
236 | return (((ip->u_format.uimmediate >> 6) & mm_jalr_op) == mm_jalr_op); | 237 | return ((ip->u_format.uimmediate >> 6) & mm_jalr_op) == mm_jalr_op; |
237 | #else | 238 | #else |
238 | if (ip->j_format.opcode == j_op) | 239 | if (ip->j_format.opcode == j_op) |
239 | return 1; | 240 | return 1; |
@@ -260,13 +261,13 @@ static inline int is_sp_move_ins(union mips_instruction *ip) | |||
260 | union mips_instruction mmi; | 261 | union mips_instruction mmi; |
261 | 262 | ||
262 | mmi.word = (ip->halfword[0] << 16); | 263 | mmi.word = (ip->halfword[0] << 16); |
263 | return ((mmi.mm16_r3_format.opcode == mm_pool16d_op && | 264 | return (mmi.mm16_r3_format.opcode == mm_pool16d_op && |
264 | mmi.mm16_r3_format.simmediate && mm_addiusp_func) || | 265 | mmi.mm16_r3_format.simmediate && mm_addiusp_func) || |
265 | (mmi.mm16_r5_format.opcode == mm_pool16d_op && | 266 | (mmi.mm16_r5_format.opcode == mm_pool16d_op && |
266 | mmi.mm16_r5_format.rt == 29)); | 267 | mmi.mm16_r5_format.rt == 29); |
267 | } | 268 | } |
268 | return (ip->mm_i_format.opcode == mm_addiu32_op && | 269 | return ip->mm_i_format.opcode == mm_addiu32_op && |
269 | ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29); | 270 | ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29; |
270 | #else | 271 | #else |
271 | /* addiu/daddiu sp,sp,-imm */ | 272 | /* addiu/daddiu sp,sp,-imm */ |
272 | if (ip->i_format.rs != 29 || ip->i_format.rt != 29) | 273 | if (ip->i_format.rs != 29 || ip->i_format.rt != 29) |
@@ -532,3 +533,20 @@ unsigned long arch_align_stack(unsigned long sp) | |||
532 | 533 | ||
533 | return sp & ALMASK; | 534 | return sp & ALMASK; |
534 | } | 535 | } |
536 | |||
537 | static void arch_dump_stack(void *info) | ||
538 | { | ||
539 | struct pt_regs *regs; | ||
540 | |||
541 | regs = get_irq_regs(); | ||
542 | |||
543 | if (regs) | ||
544 | show_regs(regs); | ||
545 | |||
546 | dump_stack(); | ||
547 | } | ||
548 | |||
549 | void arch_trigger_all_cpu_backtrace(bool include_self) | ||
550 | { | ||
551 | smp_call_function(arch_dump_stack, NULL, 1); | ||
552 | } | ||