aboutsummaryrefslogtreecommitdiff
path: root/sys/arm
diff options
context:
space:
mode:
authorOlivier Houchard <cognet@FreeBSD.org>2004-11-20 16:52:10 +0000
committerOlivier Houchard <cognet@FreeBSD.org>2004-11-20 16:52:10 +0000
commit3488a2f7d9f1089dd75344e177814a8641bb9d90 (patch)
tree65d0ea876a97c633458ca53e65120dde16a5cd48 /sys/arm
parent579d53f4cfba80bbe4ba86f7f49f68decca75d04 (diff)
downloadsrc-3488a2f7d9f1089dd75344e177814a8641bb9d90.tar.gz
src-3488a2f7d9f1089dd75344e177814a8641bb9d90.zip
Implement enough to be able to enter and leave DDB.
Notes
Notes: svn path=/head/; revision=137940
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/arm/undefined.c25
-rw-r--r--sys/arm/include/cpufunc.h1
-rw-r--r--sys/arm/include/db_machdep.h22
3 files changed, 43 insertions, 5 deletions
diff --git a/sys/arm/arm/undefined.c b/sys/arm/arm/undefined.c
index 6a62e9cc7677..0c8ea4188a35 100644
--- a/sys/arm/arm/undefined.c
+++ b/sys/arm/arm/undefined.c
@@ -60,6 +60,9 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#ifdef KDB
+#include <sys/kdb.h>
+#endif
#ifdef FAST_FPE
#include <sys/acct.h>
#endif
@@ -188,6 +191,7 @@ undefinedinstruction(trapframe_t *frame)
enable_interrupts(I32_bit);
frame->tf_pc -= INSN_SIZE;
+ atomic_add_int(&cnt.v_trap, 1);
fault_pc = frame->tf_pc;
@@ -251,13 +255,30 @@ undefinedinstruction(trapframe_t *frame)
fault_code) == 0)
break;
- if (uh == NULL) {
+ if (uh == NULL && (fault_code & FAULT_USER)) {
/* Fault has not been handled */
trapsignal(td, SIGILL, 0);
}
- if ((fault_code & FAULT_USER) == 0)
+ if ((fault_code & FAULT_USER) == 0) {
+ if (fault_instruction == KERNEL_BREAKPOINT) {
+#ifdef KDB
+ kdb_trap(0, 0, frame);
+#else
+ printf("No debugger in kernel.\n");
+#endif
+ frame->tf_pc += 4;
return;
+ } else {
+#ifdef KDB
+ printf("Undefined instruction in kernel.\n");
+ kdb_trap(0, 0, frame);
+#else
+ panic("Undefined instruction in kernel.\n");
+#endif
+ }
+
+ }
#ifdef FAST_FPE
/* Optimised exit code */
diff --git a/sys/arm/include/cpufunc.h b/sys/arm/include/cpufunc.h
index a558b393d2fa..d1b5786180f7 100644
--- a/sys/arm/include/cpufunc.h
+++ b/sys/arm/include/cpufunc.h
@@ -53,6 +53,7 @@
static __inline void
breakpoint(void)
{
+ __asm(".word 0xe7ffffff");
}
struct cpu_functions {
diff --git a/sys/arm/include/db_machdep.h b/sys/arm/include/db_machdep.h
index e0b255d5207a..f40daa537a09 100644
--- a/sys/arm/include/db_machdep.h
+++ b/sys/arm/include/db_machdep.h
@@ -47,7 +47,7 @@ typedef int db_expr_t;
#define BKPT_SET(inst) (BKPT_INST)
#define BKPT_SKIP do { \
- kdb_frame->tf_pc -= BKPT_SIZE; \
+ kdb_frame->tf_pc += BKPT_SIZE; \
} while (0)
#define db_clear_single_step(regs)
@@ -56,9 +56,25 @@ typedef int db_expr_t;
#define IS_BREAKPOINT_TRAP(type, code) (type == T_BREAKPOINT)
#define IS_WATCHPOINT_TRAP(type, code) (0)
+
#define inst_trap_return(ins) (0)
-#define inst_return(ins) (0)
-#define inst_call(ins) (0)
+/* ldmxx reg, {..., pc}
+ 01800000 stack mode
+ 000f0000 register
+ 0000ffff register list */
+/* mov pc, reg
+ 0000000f register */
+#define inst_return(ins) (((ins) & 0x0e108000) == 0x08108000 || \
+ ((ins) & 0x0ff0fff0) == 0x01a0f000)
+/* bl ...
+ 00ffffff offset>>2 */
+#define inst_call(ins) (((ins) & 0x0f000000) == 0x0b000000)
+/* b ...
+ 00ffffff offset>>2 */
+/* ldr pc, [pc, reg, lsl #2]
+ 0000000f register */
+
+
#define inst_load(ins) (0)
#define inst_store(ins) (0)