static void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, bool (*fn)(unsigned long, void *), void *arg) { unsigned long sp, pc; unsigned long *ksp; if (regs) { sp = GET_USP(regs); pc = GET_IP(regs); } else if (task == NULL || task == current) { const register unsigned long current_sp __asm__ ("sp"); sp = current_sp; pc = (unsigned long)walk_stackframe; } else { /* task blocked in __switch_to */ sp = task->thread.sp; pc = task->thread.ra; } if (unlikely(sp & 0x7)) return; ksp = (unsigned long *)sp; while (!kstack_end(ksp)) { if (__kernel_text_address(pc) && unlikely(fn(pc, arg))) break; pc = (*ksp++) - 0x4; } }
static void visit(struct task *p) { struct task *next; static int tab = 0; unsigned int i; #define print_tab() for (i = 0; i < tab; i++) puts("|\t"); print_tab(); printf("+-- 0x%x 0x%02x 0x%02x %d\n", p->addr, get_task_type(p), get_task_state(p), get_task_pri(p)); print_tab(); printf("| /vruntime %d /exec_runtime %d (%d sec)\n", (unsigned)p->se.vruntime, (unsigned)p->se.sum_exec_runtime, (unsigned)p->se.sum_exec_runtime / HZ); print_tab(); printf("| /sp 0x%08x /base 0x%08x /heap 0x%08x /size %d\n", p->mm.sp, p->mm.base, p->mm.heap, STACK_SIZE); print_tab(); printf("| /kernel stack 0x%08x base 0x%08x\n", p->mm.kernel.sp, p->mm.kernel.base); print_tab(); printf("|\n"); if (list_empty(&p->children)) return; tab++; next = get_container_of(p->children.next, struct task, sibling); visit(next); p = next; while (p->sibling.next != &p->parent->children) { next = get_container_of( p->sibling.next, struct task, sibling); visit(next); p = next; } tab--; printf("control %08x, sp %08x, msp %08x, psp %08x\n", GET_CNTL(), GET_SP(), GET_KSP(), GET_USP()); }
static void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, bool (*fn)(unsigned long, void *), void *arg) { unsigned long fp, sp, pc; if (regs) { fp = GET_FP(regs); sp = GET_USP(regs); pc = GET_IP(regs); } else if (task == NULL || task == current) { const register unsigned long current_sp __asm__ ("sp"); fp = (unsigned long)__builtin_frame_address(0); sp = current_sp; pc = (unsigned long)walk_stackframe; } else { /* task blocked in __switch_to */ fp = task->thread.s[0]; sp = task->thread.sp; pc = task->thread.ra; } for (;;) { unsigned long low, high; struct stackframe *frame; if (unlikely(!__kernel_text_address(pc) || fn(pc, arg))) break; /* Validate frame pointer */ low = sp + sizeof(struct stackframe); high = ALIGN(sp, THREAD_SIZE); if (unlikely(fp < low || fp > high || fp & 0x7)) break; /* Unwind stack frame */ frame = (struct stackframe *)fp - 1; sp = fp; fp = frame->fp; pc = frame->ra - 0x4; } }
void __attribute__((naked)) isr_fault() { unsigned int sp, lr, psr, usp; sp = GET_SP (); psr = GET_PSR(); lr = GET_LR (); usp = GET_USP(); printk("\nKernel SP 0x%08x\n" "Stacked PSR 0x%08x\n" "Stacked PC 0x%08x\n" "Stacked LR 0x%08x\n" "Current LR 0x%08x\n" "Current PSR 0x%08x(vector number:%d)\n", sp, *(unsigned int *)(sp + 28), *(unsigned int *)(sp + 24), *(unsigned int *)(sp + 20), lr, psr, psr & 0x1ff); printk("\nUser SP 0x%08x\n" "Stacked PSR 0x%08x\n" "Stacked PC 0x%08x\n" "Stacked LR 0x%08x\n", usp, *(unsigned int *)(usp + 28), *(unsigned int *)(usp + 24), *(unsigned int *)(usp + 20)); printk("\ncurrent->sp 0x%08x\n" "current->base 0x%08x\n" "current->heap 0x%08x\n" "current->kernel 0x%08x\n" "current->kernel->sp 0x%08x\n" "current->state 0x%08x\n" "current->irqflag 0x%08x\n" "current->addr 0x%08x\n" "current 0x%08x\n" , current->mm.sp, current->mm.base, current->mm.heap, current->mm.kernel.base, current->mm.kernel.sp, current->state, current->irqflag, current->addr, current); printk("\ncurrent context\n"); unsigned int i; for (i = 0; i < NR_CONTEXT*2; i++) printk("[0x%08x] 0x%08x\n", usp + i*4, ((unsigned int *)usp)[i]); printk("\nSCB_ICSR 0x%08x\n" "SCB_CFSR 0x%08x\n" "SCB_HFSR 0x%08x\n" "SCB_MMFAR 0x%08x\n" "SCB_BFAR 0x%08x\n", SCB_ICSR, SCB_CFSR, SCB_HFSR, SCB_MMFAR, SCB_BFAR); /* led for debugging */ #ifdef LED_DEBUG SET_PORT_CLOCK(ENABLE, PORTD); SET_PORT_PIN(PORTD, 2, PIN_OUTPUT_50MHZ); unsigned int j; while (1) { PUT_PORT(PORTD, GET_PORT(PORTD) ^ 4); for (i = 100; i; i--) { for (j = 10; j; j--) { __asm__ __volatile__( "nop \n\t" "nop \n\t" "nop \n\t" "nop \n\t" "nop \n\t" "nop \n\t" "nop \n\t" "nop \n\t" "nop \n\t" "nop \n\t" ::: "memory"); } } } #endif }