summaryrefslogtreecommitdiff
path: root/AT91SAM7S256/armdebug/Debugger/debug_comm.S
diff options
context:
space:
mode:
Diffstat (limited to 'AT91SAM7S256/armdebug/Debugger/debug_comm.S')
-rw-r--r--AT91SAM7S256/armdebug/Debugger/debug_comm.S254
1 files changed, 214 insertions, 40 deletions
diff --git a/AT91SAM7S256/armdebug/Debugger/debug_comm.S b/AT91SAM7S256/armdebug/Debugger/debug_comm.S
index 75f835e..b6f9cf5 100644
--- a/AT91SAM7S256/armdebug/Debugger/debug_comm.S
+++ b/AT91SAM7S256/armdebug/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
@@ -127,16 +130,30 @@ hex2char:
/* char2hex
* This routine accepts an ASCII character in R0(7:0) and returns the
- * equivalent byte sized hex value in R0(7:0)
+ * equivalent byte sized hex value in R0(7:0).
+ * It accepts lowercase and uppercase ASCII Hex char inputs.
+ * Invalid inputs return -1 as the value
*/
.global char2hex
char2hex:
- and r0, #BYTE0 /* make sure that input is sane */
- cmp r0, #'0'
+ and r1, r0, #BYTE0 /* make sure that input is sane */
+ mov r0, #-1 /* Initialize Return value to Error value */
+ cmp r1, #'0'
blo exit_char2hex
- cmp r0, #'F'
+ cmp r1, #'9'
+ bls perform_char2hex
+ cmp r1, #'A'
+ blo exit_char2hex
+ cmp r1, #'F'
+ bls perform_char2hex
+ cmp r1, #'a'
+ blo exit_char2hex
+ cmp r1, #'f'
bhi exit_char2hex
+ /* Validated Hex Char */
+perform_char2hex:
+ mov r0, r1 /* restore hex char */
_char2hex r0
exit_char2hex:
bx lr
@@ -187,7 +204,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
@@ -199,14 +217,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 */
- mov r2, r1, lsl #16 /* copy of input halfword value R1[15:0], shifted to MSH R2[31:16] */
- 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 */
-/* word2ascii
+/* 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_be
+ * Big Endian version of word2ascii conversion routine
* On entry:
* R0: ASCII buffer pointer
* R1[31:0]: Word value
@@ -218,22 +257,86 @@ 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 */
-_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}
+/* 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_le
+ ldmfd sp!, {r1,r2,r3, pc}
+
+
+/* ascii2hex_varlen_be
+ * Big Endian version of ascii2hex_varlen conversion routine
+ * (There is no Little Endian Version)
+ * On entry:
+ * R0: ASCII buffer pointer
+ * On exit:
+ * R0: Hex value
+ * R1: Address of next char slot in buffer
+ *
+ * This routine accepts an ASCII buffer pointer in R0,
+ * and returns the hex value in R0 for up to 8 Hex characters.
+ * Note: On return, R1 points to the ASCII buffer location after the hex value chars.
+ */
+ .global ascii2hex_varlen_be
+
+ascii2hex_varlen_be:
+ stmfd sp!, {r2,r3, lr}
+ mov r3, #CMD_REG_REGPARAMLEN /* Set max count to 8 (Max Register size) */
+ mov r1, r0 /* Use R1 as ASCII buffer pointer */
+ mov r2, #0 /* Initialize Cummulative Results */
+2: ldrb r0, [r1], #1 /* Load ASCII char for Hex Value */
+ bl char2hex /* on return, hex value in R0, -1 for error */
+ teq r0, #-1
+ beq _exit_ascii2hex_varlen
+ orr r2, r0, r2, lsl #4 /* combined byte value */
+ subs r3, r3, #1 /* Decrement Counter */
+ bne 2b
+_exit_ascii2hex_varlen:
+ mov r0, r2 /* Return results in R0 */
+ ldmfd sp!, {r2,r3, pc}
+
/* ascii2byte
* On entry:
@@ -251,11 +354,18 @@ _conv_byte2ascii:
.global ascii2byte
ascii2byte:
- stmfd sp!, {r2,r3, lr}
- mov r3, #2 /* Loop counter */
- b _conv_ascii2byte
-
-/* ascii2halfword
+ stmfd sp!, {r2, lr}
+ mov r1, r0 /* Use R1 as ASCII buffer pointer */
+ ldrb r0, [r1], #1 /* Load ASCII char for MSN */
+ bl char2hex /* on return, hex value in R0, -1 for error (ignored) */
+ mov r2, r0, lsl #4 /* Intermediate Results register */
+ ldrb r0, [r1], #1 /* Load ASCII char for LSN */
+ bl char2hex /* on return, hex value in R0, -1 for error (ignored) */
+ orr r0, r2, r0 /* combined byte value */
+ ldmfd sp!, {r2, pc}
+
+/* ascii2halfword_be
+ * Big Endian version of ascii2halfword conversion routine
* On entry:
* R0: ASCII buffer pointer
* On exit:
@@ -268,15 +378,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 ascii2halfword 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 ascii2word conversion routine
* On entry:
* R0: ASCII buffer pointer
* On exit:
@@ -289,28 +421,69 @@ 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 */
- 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 */
- subs r3, r3, #1
- bne 2b
- mov r0, r2 /* Copy it to R0 as return value */
-_exit_conv_ascii2byte:
+ beq _exit_conv_ascii2byte_be /* exit if NULL pointer in R0 */
+ mov r2, #0 /* Initialize Cummulative value */
+2: bl ascii2byte
+ orr r2, r0, r2, lsl #8 /* Merge current byte with cummulative value */
+ mov r0, r1 /* Copy next char pointer to R0 for next byte */
+ subs r3, r3, #1
+ bne 2b
+ mov r0, r2 /* Copy it to R0 as return value */
+
+_exit_conv_ascii2byte_be:
ldmfd sp!, {r2,r3, pc} /* return hex value in R0 */
+/* ascii2word_le
+ * Litle Endian version of ascii2word 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 */
+ push {r3} /* Need to keep couter for final value adjustment */
+ mov r2, #0 /* Initialize Cummulative value */
+2: bl ascii2byte
+ orr r2, r0, r2, ror #8 /* Merge current byte with cummulative value */
+ mov r0, r1 /* Copy next char pointer to R0 for next byte */
+ subs r3, r3, #1
+ bne 2b
+ /* Cummulative value done, need to rotate it into the correct position for return value */
+ pop {r3} /* retrieve counter */
+ rsb r3, r3, #5 /* 5 - count */
+ lsl r3, r3, #3 /* [(5-count) x 8] bits to rotate */
+ mov r0, r2, ror r3 /* Copy it to R0 as return value */
+
+_exit_conv_ascii2byte_le:
+ ldmfd sp!, {r2,r3, pc} /* return hex value in R0 */
+
@@ -596,12 +769,13 @@ _hasMsg2Copy:
strb r1, [r5, r2] /* Zero out '#' char for checksum calc later */
/* Need to account for Packet Acknowledgement */
- ldrb r0, [r5]
+1: ldrb r0, [r5]
teq r0, #MSGBUF_NAKCHAR /* Look for '-' */
beq exit_dbg__getMsgError /* FIXME: We can't handle retransmission, flag message error */
teq r0, #MSGBUF_ACKCHAR /* Look for '+' */
addeq r5, r5, #1 /* Adjust Buffer Start Pointer (excl '+') */
subeq r4, r4, #1 /* Adjust Message Length */
+ beq 1b /* Skip all Packet Acknowledgements */
#ifdef CHECK_GDBSTARTCHAR
/* Checked in dbg__bkpt_waitCMD */