aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/process.c')
-rw-r--r--arch/mips/kernel/process.c54
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
47void arch_cpu_idle_dead(void) 48void 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
537static 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
549void arch_trigger_all_cpu_backtrace(bool include_self)
550{
551 smp_call_function(arch_dump_stack, NULL, 1);
552}