summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTat-Chee Wan (USM)2011-03-23 13:37:07 +0800
committerTat-Chee Wan (USM)2011-03-23 13:37:07 +0800
commitbbdd5f023b53949d606379c606fe55ace998102e (patch)
tree1adfe26eabbc924667e7537c5b4fb91ddd45f33d
parent2a91d2fc501a9d84753586a900a01be59b6da24d (diff)
work in progress
-rw-r--r--Debugger/debug_comm.S175
-rw-r--r--Debugger/debug_stub.S19
2 files changed, 158 insertions, 36 deletions
diff --git a/Debugger/debug_comm.S b/Debugger/debug_comm.S
index 54c16a6..1a5dd07 100644
--- a/Debugger/debug_comm.S
+++ b/Debugger/debug_comm.S
@@ -111,6 +111,9 @@ hex2char_lut:
/* Utility Routines
+ * GDB requires command parameters to be specified as Big Endian values.
+ * However, the read/write register command expect the register contents to be specified in target byte order.
+ * Hence we need both versions of multibyte conversion routines for word sized values.
*/
/* hex2char
@@ -192,7 +195,8 @@ byte2ascii:
bl byte2ascii_cont
ldmfd sp!, {r1, pc} /* return original string pointer in R1 */
-/* halfword2ascii
+/* halfword2ascii_be
+ * Big Endian version of halfword2ascii conversion routine
* On entry:
* R0: ASCII buffer pointer
* R1[15:0]: Halfword value
@@ -204,16 +208,35 @@ byte2ascii:
* and stores the ASCII equivalent halfword value in the buffer pointed to by R0.
* Note: On return, R0 points to the next empty char slot in buffer
*/
- .global halfword2ascii
-halfword2ascii:
+ .global halfword2ascii_be
+halfword2ascii_be:
stmfd sp!, {r0,r2,r3, lr} /* Keep ASCII buffer pointer */
-#ifdef __BIG_ENDIAN__
- mov r2, r1, lsl #16 /* copy of input halfword value R1[15:0], shifted to MSH R2[31:16] */
-#endif
- mov r3, #2 /* Loop Counter */
- b _conv_byte2ascii /* goto Byte conversion loop */
+ mov r3, #2 /* Loop Counter */
+ mov r2, r1, lsl #16 /* copy of input halfword value R1[15:0], shifted to MSH R2[31:16] */
+ b _conv_byte2ascii_be /* goto Byte conversion loop */
+
+/* halfword2ascii_le
+ * Little Endian version of halfword2ascii conversion routine
+ * On entry:
+ * R0: ASCII buffer pointer
+ * R1[15:0]: Halfword value
+ * On exit:
+ * R0: Address of next empty char slot in buffer
+ * R1: Original Address of Buffer
+ *
+ * This routine accepts an ASCII buffer pointer in R0 and a halfword value in R1,
+ * and stores the ASCII equivalent halfword value in the buffer pointed to by R0.
+ * Note: On return, R0 points to the next empty char slot in buffer
+ */
+ .global halfword2ascii_le
+halfword2ascii_le:
+ stmfd sp!, {r0,r2,r3, lr} /* Keep ASCII buffer pointer */
+ mov r3, #2 /* Loop Counter */
+ b _conv_byte2ascii_le /* goto Byte conversion loop */
+
-/* word2ascii
+/* word2ascii_be
+ * Big Endian version of word2ascii conversion routine
* On entry:
* R0: ASCII buffer pointer
* R1[31:0]: Word value
@@ -225,36 +248,54 @@ halfword2ascii:
* and stores the ASCII equivalent word value in the buffer pointed to by R0.
* Note: On return, R0 points to the next empty char slot in buffer
*/
- .global word2ascii
-word2ascii:
+ .global word2ascii_be
+word2ascii_be:
stmfd sp!, {r0,r2,r3, lr} /* Keep ASCII buffer pointer */
mov r2, r1 /* copy of input word value R1[31:0] */
mov r3, #4 /* Loop Counter */
/* Fall through to byte coversion loop */
-#ifdef __BIG_ENDIAN__
-/* Rotate then convert */
-_conv_byte2ascii:
+
+/* Big Endian Multibyte Convert: Rotate then convert */
+_conv_byte2ascii_be:
ror r2, r2, #24 /* Rotate MSB R2[31:24] into LSB position R2[7:0] */
and r1, r2, #BYTE0 /* Copy byte value in R2[7:0] into R1 */
bl byte2ascii_cont /* R0: next ASCII buffer location pointer, R1: destroyed */
subs r3, r3, #1
- bne _conv_byte2ascii
+ bne _conv_byte2ascii_be
ldmfd sp!, {r1,r2,r3, pc}
-#else /* __LITTLE_ENDIAN__ */
-/* Convert then rotate */
-_conv_byte2ascii:
+/* word2ascii_le
+ * Little Endian version of word2ascii conversion routine
+ * On entry:
+ * R0: ASCII buffer pointer
+ * R1[31:0]: Word value
+ * On exit:
+ * R0: Address of next empty char slot in buffer
+ * R1: Original Address of Buffer
+ *
+ * This routine accepts an ASCII buffer pointer in R0 and a word value in R1,
+ * and stores the ASCII equivalent word value in the buffer pointed to by R0.
+ * Note: On return, R0 points to the next empty char slot in buffer
+ */
+ .global word2ascii_le
+word2ascii_le:
+ stmfd sp!, {r0,r2,r3, lr} /* Keep ASCII buffer pointer */
+ mov r2, r1 /* copy of input word value R1[31:0] */
+ mov r3, #4 /* Loop Counter */
+
+ /* Fall through to byte coversion loop */
+
+/* Little Endian Multibyte Convert: Convert then rotate */
+_conv_byte2ascii_le:
and r1, r2, #BYTE0 /* Copy byte value in R2[7:0] into R1 */
bl byte2ascii_cont /* R0: next ASCII buffer location pointer, R1: destroyed */
ror r2, r2, #8 /* Rotate LSB+1 R2[15:8] into LSB position R2[7:0] */
subs r3, r3, #1
- bne _conv_byte2ascii
+ bne _conv_byte2ascii_le
ldmfd sp!, {r1,r2,r3, pc}
-#endif
-
/* ascii2byte
* On entry:
* R0: ASCII buffer pointer
@@ -275,7 +316,8 @@ ascii2byte:
mov r3, #2 /* Loop counter */
b _conv_ascii2byte
-/* ascii2halfword
+/* ascii2halfword_be
+ * Big Endian version of word2ascii conversion routine
* On entry:
* R0: ASCII buffer pointer
* On exit:
@@ -288,15 +330,37 @@ ascii2byte:
* WARNING: This routine assumes that the input buffer was sanitized and contains valid Hex chars,
* otherwise it will return invalid results.
*/
- .global ascii2halfword
+ .global ascii2halfword_be
-ascii2halfword:
+ascii2halfword_be:
stmfd sp!, {r2,r3, lr}
- mov r3, #4 /* Loop counter */
- b _conv_ascii2byte
+ mov r3, #2 /* Loop counter */
+ b _conv_ascii2byte_be
+
+/* ascii2halfword_le
+ * Little Endian version of word2ascii conversion routine
+ * On entry:
+ * R0: ASCII buffer pointer
+ * On exit:
+ * R0[15:0]: Halfword value
+ * R1: Address of next char slot in buffer
+ *
+ * This routine accepts an ASCII buffer pointer in R0,
+ * and returns the Halfword value in R0[15:0].
+ * Note: On return, R1 points to the ASCII buffer location after the current 4 chars.
+ * WARNING: This routine assumes that the input buffer was sanitized and contains valid Hex chars,
+ * otherwise it will return invalid results.
+ */
+ .global ascii2halfword_le
+
+ascii2halfword_le:
+ stmfd sp!, {r2,r3, lr}
+ mov r3, #2 /* Loop counter */
+ b _conv_ascii2byte_le
-/* ascii2word
+/* ascii2word_be
+ * Big Endian version of word2ascii conversion routine
* On entry:
* R0: ASCII buffer pointer
* On exit:
@@ -309,28 +373,73 @@ ascii2halfword:
* WARNING: This routine assumes that the input buffer was sanitized and contains valid Hex chars,
* otherwise it will return invalid results.
*/
- .global ascii2word
+ .global ascii2word_be
-ascii2word:
+ascii2word_be:
stmfd sp!, {r2,r3, lr}
- mov r3, #8 /* Loop counter */
+ mov r3, #4 /* Loop counter */
/* Fall through to byte coversion loop */
-_conv_ascii2byte:
+_conv_ascii2byte_be:
teq r0, #0
- beq _exit_conv_ascii2byte /* exit if NULL pointer in R0 */
+ beq _exit_conv_ascii2byte_be /* exit if NULL pointer in R0 */
mov r1, r0 /* Copy of ASCII buffer pointer */
mov r2, #0 /* Initialize results */
2: ldrb r0, [r1], #1 /* Load ASCII char */
bl char2hex /* on return, hex value in R0 */
+ orr r2, r0, r2, lsl #4 /* merge Nibble into results */
+ ldrb r0, [r1], #1 /* Load ASCII char */
+ bl char2hex /* on return, hex value in R0 */
orr r2, r0, r2, lsl #4 /* merge Nibble into results */
subs r3, r3, #1
bne 2b
mov r0, r2 /* Copy it to R0 as return value */
-_exit_conv_ascii2byte:
+_exit_conv_ascii2byte_be:
ldmfd sp!, {r2,r3, pc} /* return hex value in R0 */
+/* ascii2word_le
+ * Litle Endian version of word2ascii conversion routine
+ * On entry:
+ * R0: ASCII buffer pointer
+ * On exit:
+ * R0[31:0]: Word value
+ * R1: Address of next char slot in buffer
+ *
+ * This routine accepts an ASCII buffer pointer in R0,
+ * and returns the word value in R0[31:0].
+ * Note: On return, R1 points to the ASCII buffer location after the current 8 chars.
+ * WARNING: This routine assumes that the input buffer was sanitized and contains valid Hex chars,
+ * otherwise it will return invalid results.
+ */
+ .global ascii2word_le
+
+ascii2word_le:
+ stmfd sp!, {r2,r3, lr}
+ mov r3, #4 /* Loop counter */
+
+ /* Fall through to byte coversion loop */
+
+_conv_ascii2byte_le:
+ teq r0, #0
+ beq _exit_conv_ascii2byte_le /* exit if NULL pointer in R0 */
+ mov r1, r0 /* Copy of ASCII buffer pointer */
+ mov r2, #0 /* Initialize results */
+2: ldrb r0, [r1], #1 /* Load ASCII char */
+ bl char2hex /* on return, hex value in R0 */
+ orr r2, r0, r2, rol #4 /* merge Nibble into results */
+ ldrb r0, [r1], #1 /* Load ASCII char */
+ bl char2hex /* on return, hex value in R0 */
+@@@@@ not correct!
+
+ orr r2, r0, r2, rol #4 /* merge Nibble into results */
+ subs r3, r3, #1
+ rorne r2, r2, #16 /* Rotate R
+ bne 2b
+ mov r0, r2 /* Copy it to R0 as return value */
+_exit_conv_ascii2byte_le:
+ ldmfd sp!, {r2,r3, pc} /* return hex value in R0 */
+
diff --git a/Debugger/debug_stub.S b/Debugger/debug_stub.S
index 7c54810..47ad2c3 100644
--- a/Debugger/debug_stub.S
+++ b/Debugger/debug_stub.S
@@ -68,7 +68,7 @@
* GrrrrRRRR.. set the value of the CPU registers OK or ENN
* where register values are given as
* 32-bit hex values in the sequence:
- * User CPSR, R0, R1, ..., R15
+ * User R0, R1, ..., R15, CPSR
* px get the value of one register (x) hex data or ENN
* Px=rrrr set the value of one register (x) to OK or ENN
* 32-bit hex value rrrr.
@@ -124,6 +124,11 @@
*
* Note: ARMDEBUG can only implement Memory Breakpoints t=0. Hardware breakpoints requires a JTAG debugger.
* Currently, watchpoints are not implemented as they require hardware support as well (need verification).
+ *
+ * GDB requires command parameters to be specified as Big Endian values.
+ * However, the read/write register command expect the register contents to be specified in target byte order.
+ * The default target byte order is Little Endian for the AT91SAM7xxx processor in the NXT.
+ * If Big Endian target byte order is required, the __BIG_ENDIAN__ preprocessor label should be defined.
*/
/* FIXME: The Hex value arguments passed by GDB does not have fixed lengths! Although the standard says
@@ -816,7 +821,11 @@ _dbg_outputOneRegValue:
stmfd sp!, {lr}
add r2, r1, #DBGSTACK_USERREG_INDEX /* Convert register index to Debug Stack index */
_getdbgregisterfromindex r2, r1 /* Retrieve Register contents into R1 */
- bl word2ascii /* Convert and put hex chars into Output Message Buffer */
+#ifdef __BIG_ENDIAN__
+ bl word2ascii_be /* Convert and put hex chars into Output Message Buffer */
+#else
+ bl word2ascii_le /* Convert and put hex chars into Output Message Buffer */
+#endif
ldmfd sp!, {pc}
/* _dbg__cmd_GetAllRegs
@@ -883,7 +892,11 @@ _dbg__cmd_SetOneReg:
_dbg__proc_setRegister:
add r2, r0, #DBGSTACK_USERREG_INDEX /* Convert register index to Debug Stack index, keep in R2 */
mov r0, r3 /* Retrieve parameter buffer pointer */
- bl ascii2word
+#ifdef __BIG_ENDIAN__
+ bl ascii2word_be
+#else
+ bl ascii2word_le
+#endif
_setdbgregisterfromindex r2, r0, r3 /* Set Register contents in R0, using index in R2, and scratch register R3 */
b __dbg__procCmdOk