1/* 2 * Copyright (C) SGI 2000 3 * 4 * Written by Dimitris Michailidis (dimitris@engr.sgi.com) 5 * Written by Goutham Rao <goutham.rao@intel.com> 6 */ 7 8#ifndef _ASM_KERNPROF_H 9#define _ASM_KERNPROF_H 10#ifdef __KERNEL__ 11 12#include <asm/unwind.h> 13#include <asm/system.h> 14#include <asm/ptrace.h> 15 16#ifdef FUNCTIONPC 17#undef FUNCTIONPC 18#endif 19#define FUNCTIONPC(func) (*(unsigned long *)&(func)) 20 21/* We can do 16-bit compare&swap */ 22#define __HAVE_ARCH_CMPXCHG16 1 23 24typedef struct unw_frame_info frame_info_t; 25 26/* 27 * default PC resolution for this platform 28 */ 29#define DFL_PC_RES 4 30 31#define supports_call_graph prof_have_mcount 32 33#define frame_get_pc(frame) ((frame)->ip) 34 35#define get_prof_freq() HZ 36 37extern void cg_record_arc(unsigned long, unsigned long); 38 39static void do_cg_record_arc(struct unw_frame_info *info, void *arg) 40{ 41 unsigned long callee_ip, caller_ip; 42 43 /* First, get the frame for our backtrace_cg_record_arc() caller */ 44 unw_get_ip(info, &caller_ip); 45 if (caller_ip == 0 || unw_unwind(info) < 0) 46 return; 47 48 /* 49 * Next, get the frame for the next higher caller -- this is the 50 * first interesting callee. 51 */ 52 unw_get_ip(info, &caller_ip); 53 if (caller_ip == 0 || unw_unwind(info) < 0) 54 return; 55 56 /* Now begin the iteration of walking further up the call graph */ 57 do { 58 callee_ip = caller_ip; 59 unw_get_ip(info, &caller_ip); 60 61 if (caller_ip == 0) 62 break; 63 64 if (pc_out_of_range(caller_ip)) 65 break; 66 67 cg_record_arc(caller_ip, callee_ip); 68 69 } while (unw_unwind(info) >= 0); 70} 71 72/* 73 * Record the call graph, which is normally done by backtrace_cg_record_arc(), 74 * and return 1 to indicate success. We expect that backtrace_cg_record_arc() 75 * will next call get_next_frame() and that will *fail*, leaving us with the 76 * backtrace that do_cg_record_arc() has recorded (above). 77 * Yes, this is a real hack. 78 */ 79static __inline__ int build_fake_frame(frame_info_t *frame) 80{ 81 unw_init_running(do_cg_record_arc, 0); 82 return 1; 83} 84 85static __inline__ unsigned long instruction_pointer(struct pt_regs *regs) 86{ 87 return regs->cr_iip + (ia64_psr(regs)->ri << 2); 88} 89 90static __inline__ int in_firmware(struct pt_regs *regs) 91{ 92 return 0; 93} 94 95static __inline__ void get_top_frame(struct pt_regs *regs, frame_info_t *frame) 96{ 97 struct switch_stack *sw = (struct switch_stack *) regs - 1; 98 unw_init_frame_info(frame, current, sw); 99 /* skip over interrupt frame */ 100 unw_unwind(frame); 101} 102 103static __inline__ int get_next_frame(frame_info_t *frame) 104{ 105 return 0; 106} 107 108#define have_perfctr() 0 109#define valid_perfctr_event(e) 0 110#define valid_perfctr_freq(n) 0 111#define perfctr_reload(x) 112#define __perfctr_stop() 113#define __perfctr_commence(x,y) 114#define setup_profiling_timer(x) (-EINVAL) 115 116#endif /* __KERNEL__ */ 117#endif /* !_ASM_KERNPROF_H */ 118