patch-2.4.4 linux/arch/cris/kernel/traps.c
Next file: linux/arch/cris/lib/checksum.S
Previous file: linux/arch/cris/kernel/sys_cris.c
Back to the patch index
Back to the overall index
- Lines: 138
- Date:
Fri Apr 6 10:42:55 2001
- Orig file:
v2.4.3/linux/arch/cris/kernel/traps.c
- Orig date:
Thu Feb 8 16:32:44 2001
diff -u --recursive --new-file v2.4.3/linux/arch/cris/kernel/traps.c linux/arch/cris/kernel/traps.c
@@ -1,16 +1,19 @@
-/* $Id: traps.c,v 1.3 2000/10/04 16:50:06 bjornw Exp $
+/* $Id: traps.c,v 1.8 2001/02/23 13:45:20 bjornw Exp $
*
* linux/arch/cris/traps.c
*
- * Etrax100 does not have any hardware traps, only IRQ's, which we setup
- * in irq.c instead. Here we just define the die_if_kernel Oops'er.
- *
- * Copyright (C) 2000 Axis Communications AB
+ * Here we handle the break vectors not used by the system call
+ * mechanism, as well as some general stack/register dumping
+ * things.
+ *
+ * Copyright (C) 2000,2001 Axis Communications AB
*
* Authors: Bjorn Wesen
+ * Orjan Friberg
*
*/
+#include <linux/config.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -35,7 +38,8 @@
#define MODULE_RANGE (8*1024*1024)
-void show_stack(unsigned long *sp)
+void
+show_stack(unsigned long *sp)
{
unsigned long *stack, addr, module_start, module_end;
int i;
@@ -86,7 +90,8 @@
#if 0
/* displays a short stack trace */
-int show_stack()
+int
+show_stack()
{
unsigned long *sp = (unsigned long *)rdusp();
int i;
@@ -97,7 +102,8 @@
}
#endif
-void show_registers(struct pt_regs * regs)
+void
+show_registers(struct pt_regs * regs)
{
unsigned long usp = rdusp();
@@ -145,9 +151,8 @@
#endif
}
-
-
-void die_if_kernel(const char * str, struct pt_regs * regs, long err)
+void
+die_if_kernel(const char * str, struct pt_regs * regs, long err)
{
if(user_mode(regs))
return;
@@ -160,8 +165,68 @@
do_exit(SIGSEGV);
}
-void __init trap_init(void)
+void __init
+trap_init(void)
{
-
}
+
+/* Use static variables instead of the stack for temporary storage. */
+static int saved_r0 = 0;
+static int saved_dccr = 0;
+
+asm ("
+ .global _gdb_handle_breakpoint
+ .global _do_sigtrap
+_gdb_handle_breakpoint:
+;;
+;; This handles a break instruction for entering a debug session.
+;;
+ move dccr,[_saved_dccr] ; Save dccr.
+ move.d r0,[_saved_r0] ; Save r0. "
+#ifdef CONFIG_KGDB
+"
+ move ccr,r0
+ btstq 8,r0 ; Test the U-flag.
+ bmi _ugdb_handle_breakpoint ; Go to user mode debugging.
+ nop ; Delay slot.
+ move.d [_saved_r0],r0 ; Restore r0.
+ move [_saved_dccr],dccr ; Restore dccr.
+ ba _kgdb_handle_breakpoint ; Go to kernel debugging.
+ nop ; Delay slot. "
+#endif
+"
+_ugdb_handle_breakpoint:
+;;
+;; Yes, we could do a 'push brp' here and let gdb adjust the pc once it
+;; starts talking to the target again, but this way we avoid a 'P' packet.
+;;
+ move brp,r0 ; Use r0 temporarily for calculation.
+ subq 2,r0 ; Set to address of previous instruction.
+ move r0,brp ; Restore new brp.
+ move.d [_saved_r0],r0 ; Restore r0.
+ move [_saved_dccr],dccr ; Restore dccr.
+
+_do_sigtrap:
+;;
+;; SIGTRAP the process that executed the break instruction.
+;; Make a frame that Rexit in entry.S expects.
+;;
+ push brp ; Push breakpoint return pointer.
+ push srp ; Push subroutine return pointer.
+ push dccr ; Push condition codes.
+ push mof ; Push multiply overflow reg.
+ di ; Need to disable irq's at this point.
+ subq 14*4,sp ; Make room for r0-r13.
+ movem r13,[sp] ; Push the r0-r13 registers.
+ push r10 ; Push orig_r10.
+ clear.d [sp=sp-4] ; Frametype - this is a normal stackframe.
+
+ movs.w -8192,r9 ; THREAD_SIZE == 8192
+ and.d sp,r9
+ move.d [r9+LTASK_PID],r10 ; current->pid as arg1.
+ moveq 5,r11 ; SIGTRAP as arg2.
+ jsr _sys_kill
+
+ jump _ret_from_intr ; Use the return routine for interrupts.
+");
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)