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