summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTC Wan2010-11-30 15:36:42 +0800
committerTC Wan2010-12-01 13:40:09 +0800
commit6512a0b005edffc1e37b252e3a8262964ab2110a (patch)
tree0d6d971ae91951ded28e129c77150d767d97d75d
parente77f061f50a25ac3dcbfb245f4c61fde2e7505ed (diff)
added interrupt handler and prelim support for thumb instructions
Added Interrupt Handler routine for UNDEF exception. This should be integrated with the NXT Interrupt handlers. Updated debugger to have preliminary Thumb mode support.
-rw-r--r--AT91SAM7S256/Debugger/debug_stub.S80
-rw-r--r--AT91SAM7S256/Debugger/debug_stub.h15
-rw-r--r--AT91SAM7S256/Debugger/undef_handler.S71
3 files changed, 146 insertions, 20 deletions
diff --git a/AT91SAM7S256/Debugger/debug_stub.S b/AT91SAM7S256/Debugger/debug_stub.S
index 34bda59..98bc968 100644
--- a/AT91SAM7S256/Debugger/debug_stub.S
+++ b/AT91SAM7S256/Debugger/debug_stub.S
@@ -440,20 +440,42 @@ _dbg__flush_icache:
bx lr
- .global dbg__bkpt_handler
-/* dbg__bkpt_handler
- * GDB handle_exception() routine
+ .global dbg__thumb_bkpt_handler
+/* dbg__thumb_bkpt_handler
+ * GDB handle_exception() routine (Thumb Mode)
*/
-dbg__bkpt_handler:
+dbg__thumb_bkpt_handler:
+/* On entry, r0 contains breakpoint index value */
+ mov r4, #BKPT16_AUTO_BKPT
+ and r4, r0, #BKPT16_AUTO_BKPT /* keep AUTO flag value in r4 */
+ bic r0, r0, #BKPT16_AUTO_BKPT /* mask out AUTO flag */
+ _dbg_setcurrbkpt_index r0 /* keep current breakpoint index in memory */
+ ldr r1, =BKPT16_MANUAL_BKPT
+ teq r0, r1
+ beq _process_manual_breakpoint_thumb
+ ldr r1, =__breakpoints_num__
+ cmp r0, r1 /* Sanity check that index is in range */
+ bhs dbg__bkpt_offset_outofrange
+/* Valid index value found */
+ teq r4, #0 /* Check if AUTO flag set */
+ bne _process_auto_breakpoint
+/* else */
+ _dbg_setstate DBG_NORMAL_BKPT_THUMB
+ b _process_normal_breakpoint
+
+ .global dbg__arm_bkpt_handler
+/* dbg__arm_bkpt_handler
+ * GDB handle_exception() routine (ARM Mode)
+ */
+dbg__arm_bkpt_handler:
/* On entry, r0 contains breakpoint index value */
-/* FIXME: Currently we only deal with ARM mode, Thumb mode checks are missing! */
mov r4, #BKPT32_AUTO_BKPT
and r4, r0, #BKPT32_AUTO_BKPT /* keep AUTO flag value in r4 */
bic r0, r0, #BKPT32_AUTO_BKPT /* mask out AUTO flag */
_dbg_setcurrbkpt_index r0 /* keep current breakpoint index in memory */
ldr r1, =BKPT32_MANUAL_BKPT
teq r0, r1
- beq _process_manual_breakpoint
+ beq _process_manual_breakpoint_arm
ldr r1, =__breakpoints_num__
cmp r0, r1 /* Sanity check that index is in range */
bhs dbg__bkpt_offset_outofrange
@@ -461,11 +483,14 @@ dbg__bkpt_handler:
teq r4, #0 /* Check if AUTO flag set */
bne _process_auto_breakpoint
/* else */
+ _dbg_setstate DBG_NORMAL_BKPT_ARM
+/* b _process_normal_breakpoint */
+
+_process_normal_breakpoint:
bl _dbg__restore_breakpoints
bl _dbg__restore_singlestep
bl _dbg__clear_singlestep
bl _dbg__flush_icache
- _dbg_setstate DBG_NORMAL_BKPT_ARM
b dbg__bkpt_waitCMD
_process_auto_breakpoint:
@@ -479,7 +504,11 @@ _process_auto_breakpoint:
bl _dbg__clear_singlestep
b __dbg__resume_execution
-_process_manual_breakpoint:
+_process_manual_breakpoint_thumb:
+ _dbg_setstate DBG_MANUAL_BKPT_THUMB
+ b dbg__bkpt_waitCMD
+
+_process_manual_breakpoint_arm:
_dbg_setstate DBG_MANUAL_BKPT_ARM
/* b dbg__bkpt_waitCMD */
@@ -644,10 +673,13 @@ _dbg__procGetRegs:
* NOP Command Handler (placeholder)
* On entry:
* r0: parameter buffer (contents after '$' and '<cmdchar>')
- * r1: output message buffer
*/
_dbg__nop:
- bx lr /* Dummy, just return */
+ stmfd sp!, {lr}
+ mov r0, #MSG_ERRIMPL /* Stub, not implemented yet */
+ _dbg_outputMsgStatusErr
+ bl dbg__putDebugMsg /* Send error response to the GDB server */
+ ldmfd sp!, {pc}
/* dbg__cmd_install_breakpoint
@@ -1188,18 +1220,28 @@ void __single_step (void)
* the next instruction address (for inserting a Breakpoint).
*/
_dbg_next_instruction_addr:
-/* FIXME: Currently we only deal with ARM mode, Thumb mode checks are missing! */
/* We assume that any BKPT instructions in the code will be Manual Breakpoints,
* i.e., the Debugger does not leave stray Single Step / Auto / Normal breakpoints in memory
*/
- _dbg_getabortedinstr_addr r2 /* Retrieve aborted instruction address */
-1: ldr r0, [r2] /* Read actual instruction from memory */
- ldr r1, =(BKPT32_INSTR | BKPT32_MANUAL_BKPT) /* check for ARM Manual Breakpoint Instruction */
- teq r0, r1
- bne 2f /* Not Manual breakpoint */
- add r2, r2, #4 /* Is Manual Breakpoint, Skip to next ARM instruction */
- _dbg_setabortedinstr_addr r2 /* Update aborted instruction address */
- b 1b /* To protect against a sequence of Manual Breakpoint Instructions */
+
+ mov r2, #DBGSTACK_USERCPSR_INDEX /* Retrieve User CPSR */
+ _index2dbgstackaddr r2, r0 /* Calculate address pointer to relevant register, result in R0 */
+ ldr r0, [r0] /* Retrieve Register contents into R0 */
+ and r4, r0, #CPSR_THUMB /* store Thumb Mode status in R4 */
+
+ _dbg_getabortedinstr_addr r2 /* Retrieve aborted instruction address */
+1: teq r4, #0 /* Check if it is ARM or Thumb instruction */
+ ldrneh r0, [r2]
+ ldrne r1, =(BKPT16_INSTR | BKPT16_MANUAL_BKPT) /* check for Thumb Manual Breakpoint Instruction */
+ ldreq r0, [r2]
+ ldreq r1, =(BKPT32_INSTR | BKPT32_MANUAL_BKPT) /* check for ARM Manual Breakpoint Instruction */
+ teq r0, r1
+ bne 2f /* Not Manual breakpoint */
+ teq r4, #0 /* Check if it is ARM or Thumb instruction */
+ addne r2, r2, #2 /* Is Manual Breakpoint, Skip to next Thumb instruction */
+ addeq r2, r2, #4 /* Is Manual Breakpoint, Skip to next ARM instruction */
+ _dbg_setabortedinstr_addr r2 /* Update aborted instruction address */
+ b 1b /* To protect against a sequence of Manual Breakpoint Instructions */
/* Here, r0 contains the instruction which will be reexecuted when program resumes. We need to dissect it to see if
* it is a branch instruction.
diff --git a/AT91SAM7S256/Debugger/debug_stub.h b/AT91SAM7S256/Debugger/debug_stub.h
index 9a120e5..7849d56 100644
--- a/AT91SAM7S256/Debugger/debug_stub.h
+++ b/AT91SAM7S256/Debugger/debug_stub.h
@@ -39,6 +39,7 @@
#define MSGBUF_ERRCHAR 'E'
#define MSGBUF_SIGCHAR 'S'
#define MSGBUF_CPSRREG '!'
+#define MSGBUF_SETCHAR '='
#define MSGBUF_CMDINDEX_OUTOFRANGE_VAL -1
/*@}*/
@@ -75,6 +76,17 @@
#define HLFWRD1 0xFFFF0000 /* Halfword 0 word(31:16) */
/*@}*/
+/** @name CPSR Bit Definitions.
+ *
+ * Various Bit definitions for accessing the CPSR register.
+ */
+/*@{*/
+#define CPSR_THUMB 0x00000020
+#define CPSR_FIQ 0x00000040
+#define CPSR_IRQ 0x00000080
+
+/*@}*/
+
/** @name BKPT suppport constants
*
* ARM and Thumb Breakpoint Instructions.
@@ -111,7 +123,8 @@ ENUM_END(dbg_state_t)
* The enums must be consecutive, starting from 1
*/
ENUM_BEGIN
-ENUM_VALASSIGN(MSG_ERRCHKSUM, 1) /**< Checksum Error. */
+ENUM_VALASSIGN(MSG_ERRIMPL, 0) /**< Stub (not implemented) Error. */
+ENUM_VAL(MSG_ERRCHKSUM) /**< Checksum Error. */
ENUM_VAL(MSG_ERRFORMAT) /**< Message Format Error. */
ENUM_VAL(MSG_UNKNOWNCMD) /**< Unrecognized Command Error. */
ENUM_VAL(MSG_UNKNOWNPARAM) /**< Unrecognized Parameter Error. */
diff --git a/AT91SAM7S256/Debugger/undef_handler.S b/AT91SAM7S256/Debugger/undef_handler.S
new file mode 100644
index 0000000..c160179
--- /dev/null
+++ b/AT91SAM7S256/Debugger/undef_handler.S
@@ -0,0 +1,71 @@
+
+/* Copyright (C) 2007-2010 the NxOS developers
+ *
+ * Module Developed by: TC Wan <tcwan@cs.usm.my>
+ *
+ * See AUTHORS for a full list of the developers.
+ *
+ * Redistribution of this file is permitted under
+ * the terms of the GNU Public License (GPL) version 2.
+ */
+#define __ASSEMBLY__
+#include "debug_stub.h"
+
+#define MODE_SVC 0x13 /* Supervisor mode. */
+
+.text
+.code 32
+.align 0
+
+ .extern dbg__thumb_bkpt_handler
+ .extern dbg__arm_bkpt_handler
+
+ .global undef_handler
+
+undef_handler:
+/* Remote GDB Debugger relies on BKPT instruction being trapped here
+ In ARMv4t, it is an Illegal (Undefined) Instruction.
+ On triggering, lr (R14) contains the previous mode's pc (R15).
+ Based on example in Hohl, "ARM Assembly Language: Fundamentals and Techniques"
+ Chapter 11, Example 11.1.
+ Note: The handler is not AAPCS compliant (8 byte-alignment and stack, etc.)
+ */
+ /* We assume that the UNDEF stack has been setup previously
+ On entry, LR_undef points to one instruction past the UNDEF instruction
+ */
+ ldr sp, =__debugger_stack__
+ stmfd sp, {r0-r15}^ /* Save workspace, user mode's pc via 'S' flag */
+ sub sp, sp, #(4*16) /* Need to manually update SP(undef) */
+ mrs r1, spsr /* Copy SPSR to r0 */
+ sub r0, lr, #-4 /* LR points to instruction after UNDEF instruction */
+ stmfd sp!, {r0,r1} /* Save UNDEF instruction addr and previous mode's CPSR to stack */
+ tst r1, #CPSR_THUMB /* Check for Thumb Mode */
+ beq _is_arm /* Clear, so it's ARM mode */
+_is_thumb:
+ ldrh r0, [r0] /* load UNDEF instruction into r0 */
+ ldr r1, =BKPT16_ENUM_MASK /* Thumb BKPT enum mask */
+ bic r2, r0, r1 /* leave only opcode */
+ ldr r1, =BKPT16_INSTR /* check for Thumb Breakpoint Instruction */
+ teq r2, r1
+ bne default_undef_handler
+ ldr r1, =BKPT16_ENUM_MASK /* get Thumb BKPT Enum Mask */
+ and r0, r1, r0 /* Keep index value */
+ msr cpsr_c, #(MODE_SVC) /* Configure Supervisor Mode */
+ ldr lr, =dbg__thumb_bkpt_handler /* handle BKPT, BKPT index in r0 */
+ mov pc, lr /* Invoke Debugger State (Supervisor Mode) */
+_is_arm:
+ ldr r0, [r0] /* load UNDEF instruction into r0 */
+ ldr r1, =BKPT32_ENUM_MASK /* ARM BKPT enum mask */
+ bic r2, r0, r1 /* leave only opcode */
+ ldr r1, =BKPT32_INSTR /* check for ARM Breakpoint Instruction */
+ teq r2, r1
+ bne default_undef_handler
+ ldr r1, =BKPT32_ENUM_MASK /* get ARM BKPT Enum Mask */
+ and r0, r1, r0 /* Keep index value */
+ msr cpsr_c, #(MODE_SVC) /* Configure Supervisor Mode */
+ ldr lr, =dbg__arm_bkpt_handler /* handle BKPT, BKPT index in r0 */
+ mov pc, lr /* Invoke Debugger State (Supervisor Mode) */
+
+
+default_undef_handler:
+ b default_undef_handler /* Infinite loop */