inline int aee_nested_save_stack(struct pt_regs *regs) { int len = 0; if (!virt_addr_valid(regs->ARM_sp)) return -1; aee_nested_printf("[%08lx %08lx]\n", regs->ARM_sp, regs->ARM_sp + 256); len = aee_dump_stack_top_binary(nested_panic_buf, sizeof(nested_panic_buf), regs->ARM_sp, regs->ARM_sp + 256); if (len > 0) aee_sram_fiq_save_bin(nested_panic_buf, len); else print_error_msg(len); return len; }
void aee_stop_nested_panic(struct pt_regs *regs) { struct thread_info *thread = current_thread_info(); int i = 0; int len = 0; int timeout = 1000000; local_irq_disable(); preempt_disable(); /*Data abort handler data abort again on many cpu. Since ram console api is lockless, this should be prevented*/ if(atomic_xchg(&nested_panic_time, 1) != 0) { aee_nested_printf("multicore enters nested panic\n"); goto out; } mtk_wdt_restart(WK_WDT_LOC_TYPE_NOLOCK); hw_reboot_mode(); /*must guarantee Only one cpu can run here*/ aee_nested_printf("Nested panic\n"); aee_nested_printf("Log for the previous panic:\n"); aee_nested_printf("pc: %08lx lr: %08lx psr: %08lx\n", ((struct pt_regs *)thread->regs_on_excp)->ARM_pc, ((struct pt_regs *)thread->regs_on_excp)->ARM_lr, ((struct pt_regs *)thread->regs_on_excp)->ARM_cpsr); aee_nested_printf("sp: %08lx ip: %08lx fp: %08lx\n", ((struct pt_regs *)thread->regs_on_excp)->ARM_sp, ((struct pt_regs *)thread->regs_on_excp)->ARM_ip, ((struct pt_regs *)thread->regs_on_excp)->ARM_fp); aee_nested_printf("r10: %08lx r9: %08lx r8: %08lx\n", ((struct pt_regs *)thread->regs_on_excp)->ARM_r10, ((struct pt_regs *)thread->regs_on_excp)->ARM_r9, ((struct pt_regs *)thread->regs_on_excp)->ARM_r8); aee_nested_printf("r7: %08lx r6: %08lx r5: %08lx r4: %08lx\n", ((struct pt_regs *)thread->regs_on_excp)->ARM_r7, ((struct pt_regs *)thread->regs_on_excp)->ARM_r6, ((struct pt_regs *)thread->regs_on_excp)->ARM_r5, ((struct pt_regs *)thread->regs_on_excp)->ARM_r4); aee_nested_printf("r3: %08lx r2: %08lx r1: %08lx r0: %08lx\n", ((struct pt_regs *)thread->regs_on_excp)->ARM_r3, ((struct pt_regs *)thread->regs_on_excp)->ARM_r2, ((struct pt_regs *)thread->regs_on_excp)->ARM_r1, ((struct pt_regs *)thread->regs_on_excp)->ARM_r0); aee_nested_printf("Log for the current panic:\n"); aee_nested_printf("pc: %08lx lr: %08lx psr: %08lx\n", regs->ARM_pc, regs->ARM_lr, regs->ARM_cpsr); aee_nested_printf("sp: %08lx ip: %08lx fp: %08lx\n", regs->ARM_sp, regs->ARM_ip, regs->ARM_fp); aee_nested_printf("r10: %08lx r9: %08lx r8: %08lx\n", regs->ARM_r10, regs->ARM_r9, regs->ARM_r8); aee_nested_printf("r7: %08lx r6: %08lx r5: %08lx r4: %08lx\n", regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4); len = aee_nested_printf("r3: %08lx r2: %08lx r1: %08lx r0: %08lx\n", regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0); /*should not print stack info. this may overwhelms ram console used by fiq*/ if(0!= in_fiq_handler()) { goto out; } aee_nested_printf("stack [%08lx %08lx]", ((struct pt_regs *)thread->regs_on_excp)->ARM_sp, ((struct pt_regs *)thread->regs_on_excp)->ARM_sp + 512); /*Dump first panic stack*/ len = aee_dump_stack_top_binary(nested_panic_buf, sizeof(nested_panic_buf), ((struct pt_regs *)thread->regs_on_excp)->ARM_sp, ((struct pt_regs *)thread->regs_on_excp)->ARM_sp + 512 ); if(len > 0) { aee_sram_fiq_save_bin(nested_panic_buf, len); }else{ print_error_msg(len); } aee_nested_printf("stack [%08lx %08lx]", regs->ARM_sp, regs->ARM_sp + 256); /*Dump second panic stack*/ len = aee_dump_stack_top_binary(nested_panic_buf, sizeof(nested_panic_buf), regs->ARM_sp, regs->ARM_sp + 256); if(len > 0) { aee_sram_fiq_save_bin(nested_panic_buf, len); }else { print_error_msg(len); } out: /* waiting for the WDT timeout */ while (1) { printk("%s hang here%d\t", __func__, i++); while(timeout--) { udelay(1); } timeout = 1000000; } }