Esempio n. 1
0
void aee_stop_nested_panic(struct pt_regs *regs)
{
    struct thread_info *thread = current_thread_info();
    int len = 0;
    int timeout = 1000000;
    int res = 0, cpu = 0;
    struct wd_api *wd_api = NULL;
    struct pt_regs *excp_regs = NULL;
    int prev_fiq_step = aee_rr_curr_fiq_step();
    /* everytime enter nested_panic flow, add 8 */
    static int step_base = -8;
    step_base = step_base < 48 ? step_base + 8 : 56;

    aee_rec_step_nested_panic(step_base);
    local_irq_disable();
    preempt_disable();

    aee_rec_step_nested_panic(step_base + 1);
    cpu = get_HW_cpuid();
    aee_rec_step_nested_panic(step_base + 2);
    /*nested panic may happens more than once on many/single cpus */
    if (atomic_read(&nested_panic_time) < 3)
        aee_nested_printf("\nCPU%dpanic%d@%d\n", cpu, nested_panic_time, prev_fiq_step);
    atomic_inc(&nested_panic_time);

    switch (atomic_read(&nested_panic_time)) {
    case 2:
        aee_print_regs(regs);
        aee_nested_printf("backtrace:");
        aee_print_bt(regs);
        break;

    /* must guarantee Only one cpu can run here */
    /* first check if thread valid */
    case 1:
        if (virt_addr_valid(thread) && virt_addr_valid(thread->regs_on_excp)) {
            excp_regs = thread->regs_on_excp;
        } else {
            /* if thread invalid, which means wrong sp or thread_info corrupted,
               check global aee_excp_regs instead */
            aee_nested_printf("invalid thread [%x], excp_regs [%x]\n", thread,
                              aee_excp_regs);
            excp_regs = aee_excp_regs;
        }

        aee_nested_printf("Nested panic\n");
        if (excp_regs) {
            aee_nested_printf("Previous\n");
            aee_print_regs(excp_regs);
        }
        aee_nested_printf("Current\n");
        aee_print_regs(regs);

        /*should not print stack info. this may overwhelms ram console used by fiq */
        if (0 != in_fiq_handler()) {
            aee_nested_printf("in fiq hander\n");
        } else {
            /*Dump first panic stack */
            aee_nested_printf("Previous\n");
            if (excp_regs) {
                len = aee_nested_save_stack(excp_regs);
                aee_nested_printf("\nbacktrace:");
                aee_print_bt(excp_regs);
            }

            /*Dump second panic stack */
            aee_nested_printf("Current\n");
            if (virt_addr_valid(regs)) {
                len = aee_nested_save_stack(regs);
                aee_nested_printf("\nbacktrace:");
                aee_print_bt(regs);
            }
        }
        aee_rec_step_nested_panic(step_base + 5);
        ipanic_recursive_ke(regs, excp_regs, cpu);

        aee_rec_step_nested_panic(step_base + 6);
        /* we donot want a FIQ after this, so disable hwt */
        res = get_wd_api(&wd_api);
        if (res) {
            aee_nested_printf("get_wd_api error\n");
        } else {
            wd_api->wd_aee_confirm_hwreboot();
        }
        aee_rec_step_nested_panic(step_base + 7);
        break;
    default:
        break;
    }
    /* waiting for the WDT timeout */
    while (1) {
        /* output to UART directly to avoid printk nested panic */
        /* mt_fiq_printf("%s hang here%d\t", __func__, i++); */
        while (timeout--) {
            udelay(1);
        }
        timeout = 1000000;
    }
}
Esempio n. 2
0
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;
    }

}