1*24b45a12SMichal Simek /* 2*24b45a12SMichal Simek * Stack trace support for Microblaze. 3*24b45a12SMichal Simek * 4*24b45a12SMichal Simek * Copyright (C) 2009 Michal Simek <monstr@monstr.eu> 5*24b45a12SMichal Simek * Copyright (C) 2009 PetaLogix 6*24b45a12SMichal Simek * 7*24b45a12SMichal Simek * This file is subject to the terms and conditions of the GNU General Public 8*24b45a12SMichal Simek * License. See the file "COPYING" in the main directory of this archive 9*24b45a12SMichal Simek * for more details. 10*24b45a12SMichal Simek */ 11*24b45a12SMichal Simek 12*24b45a12SMichal Simek #include <linux/sched.h> 13*24b45a12SMichal Simek #include <linux/stacktrace.h> 14*24b45a12SMichal Simek #include <linux/thread_info.h> 15*24b45a12SMichal Simek #include <linux/ptrace.h> 16*24b45a12SMichal Simek #include <linux/module.h> 17*24b45a12SMichal Simek 18*24b45a12SMichal Simek /* FIXME initial support */ 19*24b45a12SMichal Simek void save_stack_trace(struct stack_trace *trace) 20*24b45a12SMichal Simek { 21*24b45a12SMichal Simek unsigned long *sp; 22*24b45a12SMichal Simek unsigned long addr; 23*24b45a12SMichal Simek asm("addik %0, r1, 0" : "=r" (sp)); 24*24b45a12SMichal Simek 25*24b45a12SMichal Simek while (!kstack_end(sp)) { 26*24b45a12SMichal Simek addr = *sp++; 27*24b45a12SMichal Simek if (__kernel_text_address(addr)) { 28*24b45a12SMichal Simek if (trace->skip > 0) 29*24b45a12SMichal Simek trace->skip--; 30*24b45a12SMichal Simek else 31*24b45a12SMichal Simek trace->entries[trace->nr_entries++] = addr; 32*24b45a12SMichal Simek 33*24b45a12SMichal Simek if (trace->nr_entries >= trace->max_entries) 34*24b45a12SMichal Simek break; 35*24b45a12SMichal Simek } 36*24b45a12SMichal Simek } 37*24b45a12SMichal Simek } 38*24b45a12SMichal Simek EXPORT_SYMBOL_GPL(save_stack_trace); 39*24b45a12SMichal Simek 40*24b45a12SMichal Simek void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) 41*24b45a12SMichal Simek { 42*24b45a12SMichal Simek unsigned int *sp; 43*24b45a12SMichal Simek unsigned long addr; 44*24b45a12SMichal Simek 45*24b45a12SMichal Simek struct thread_info *ti = task_thread_info(tsk); 46*24b45a12SMichal Simek 47*24b45a12SMichal Simek if (tsk == current) 48*24b45a12SMichal Simek asm("addik %0, r1, 0" : "=r" (sp)); 49*24b45a12SMichal Simek else 50*24b45a12SMichal Simek sp = (unsigned int *)ti->cpu_context.r1; 51*24b45a12SMichal Simek 52*24b45a12SMichal Simek while (!kstack_end(sp)) { 53*24b45a12SMichal Simek addr = *sp++; 54*24b45a12SMichal Simek if (__kernel_text_address(addr)) { 55*24b45a12SMichal Simek if (trace->skip > 0) 56*24b45a12SMichal Simek trace->skip--; 57*24b45a12SMichal Simek else 58*24b45a12SMichal Simek trace->entries[trace->nr_entries++] = addr; 59*24b45a12SMichal Simek 60*24b45a12SMichal Simek if (trace->nr_entries >= trace->max_entries) 61*24b45a12SMichal Simek break; 62*24b45a12SMichal Simek } 63*24b45a12SMichal Simek } 64*24b45a12SMichal Simek } 65*24b45a12SMichal Simek EXPORT_SYMBOL_GPL(save_stack_trace_tsk); 66