From d0f53c2f890deef5138ec3d873e15a8cfc3ff0c9 Mon Sep 17 00:00:00 2001
From: Atle Nissestad <atle@nissestad.no>
Date: Sun, 16 Dec 2007 16:11:21 +0100
Subject: [PATCH] nios2: Added breakpoint exception handler

This is an initial attempt of enabling gdb/gdbserver application debug support
on the nios2 platform. To distinguish a gdb breakpoint from a system call, we put
an immediate value of 1 into the trap instruction. In the instruction set the immediate
value is undefined for trap, but apparently the instruction decoder recognizes the
instruction anyway. Thus we in the kernel exception handler can do an additional check
for imme=1 if a trap instruction is detected, and then run an appropriate handler.

Signed-off-by: Atle Nissestad <atle@nissestad.no>
---
 linux-2.6.x/arch/nios2nommu/kernel/entry.S |    7 +++++++
 linux-2.6.x/arch/nios2nommu/kernel/traps.c |   16 ++++++++++++++++
 2 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/linux-2.6.x/arch/nios2nommu/kernel/entry.S b/linux-2.6.x/arch/nios2nommu/kernel/entry.S
index 14f776a..e177492 100644
--- a/linux-2.6.x/arch/nios2nommu/kernel/entry.S
+++ b/linux-2.6.x/arch/nios2nommu/kernel/entry.S
@@ -125,6 +125,8 @@ software_exception:
 	ldw	r24,-4(ea)		// instruction that caused the exception
 	xorhi	r24,r24,0x003b		// upper half of trap opcode
 	xori	r24,r24,0x683a		// lower half of trap opcode
+	cmpeqi	r11,r24,0x40		/* Check for imm=0x01 => breakpoint */
+	bne	r11,r0,breakpoint
 	bne	r24,r0,instruction_trap	/* N - check for instruction trap */
 	cmpeqi	r11,r2,TRAP_ID_SYSCALL	/* ? Is this a syscall */
 	bne	r11,r0,system_call	/* Y - handle syscall */
@@ -142,6 +144,11 @@ app_debug:
 	stw	r24,(TASK_THREAD + THREAD_FLAGS)(r1)	/* save thread_info->task->thread.flags */
 	br	restore_all
 
+breakpoint:
+	mov  r4,sp
+	call breakpoint_c
+	br restore_all
+
 /*
  * This is the generic interrupt handler (for all hardware interrupt
  * sources). It figures out the vector number and calls the appropriate
diff --git a/linux-2.6.x/arch/nios2nommu/kernel/traps.c b/linux-2.6.x/arch/nios2nommu/kernel/traps.c
index 14b7e4c..6c55c04 100644
--- a/linux-2.6.x/arch/nios2nommu/kernel/traps.c
+++ b/linux-2.6.x/arch/nios2nommu/kernel/traps.c
@@ -176,3 +176,19 @@ void trap_init(void)
 	printk("trap_init reached\n");
 #endif
 }
+
+/* Breakpoint handler */
+asmlinkage void breakpoint_c(struct pt_regs *fp)
+{
+	siginfo_t info;
+
+/*
+	printk(KERN_DEBUG "Breakpoint detected, instr=0x%08x ea=0x%08x ra=0x%08x sp=0x%08x\n", *(u32*)((fp->ea)-4), *(u32*)(fp->ea), *(u32*)(fp->ra), *(u32*)(fp->sp));
+*/
+
+	info.si_code = TRAP_BRKPT;
+	info.si_signo = SIGTRAP;
+	info.si_errno = 0;
+
+	force_sig_info(info.si_signo, &info, current);
+}
-- 
1.5.3.3

