linux-hexagon.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Richard Kuo <rkuo@codeaurora.org>
To: linux-kernel@vger.kernel.org, linux-hexagon@vger.kernel.org
Cc: Linas Vepstas <linas@codeaurora.org>
Subject: [patch v2 20/35] Hexagon: Provide basic debugging and system trap support.
Date: Tue, 30 Aug 2011 14:07:49 -0500	[thread overview]
Message-ID: <20110830190801.615083995@codeaurora.org> (raw)
In-Reply-To: 20110830190729.923334292@codeaurora.org

[-- Attachment #1: traps.diff --]
[-- Type: text/plain, Size: 10863 bytes --]

Signed-off-by: Richard Kuo <rkuo@codeaurora.org>
Signed-off-by: Linas Vepstas <linas@codeaurora.org>

---
 arch/hexagon/include/asm/traps.h |   29 +++
 arch/hexagon/kernel/traps.c      |  356 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 385 insertions(+)

Index: linux-hexagon-kernel/arch/hexagon/kernel/traps.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-hexagon-kernel/arch/hexagon/kernel/traps.c	2011-08-24 18:45:48.253877210 -0500
@@ -0,0 +1,356 @@
+/*
+ * Kernel traps/events for Hexagon processor
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/kallsyms.h>
+#include <linux/kdebug.h>
+#include <linux/syscalls.h>
+#include <linux/signal.h>
+#include <linux/tracehook.h>
+#include <asm/traps.h>
+#include <asm/vm_fault.h>
+#include <asm/syscall.h>
+#include <asm/registers.h>
+#include <asm/unistd.h>
+#ifdef CONFIG_KGDB
+# include <linux/kgdb.h>
+#endif
+
+#define TRAP_SYSCALL	1
+#define TRAP_DEBUG	0xdb
+
+void __init trap_init(void)
+{
+}
+
+#ifdef CONFIG_GENERIC_BUG
+/* Maybe should resemble arch/sh/kernel/traps.c ?? */
+int is_valid_bugaddr(unsigned long addr)
+{
+	return 1;
+}
+#endif /* CONFIG_GENERIC_BUG */
+
+void show_stack(struct task_struct *task, unsigned long *fp)
+{
+	int kstack_depth_to_print = 20;
+	unsigned long offset, size;
+	const char *name = NULL;
+	unsigned long *newfp;
+	unsigned long ip;
+	char tmpstr[128];
+	char *modname;
+	int i;
+
+	if (task == NULL)
+		task = current;
+
+	if (fp == NULL) {
+		if (task == current) {
+			asm("%0 = r30" : "=r" (fp));
+		} else {
+			fp = (unsigned long *)
+			     ((struct hexagon_switch_stack *)
+			     task->thread.switch_sp)->fp;
+		}
+	}
+
+	printk(KERN_INFO "CPU#%d, %s/%d, Call Trace:\n",
+	       raw_smp_processor_id(), current->comm,
+	       task_pid_nr(current));
+	for (i = 0; i < kstack_depth_to_print; i++) {
+		if (0 /* Check irq stack at some point */)
+			printk(KERN_INFO " <EOI> ");
+		else if (((long) fp & (THREAD_SIZE-1)) == 0)
+			break;
+
+		newfp = (unsigned long *) *fp;
+
+		ip = *(unsigned long *)((char *)fp + sizeof(unsigned long));
+		name = kallsyms_lookup(ip, &size, &offset, &modname, tmpstr);
+
+		printk(KERN_INFO "[%p] 0x%lx: %s + 0x%lx", fp, ip, name,
+			offset);
+		if (modname)
+			printk(KERN_CONT " [%s] ", modname);
+		if (i == 0)
+			printk(KERN_CONT " (unreliable)");
+		printk(KERN_CONT "\n");
+
+		/* If newfp isn't larger, we're tracing garbage */
+		if (newfp > fp)
+			fp = newfp;
+		else
+			break;
+	}
+}
+
+void dump_state(struct pt_regs *regs)
+{
+	show_regs(regs);
+	show_stack(current, &regs->r30);
+}
+
+void dump_stack(void)
+{
+	show_stack(current, NULL);
+}
+EXPORT_SYMBOL(dump_stack);
+
+int die(const char *str, struct pt_regs *regs, long err)
+{
+	static struct {
+		spinlock_t lock;
+		int counter;
+	} die = {
+		.lock = __SPIN_LOCK_UNLOCKED(die.lock),
+		.counter = 0
+	};
+
+	spin_lock_irq(&die.lock);
+	bust_spinlocks(1);
+	printk(KERN_INFO "%s[#%d]:\n", str, ++die.counter);
+
+	if (notify_die(DIE_OOPS, str, regs, err, pt_cause(regs), SIGSEGV) ==
+	    NOTIFY_STOP)
+		return 1;
+
+	print_modules();
+	dump_state(regs);
+
+	do_exit(err);
+	return 0;
+}
+
+int die_if_kernel(char *str, struct pt_regs *regs, long err)
+{
+	if (!user_mode(regs))
+		return die(str, regs, err);
+	else
+		return 0;
+}
+
+/*
+ * It's not clear that misaligned fetches are ever recoverable.
+ */
+static void misaligned_instruction(struct pt_regs *regs)
+{
+	die_if_kernel("Misaligned Instruction", regs, 0);
+	force_sig(SIGBUS, current);
+}
+
+/*
+ * Misaligned loads and stores, on the other hand, can be
+ * emulated, and probably should be, some day.  But for now
+ * they will be considered fatal.
+ */
+static void misaligned_data_load(struct pt_regs *regs)
+{
+	die_if_kernel("Misaligned Data Load", regs, 0);
+	force_sig(SIGBUS, current);
+}
+
+static void misaligned_data_store(struct pt_regs *regs)
+{
+	die_if_kernel("Misaligned Data Store", regs, 0);
+	force_sig(SIGBUS, current);
+}
+
+static void illegal_instruction(struct pt_regs *regs)
+{
+	die_if_kernel("Illegal Instruction", regs, 0);
+	force_sig(SIGILL, current);
+}
+
+/*
+ * Precise bus errors may be recoverable with a a retry,
+ * but for now, treat them as irrecoverable.
+ */
+static void precise_bus_error(struct pt_regs *regs)
+{
+	die_if_kernel("Precise Bus Error", regs, 0);
+	force_sig(SIGBUS, current);
+}
+
+/*
+ * If anything is to be done here other than panic,
+ * it will probably be complex and migrate to another
+ * source module.  For now, just die.
+ */
+static void cache_error(struct pt_regs *regs)
+{
+	die("Cache Error", regs, 0);
+}
+
+/*
+ * General exception handler
+ */
+void do_genex(struct pt_regs *regs)
+{
+
+	/*
+	 * Decode Cause and Dispatch
+	 */
+	switch (pt_cause(regs)) {
+	case HVM_GE_C_XPROT:
+	case HVM_GE_C_XUSER:
+		execute_protection_fault(regs);
+		break;
+	case HVM_GE_C_RPROT:
+	case HVM_GE_C_RUSER:
+		read_protection_fault(regs);
+		break;
+	case HVM_GE_C_WPROT:
+	case HVM_GE_C_WUSER:
+		write_protection_fault(regs);
+		break;
+	case HVM_GE_C_XMAL:
+		misaligned_instruction(regs);
+		break;
+	case HVM_GE_C_RMAL:
+		misaligned_data_load(regs);
+		break;
+	case HVM_GE_C_WMAL:
+		misaligned_data_store(regs);
+		break;
+	case HVM_GE_C_INVI:
+	case HVM_GE_C_PRIVI:
+		illegal_instruction(regs);
+		break;
+	case HVM_GE_C_BUS:
+		precise_bus_error(regs);
+		break;
+	case HVM_GE_C_CACHE:
+		cache_error(regs);
+		break;
+	default:
+		/* Halt and catch fire */
+		panic("Unrecognized exception 0x%lx\n", pt_cause(regs));
+		break;
+	}
+}
+
+/* Indirect system call dispatch */
+long sys_syscall(void)
+{
+	printk(KERN_ERR "sys_syscall invoked!\n");
+	return -ENOSYS;
+}
+
+void do_trap0(struct pt_regs *regs)
+{
+	unsigned long syscallret = 0;
+	syscall_fn syscall;
+
+	switch (pt_cause(regs)) {
+	case TRAP_SYSCALL:
+		/* System call is trap0 #1 */
+
+		/* allow strace to catch syscall args  */
+		if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE) &&
+			tracehook_report_syscall_entry(regs)))
+			return;  /*  return -ENOSYS somewhere?  */
+
+		/* Interrupts should be re-enabled for syscall processing */
+		__vmsetie(VM_INT_ENABLE);
+
+		/*
+		 * System call number is in r6, arguments in r0..r5.
+		 * Fortunately, no Linux syscall has more than 6 arguments,
+		 * and Hexagon ABI passes first 6 arguments in registers.
+		 * 64-bit arguments are passed in odd/even register pairs.
+		 * Fortunately, we have no system calls that take more
+		 * than three arguments with more than one 64-bit value.
+		 * Should that change, we'd need to redesign to copy
+		 * between user and kernel stacks.
+		 */
+		regs->syscall_nr = regs->r06;
+
+		/*
+		 * GPR R0 carries the first parameter, and is also used
+		 * to report the return value.  We need a backup of
+		 * the user's value in case we need to do a late restart
+		 * of the system call.
+		 */
+		regs->restart_r0 = regs->r00;
+
+		if ((unsigned long) regs->syscall_nr >= __NR_syscalls) {
+			regs->r00 = -1;
+		} else {
+			syscall = (syscall_fn)
+				  (sys_call_table[regs->syscall_nr]);
+			syscallret = syscall(regs->r00, regs->r01,
+				   regs->r02, regs->r03,
+				   regs->r04, regs->r05);
+		}
+
+		/*
+		 * If it was a sigreturn system call, don't overwrite
+		 * r0 value in stack frame with return value.
+		 *
+		 * __NR_sigreturn doesn't seem to exist in new unistd.h
+		 */
+
+		if (regs->syscall_nr != __NR_rt_sigreturn)
+			regs->r00 = syscallret;
+
+		/* allow strace to get the syscall return state  */
+		if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE)))
+			tracehook_report_syscall_exit(regs, 0);
+
+		break;
+	case TRAP_DEBUG:
+		/* Trap0 0xdb is debug breakpoint */
+		if (user_mode(regs)) {
+			struct siginfo info;
+
+			info.si_signo = SIGTRAP;
+			info.si_errno = 0;
+			/*
+			 * Some architecures add some per-thread state
+			 * to distinguish between breakpoint traps and
+			 * trace traps.  We may want to do that, and
+			 * set the si_code value appropriately, or we
+			 * may want to use a different trap0 flavor.
+			 */
+			info.si_code = TRAP_BRKPT;
+			info.si_addr = (void __user *) pt_elr(regs);
+			send_sig_info(SIGTRAP, &info, current);
+		} else {
+#ifdef CONFIG_KGDB
+			kgdb_handle_exception(pt_cause(regs), SIGTRAP,
+					      TRAP_BRKPT, regs);
+#endif
+		}
+		break;
+	}
+	/* Ignore other trap0 codes for now, especially 0 (Angel calls) */
+}
+
+/*
+ * Machine check exception handler
+ */
+void do_machcheck(struct pt_regs *regs)
+{
+	/* Halt and catch fire */
+	__vmstop();
+}
Index: linux-hexagon-kernel/arch/hexagon/include/asm/traps.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-hexagon-kernel/arch/hexagon/include/asm/traps.h	2011-08-24 18:45:48.253877210 -0500
@@ -0,0 +1,29 @@
+/*
+ * Trap support for Hexagon
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_HEXAGON_TRAPS_H
+#define _ASM_HEXAGON_TRAPS_H
+
+#include <asm/registers.h>
+
+extern int die(const char *str, struct pt_regs *regs, long err);
+extern int die_if_kernel(char *str, struct pt_regs *regs, long err);
+
+#endif /* _ASM_HEXAGON_TRAPS_H */

--

Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

  parent reply	other threads:[~2011-08-30 19:07 UTC|newest]

Thread overview: 82+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-30 19:07 [patch v2 00/35] Hexagon: Add support for Qualcomm Hexagon architecture Richard Kuo
2011-08-30 19:07 ` [patch v2 01/35] Hexagon: Add generic headers Richard Kuo
2011-08-31 13:24   ` Arnd Bergmann
2011-08-31 19:51     ` David Brown
2011-08-31 20:00       ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 02/35] Hexagon: Core arch-specific header files Richard Kuo
2011-08-31 13:25   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 03/35] Hexagon: Add bitops support Richard Kuo
2011-08-31 13:26   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 04/35] Hexagon: Add atomic ops support Richard Kuo
2011-08-31 13:26   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 05/35] Hexagon: Add syscalls Richard Kuo
2011-08-31 13:34   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 06/35] Hexagon: Add processor and system headers Richard Kuo
2011-08-31 13:35   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 07/35] Hexagon: Add threadinfo Richard Kuo
2011-08-31 13:36   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 08/35] Hexagon: Add delay functions Richard Kuo
2011-08-31 13:39   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 09/35] Hexagon: Add checksum functions Richard Kuo
2011-08-30 19:34   ` Joe Perches
2011-08-30 19:52     ` Sam Ravnborg
2011-08-31 14:49   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 10/35] Hexagon: Add memcpy and memset accelerated functions Richard Kuo
2011-08-31 13:40   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 11/35] Hexagon: Add hypervisor interface Richard Kuo
2011-08-31 13:41   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 12/35] Hexagon: Export ksyms defined in assembly files Richard Kuo
2011-08-31 13:41   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 13/35] Hexagon: Support dynamic module loading Richard Kuo
2011-08-31 13:41   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 14/35] Hexagon: Add signal functions Richard Kuo
2011-08-31 13:42   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 15/35] Hexagon: Add init_task and process functions Richard Kuo
2011-08-31 13:45   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 16/35] Hexagon: Add startup code Richard Kuo
2011-08-31 13:46   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 17/35] Hexagon: Add interrupts Richard Kuo
2011-08-31 13:50   ` Arnd Bergmann
2011-08-31 16:16     ` Linas Vepstas (Code Aurora)
2011-08-30 19:07 ` [patch v2 18/35] Hexagon: Add time and timer functions Richard Kuo
2011-08-31 14:04   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 19/35] Hexagon: Add ptrace support Richard Kuo
2011-08-31 14:07   ` Arnd Bergmann
2011-08-30 19:07 ` Richard Kuo [this message]
2011-08-31 14:08   ` [patch v2 20/35] Hexagon: Provide basic debugging and system trap support Arnd Bergmann
2011-08-30 19:07 ` [patch v2 21/35] Hexagon: Add SMP support Richard Kuo
2011-08-30 19:30   ` Joe Perches
2011-08-30 20:50     ` Richard Kuo
2011-08-31 15:00   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 22/35] Hexagon: Add locking types and functions Richard Kuo
2011-08-31 14:09   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 23/35] Hexagon: Add user access functions Richard Kuo
2011-08-31 14:10   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 24/35] Hexagon: Provide basic implementation and/or stubs for I/O routines Richard Kuo
2011-08-31 14:28   ` Arnd Bergmann
2011-08-31 14:47   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 25/35] Hexagon: Implement basic cache-flush support Richard Kuo
2011-08-31 14:49   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 26/35] Hexagon: Implement basic TLB management routines for Hexagon Richard Kuo
2011-08-31 14:49   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 27/35] Hexagon: Provide DMA implementation Richard Kuo
2011-08-31 14:51   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 28/35] Hexagon: Add ioremap support Richard Kuo
2011-08-31 14:53   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 29/35] Hexagon: Add page table header files & etc Richard Kuo
2011-08-31 14:57   ` Arnd Bergmann
2011-08-30 19:07 ` [patch v2 30/35] Hexagon: Add page-fault support Richard Kuo
2011-08-31 14:58   ` Arnd Bergmann
2011-08-30 19:08 ` [patch v2 31/35] Hexagon: kgdb support files Richard Kuo
2011-08-31 14:58   ` Arnd Bergmann
2011-08-30 19:08 ` [patch v2 32/35] Hexagon: Comet platform support Richard Kuo
2011-08-31 15:00   ` Arnd Bergmann
2011-08-30 19:08 ` [patch v2 33/35] Hexagon: Add configuration and makefiles for the Hexagon architecture Richard Kuo
2011-08-31 14:59   ` Arnd Bergmann
2011-08-30 19:08 ` [patch v2 34/35] Hexagon: Add basic stacktrace functionality for " Richard Kuo
2011-08-31 14:59   ` Arnd Bergmann
2011-08-30 19:08 ` [patch v2 35/35] Hexagon: Add self to MAINTAINERS Richard Kuo
2011-08-31 14:59   ` Arnd Bergmann
2011-08-30 20:18 ` [patch v2 00/35] Hexagon: Add support for Qualcomm Hexagon architecture Pekka Enberg
2011-08-30 20:48   ` Linas Vepstas (Code Aurora)
2011-08-31 15:08 ` Arnd Bergmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110830190801.615083995@codeaurora.org \
    --to=rkuo@codeaurora.org \
    --cc=linas@codeaurora.org \
    --cc=linux-hexagon@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).