1/* 2 * Blackfin stacktrace code (mostly copied from avr32) 3 * 4 * Copyright 2009 Analog Devices Inc. 5 * Licensed under the GPL-2 or later. 6 */ 7 8#include <linux/sched.h> 9#include <linux/stacktrace.h> 10#include <linux/thread_info.h> 11#include <linux/module.h> 12 13register unsigned long current_frame_pointer asm("FP"); 14 15struct stackframe { 16 unsigned long fp; 17 unsigned long rets; 18}; 19 20/* 21 * Save stack-backtrace addresses into a stack_trace buffer. 22 */ 23void save_stack_trace(struct stack_trace *trace) 24{ 25 unsigned long low, high; 26 unsigned long fp; 27 struct stackframe *frame; 28 int skip = trace->skip; 29 30 low = (unsigned long)task_stack_page(current); 31 high = low + THREAD_SIZE; 32 fp = current_frame_pointer; 33 34 while (fp >= low && fp <= (high - sizeof(*frame))) { 35 frame = (struct stackframe *)fp; 36 37 if (skip) { 38 skip--; 39 } else { 40 trace->entries[trace->nr_entries++] = frame->rets; 41 if (trace->nr_entries >= trace->max_entries) 42 break; 43 } 44 45 /* 46 * The next frame must be at a higher address than the 47 * current frame. 48 */ 49 low = fp + sizeof(*frame); 50 fp = frame->fp; 51 } 52} 53EXPORT_SYMBOL_GPL(save_stack_trace); 54