void fiq_debugger_dump_stacktrace(struct fiq_debugger_output *output, const struct pt_regs *regs, unsigned int depth, void *ssp) { struct thread_info *real_thread_info = THREAD_INFO(ssp); struct stacktrace_state sts; sts.depth = depth; sts.output = output; *current_thread_info() = *real_thread_info; if (!current) output->printf(output, "current NULL\n"); else output->printf(output, "pid: %d comm: %s\n", current->pid, current->comm); fiq_debugger_dump_regs(output, regs); if (!user_mode(regs)) { struct stackframe frame; frame.fp = regs->regs[29]; frame.sp = regs->sp; frame.pc = regs->pc; output->printf(output, "\n"); walk_stackframe(&frame, report_trace, &sts); } }
static void mt_debug_fiq(void *arg, void *regs, void *svc_sp) { u32 iir; int data = -1; int max_count = UART_FIFO_SIZE; unsigned int this_cpu; int need_irq = 1; iir = REG_UART_IIR; iir &= UART_IIR_INT_MASK; if (iir == UART_IIR_NO_INT_PENDING) return ; if (iir == UART_IIR_THRE) { } __push_event(iir, data); while (max_count-- > 0) { if (!(REG_UART_STATUS & 0x01)) { break; } if (is_fiq_debug_console_enable(arg)) { data = mt_console_uart->read_byte(mt_console_uart); if (data == FIQ_DEBUGGER_BREAK_CH) { /* enter FIQ debugger mode */ ret_FIQ_DEBUGGER_BREAK = 1; this_cpu = THREAD_INFO(svc_sp)->cpu; debug_handle_uart_interrupt(arg, this_cpu, regs, svc_sp); return ; } __push_event(UART_IIR_NO_INT_PENDING, data); /*why need_irq?*/ need_irq = 1; } else { this_cpu = THREAD_INFO(svc_sp)->cpu; need_irq = debug_handle_uart_interrupt(arg, this_cpu, regs, svc_sp); } } if (need_irq) { mt_disable_fiq(uart_irq_number); trigger_sw_irq(FIQ_DBG_SGI); } }
void fiq_watchdog_triggered(const struct pt_regs *regs, void *svc_sp) { char msg[24]; int len; raw_spin_lock(&fiq_watchdog_lock); len = scnprintf(msg, sizeof(msg), "watchdog fiq cpu %d\n", THREAD_INFO(svc_sp)->cpu); ramoops_console_write_buf(msg, len); fiq_debugger_dump_stacktrace(&fiq_watchdog_output, regs, 100, svc_sp); raw_spin_unlock(&fiq_watchdog_lock); }