aboutsummaryrefslogtreecommitdiff
path: root/AT91SAM7S256/armdebug/Debugger/debug_stub.S
diff options
context:
space:
mode:
authorTC Wan2011-03-23 16:27:58 +0800
committerTC Wan2011-03-23 16:27:58 +0800
commit2f91494901e933524a0c6c117c0fa4c984835589 (patch)
treed4e7d352aadf6b9758d7f7b319a772b7bf300298 /AT91SAM7S256/armdebug/Debugger/debug_stub.S
parent0f08888a613ec00fb681e6da71152f99c27476f8 (diff)
parent9eaeb4f0b79cfb0015afba33a1f044530fcb7652 (diff)
Merge branch 'master' of ssh://svc.cs.usm.my/~/gitrepo-bare/armdebug
Diffstat (limited to 'AT91SAM7S256/armdebug/Debugger/debug_stub.S')
-rw-r--r--AT91SAM7S256/armdebug/Debugger/debug_stub.S150
1 files changed, 131 insertions, 19 deletions
diff --git a/AT91SAM7S256/armdebug/Debugger/debug_stub.S b/AT91SAM7S256/armdebug/Debugger/debug_stub.S
index 796de04..47ad2c3 100644
--- a/AT91SAM7S256/armdebug/Debugger/debug_stub.S
+++ b/AT91SAM7S256/armdebug/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,8 +124,18 @@
*
* 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
+ * there should be x digits, it does not follow this requirement. e.g., register index.
+ */
+
+
#define __ASSEMBLY__
#include "debug_stub.h"
#include "debug_macros.h"
@@ -210,7 +220,7 @@ debug_OkResponse:
/* The CmdIndexTable and CmdJumpTable must be kept in sync */
debug_cmdIndexTable:
- .byte 'g','G','p','P','m','M','c','s','k','z','Z','?',0
+ .byte 'g','G','p','P','m','M','c','s','k','z','Z','?','q','Q',0
/* Command Handlers
* On entry:
@@ -224,12 +234,14 @@ debug_cmdJumpTable:
.word _dbg__cmd_SetOneReg /* 'P' */
.word _dbg__cmd_ReadMem /* 'm' */
.word _dbg__cmd_WriteMem /* 'M' */
- .word _dbg__nop /* 'c' */
+ .word _dbg__cmd_Continue /* 'c' */
.word _dbg__nop /* 's' */
.word _dbg__nop /* 'k' */
.word _dbg__cmd_remove_breakpoint /* 'z' */
.word _dbg__cmd_insert_breakpoint /* 'Z' */
- .word _dbg__nop /* '?' */
+ .word _dbg__cmd_Status /* '?' */
+ .word _dbg__cmd_Query /* 'q' */
+ .word _dbg__nop /* 'Q' */
.word 0
/*
@@ -578,11 +590,18 @@ dbg__bkpt_offset_outofrange:
*
****************************************************************************/
dbg__bkpt_waitCMD:
+ /* We enter this code section when a Breakpoint Triggers */
_dbg_setmode TRUE /* Debug Mode = True */
+ _dbg_getstate r0
+ cmp r0, #DBG_CONFIGURED
+ blo dbg__bkpt_waitCMD_cont /* Not configured yet, don't send Breakpoint Signal Response */
+ bl _dbg__cmd_Status /* Send signal response to the GDB server */
+
dbg__bkpt_waitCMD_cont:
+ bl dbg__runloopTasks /* Execute housekeeping tasks while in ABRT mode */
bl dbg__getDebugMsg /* Read new message from Debugger, buflen in R0, 0 if none, -1 if error, msgbuf pointer in R1 */
cmp r0, #0
- beq _dbg__housekeeping /* No message yet, do housekeeping tasks */
+ beq dbg__bkpt_waitCMD_cont /* No message yet, do housekeeping tasks */
blt __dbg__procChecksumError /* Message invalid, checksum error? */
/* Message now has $<packet info>\0 */
mov r4, r1 /* Use R4 as buffer pointer */
@@ -594,29 +613,33 @@ dbg__bkpt_waitCMD_cont:
bl _dbg__cmdChar2Index /* Index in R0 */
mov r1, #CMDINDEX_OUTOFRANGE
teq r0, r1
+ bne _dbg__cmdExists /* Found valid command, execute it */
+_dbg_unknown_command:
+ bl _dbg__nop /* Command character not recognized, send empty response to GDB server */
+ b dbg__bkpt_waitCMD_cont
+
+#if 0
moveq r0, #MSG_UNKNOWNCMD /* Out of range, Command character not recognized */
beq _dbg__cmdError /* Send response to GDB server */
+#endif
_dbg__cmdExists:
mov r3, r0 /* put Command Handler Index in R3 */
mov r0, r4 /* R0 now contains Input Message Buffer Parameter Pointer (previously in R4) */
_dbg_jumpTableHandler debug_cmdJumpTable, r2, r3 /* Call Command Handler Routine, use R2 as jump address pointer */
- b _dbg__housekeeping
+ b dbg__bkpt_waitCMD_cont
__dbg__procChecksumError:
_dbg_outputRetransmitFlag
bl dbg__requestRetransmission /* Request message retransmission from GDB server */
cmp r0, #0
- beq _dbg__housekeeping /* Sending of retransmission request succeeded */
+ beq dbg__bkpt_waitCMD_cont /* Sending of retransmission request succeeded */
bl dbg__runloopTasks /* Service run loop tasks */
b __dbg__procChecksumError /* Retry retransmission */
_dbg__cmdError:
_dbg_outputMsgStatusErr
bl dbg__putDebugMsg /* Send error response to the GDB server */
-
-_dbg__housekeeping:
- bl dbg__runloopTasks /* Execute platform run loop tasks while in ABRT mode */
b dbg__bkpt_waitCMD_cont
/* _dbg__cmdChar2Index
@@ -724,6 +747,31 @@ __dbg__sendDebugMsgExit:
bl dbg__putDebugMsg /* Send error response to the GDB server */
ldmfd sp!, {pc}
+/* _dbg__cmd_Status
+ * Status Command Handler
+ * On entry:
+ * r0: parameter buffer (contents after '$' and '<cmdchar>')
+ * On exit:
+ * r0, r1, r2, r3: destroyed
+ */
+_dbg__cmd_Status:
+ stmfd sp!, {lr}
+ _dbg_outputMsgStatusSig 0x0 /* FIXME: Dummy Signal number */
+ b __dbg__sendDebugMsgExit
+
+/* _dbg__cmd_Query
+ * Query Command Handler
+ * On entry:
+ * r0: parameter buffer (contents after '$' and '<cmdchar>')
+ * [varied, see GDB General Packets query docs]
+ * http://sourceware.org/gdb/current/onlinedocs/gdb/General-Query-Packets.html
+ * On exit:
+ * r0, r1, r2, r3: destroyed
+ */
+_dbg__cmd_Query:
+ stmfd sp!, {lr}
+ _dbg_setstate DBG_CONFIGURED /* We have exchanged query messages with the GDB server */
+ b __dbg__procUnimplementedError /* FIXME: return an empty message to GDB (no modifiable settings) */
/* _dbg__cmd_GetOneReg
@@ -773,12 +821,16 @@ _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
* Get All Register Values Command Handler
- * Output Buffer returns register values in the order: User CPSR, R0, R1, R2, ..., R15
+ * Output Buffer returns register values in the order: User R0, R1, R2, ..., R15, CPSR
* On entry:
* r0: parameter buffer pointer (contents after '$' and '<cmdchar>')
* <NULL> (no parameters)
@@ -792,13 +844,18 @@ _dbg__cmd_GetAllRegs:
bne __dbg__procCmdParamError /* Unexpected input, report error */
_dbg_outputMsgValidResponse /* R0: address of output message buffer data pointer (after response prefix) */
- mov r3, #DBGSTACK_USERCPSR_OFFSET /* Output User CPSR Value first */
+
+ /* We must return R0-R15, then CPSR */
+ mov r3, #DBGSTACK_USERREG_INDEX /* Output User Register Values first */
1: mov r1, r3
bl _dbg_outputOneRegValue /* update output buffer */
add r3, r3, #1 /* increment index */
cmp r3, #0xF
ble 1b /* process all the registers */
+ mov r1, #DBGSTACK_USERCPSR_OFFSET /* Output User CPSR Value lasat */
+ bl _dbg_outputOneRegValue /* update output buffer */
+
_asciiz r0, r1
bl dbg__putDebugMsg /* Send response to the GDB server */
ldmfd sp!, {pc}
@@ -835,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
@@ -849,20 +910,26 @@ _dbg__proc_setRegister:
*
*/
_dbg__cmd_SetAllRegs:
-/* FIXME: Assumes that the registers are in the sequence CPSR, R0, R1, ... R15 -- May not be GDB ordering */
+/* FIXME: Assumes that the registers are in the sequence R0, R1, ... R15, CPSR -- May not be GDB ordering */
stmfd sp!, {lr}
bl __dbg__cmdParamLen /* R0: pointer to parameters in buffer */
teq r1, #CMD_REG_SETALL_PARAMLEN /* Check for correct length */
bne __dbg__procCmdParamError /* Unexpected input, report error */
- mov r2, #DBGSTACK_USERCPSR_INDEX /* R2: register index, starting with CPSR */
+ mov r2, #DBGSTACK_USERREG_INDEX /* R2: register index, starting with R0 */
1: bl ascii2word /* R0: value, R1: pointer to next char in buffer */
_setdbgregisterfromindex r2, r0, r3 /* Set Register contents in R0, using index in R2, and scratch register R3 */
+ mov r0, r1 /* setup R0 for next ascii2word call */
add r2, r2, #1 /* increment index */
+ cmp r2, #DBGSTACK_USERPC_INDEX
+ bls 1b
+
+_set_cpsr:
+ mov r2, #DBGSTACK_USERCPSR_INDEX /* R2: CPSR Index */
+ _setdbgregisterfromindex r2, r0, r3 /* Set Register contents in R0, using index in R2, and scratch register R3 */
ldrb r0, [r1]
teq r0, #0 /* Look for ASCIIZ character to terminate loop */
- mov r0, r1 /* setup R0 for next ascii2word call */
- bne 1b /* continue only if ASCIIZ not found */
- b __dbg__procCmdOk
+ beq __dbg__procCmdOk
+ bne __dbg__procCmdParamError /* Unexpected input, report error */
/* _dbg__nop
* NOP Command Handler (placeholder)
@@ -947,6 +1014,51 @@ _dbg__cmd_WriteMem:
bne 1b
b __dbg__procCmdOk
+/* _dbg__cmd_Continue
+ * Continue User Program Execution Command Handler
+ * On entry:
+ * r0: parameter buffer pointer (contents after '$' and '<cmdchar>')
+ * Optional: AA..AA
+ * On exit:
+ * r0, r1, r2: destroyed
+ * Note: This routine does not return to caller. Instead it switches
+ * operating mode to UNDEF and returns to previously active program
+ */
+_dbg__cmd_Continue:
+ bl __dbg__cmdParamLen
+ cmp r1, #CMD_REG_CONTINUE_PARAMLEN /* Check for correct parameter length */
+ beq _dbg__cmd_processContinue /* Continue from current PC */
+ cmp r1, #CMD_REG_CONTINUEFROM_PARAMLEN /* Check for correct parameter length */
+ bne __dbg__procCmdParamError /* Unexpected input, report error */
+ /* Continue from Specified Address */
+ bl ascii2word /* convert ASCII address location to Hex (in R0), R1 has address of next buffer char */
+ mov r2, #DBGSTACK_NEXTINSTR_INDEX /* The Next Instruction Pointer for Resume is in index 0 of the Debug Stack */
+ _setdbgregisterfromindex r2, r0, r1 /* Set Register contents in R0, using index in R2, and scratch register R1 */
+
+_dbg__cmd_processContinue:
+/* FIXME: Currently we assume that the trigger is a Manual Breakpoint, i.e., no need to
+ restore instructions to memory, and handle auto-breakpoints (needed to reenable the memory
+ breakpoint that was triggered) */
+
+@@@@@
+#if 0
+/* Not part of the GDB Remote Protocol spec. Messages are sent only when system halts, not when we resume */
+__dbg__sendOkBeforeResume:
+ _dbg_outputMsgStatusOk
+ bl dbg__putDebugMsg /* Send Ok response to the GDB server */
+ cmp r0, #0
+ beq _dbg__switch2undefmode /* Sending of retransmission request succeeded */
+ bl dbg__runloopTasks /* Service run loop tasks */
+ b __dbg__sendOkBeforeResume /* Retry retransmission */
+#endif
+
+_dbg__switch2undefmode:
+ msr cpsr_c, #(MODE_UND | CPSR_FIQ | CPSR_IRQ) /* Configure Undef Mode */
+ _dbg_setmode FALSE /* Debug Mode = False */
+ ldr lr, =resume_execution
+ mov pc, lr /* Exit via UNDEF mode */
+
+
/* _dbg__proc_brkpt_params
* Process Breakpoint Parameters
* On entry: