From cb09675818731776be4129ba19fb90e299c130aa Mon Sep 17 00:00:00 2001 From: Tat-Chee Wan (USM) Date: Tue, 22 Mar 2011 14:34:30 +0800 Subject: rework message handling logic to take care of packet acknowledgements sent by gdb server --- Debugger/debug_comm.S | 51 +++++++++++++++++++++++++++++++++++++++++-------- Debugger/debug_macros.h | 19 +++++++++++++++--- Debugger/debug_stub.S | 46 ++++++++++++++++++++++++++++---------------- Debugger/debug_stub.h | 7 +++---- 4 files changed, 92 insertions(+), 31 deletions(-) diff --git a/Debugger/debug_comm.S b/Debugger/debug_comm.S index 6a7aa11..a43cc5f 100644 --- a/Debugger/debug_comm.S +++ b/Debugger/debug_comm.S @@ -578,14 +578,11 @@ _hasMsg2Copy: ldr r5, =debug_msgRxBufPtr ldr r5, [r5] /* Rx buffer Start Address */ -#ifdef CHECK_GDBSTARTCHAR - /* Checked in dbg__bkpt_waitCMD */ - ldrb r0, [r5] - teq r0, #MSGBUF_STARTCHAR /* Look for '$' */ - bne exit_dbg__getMsgError /* No start char '$', exit with error */ -#endif - - sub r2, r4, #MSGBUF_CHKSUMOFFSET /* Look for '#': Message Length - 3 = '#' offset */ + /* Note: Here we assume that we won't get a single ACK '+' or NAK '-' character message. + * If we do, it'll be flagged as an error + */ + subs r2, r4, #MSGBUF_CHKSUMOFFSET /* Look for '#': Message Length - 3 = '#' offset */ + blt exit_dbg__getMsgError /* Message Length is too short, exit with error */ ldrb r0, [r5, r2] teq r0, #MSGBUF_CHKSUMCHAR bne exit_dbg__getMsgError /* No checksum char '#', exit with error */ @@ -593,6 +590,21 @@ _hasMsg2Copy: mov r1, #0 strb r1, [r5, r2] /* Zero out '#' char for checksum calc later */ +/* Need to account for Packet Acknowledgement */ + 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 */ + +#ifdef CHECK_GDBSTARTCHAR + /* Checked in dbg__bkpt_waitCMD */ + ldrb r0, [r5] + teq r0, #MSGBUF_STARTCHAR /* Look for '$' */ + bne exit_dbg__getMsgError /* No start char '$', exit with error */ +#endif + add r0, r5, #1 /* Checksum packet data (excl '$') */ bl _msgbuf_checksum /* R2: length (excl '$'), R1: calculated checksum, R0: pointer to checksum in receive buffer */ mov r3, r1 /* Keep calculated checksum in R3 (R1 destroyed by ascii2byte) */ @@ -762,4 +774,27 @@ exit_dbg__putMsgError: exit_dbg__putDebugMsg: ldmfd sp!, {r4,r5,pc} + .global dbg__requestRetransmission +/* dbg__requestRetransmission + * Request for Retransmission due to received message Checksum error (Blocking) . + * On entry: + * No parameters (assume pointers were initialized previously using dbg__comm_init) + * On exit: + * r0: status (0: success, -1: error) + * r1: destroyed + * Note: A Retransmission is indicated by '-', which is prepended with the USB header and sent (without checksum) + */ +dbg__requestRetransmission: + stmfd sp!, {lr} + ldr r1, =debug_msgTxBufPtr /* R2: data structure base pointer */ + ldr r0, [r1] /* Tx buffer Start Address */ + str r0, [r1, #TXAPPENDPTR_OFFSET] /* Reset Tx buffer Append Pointer */ + + mov r1, #0 /* Initialize Segment Number = 0 (last segment) */ + mov r0, #1 /* Retransmission message length = 1 */ + bl _copy_msg_to_usbbuf /* R0: cummulative message length, R1: segment number */ + cmp r0, #1 /* Check if we managed to transmit the previous message */ + moveq r0, #0 /* R0: Exit status (success) */ + movne r0, #MSGBUF_MSGERROR /* R0: Exit status (error) */ + ldmfd sp!, {pc} diff --git a/Debugger/debug_macros.h b/Debugger/debug_macros.h index b7f4ea1..3fcc78c 100644 --- a/Debugger/debug_macros.h +++ b/Debugger/debug_macros.h @@ -121,6 +121,19 @@ bne 1b .endm +/* _dbg_outputRetransmitFlag + * Return Flag ('-') for Checksum Error (retransmission needed) + * On exit: + * R0: Pointer to Output Buffer ASCIIZ location + * R1: destroyed + * R2: destroyed + */ + .macro _dbg_outputRetransmitFlag + ldr r0, =debug_OutMsgBuf + ldr r1, =debug_RetransmitFlag /* ASCIIZ terminated */ + _dbg_stpcpy r0, r1, r2 + .endm + /* _dbg_outputMsgValidResponse * Return Message with valid response ('+$') * On exit: @@ -150,7 +163,7 @@ /* __dbg_outputErrMsg * Internal Routine called to generate error messages - * Return Message with Error ('-$ENN') status + * Return Message with Error ('+$ENN') status * On entry: * R1: error code * On exit: @@ -168,7 +181,7 @@ .endm /* _dbg_outputMsgStatusErr - * Return Message with Error ('-$ENN') status + * Return Message with Error ('+$ENN') status * On entry: * R0: error code * On exit: @@ -183,7 +196,7 @@ .endm /* _dbg_outputMsgStatusErrCode - * Return Message with Error ('-$ENN') status + * Return Message with Error ('+$ENN') status * On exit: * R0: Pointer to Output Buffer ASCIIZ location * R1: destroyed diff --git a/Debugger/debug_stub.S b/Debugger/debug_stub.S index f7d6fd7..796de04 100644 --- a/Debugger/debug_stub.S +++ b/Debugger/debug_stub.S @@ -193,11 +193,14 @@ debug_mode: .data .align 4 +debug_RetransmitFlag: + .byte '-',0 + debug_ValidResponsePrefix: .byte '+','$',0 debug_ErrorResponsePrefix: - .byte '-','$','E',0 + .byte '+','$','E',0 debug_SignalResponsePrefix: .byte '+','$','S',0 @@ -343,6 +346,7 @@ debug_armComplexCCTable: .extern dbg__hasDebugMsg /* Check for message from the communications link */ .extern dbg__getDebugMsg /* Read a message from the communications link */ .extern dbg__putDebugMsg /* Write a message to the communications link */ + .extern dbg__requestRetransmission /* Request Retransmission due to Checksum Error */ .extern dbg__runloopTasks /* Platform specific Run Loop processing */ @@ -384,13 +388,14 @@ debug_armComplexCCTable: * Breakpoint 02 State * Breakpoint 01 State * Single Step State __debugger_stack__ / __breakpoints_start__ - * User Mode R15 - * User Mode R14 + * Previous Mode R15 + * Previous Mode R14 + * Previous Mode R13 * ... * User Mode R02 * User Mode R01 * User Mode R00 - * User Mode CPSR (UNDEF SPSR) + * Previous Mode CPSR (UNDEF SPSR) * UNDEF Next Instr Addr __debugger_stack_bottom__ * [Low Memory Address] * @@ -578,8 +583,7 @@ dbg__bkpt_waitCMD_cont: 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 */ - movlt r0, #MSG_ERRCHKSUM /* Message invalid, checksum error? */ - blt _dbg__cmdError /* Send response to GDB server */ + blt __dbg__procChecksumError /* Message invalid, checksum error? */ /* Message now has $\0 */ mov r4, r1 /* Use R4 as buffer pointer */ ldrb r0, [r4], #1 /* Look for '$' */ @@ -597,16 +601,24 @@ _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__bkpt_waitCMD_cont + b _dbg__housekeeping + +__dbg__procChecksumError: + _dbg_outputRetransmitFlag + bl dbg__requestRetransmission /* Request message retransmission from GDB server */ + cmp r0, #0 + beq _dbg__housekeeping /* 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 * Convert Command Character to Jump Table Index * On entry: @@ -657,6 +669,16 @@ __dbg__procCmdOk: _dbg_outputMsgStatusOk b __dbg__sendDebugMsgExit +/* __dbg__procUnimplementedError + * Common subroutine exit stub to handle Unimplemented GDB Command Error + * DO NOT CALL THIS STUB DIRECTLY! It Assumes that the return address is in the stack. + * Note: GDB Remote Protocol specifies returning blank message ('+$') + * + */ +__dbg__procUnimplementedError: + _dbg_outputMsgValidResponse + b __dbg__sendDebugMsgExit + /* __dbg__procCmdParamError * Common subroutine exit stub to handle Command Parameter Error for Command Handlers * DO NOT CALL THIS STUB DIRECTLY! It Assumes that the return address is in the stack. @@ -693,14 +715,6 @@ __dbg__procBreakpointAddrError: mov r1, #MSG_UNKNOWNBRKPT b __dbg__procErrorMsg -/* __dbg__procUnimplementedError - * Common subroutine exit stub to handle Unimplemented GDB Command Error - * DO NOT CALL THIS STUB DIRECTLY! It Assumes that the return address is in the stack. - * - */ -__dbg__procUnimplementedError: - mov r1, #MSG_ERRIMPL - /* b __dbg__procErrorMsg */ __dbg__procErrorMsg: __dbg_outputErrMsg diff --git a/Debugger/debug_stub.h b/Debugger/debug_stub.h index 09750be..67f86c4 100644 --- a/Debugger/debug_stub.h +++ b/Debugger/debug_stub.h @@ -46,12 +46,12 @@ #define USB_GDBMSG_START 3 /* Offset into USB Telegram buffer */ -#define MSG_NUMSEGMENTS 3 /* For packet transfers */ +#define MSG_NUMSEGMENTS 3 /* For packet transfers */ #define MSG_SEGMENTSIZE (USB_BUFSIZE - USB_GDBMSG_START) /* 61 bytes per segment */ #define MSGBUF_SIZE (MSG_SEGMENTSIZE*MSG_NUMSEGMENTS) /* Debug Message Buffer Size, 61 x 3 = 183 chars = ~80 bytes of actual data */ #define MSGBUF_CHKSUMOFFSET 3 /* to be subtracted from message length */ -#define MSGBUF_IN_OVERHEADLEN 5 /* For calculating max message data length (include ASCIIZ char) */ -#define MSGBUF_OUT_OVERHEADLEN 6 /* For calculating max message data length (include ASCIIZ char) */ +#define MSGBUF_IN_OVERHEADLEN 5 /* For calculating max message data length (include ASCIIZ char) */ +#define MSGBUF_OUT_OVERHEADLEN 6 /* For calculating max message data length (include ASCIIZ char) */ #define MSGBUF_CTRLC 0x03 /* For Out of Band Signaling: not implemented yet */ #define MSGBUF_STARTCHAR '$' @@ -223,7 +223,6 @@ ENUM_END(dbg_state_t) ENUM_BEGIN ENUM_VALASSIGN(MSG_ERRIMPL, 0) /**< Stub (not implemented) Error. */ ENUM_VAL(MSG_ERRINLENGTH) /**< Message Write Length Error. */ -ENUM_VAL(MSG_ERRCHKSUM) /**< Checksum Error. */ ENUM_VAL(MSG_ERROUTLENGTH) /**< Message Read Length Error. */ ENUM_VAL(MSG_ERRFORMAT) /**< Message Format Error. */ ENUM_VAL(MSG_UNKNOWNCMD) /**< Unrecognized Command Error. */ -- cgit v1.2.3 From 39f866e05f703d64f621d77b135b7958d0ccf110 Mon Sep 17 00:00:00 2001 From: Tat-Chee Wan (USM) Date: Tue, 22 Mar 2011 15:27:49 +0800 Subject: clarified comments regarding usb and gdb message formats --- Debugger/debug_comm.S | 25 +++++++++++++++---------- Debugger/debug_stub.h | 4 ++-- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/Debugger/debug_comm.S b/Debugger/debug_comm.S index a43cc5f..75f835e 100644 --- a/Debugger/debug_comm.S +++ b/Debugger/debug_comm.S @@ -338,14 +338,16 @@ _exit_conv_ascii2byte: * Byte 3-N: Message data | GDB Command * * The GDB Command (of size M) has the following format: - * Offset 0: '$' - * Offset 1: GDB Command char - * Offset 2 - (M-4): Command packet info + * Offset 0: '+'/'-' Command Received Status (Optional) + * Offset 1/0: '$' + * Offset 2/1: GDB Command char + * Offset 3 - (M-4): Command packet info * Offset M-3: '#' * Offset M-2: MSB of Checksum * Offset M-1: LSB of Checksum * - * The maximum size of a GDB Command packet is MSGBUF_SIZE - 4 ('$', '#', 2 byte checksum) + * To be safe, we assume that the Command Received Status is always sent by the GDB server. Therefore, + * The maximum size of a GDB Command packet is MSGBUF_SIZE - 5 ('+'/'-', '$', '#', 2 byte checksum) * * GDB Response * ============ @@ -354,15 +356,18 @@ _exit_conv_ascii2byte: * Byte 2: Telegram Size (Len of USB Buffer - 3, max is MSG_SEGMENTSIZE) | * Byte 3-N: Message data | GDB Response * + * The GDB Retransmission Request has the following format: + * Offset 0: '-' Command Received Status + * * The GDB Response (of size M) has the following format: - * Offset 0: '+' or '-' Command Received Status + * Offset 0: '+' Command Received Status * Offset 1: '$' * Offset 2 - (M-4): Response packet info * Offset M-3: '#' * Offset M-2: MSB of Checksum * Offset M-1: LSB of Checksum * - * The maximum size of a GDB Response packet is MSGBUF_SIZE - 5 ('-'/'+', '$', '#', 2 byte checksum) + * The maximum size of a GDB Response packet is MSGBUF_SIZE - 5 ('+', '$', '#', 2 byte checksum) * * Note: The Telegram Size is the actual size of the Message Data portion * (i.e., excludes the three header bytes, includes the GDB Command/Response Packet checksum bytes @@ -723,7 +728,7 @@ _exit_copy_msg_to_usbbuf: * On exit: * r0: status (0: success, -1: error) * Note: GDB Message to be sent must be ASCIIZ terminated, does not include '#' and checksum - * Response packets start with '+'/'-' followed by '$' (2 bytes prefix) + * Response packets start with '+' followed by '$' (2 bytes prefix) */ dbg__putDebugMsg: stmfd sp!, {r4,r5,lr} @@ -731,8 +736,8 @@ dbg__putDebugMsg: ldr r5, =debug_msgTxBufPtr /* R5: data structure base pointer */ ldr r4, [r5] /* Tx buffer Start Address */ str r4, [r5, #TXAPPENDPTR_OFFSET] /* Reset Tx buffer Append Pointer */ - add r0, r4, #2 /* skip '+'/'-' and '$' */ - bl _msgbuf_checksum /* R2: length (excl '+'/'-' and '$'), R1: calculated checksum, R0: pointer to checksum in tx buffer */ + add r0, r4, #2 /* skip '+' and '$' */ + bl _msgbuf_checksum /* R2: length (excl '+' and '$'), R1: calculated checksum, R0: pointer to checksum in tx buffer */ #ifdef CHECK_TXLEN add r2, r2, #2 /* r2: returned length from _msgbuf_checksum, added with prefix length */ @@ -744,7 +749,7 @@ dbg__putDebugMsg: mov r3, #MSGBUF_CHKSUMCHAR strb r3, [r0, #-1] /* Insert '#' */ bl byte2ascii /* On return, R0 points to location after checksum bytes, R1 is original pointer to checksum */ - sub r4, r0, r4 /* R4 = Calculated total message length (incl '+'/'-' and '$', '#' and checksum bytes */ + sub r4, r0, r4 /* R4 = Calculated total message length (incl '+' and '$', '#' and checksum bytes */ cmp r4, #MSG_SEGMENTSIZE /* If total message length > MSG_SEGMENTSIZE */ mov r1, #0 /* Initialize Segment Number = 0 (last segment) first */ mov r0, #0 /* Initial cummulative message length */ diff --git a/Debugger/debug_stub.h b/Debugger/debug_stub.h index 67f86c4..e39fc8e 100644 --- a/Debugger/debug_stub.h +++ b/Debugger/debug_stub.h @@ -50,8 +50,8 @@ #define MSG_SEGMENTSIZE (USB_BUFSIZE - USB_GDBMSG_START) /* 61 bytes per segment */ #define MSGBUF_SIZE (MSG_SEGMENTSIZE*MSG_NUMSEGMENTS) /* Debug Message Buffer Size, 61 x 3 = 183 chars = ~80 bytes of actual data */ #define MSGBUF_CHKSUMOFFSET 3 /* to be subtracted from message length */ -#define MSGBUF_IN_OVERHEADLEN 5 /* For calculating max message data length (include ASCIIZ char) */ -#define MSGBUF_OUT_OVERHEADLEN 6 /* For calculating max message data length (include ASCIIZ char) */ +#define MSGBUF_IN_OVERHEADLEN 5 /* For calculating max message data length (exclude ASCIIZ char) */ +#define MSGBUF_OUT_OVERHEADLEN 5 /* For calculating max message data length (exclude ASCIIZ char) */ #define MSGBUF_CTRLC 0x03 /* For Out of Band Signaling: not implemented yet */ #define MSGBUF_STARTCHAR '$' -- cgit v1.2.3