Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 24b45a12 authored by Michal Simek's avatar Michal Simek
Browse files

microblaze: Stack trace support



This is working implemetation but the problem is that
Microblaze misses frame pointer that's why is there
big loop which trace and show all addresses which are in text.
It shows addresses which are in registers, etc.

This is problem and this is the reason why all Microblaze
traces are wrong. There is an option to do hacks and trace
the kernel code but this is too complicated.

Signed-off-by: default avatarMichal Simek <monstr@monstr.eu>
parent 7cf79d59
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -57,6 +57,9 @@ config GENERIC_GPIO
config GENERIC_CSUM
	def_bool y

config STACKTRACE_SUPPORT
	def_bool y

config PCI
	def_bool n

+1 −0
Original line number Diff line number Diff line
@@ -16,5 +16,6 @@ obj-$(CONFIG_SELFMOD) += selfmod.o
obj-$(CONFIG_HEART_BEAT)	+= heartbeat.o
obj-$(CONFIG_MODULES)		+= microblaze_ksyms.o module.o
obj-$(CONFIG_MMU)		+= misc.o
obj-$(CONFIG_STACKTRACE)	+= stacktrace.o

obj-y	+= entry$(MMU).o
+65 −0
Original line number Diff line number Diff line
/*
 * Stack trace support for Microblaze.
 *
 * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
 * Copyright (C) 2009 PetaLogix
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License. See the file "COPYING" in the main directory of this archive
 * for more details.
 */

#include <linux/sched.h>
#include <linux/stacktrace.h>
#include <linux/thread_info.h>
#include <linux/ptrace.h>
#include <linux/module.h>

/* FIXME initial support */
void save_stack_trace(struct stack_trace *trace)
{
	unsigned long *sp;
	unsigned long addr;
	asm("addik %0, r1, 0" : "=r" (sp));

	while (!kstack_end(sp)) {
		addr = *sp++;
		if (__kernel_text_address(addr)) {
			if (trace->skip > 0)
				trace->skip--;
			else
				trace->entries[trace->nr_entries++] = addr;

			if (trace->nr_entries >= trace->max_entries)
				break;
		}
	}
}
EXPORT_SYMBOL_GPL(save_stack_trace);

void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
{
	unsigned int *sp;
	unsigned long addr;

	struct thread_info *ti = task_thread_info(tsk);

	if (tsk == current)
		asm("addik %0, r1, 0" : "=r" (sp));
	else
		sp = (unsigned int *)ti->cpu_context.r1;

	while (!kstack_end(sp)) {
		addr = *sp++;
		if (__kernel_text_address(addr)) {
			if (trace->skip > 0)
				trace->skip--;
			else
				trace->entries[trace->nr_entries++] = addr;

			if (trace->nr_entries >= trace->max_entries)
				break;
		}
	}
}
EXPORT_SYMBOL_GPL(save_stack_trace_tsk);