1/* 2 * Blackfin ftrace code 3 * 4 * Copyright 2009 Analog Devices Inc. 5 * Licensed under the GPL-2 or later. 6 */ 7 8#ifndef __ASM_BFIN_FTRACE_H__ 9#define __ASM_BFIN_FTRACE_H__ 10 11#define MCOUNT_INSN_SIZE 6 /* sizeof "[++sp] = rets; call __mcount;" */ 12 13#ifndef __ASSEMBLY__ 14 15#ifdef CONFIG_DYNAMIC_FTRACE 16 17extern void _mcount(void); 18#define MCOUNT_ADDR ((unsigned long)_mcount) 19 20static inline unsigned long ftrace_call_adjust(unsigned long addr) 21{ 22 return addr; 23} 24 25struct dyn_arch_ftrace { 26 /* No extra data needed for Blackfin */ 27}; 28 29#endif 30 31#ifdef CONFIG_FRAME_POINTER 32#include <linux/mm.h> 33 34extern inline void *return_address(unsigned int level) 35{ 36 unsigned long *endstack, *fp, *ret_addr; 37 unsigned int current_level = 0; 38 39 if (level == 0) 40 return __builtin_return_address(0); 41 42 fp = (unsigned long *)__builtin_frame_address(0); 43 endstack = (unsigned long *)PAGE_ALIGN((unsigned long)&level); 44 45 while (((unsigned long)fp & 0x3) == 0 && fp && 46 (fp + 1) < endstack && current_level < level) { 47 fp = (unsigned long *)*fp; 48 current_level++; 49 } 50 51 if (((unsigned long)fp & 0x3) == 0 && fp && 52 (fp + 1) < endstack) 53 ret_addr = (unsigned long *)*(fp + 1); 54 else 55 ret_addr = NULL; 56 57 return ret_addr; 58} 59 60#else 61 62extern inline void *return_address(unsigned int level) 63{ 64 return NULL; 65} 66 67#endif /* CONFIG_FRAME_POINTER */ 68 69#define ftrace_return_address(n) return_address(n) 70 71#endif /* __ASSEMBLY__ */ 72 73#endif 74