aboutsummaryrefslogtreecommitdiff
path: root/AT91SAM7S256/armdebug
diff options
context:
space:
mode:
authorTC Wan2010-12-15 12:13:30 +0800
committerTC Wan2010-12-15 12:13:30 +0800
commit941a22c0adadb5098f8f33335a864fc7d0356bf5 (patch)
tree6b8749c994919153ac2c9372433fa4ed418444c4 /AT91SAM7S256/armdebug
parentdb39d3ab16c967fede452c6eda6f023ae53a1654 (diff)
parente0a7c25e589c3a7cc694eb28dfa687a0901f0757 (diff)
Merge branch 'master' of ssh://svc.cs.usm.my/~/gitrepo-bare/armdebug
Diffstat (limited to 'AT91SAM7S256/armdebug')
-rw-r--r--AT91SAM7S256/armdebug/Debugger/debug_stub.S199
-rw-r--r--AT91SAM7S256/armdebug/Debugger/debug_stub.h18
2 files changed, 210 insertions, 7 deletions
diff --git a/AT91SAM7S256/armdebug/Debugger/debug_stub.S b/AT91SAM7S256/armdebug/Debugger/debug_stub.S
index cc901ef..1ca4099 100644
--- a/AT91SAM7S256/armdebug/Debugger/debug_stub.S
+++ b/AT91SAM7S256/armdebug/Debugger/debug_stub.S
@@ -178,11 +178,12 @@ debug_cmdJumpTable:
/* ARM Instruction Decode Table
* .word IID, IBM, IHA (12 bytes)
*/
+
debug_armDecodeTable:
.word 0x0000f000, 0x0c00f000, _arm_data_instr_handler /* Data Processing instr with Rd = R15 */
.word 0x012fff10, 0x0ffffff0, _arm_bx_blx_handler /* BX or BLX */
.word 0x0410f000, 0x0410f000, _arm_ldr_pc_handler /* LDR with Rd = PC */
-/* .word 0x06000010, 0x0e000010, _arm_undef_handler */ /* Undefined instr: shouldn't occur, as it would've been trapped already */
+/* .word 0x06000010, 0x0e000010, _arm_undef_handler */ /* Undefined instr: shouldn't occur, as it would've been trapped already. See _dbg_next_instruction_addr */
.word 0x08108000, 0x0e108000, _arm_ldm_pc_handler /* LDM {pc} */
.word 0x0a000000, 0x0e000000, _arm_b_bl_handler /* B or BL. Note v4t does not have BLX instr */
.word 0x0c000000, 0x0c000000, _arm_coproc_swi_handler /* Coprocessor instr or SWI */
@@ -192,6 +193,7 @@ debug_armDecodeTable:
* .hword IID, IBM
* .word IHA (8 bytes)
*/
+
debug_thumbDecodeTable:
.hword 0x4700, 0xff07
.word _thumb_bx_blx_handler /* BX or BLX. Note: b7 (H1) is not matched in the mask */
@@ -206,6 +208,64 @@ debug_thumbDecodeTable:
.hword 0x0,0x0
.word 0x0 /* Null Entry */
+/* ARM Condition Code Mapping Table
+ * Converts Instruction encoding to SPSR Flags.
+ * b31 b30 b29 b28
+ * N Z C V
+ * Indexed according to Instruction Encoding order (pg 30, Table 6, ATMEL ARM7TDMI Data Sheet)
+ * Condition Code stored in MSN(set), LSN(clr) order
+ * Note1: 0x00 = AL. NV is deprecated, treat as AL
+ * Note2: 0xFF indicates that the condition checks needs to be handled separately (complex checks)
+ *
+ * EQ: Z set
+ * NE: Z clr
+ * HS/CS: C set
+ * LO/CC: C clr
+ * MI: N set
+ * PL: N clr
+ * VS: V set
+ * VC: V clr
+ * HI: C set AND Z clr
+ * LS: C clr AND Z set
+ */
+
+
+debug_armCondCodeTable:
+ /* EQ, NE, HS/CS, LO/CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL, NV */
+ .byte 0x40, 0x04, 0x20, 0x02, 0x80, 0x08, 0x10, 0x01, 0x24, 0x42, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00
+
+/* ARM Complex Condition Code Mapping Table
+ * Converts Instruction encoding to SPSR Flags.
+ * b31 b30 b29 b28
+ * N Z C V
+ * Indexed according to Instruction Encoding order (pg 30, Table 6, ATMEL ARM7TDMI Data Sheet)
+ * for GE, LT, GT and LE instructions only
+ * Condition Code stored in the following order:
+ * b7 b6 b5 b4 b3 b2 b1 b0
+ * - - - ANDOR - Z set AND N==V (bit set = 1)
+ * - - - ANDOR - Z clr OR N!=V (bit clr = 0)
+ *
+ * GE: N == V
+ * LT: N != V
+ * GT: Z clr AND (N == V)
+ * LE: Z set OR (N != V)
+ */
+
+#define COMPLEX_CONDCODE_START 0x0A
+#define COMPLEX_CONDCODE_NEQV_MASK 0x01
+#define COMPLEX_CONDCODE_AND_MASK 0x02
+#define COMPLEX_CONDCODE_ZSET_MASK 0x04
+#define COMPLEX_CONDCODE_ANDOR_MASK 0x10
+
+#define COMPLEX_CONDCODE_NFLAG 0x08
+#define COMPLEX_CONDCODE_ZFLAG 0x04
+#define COMPLEX_CONDCODE_CFLAG 0x02
+#define COMPLEX_CONDCODE_VFLAG 0x01
+
+
+debug_armComplexCCTable:
+ /* GE, LT, GT, LE */
+ .byte 0x01, 0x00, 0x15, 0x12
.code 32
.text
@@ -532,6 +592,10 @@ _dbg__procGetRegs:
ldmfd sp!, {pc}
+_dbg__procSetOneReg:
+_dbg__procSetRegs:
+ bx lr
+
/* _dbg__nop
* NOP Command Handler (placeholder)
* On entry:
@@ -1090,6 +1154,7 @@ _dbg_next_instruction_addr:
mov r2, #DBGSTACK_USERCPSR_INDEX /* Retrieve User CPSR */
_getdbgregisterfromindex r2, r0 /* Retrieve Register contents into R0 */
and r4, r0, #CPSR_THUMB /* store Thumb Mode status in R4 */
+ mov r5, r0, lsr #28 /* store CPSR condition flags in R5[3:0] */
_dbg_getabortedinstr_addr r2 /* Retrieve aborted instruction address */
1: teq r4, #0 /* Check if it is ARM or Thumb instruction */
@@ -1111,14 +1176,14 @@ _dbg_next_instruction_addr:
* If not, then the next instruction is the instruction following the current instruction.
*/
2:
- /* Use R5 to store candidate next instruction address */
+ /* Use R6 to store candidate next instruction address */
teq r4, #0 /* Check if it is ARM or Thumb instruction */
beq _next_instr_is_arm
_next_instr_is_thumb:
- add r5, r2, #2 /* set next Thumb instruction address */
+ add r6, r2, #2 /* set next Thumb instruction address */
/*_is_thumb_branch_instr r0 */ /* check if the current instruction is a branch instruction */
_next_instr_is_arm:
- add r5, r2, #4 /* Is ARM, set next ARM instruction address */
+ add r6, r2, #4 /* Is ARM, set next ARM instruction address */
@@@@@@@@@
bx lr
@@ -1131,6 +1196,132 @@ __dbg__resume_execution:
bl _dbg__flush_icache
b __dbg__resume_execution
+/****************************************************************************
+ *
+ * Instruction Decode Routines
+ *
+ ****************************************************************************/
+
+/* _dbg_check_arm_condcode
+ * Check ARM conditional execution code
+ * On entry:
+ * R0: instruction to be executed
+ * R5[3:0]: CPSR condition codes
+ * On exit:
+ * R0: will_execute (boolean)
+ */
+
+_dbg_check_arm_condcode:
+ stmfd sp!, {r6,lr} /* Use R6 as temporary will_execute variable */
+ mov r6, #TRUE
+ mov r0, r0, lsr #28 /* convert condition code to index (0-F) */
+ ldr r2, =debug_armCondCodeTable
+ ldrb r1, [r2, r0] /* Get condition code mask */
+/*
+ * The following check is unnecessary as it is covered by the set/clear checking algorithm
+ teq r1, #0
+ beq _dbg_check_arm_condcode_exit
+*/
+ teq r1, #0xFF
+ bne _dbg_check_bits_set
+
+
+/*
+ * Complex Checks:
+ *
+ * will_execute = TRUE [default condition]
+ * If (N == V) bit set
+ * will_execute = (N == V)
+ * else
+ * will_execute = (N != V)
+ *
+ * If (ANDOR bit) set
+ * z_cond = ((Z XOR Z set) == 0)
+ * If (AND bit set)
+ * will_execute = will_execute && z_cond
+ * else
+ * will_execute = will_execute || z_cond
+ */
+_dbg_cond_complex_check:
+ sub r1, r0, #COMPLEX_CONDCODE_START /* Convert complex condition code to new index (0-3) */
+ ldr r2, =debug_armComplexCCTable
+ ldrb r1, [r2, r1] /* Get complex condition code bitmap */
+
+ /* Use r2 to store N, r3 to store V */
+ tst r5, #COMPLEX_CONDCODE_NFLAG
+ moveq r2, #FALSE
+ movne r2, #TRUE /* r2 = N flag */
+ tst r5, #COMPLEX_CONDCODE_VFLAG
+ moveq r3, #FALSE
+ movne r3, #TRUE /* r3 = V flag */
+ eor r2, r2, r3 /* r2 = (N xor V): 0 if equal, 0xFF if not equal */
+ tst r1, #COMPLEX_CONDCODE_NEQV_MASK
+ mvnne r6, r1 /* If (N == V) bit set, will_execute (r6) = TRUE if (N == V) [r2 == 0] -> invert r2 */
+ moveq r6, r1 /* else (N == V) bit clr, will_execute (r6) = TRUE if (N != V) [r2 == 0xFF] */
+
+ tst r1, #COMPLEX_CONDCODE_ANDOR_MASK
+ beq _dbg_check_arm_condcode_exit /* No additional checks needed, exit */
+
+ /* Use r2 to store Z, r3 to store Z set */
+ and r2, r5, #COMPLEX_CONDCODE_ZFLAG /* r2 = Z flag */
+ and r3, r1, #COMPLEX_CONDCODE_ZSET_MASK /* r3 = Z set */
+ eors r2, r2, r3 /* r2 = (Z xor Z set): 0 if matched, non-zero if not matched */
+ moveq r2, #TRUE
+ movne r2, #FALSE /* r2 (z_cond): TRUE if matched, FALSE if not matched */
+
+ tst r1, #COMPLEX_CONDCODE_AND_MASK
+ andne r6, r6, r2 /* If AND bit set, will_execute = will_execute && z_cond */
+ orreq r6, r6, r2 /* else, will_execute = will_execute || z_cond */
+ b _dbg_check_arm_condcode_exit
+
+
+/*
+ * Simple Checks:
+ *
+ * will_execute = TRUE [default condition, equivalent to 0x00 (AL) ]
+ * If (SetBitMask is Non-Zero)
+ * will_execute = ((cond_code & SetBitMask) == SetBitMask)
+ * If will_execute && (ClearBitMask is Non-Zero)
+ * will_execute = will_execute && ((cond_code | ~ClearBitMask) == ~ClearBitMask)
+ */
+
+_dbg_check_bits_set:
+ movs r0, r1, lsr #4 /* R0: bits set */
+ beq _dbg_check_bits_clear
+ and r2, r5, r0 /* Check bits set IF bitmask non-zero */
+ teq r2, r0 /* ((cond_code & SetBitMask) == SetBitMask)? */
+ movne r6, #FALSE /* No, so will_execute = FALSE */
+ bne _dbg_check_arm_condcode_exit
+
+_dbg_check_bits_clear:
+ ands r1, r1, #NIBBLE0 /* R1: bits clear */
+ beq _dbg_check_arm_condcode_exit
+ mvn r1, r1 /* Invert Bitmask */
+ orr r2, r5, r1 /* Check bits clear IF bitmask non-zero */
+ teq r2, r1 /* ((cond_code | ~ClearBitMask) == ~ClearBitMask)? */
+ movne r6, #FALSE /* No, so will_execute = FALSE */
+ bne _dbg_check_arm_condcode_exit
+
+
+_dbg_check_arm_condcode_exit:
+ mov r0, r6 /* Update return value */
+ ldmfd sp!, {r6, pc}
+
+
+_arm_data_instr_handler: /* Data Processing instr with Rd = R15 */
+_arm_bx_blx_handler: /* BX or BLX */
+_arm_ldr_pc_handler: /* LDR with Rd = PC */
+_arm_ldm_pc_handler: /* LDM {pc} */
+_arm_b_bl_handler: /* B or BL. Note v4t does not have BLX instr */
+_arm_coproc_swi_handler: /* Coprocessor instr or SWI */
+ bx lr
+
+_thumb_bx_blx_handler: /* BX or BLX. Note: b7 (H1) is not matched in the mask */
+_thumb_poppc_handler: /* PUSH/POP, specifically POP {Rlist,PC} */
+_thumb_bcond_swi_handler: /* B<cond> or SWI */
+_thumb_b_handler: /* B */
+_thumb_long_b_handler: /* Long BL or BLX (4 bytes) Note: b11 (H) indicates 1st or 2nd instr */
+ bx lr
/****************************************************************************
diff --git a/AT91SAM7S256/armdebug/Debugger/debug_stub.h b/AT91SAM7S256/armdebug/Debugger/debug_stub.h
index 897c2b8..ada5858 100644
--- a/AT91SAM7S256/armdebug/Debugger/debug_stub.h
+++ b/AT91SAM7S256/armdebug/Debugger/debug_stub.h
@@ -29,7 +29,17 @@
* Debug Message Values
*/
/*@{*/
-#define MSGBUF_SIZE 256 /* Debug Message Buffer Size */
+
+/*
+ * USB Buffer Sizes: Ctrl Intr Iso Bulk
+ * Full Speed Device 64 64 1023 64
+ * High Speed Device 64 1024 1024 512
+ */
+
+#define USB_BUFSIZE 64
+#define USB_NUMDATAPKTS 3 /* For packet transfers */
+
+#define MSGBUF_SIZE (USB_BUFSIZE*USB_NUMDATAPKTS) /* Debug Message Buffer Size, 64 x 3 = 192 chars = ~90 bytes */
#define MSGBUF_STARTCHAR '$'
#define MSGBUF_ACKCHAR '+'
#define MSGBUF_NAKCHAR '-'
@@ -148,12 +158,14 @@ FUNCDEF void dbg__bkpt_handler(void);
/** dbg_breakpoint_arm.
* Equivalent to GDB breakpoint() routine for ARM code
*/
-FUNCDEF inline void dbg_breakpoint_arm(void) { asm volatile (".word BKPT32_INSTR | BKPT32_MANUAL_BKPT") }
+FUNCDEF void dbg_breakpoint_arm(void);
+inline void dbg_breakpoint_arm(void) { asm volatile (".word 0xE127FF7F" /* (BKPT32_INSTR | BKPT32_MANUAL_BKPT) */ ); }
/** dbg_breakpoint_thumb.
* Equivalent to GDB breakpoint() routine for Thumb code
*/
-FUNCDEF inline void dbg_breakpoint_thumb(void) { asm volatile (".hword BKPT16_INSTR | BKPT16_MANUAL_BKPT") }
+FUNCDEF void dbg_breakpoint_thumb(void);
+inline void dbg_breakpoint_thumb(void) { asm volatile (".hword 0xBE7F" /* (BKPT16_INSTR | BKPT16_MANUAL_BKPT) */); }
/*@}*/