aboutsummaryrefslogtreecommitdiff
path: root/Debugger
diff options
context:
space:
mode:
Diffstat (limited to 'Debugger')
-rw-r--r--Debugger/_c_arm_macros.h88
-rw-r--r--Debugger/abort_handler.S106
-rw-r--r--Debugger/debug_comm.S550
-rw-r--r--Debugger/debug_hexutils.S459
-rw-r--r--Debugger/debug_internals.h395
-rw-r--r--Debugger/debug_macros.h463
-rw-r--r--Debugger/debug_opcodes.S1499
-rw-r--r--Debugger/debug_runlooptasks.S411
-rw-r--r--Debugger/debug_runlooptasks.h81
-rw-r--r--Debugger/debug_stack.ld15
-rw-r--r--Debugger/debug_stub.S1579
-rw-r--r--Debugger/debug_stub.h165
-rw-r--r--Debugger/debug_test.S161
-rw-r--r--Debugger/debug_test.h50
-rw-r--r--Debugger/undef_handler.S144
15 files changed, 0 insertions, 6166 deletions
diff --git a/Debugger/_c_arm_macros.h b/Debugger/_c_arm_macros.h
deleted file mode 100644
index 025542e..0000000
--- a/Debugger/_c_arm_macros.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/** @file _c_arm_macros.h
- * @brief Define macros to support shared C and ASM headers
- *
- */
-
-/* Copyright (C) 2010 the NxOS developers
- *
- * Module Developed by: TC Wan <tcwan@cs.usm.my>
- *
- * Thanks to Bartli (forum post @ embdev.net ARM programming with GCC/GNU tools forum)
- *
- * See AUTHORS for a full list of the developers.
- *
- * See COPYING for redistribution license
- *
- */
-
-#ifndef __C_ARM_MACROS__
-#define __C_ARM_MACROS__
-
-
-#ifdef __ASSEMBLY__
-
-#define NULL 0x0
-#define FALSE 0
-#define TRUE ~FALSE
-
-#define TYPEDEF @
-#define FUNCDEF @
-
- .set last_enum_value, 0
- .macro enum_val name
- .equiv \name, last_enum_value
- .set last_enum_value, last_enum_value + 1
- .endm
-
-#define ENUM_BEGIN .set last_enum_value, 0
-
-#define ENUM_VAL(name) enum_val name
-#define ENUM_VALASSIGN(name, value) \
- .set last_enum_value, value ;\
- enum_val name
-#define ENUM_END(enum_name)
-
-#else /* C Defines */
-/** Macro to control typedef generation
- *
- */
-#define TYPEDEF typedef
-
-/** Macro to control extern generation
- *
- */
-#ifndef FUNCDEF
-#define FUNCDEF extern
-#endif
-
-/** Macro to control typedef enum generation
- *
- */
-#define ENUM_BEGIN typedef enum {
-
-/** Macro to specify enum instance (auto value assignment)
- *
- */
-#define ENUM_VAL(name) name,
-
-/** Macro to control enum specification and value assignment
-*
-*/
-#define ENUM_VALASSIGN(name, value) name = value,
-
-/** Macro to control enum named type generation
- *
- */
-#define ENUM_END(enum_name) } enum_name;
-
-#endif
-
-/* Example of how to use the ENUM definition macros
-ENUM_BEGIN
-ENUM_VAL(INIT)
-ENUM_VAL(RESET)
-ENUM_VAL(CONFIGURED)
-ENUM_END(enum_label)
-*/
-
-#endif /* __C_ARM_MACROS__ */
diff --git a/Debugger/abort_handler.S b/Debugger/abort_handler.S
deleted file mode 100644
index dab25d1..0000000
--- a/Debugger/abort_handler.S
+++ /dev/null
@@ -1,106 +0,0 @@
-
-/* Copyright (C) 2007-2011 the NxOS developers
- *
- * Module Developed by: TC Wan <tcwan@cs.usm.my>
- *
- * See AUTHORS for a full list of the developers.
- *
- * Redistribution of this file is permitted under
- * the terms of the GNU Public License (GPL) version 2.
- */
-#define __ASSEMBLY__
-#include "debug_stub.h"
-#include "debug_internals.h"
-
-#define PREFETCH_OFFSET 4
-#define DATA_OFFSET 8
-
-/* Trap Abort Exceptions.
- * On triggering, lr (R14) contains the previous mode's pc (R15).
- * Based on example in Hohl, "ARM Assembly Language: Fundamentals and Techniques"
- * Chapter 11, Example 11.1.
- */
-/*
- * NOTE: This routine closely mirrors the undef_handler routine, since we will store
- * the ABORT stack frame in the UNDEF stack.
- * In addition, since ARMDEBUG uses Abort mode, if the ABORT occurs while the
- * debugger is running, the value of SP_abort is not valid. This should not happen
- * in any case (it is a BUG if ARMDEBUG triggers an ABORT).
- *
- * We assume that the DEBUG stack holds only one stack frame and we will overwrite it.
- * On entry, LR_undef contains the PC+4 for Prefetch Abort, and PC+8 for Data Abort.
- *
- * For the purpose of Debugging, the stack frame should present the PC (R15) as the address
- * of the instruction that triggered the Abort. Hence we need to adjust R15
- * to point to the address of the ABORTed instruction.
- *
- * We will also store ABORT LR (next instruction pointer) and ABORT SPSR to the stack.
- *
- * For the handler, once the user registers have been stored in the DEBUG stack, the
- * registers will be used as follows:
- *
- * R0: ABORT LR, then ABORT instruction address
- * R1: SPSR
- * R2: PC Offset, then Mode
- * R3: DEBUG Stack Pointer (for Banked R13-R14 update)
- * R4: Abort Type Enum
- */
-
-.text
-.code 32
-.align 0
-
- .extern dbg__display_abort_info
- .extern dbg__abort_exception_handler
- .extern default_prefetch_abort_handler
- .extern default_data_abort_handler
-
-
- dbg_interwork prefetch_abort_handler
- ldr sp, =__debugger_stack__
- stmfd sp, {r0-r15}^ /* Save workspace, previous mode's pc via 'S' flag, R13-R15: placeholders */
- mov r2, #PREFETCH_OFFSET
- mov r4, #DISP_ABORT_PREFETCH /* Display Abort Info Type */
- mov r5, #DBG_ABORT_PREFETCH /* Debugger Abort Type */
- b _common_abort_handler
-
- dbg_interwork data_abort_handler
- ldr sp, =__debugger_stack__
- stmfd sp, {r0-r15}^ /* Save workspace, previous mode's pc via 'S' flag, R13-R15: placeholders */
- mov r2, #DATA_OFFSET
- mov r4, #DISP_ABORT_DATA /* Display Abort Info Type */
- mov r5, #DBG_ABORT_DATA /* Debugger Abort Type */
-
-_common_abort_handler:
- sub r0, lr, r2 /* R0: Adjust PC to ABORTed instruction address */
- str r0, [sp, #-4] /* Save ABORTed Instruction PC to stack (R15 slot) */
- sub r3, sp, #4 /* Use R3 to write Banked R13-R14 of ABORT instruction, update R3 to point to R14 slot */
-
- mrs r1, spsr /* Copy SPSR to r1 */
- tst r1, #CPSR_THUMB /* Check for Thumb Mode */
- addne r0, r0, #2 /* Is Thumb instruction, adjust PC for ABORT next instruction address */
- addeq r0, r0, #4 /* Is ARM instruction, adjust PC for ABORT next instruction address */
- sub sp, sp, #(4*16) /* Need to manually update SP(abort) */
- stmfd sp!, {r0,r1} /* Save ABORTed Next Instr Pointer (in R0) and previous mode's CPSR to stack */
-
- and r2, r1, #CPSR_MODE /* Get previous mode */
- teq r2, #MODE_USR
- beq _exit_abort_handler /* Can't switch back if we're in User mode! */
-
-_store_prev_mode_banked_regs:
- /* FIXME: We don't handle FIQ properly! */
-
- orr r2, #(CPSR_FIQ | CPSR_IRQ) /* Disable Interrupts */
- msr cpsr_c, r2 /* Switch to previous mode */
- stmfd r3!, {sp, lr} /* Store Previous Mode's LR (R14), SP (R13) via R3 */
- msr cpsr_c, #(MODE_ABT | CPSR_FIQ | CPSR_IRQ) /* Revert to ABORT Mode */
-
-_exit_abort_handler:
- ldr sp, =__abort_stack__ /* Reinitialize stack pointer each time an Abort happens */
- bic sp, sp, #7
- mov r0, r4 /* Copy Display Abort Type Enum to R0 */
- bl dbg__display_abort_info /* Display Abort Type to LCD */
- mov r0, r5 /* Copy Debugger Abort Type Enum to R0 */
- b dbg__abort_exception_handler /* Invoke Debugger */
-
-
diff --git a/Debugger/debug_comm.S b/Debugger/debug_comm.S
deleted file mode 100644
index b4590eb..0000000
--- a/Debugger/debug_comm.S
+++ /dev/null
@@ -1,550 +0,0 @@
-/** @file debug_comm.S
- * @brief GDB Server communications support routines
- *
- */
-
-/* Copyright (C) 2007-2011 the NxOS developers
- *
- * Module Developed by: TC Wan <tcwan@cs.usm.my>
- *
- * See AUTHORS for a full list of the developers.
- *
- * See COPYING for redistribution license
- *
- */
-
-#define __ASSEMBLY__
-#include "debug_macros.h"
-#include "debug_stub.h"
-#include "debug_internals.h"
-
- .extern dbg__sendCommMsg
-
- /* Hexutils function references */
- .extern hex2char
- .extern char2hex
- .extern byte2ascii
- .extern halfword2ascii_be
- .extern halfword2ascii_le
- .extern word2ascii_be
- .extern word2ascii_le
- .extern ascii2hex_varlen_be
- .extern ascii2byte
- .extern ascii2halfword_be
- .extern ascii2halfword_le
- .extern ascii2word_be
- .extern ascii2word_le
-
-
-.bss
-.align 4
-
- .global debug_InCommBuf
- .global debug_OutCommBuf
-debug_InCommBuf:
- .space USB_BUFSIZE,0
-debug_OutCommBuf:
- .space USB_BUFSIZE,0
-
-debug_msgRxBufPtr:
- .word 0x0
-debug_msgTxBufPtr:
- .word 0x0
-
-debug_msgRxBuf_AppendPtr:
- .word 0x0
-debug_msgTxBuf_AppendPtr:
- .word 0x0
-
- .equ RXAPPENDPTR_OFFSET, (debug_msgRxBuf_AppendPtr - debug_msgRxBufPtr)
- .equ TXAPPENDPTR_OFFSET, (debug_msgTxBuf_AppendPtr - debug_msgTxBufPtr)
-
-debug_segmentRxNum: /* Current Rx Segment Number */
- .word 0x0
-
-/* Comm Channel and NXT Received Message Length is now common to both NxOS and NXT Firmware */
-debug_nxtMsgLength:
- .word 0x0
-
- .global debug_nxtCommChannel
-debug_nxtCommChannel:
- .word 0x0
-
- .global debug_nxtCommOverrun
-debug_nxtCommOverrun:
- .word 0x0
-
- .equ NXTCOMMCHANNEL_OFFSET, (debug_nxtCommChannel - debug_nxtMsgLength)
- .equ NXTCOMMOVERRUN_OFFSET, (debug_nxtCommOverrun - debug_nxtMsgLength)
-
-.data
-.align 4
-
-nxt_commcmd_header:
- .byte NXT_GDBMSG_TELEGRAMTYPE, 0x00, 0x00 /* padded to 3 bytes */
-
-.code 32
-.text
-.align 4
-/* Debugger Communications Routines
- * It does not make sense to pass information from the Debugger Module to the Comm. link one character
- * at a time, especially if we're not using a native serial interface (e.g., EIA-232). Consequently
- * a Message interface has been defined. This can still call getChar() and putChar() subroutines
- * if so desired, but it'll be a purely internal matter.
- *
- * Message Format
- * Since we need to use EP1&2 (Bulk channels) to communicate with the PC Host, the messages should
- * follow the NXT Direct Commands message structure (this will allow for interoperability with NXT Firmware
- * in addition to NxOS). The maximum length of any USB communications via the Bulk channel is 64 bytes.
- * There is a one byte Telegram Type field which identifies the type of telegram, followed by the
- * Telegram header and actual message.
- *
- * The LEGO Mindstorms Communications Protocol Direct Commands GDB Message format (including all headers)
- * is as follows:
- *
- * GDB Command
- * ===========
- * Byte 0: Telegram Type Field (0x8d Direct Command, No response required) | NXT Msg Header
- * Byte 1: Segment No (1-255, 0: Last Segment; limit is MSG_NUMSEGMENTS) |
- * Byte 2: Telegram Size (Len of USB Buffer - 3, max is MSG_SEGMENTSIZE) |
- * Byte 3-N: Message data | GDB Command
- *
- * The GDB Command (of size M) has the following format:
- * 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
- *
- * 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
- * ============
- * Byte 0: Telegram Type Field (0x8d Direct Command, No response required) | NXT Msg Header
- * Byte 1: Segment No (1-255, 0: Last Segment; limit is MSG_NUMSEGMENTS) |
- * 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: '+' 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)
- *
- * 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
- * in the last segment)
- */
-
-/* dbg__comm_init
- * Initialize communications channel.
- * On Entry:
- * R0: MSG Rx Buf Pointer
- * R1: MSG Tx Buf Pointer
- */
-
- dbg_interwork dbg__comm_init
- stmfd sp!, {lr}
- ldr r2, =debug_msgRxBufPtr
- stmia r2!, {r0, r1} /* debug_msgRxBufPtr and debug_msgTxBufPtr */
- stmia r2!, {r0, r1} /* debug_msgRxBuf_AppendPtr and debug_msgTxBuf_AppendPtr */
- bl _dbg__comm_readbuf_reset
- ldr r1, =debug_nxtMsgLength
- mov r0, #0
- str r0, [r1, #NXTCOMMCHANNEL_OFFSET] /* Clear NXT Channel on INIT */
- ldmfd sp!, {pc}
-
-
-_dbg__comm_readbuf_reset:
- ldr r1, =debug_nxtMsgLength
- mov r0, #0
- str r0, [r1] /* Clear Received Comm Message Length */
- bx lr
-
-/* dbg__copyNxtDebugMsg
- * Copy NXT Debug Message to our own Buffers, indicate Msg Received status.
- * Note: This routine is now used by both NXT Firmware and NxOS
- * On Entry:
- * R0: NXT Input Buf Pointer
- * R1: NXT Communications Channel Enum (CmdBit)
- * R2: NXT Raw Message Length
- * On Exit:
- * R0-R3: Destroyed
- */
- dbg_interwork dbg__copyNxtDebugMsg
- ldr r3, =debug_nxtMsgLength
- str r1, [r3, #NXTCOMMCHANNEL_OFFSET] /* save Communications Channel first */
- ldr r1, [r3] /* Check if there's an unread message in the buffer */
- cmp r1, #0
- beq cont_dbg__copyNxtDebugMsg /* No unread message, so continue */
-exit_dbg__NxtDebugMsgOverrun:
- ldr r1, [r3, #NXTCOMMOVERRUN_OFFSET]
- add r1, r1, #1
- str r1, [r3, #NXTCOMMOVERRUN_OFFSET] /* update message overrun stats */
- b exit_dbg__copyNxtDebugMsg
-cont_dbg__copyNxtDebugMsg:
- str r2, [r3]
- ldr r1, =debug_InCommBuf
- _dbg_memcpy r1, r0, r2, r3 /* r3: scratch register */
-exit_dbg__copyNxtDebugMsg:
- bx lr
-
-/* _dbg_reset_msgTxBuf_AppendPtr
- * Internal variable to reset pointers.
- * On Exit:
- * R0: debug_msgTxBuf_AppendPtr
- * R1: destroyed
- */
-_dbg_reset_msgTxBuf_AppendPtr:
- ldr r1, =debug_msgTxBufPtr /* Should not be modified */
- ldr r0, [r1]
- str r0, [r1, #TXAPPENDPTR_OFFSET]
- mov pc, lr
-
-/* _dbg__commHasMsg
- * Internal Segment Reassembly Routine.
- * On exit:
- * r0: !0: (Availale Telegram Message Size), 0: no incoming message/segment
- * r1: message segment number
- */
-_dbg__commHasMsg:
- stmfd sp!, {lr}
- ldr r0, =debug_nxtMsgLength
- ldr r0, [r0] /* R0 contains the Comm Buffer Size, including the NXT Direct Command Header */
-
- ldr r2, =debug_InCommBuf
- ldrb r1, [r2, #NXT_MSG_TELEGRAMTYPE_OFFSET]
- cmp r1, #NXT_GDBMSG_TELEGRAMTYPE
- bne invalid_CommMsg /* Invalid telegram type, ignore */
-
- ldrb r1, [r2, #NXT_MSG_TELEGRAMSIZE_OFFSET]
- sub r0, r0, r1 /* Comm Buffer Size - Telegram Size = 3 (header size) */
- cmp r0, #NXT_GDBMSG_START /* Start offset is equal to header size */
- bne invalid_CommMsg /* Invalid Message Length, ignore */
-
- mov r0, r1 /* Telegram Message Size */
- ldrb r1, [r2, #NXT_MSG_SEGNUM_OFFSET]
- b _exit_dbg__commHasMsg
-
-invalid_CommMsg:
- bl _dbg__comm_readbuf_reset /* Next Comm telegram transaction */
- mov r0, #0
-_exit_dbg__commHasMsg:
- ldmfd sp!, {pc}
-
-/* _copy_msg_from_commbuf
- * Internal Comm buffer copy routine, handles segment reassembly.
- * On entry:
- * r0: number of bytes to copy
- * r1: segment number
- * On exit:
- * r0: cummulative message length
- * r1: segment number
- * r2, r3: Destroyed
- */
-_copy_msg_from_commbuf:
- stmfd sp!, {r1,r4,r5,r6,lr}
- movs r4, r0
- beq _exit_copy_msg_from_commbuf
-
- ldr r6, =debug_msgRxBufPtr /* Address of Pointers */
- ldr r5, [r6] /* Rx buffer Start Address */
- ldr r2, [r6, #RXAPPENDPTR_OFFSET] /* Append Pointer */
-
- sub r3, r2, r5 /* r3: current length of message */
- add r3, r3, r4 /* new cummulative length of message */
- cmp r3, #MSGBUF_SIZE
- movhi r4, #0 /* Buffer overflow! */
- strhi r5, [r6, #RXAPPENDPTR_OFFSET] /* Reset AppendPtr to beginning of Rx Buffer */
- bhi _exit_copy_msg_from_commbuf
-
- ldr r3, =debug_InCommBuf
- add r3, r3, #NXT_GDBMSG_START
- _dbg_memcpy r2, r3, r4, r0 /* r2 updated to point to next empty char slot in Rx buffer */
- sub r4, r2, r5 /* r4: cummulative length of message */
-
- /* Update debug_msgRxBuf_AppendPtr */
- teq r1, #0 /* Check if this is last segment (segment 0) */
- streq r5, [r6, #RXAPPENDPTR_OFFSET] /* Reset AppendPtr to beginning of Rx Buffer if so */
- strne r2, [r6, #RXAPPENDPTR_OFFSET] /* Otherwise, update Append Pointer to receive next segment */
-
-_exit_copy_msg_from_commbuf:
- bl _dbg__comm_readbuf_reset /* Next Comm telegram transaction */
- mov r0, r4 /* Return cummulative message length in R0 */
- ldmfd sp!, {r1,r4,r5,r6,pc} /* Return segment number in R1 */
-
-
-/* _msgbuf_checksum
- * Internal routine to calculate checksum character buffer.
- * On entry:
- * r0: pointer to character buffer to checksum (assume ASCIIZ terminated)
- * On exit:
- * r0: pointer to character buffer after ASCIIZ
- * r1: checksum (8-bit binary)
- * r2: message length
- * r3: destroyed
- */
-_msgbuf_checksum:
- mov r1, #0 /* clear checksum */
- mov r2, #0 /* clear length */
-1: ldrb r3, [r0], #1 /* Iterate through buffer */
- add r1, r1, r3 /* cummulative sum of char */
- teq r3, #0
- addne r2, r2, #1 /* increment message length */
- bne 1b /* until ASCIIZ found */
- and r1, #BYTE0 /* Modulo 256 */
- mov pc, lr
-
-/* dbg__getDebugMsg
- * Retrieve pending Debugger Message if available (Non-Blocking).
- * On entry:
- * No parameters (assume pointers were initialized previously using dbg__comm_init)
- * On exit:
- * r0: >0 = Valid GDB Message Length (incl '$', excluding '#' and checksum),
- * 0 = no valid message (yet), -1 = error
- * r1: GDB Message Buffer Pointer (incl '$', excluding '#' and checksum)
- * r2, r3: Destroyed
- * Note: If GDB Message were returned, it is ASCIIZ terminated, does not include '#' and checksum
- */
- dbg_interwork dbg__getDebugMsg
- stmfd sp!, {r4,r5,lr}
- bl _dbg__commHasMsg /* r0: message length, r1: segment number */
- teq r0, #0
- beq exit_dbg__getDebugMsg /* no new message, exit with R0 = 0 */
-
- ldr r4, =debug_segmentRxNum
- ldr r2, [r4] /* Get current Segment Number */
- add r2, r2, #1 /* Expected Segment Number for comparison */
- teq r1, #0
- streq r1, [r4] /* Update current Segment Number with 0 since it is the last segment */
- beq _hasMsg2Copy
- cmp r1, #MSG_NUMSEGMENTS /* Segment Number < MSG_NUMSEGMENTS? */
- bhs _invalid_segment
- teq r1, r2 /* Valid Segment Number, check against Expected Segment Number */
- beq _hasMsg2Copy /* Segment Number matches Expected Segment Number, update buffers */
-
-_invalid_segment:
- bl _dbg__comm_readbuf_reset /* Invalid, Next Comm telegram transaction */
- mov r0, #0 /* Reset Segment Number */
- str r0, [r4] /* Update current Segment Number with 0 to prepare for new message */
- b exit_dbg__getMsgError /* Exit with error */
-
-_hasMsg2Copy:
- str r1, [r4] /* Update current Segment Number */
- bl _copy_msg_from_commbuf /* r0: cummulative message length, r1: segment number */
- teq r1, #0
- movne r0, #0 /* Incomplete message, ignore for now */
- bne exit_dbg__getDebugMsg /* Message not complete yet, exit */
-
- /* Check for valid GDB message */
- mov r4, r0 /* keep message length in R4, assume to be within MSGBUF_SIZE */
- ldr r5, =debug_msgRxBufPtr
- ldr r5, [r5] /* Rx buffer Start Address */
-
-/* Need to account for Packet Acknowledgement */
-1: ldrb r0, [r5]
- teq r0, #MSGBUF_CTRLC /* Look for Ctrl-C */
- moveq r0, r4 /* If found, set R0 to current message length */
- beq exit_dbg__getDebugMsg /* and return */
- teq r0, #MSGBUF_NAKCHAR /* Look for '-' */
- beq exit_dbg__getMsgError /* Error from Host, Retransmit previous message */
- 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 */
-
- /* 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 */
-
- mov r1, #0
- strb r1, [r5, r2] /* Zero out '#' char for checksum calc later */
-
-#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) */
- bl ascii2byte /* R0: received checksum, R1: address of next buffer location */
- teq r0, r3 /* Compare calculated checksum in R3 against received checksum in R0 */
- bne exit_dbg__getMsgError /* Checksums do not match, exit with error */
-
- subeq r0, r4, #MSGBUF_CHKSUMOFFSET /* Update message length (incl '$') as return parameter */
- add r2, r2, #1 /* expected message length (from _msgbuf_checksum) */
- teq r0, r2
- beq exit_dbg__getDebugMsg /* Valid length, return */
-
-exit_dbg__getMsgError:
- /* We must first clear the existing message checksum */
- ldr r1, =debug_msgTxBufPtr /* R5: data structure base pointer */
- ldr r1, [r1] /* Tx buffer Start Address */
-
-1: ldrb r0, [r1], #1
- teq r0, #MSGBUF_CHKSUMCHAR
- bne 1b
-
- mov r0, #0 /* ASCIIZ */
- strb r0, [r1, #-1] /* Pointer R1 is now one past the MSGBUF_CHKSUMCHAR */
-
- bl dbg__putDebugMsg /* Retransmit message */
- mov r0, #0 /* Flag no message received */
-
-#if 0
- mov r0, #MSGBUF_MSGERROR
-#endif
-
-exit_dbg__getDebugMsg:
- mov r1, r5 /* Return GDB Message Buffer Pointer in R1 */
- ldmfd sp!, {r4,r5,pc}
-
-
-/* _copy_msg_to_commbuf
- * Internal Comm buffer copy routine, handles segment fragmentation.
- * On entry:
- * r0: number of bytes to copy
- * r1: segment number
- * On exit:
- * r0: cummulative message length
- * r1: segment number
- * r2, r3: Destroyed
- */
-_copy_msg_to_commbuf:
- stmfd sp!, {r1,r4,r5,r6,lr}
- ldr r6, =debug_msgTxBufPtr /* Address of Pointers */
- ldr r5, [r6, #TXAPPENDPTR_OFFSET] /* Retrieve Tx Append Pointer */
-
- movs r4, r0
- beq _exit_copy_msg_to_commbuf
-
-#ifdef CHECK_TXLEN
- add r0, r4, #NXT_GDBMSG_START /* offset = header size */
- cmp r0, #USB_BUFSIZE
- bhi _exit_copy_msg_to_commbuf /* We let calling routine detect problem (segment number will increment) */
-#endif
-
- /* Fill in Comm Message Header */
- ldr r3, =debug_OutCommBuf
- mov r2, #NXT_GDBMSG_TELEGRAMTYPE
- strb r2, [r3], #1 /* Telegram type */
- strb r1, [r3], #1 /* Segment Number */
- strb r0, [r3], #1 /* Message Length */
-
- mov r2, r5 /* Copy to R2 for updating */
- mov r1, r4 /* actual GDB message fragment length (exclude Comm header) */
- _dbg_memcpy r3, r2, r1, r0 /* This copies over the message fragment, r3, r2 updated */
- mov r5, r2 /* Updated Tx Append Pointer, keep in R5 for now */
-
- add r0, r4, #NXT_GDBMSG_START /* Total Comm Buffer Size for Tx (NXT_GDBMSG_START offset = header size) */
- bl dbg__sendCommMsg /* Common interface routine to commnuncations drivers */
- cmp r0, #TRUE
- ldrne r5, [r6, #TXAPPENDPTR_OFFSET] /* Tx failed, Retrieve Original Tx Append Pointer */
- streq r5, [r6, #TXAPPENDPTR_OFFSET] /* Tx succeeded, Update Tx Append Pointer to new position */
-
-_exit_copy_msg_to_commbuf:
- ldr r6, [r6] /* Retrieve Tx Buffer Start Address */
- sub r0, r5, r6 /* Return calculated cummulative message length (R0) */
- ldmfd sp!, {r1,r4,r5,r6,pc} /* Return segment number in R1 */
-
-/* dbg__putDebugMsg
- * Sends Debugger Message from calling routine after appending checksum (Blocking) .
- * On entry:
- * No parameters (assume pointers were initialized previously using dbg__comm_init)
- * 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)
- */
- dbg_interwork dbg__putDebugMsg
- stmfd sp!, {r4,r5,lr}
- /* Perform Checksum Calculation */
- 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 */
-
-#ifdef CHECK_TXLEN
- add r2, r2, #2 /* r2: returned length from _msgbuf_checksum, added with prefix length */
- sub r3, r0, r4 /* r3: calculated length from pointers (incl. prefix length) */
- teq r2, r3
- bne exit_dbg__putMsgError
-#endif
-
- 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 */
- 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 */
- mov r5, #0 /* Previous cummulative message length */
-
- /* We assume unsigned message lengths, so the arithmetic MUST NOT result in negative values */
-_cont_putMsg:
- cmp r4, r0
- movls r0, #0 /* R0: Exit status (success) */
- bls exit_dbg__putDebugMsg /* If Total message length (r4) <= Cummulative message length (r0), we're done */
- add r2, r0, #MSG_SEGMENTSIZE /* R2: calculate new Max cummulative message length */
- cmp r4, r2 /* Check total message length (R4) against new Max cummulative message length (R2) */
- subls r0, r4, r0 /* if total message length (R4) <= new Max cummulative message length (R2), send remainder */
- movls r1, #0 /* Flag as last segment (Segment Number = 0) */
- movhi r0, #MSG_SEGMENTSIZE /* else send MSG_SEGMENTSIZE bytes */
- addhi r1, r1, #1 /* Increment Segment Number */
- cmp r1, #MSG_NUMSEGMENTS
- bhs exit_dbg__putMsgError /* If Segment Number >= MSG_NUMSEGMENTS, flag error */
- bl _copy_msg_to_commbuf /* R0: cummulative message length, R1: segment number */
- teq r5, r0 /* Check if we managed to transmit the previous message */
- beq exit_dbg__putMsgError /* No, flag error */
- movne r5, r0 /* Update previous cummulative message length */
- b _cont_putMsg
-
-exit_dbg__putMsgError:
- mov r0, #MSGBUF_MSGERROR
-exit_dbg__putDebugMsg:
- ldmfd sp!, {r4,r5,pc}
-
-/* dbg__sendAckOrNak
- * Send Ack (for successful receipt of message)
- * or Nak (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: An Ack Or Nak is indicated by '+' or '-', which is prepended with the Comm header and sent (without checksum)
- * Sending Ack is only done for Continue and Step commands, where GDB does not expect any replies.
- */
- dbg_interwork dbg__sendAckOrNak
- 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_commbuf /* 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_hexutils.S b/Debugger/debug_hexutils.S
deleted file mode 100644
index 267406f..0000000
--- a/Debugger/debug_hexutils.S
+++ /dev/null
@@ -1,459 +0,0 @@
-/** @file debug_hexutils.S
- * @brief GDB hexadecimal conversion utility routines
- *
- */
-
-/* Copyright (C) 2007-2011 the NxOS developers
- *
- * Module Developed by: TC Wan <tcwan@cs.usm.my>
- *
- * See AUTHORS for a full list of the developers.
- *
- * See COPYING for redistribution license
- *
- */
-
-
-#define __ASSEMBLY__
-
-#include "debug_internals.h"
-
-.data
-.align 4
-
-hex2char_lut:
- /* .ascii "0123456789ABCDEF" */
- /* Need to use lowercase hex chars to avoid confusion with GDB Error (E NN) response */
- .ascii "0123456789abcdef"
-
-/* Macros
- */
-
-
-/* _hex2char_lut
- * Internal routine to intialize the LUT address pointer
- */
- .macro _hex2char_lut addrptr
- ldr \addrptr, =hex2char_lut
- .endm
-
-/* _hex2char_cont
- * Internal routine that assumes that the LUT has been loaded.
- * This macro accepts a byte sized hex value as a parameter register(7:0) and returns the
- * ASCII equivalent in in the same register(7:0)
- * The second parameter is the LUT address pointer register to use (assumed to be initialized)
- * WARNING: Assumes that the value in register is sanity checked before invoking macro
- */
- .macro _hex2char_cont reg, addrptr
- ldrb \reg, [\addrptr, \reg]
- .endm
-
-/* _hex2char
- * This macro accepts a byte sized hex value as a parameter register(7:0) and returns the
- * ASCII equivalent in in the same register(7:0)
- * The second parameter is the LUT address pointer register to use (register content is destroyed)
- * WARNING: Assumes that the value in register is sanity checked before invoking macro
- */
- .macro _hex2char reg, addrptr
- _hex2char_lut \addrptr
- _hex2char_cont \reg, \addrptr
- .endm
-
-/* _char2hex
- * This macro accepts an ASCII char as a parameter register(7:0) and returns the
- * equivalent byte sized hex value in in the same register(7:0)
- * WARNING: Assumes that the char in register is a valid hex char before invoking macro
- */
- .macro _char2hex reg
- cmp \reg, #'A' /* If Alpha */
- bichs \reg, \reg, #ASCII_LOWER2UPPER_MASK /* Convert to Uppercase */
- subhs \reg, \reg, #7 /* Adjustment to allow for subtraction with 0x30 */
- sub \reg, \reg, #0x30 /* get final hex value */
- .endm
-
-
-.code 32
-.text
-.align 4
-
-
-/* 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
- * This routine accepts a byte sized hex value in R0(7:0) and returns the
- * ASCII equivalent in R0(7:0)
- */
- .global hex2char
-
-hex2char:
- stmfd sp!, {r1,lr}
- and r0, #NIBBLE0 /* make sure that input is sane */
- _hex2char r0, r1
- ldmfd sp!, {r1,pc}
-
-/* char2hex
- * This routine accepts an ASCII character in R0(7:0) and returns the
- * 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
-* On entry:
- * R0: ASCII character
- * On exit:
- * R0: Hex value
- */
- .global char2hex
-
-char2hex:
- and r0, r0, #BYTE0 /* make sure that input is sane */
- cmp r0, #'0'
- blo char2hex_error
- cmp r0, #'9'
- bls perform_char2hex
- cmp r0, #'A'
- blo char2hex_error
- cmp r0, #'F'
- bls perform_char2hex
- cmp r0, #'a'
- blo char2hex_error
- cmp r0, #'f'
- bhi char2hex_error
- /* Validated Hex Char */
-perform_char2hex:
- _char2hex r0 /* Return hex value in R0 */
- bx lr
-
-char2hex_error:
- mov r0, #-1 /* Set Return value to Error value */
- bx lr
-
-/* byte2ascii_cont
- * (Shared routine, does not perform sanity checks)
- * On entry:
- * R0: ASCII buffer pointer
- * R1[7:0]: byte value
- * On exit:
- * R0: Address of next empty char slot in buffer
- * R1: Destroyed
- *
- * This routine accepts an ASCII buffer pointer in R0 and a byte value in R1,
- * and stores the ASCII equivalent byte value in the buffer pointed to by R0.
- * Note: On return, R0 points to next empty char slot in buffer
- */
-byte2ascii_cont:
- stmfd sp!, {r2,r3,r4, lr}
- lsl r2, r1, #24 /* Keep copy of input byte value R1[7:0], shifted to MSB R2[31:24] */
- mov r4, #2 /* Loop counter */
- _hex2char_lut r3 /* initialize LUT pointer */
-1: ror r2, r2, #28 /* Rotate MSNibble R2[31:28] into LSNibble position R2[3:0] */
- and r1, r2, #NIBBLE0 /* Mask out everything else, store Nibble in R1 */
- _hex2char_cont r1, r3 /* Convert nibble to ASCII char */
- strb r1, [r0], #1
- subs r4, r4, #1 /* decrement loop counter */
- bne 1b
- ldmfd sp!, {r2,r3,r4, pc}
-
-/* byte2ascii
- * On entry:
- * R0: ASCII buffer pointer
- * R1[7:0]: Byte 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 byte value in R1,
- * and stores the ASCII equivalent byte value in the buffer pointed to by R0.
- * Note: On return, R0 points to the next empty char slot in buffer
- */
- .global byte2ascii
-
-byte2ascii:
- stmfd sp!, {r0, lr} /* Keep ASCII buffer pointer */
- and r1, #BYTE0 /* sanitize input */
- bl byte2ascii_cont
- ldmfd sp!, {r1, pc} /* return original string pointer in R1 */
-
-/* halfword2ascii_be
- * Big 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_be
-halfword2ascii_be:
- stmfd sp!, {r0,r2,r3, lr} /* Keep ASCII buffer pointer */
- 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_be
- * Big 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_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 */
-
-
-/* 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_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] /* Load ASCII char for Hex Value */
- bl char2hex /* on return, hex value in R0, -1 for error */
- cmp r0, #-1
- beq _exit_ascii2hex_varlen
- orr r2, r0, r2, lsl #4 /* combined byte value */
- subs r3, r3, #1 /* Decrement Counter */
- add r1, r1, #1 /* Go to next char slot */
- bne 2b
-_exit_ascii2hex_varlen:
- mov r0, r2 /* Return results in R0 */
- ldmfd sp!, {r2,r3, pc}
-
-
-/* ascii2byte
- * On entry:
- * R0: ASCII buffer pointer
- * On exit:
- * R0[7:0]: Byte value
- * R1: Address of next char slot in buffer
- *
- * This routine accepts an ASCII buffer pointer in R0,
- * and returns the byte value in R0[7:0].
- * Note: On return, R1 points to the ASCII buffer location after the current 2 chars.
- * WARNING: This routine assumes that the input buffer was sanitized and contains valid Hex chars,
- * otherwise it will return invalid results.
- */
- .global ascii2byte
-
-ascii2byte:
- 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:
- * 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_be
-
-ascii2halfword_be:
- stmfd sp!, {r2,r3, lr}
- 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_be
- * Big 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_be
-
-ascii2word_be:
- stmfd sp!, {r2,r3, lr}
- mov r3, #4 /* Loop counter */
-
- /* Fall through to byte coversion loop */
-
-_conv_ascii2byte_be:
- teq r0, #0
- 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 */
-
diff --git a/Debugger/debug_internals.h b/Debugger/debug_internals.h
deleted file mode 100644
index bdab463..0000000
--- a/Debugger/debug_internals.h
+++ /dev/null
@@ -1,395 +0,0 @@
-/** @file debug_internals.h
- * @brief Shared C/ASM header file for debugger internal constants
- *
- */
-
-/* Copyright (C) 2007-2011 the NxOS developers
- *
- * Module Developed by: TC Wan <tcwan@cs.usm.my>
- *
- * See AUTHORS for a full list of the developers.
- *
- * See COPYING for redistribution license
- *
- */
-
-#ifndef __DEBUG_INTERNALS_H__
-#define __DEBUG_INTERNALS_H__
-
-#include "_c_arm_macros.h"
-
-
-/** @addtogroup debugger */
-/*@{*/
-
-
-/* Declarations go here. */
-/** @name Debug Message Constants.
- *
- * Debug Message Values
- */
-/*@{*/
-
-/*
- * 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 /* USB Buffer size for AT91SAM7S */
-
-#define NXT_MSG_TELEGRAMTYPE_OFFSET 0 /* NXT Direct Command/Response Header */
-#define NXT_MSG_SEGNUM_OFFSET 1
-#define NXT_MSG_TELEGRAMSIZE_OFFSET 2
-
-#define NXT_GDBMSG_TELEGRAMTYPE 0x8d /* GDB debugger specific, no Response required */
-
-#define NXT_GDBMSG_START 3 /* Offset into USB Telegram buffer */
-
-#define MSG_NUMSEGMENTS 3 /* For packet transfers */
-#define MSG_SEGMENTSIZE (USB_BUFSIZE - NXT_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 (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 '$'
-#define MSGBUF_ACKCHAR '+'
-#define MSGBUF_NAKCHAR '-'
-#define MSGBUF_ERRCHAR 'E'
-#define MSGBUF_SIGCHAR 'S'
-#define MSGBUF_SETCHAR '='
-#define MSGBUF_CHKSUMCHAR '#'
-#define MSGBUF_SEPCHAR ','
-#define MSGBUF_ARGCHAR ':'
-#define MSGBUF_MSGERROR -1
-/*@}*/
-
-/** @name Debug Command Lookup Constants.
- *
- * Debug Command Lookup
- */
-/*@{*/
-
-#define CMDINDEX_OUTOFRANGE -1
-/*@}*/
-
-/** @name Debug Register Command Constants.
- *
- * Debug Register Command
- */
-/*@{*/
-#define CMD_REG_NUMREGS 17
-#define CMD_REG_GETONE_MINPARAMLEN 1
-#define CMD_REG_GETONE_MAXPARAMLEN 2
-#define CMD_REG_GETALL_PARAMLEN 0
-#define CMD_REG_REGPARAMLEN 8 /* 32-bit ASCII Hex Value */
-#define CMD_REG_SETONE_MINPARAMLEN (2 + CMD_REG_REGPARAMLEN)
-#define CMD_REG_SETONE_MAXPARAMLEN (3 + CMD_REG_REGPARAMLEN)
-#define CMD_REG_SETALL_PARAMLEN (CMD_REG_NUMREGS*CMD_REG_REGPARAMLEN)
-#define CMD_KILL_PARAMLEN 0
-#define CMD_DETACH_PARAMLEN 0
-
-/*@}*/
-
-/** @name Debug Memory Command Constants.
- *
- * Debug Memory Command
- * FIXME: These limits are not enforced by the GDB client, it truncates addresses and lengths to remove leading '0's
- * The PARAMLEN constants would probably be removed
- */
-/*@{*/
-#define CMD_NUMITEMS_PARAMLEN 4 /* 16-bit ASCII Hex Value */
-#define CMD_MEM_READ_PARAMLEN (CMD_REG_REGPARAMLEN + CMD_NUMITEMS_PARAMLEN + 1) /* Address length is equivalent to reg param len */
-#define CMD_MEM_WRITE_MINPARAMLEN (CMD_REG_REGPARAMLEN + CMD_NUMITEMS_PARAMLEN + 2) /* Address length is equivalent to reg param len */
-#define CMD_MEM_SEPCHAR_OFFSET CMD_REG_REGPARAMLEN /* Address length is equivalent to reg param len */
-#define CMD_MEM_MAXOUTBUFLEN (MSGBUF_SIZE - MSGBUF_OUT_OVERHEADLEN)
-#define CMD_MEM_MAXREADBYTES (CMD_MEM_MAXOUTBUFLEN/2)
-#define CMD_MEM_MAXINBUFLEN (MSGBUF_SIZE - MSGBUF_IN_OVERHEADLEN)
-#define CMD_MEM_MAXWRITEBYTES ((CMD_MEM_MAXINBUFLEN - CMD_MEM_WRITE_MINPARAMLEN)/2)
-/*@}*/
-
-/** @name Debug Continue and Step Command Constants.
- *
- * Debug Continue and Step Command
- */
-/*@{*/
-#define CMD_CONTINUE_MINPARAMLEN 0
-#define CMD_STEP_MINPARAMLEN 0
-/*@}*/
-
-/** @name Debug Query Command Constants.
- *
- * Debug Query Command
- */
-/*@{*/
-#define CMD_QUERY_MINPARAMLEN 0
-#define CMD_QUERY_CURRTID_PARAMLEN 1
-#define CMD_QUERY_FTINFO_PARAMLEN 11
-#define CMD_QUERY_STINFO_PARAMLEN 11
-#define CMD_QUERY_CURRTID_CHAR 'C'
-#define CMD_QUERY_FTINFO_CHAR 'f'
-#define CMD_QUERY_STINFO_CHAR 's'
-/*@}*/
-
-
-/** @name Debug Breakpoint Command Constants.
- *
- * Debug Breakpoint Command
- */
-/*@{*/
-
-#define CMD_BKPT_INSERT_MINPARAMLEN 5
-#define CMD_BKPT_REMOVE_MINPARAMLEN 5
-
-
-#define CMD_BKPT_TYPE_BREAK_MEMORY 0
-#define CMD_BKPT_TYPE_BREAK_HARD 1 /* Not supported */
-#define CMD_BKPT_TYPE_WATCH_WRITE 2 /* Not supported (yet) */
-#define CMD_BKPT_TYPE_WATCH_READ 3 /* Not supported (yet) */
-#define CMD_BKPT_TYPE_WATCH_ACCESS 4 /* Not supported (yet) */
-
-#define CMD_BKPT_KIND_THUMB 2
-#define CMD_BKPT_KIND_THUMB2 3 /* Not supported */
-#define CMD_BKPT_KIND_ARM 4
-
-#define CMD_BKPT_NOTFOUND -1
-
-/*@}*/
-
-/** @name Debug Stack Constants.
- *
- * Debug Stack Manipulation Values
- */
-/*@{*/
-#define DBGSTACK_NEXTINSTR_INDEX 0 /* Next Instruction Address is at index 0 from bottom of Debug Stack */
-#define DBGSTACK_USERCPSR_INDEX 1 /* User CPSR (SPSR_UNDEF) is at index 1 from bottom of Debug Stack */
-#define DBGSTACK_USERREG_INDEX 2 /* R0 starts at index 2 from bottom of Debug Stack */
-#define DBGSTACK_USERSP_INDEX (DBGSTACK_USERREG_INDEX + REG_SP) /* SP is R13 */
-#define DBGSTACK_USERLR_INDEX (DBGSTACK_USERREG_INDEX + REG_LR) /* LR is R14 */
-#define DBGSTACK_USERPC_INDEX (DBGSTACK_USERREG_INDEX + REG_PC) /* PC is R15 */
-/*@}*/
-
-
-/** @name Exception Handler Vector Definitions.
- *
- * Exception Handler Vectors.
- */
-/*@{*/
-
-#define RESET_VECTOR 0x00000000
-#define UNDEF_VECTOR 0x00000004
-#define SVC_VECTOR 0x00000008
-#define PABRT_VECTOR 0x0000000C
-#define DABRT_VECTOR 0x00000010
-#define RESERVED_VECTOR 0x00000014
-#define IRQ_VECTOR 0x00000018
-#define FIQ_VECTOR 0x0000001C
-
-
-/*@}*/
-
-
-/** @name Bitmask Definitions.
- *
- * Various Bitmasks used for data manipulation.
- */
-/*@{*/
-#define BKPT_STATE_THUMB_FLAG 0x01 /* Flag Thumb Breakpoint */
-#define ASCII_LOWER2UPPER_MASK 0x20 /* ASCII Conversion bitmask */
-#define NIBBLE0 0x0000000F /* Nibble 0 word(3:0) */
-#define NIBBLE1 0x000000F0 /* Nibble 1 word(7:4) */
-#define NIBBLE2 0x00000F00 /* Nibble 2 word(11:8) */
-#define NIBBLE3 0x0000F000 /* Nibble 3 word(15:12) */
-#define NIBBLE4 0x000F0000 /* Nibble 4 word(19:16) */
-#define NIBBLE5 0x00F00000 /* Nibble 5 word(23:20) */
-#define NIBBLE6 0x0F000000 /* Nibble 6 word(27:24) */
-#define NIBBLE7 0xF0000000 /* Nibble 7 word(31:28) */
-#define BYTE0 0x000000FF /* Byte 0 word(7:0) */
-#define BYTE1 0x0000FF00 /* Byte 1 word(15:8) */
-#define BYTE2 0x00FF0000 /* Byte 2 word(23:16) */
-#define BYTE3 0xFF000000 /* Byte 3 word(31:24) */
-#define HLFWRD0 0x0000FFFF /* Halfword 0 word(15:0) */
-#define HLFWRD1 0xFFFF0000 /* Halfword 0 word(31:16) */
-/*@}*/
-
-/** @name CPSR Bit Definitions.
- *
- * Various Bit definitions for accessing the CPSR register.
- */
-/*@{*/
-#define CPSR_THUMB 0x00000020
-#define CPSR_FIQ 0x00000040
-#define CPSR_IRQ 0x00000080
-#define CPSR_MODE 0x0000001F
-#define CPSR_COND 0xF0000000
-
-/* ARM Exception Modes */
-#define MODE_USR 0x10 /* User mode */
-#define MODE_FIQ 0x11 /* FIQ mode */
-#define MODE_IRQ 0x12 /* IRQ mode */
-#define MODE_SVC 0x13 /* Supervisor mode */
-#define MODE_ABT 0x17 /* Abort mode */
-#define MODE_UND 0x1B /* Undefined mode */
-#define MODE_SYS 0x1F /* System mode */
-
-/* Condition Flags
- * b31 b30 b29 b28
- * N Z C V
- */
-#define CPSR_NFLAG 0x80000000
-#define CPSR_ZFLAG 0x40000000
-#define CPSR_CFLAG 0x20000000
-#define CPSR_VFLAG 0x10000000
-
-
-/*
- * ARM Opcode Masks (for Parser)
- */
-#define ARM_DATA_INSTR_MASK 0x0FBF0000
-#define ARM_DATA_INSTR_MSRMRS 0x010F0000
-#define ARM_DATA_INSTR_NORMAL 0x01E00000
-#define ARM_DATA_INSTR_IMMREG 0x02000000
-
-#define ARM_LDR_INSTR_REGIMM 0x02000000
-#define ARM_LDR_INSTR_PREPOST 0x01000000
-#define ARM_LDR_INSTR_UPDOWN 0x00800000
-
-#define ARM_LDM_INSTR_PREPOST 0x01000000
-#define ARM_LDM_INSTR_UPDOWN 0x00800000
-
-#define ARM_BLX_INSTR_MASK 0xFE000000
-#define ARM_BLX_INSTR_BLX 0xFA000000
-#define ARM_BLX_INSTR_HBIT 0x01000000
-
-#define ARM_SWI_INSTR_MASK 0x0F000000
-#define ARM_SWI_INSTR_VAL 0x0F000000
-
-
-/*
- * Thumb Opcode Masks (for Parser)
- */
-#define THUMB_BLX_INSTR_REG_RNMASK 0x0078
-
-#define THUMB_BCOND_SWI_INSTR_CONDMASK 0x0F00
-#define THUMB_BCOND_SWI_COND_UNUSED 0x0E00
-#define THUMB_BCOND_SWI_INSTR_SWI 0x0F00
-
-#define THUMB_BLX_INSTR_IMM_HBIT 0x0800
-#define THUMB_BLX_INSTR_IMM_MASK 0xF000
-#define THUMB_BLX_INSTR_IMM_BL 0xF000
-#define THUMB_BLX_INSTR_IMM_BLX 0xE000
-
-/*@}*/
-
-/** Debugger State Enums
- *
- * Debugger State.
- * The enums must be consecutive, starting from 0
- */
-ENUM_BEGIN
-ENUM_VALASSIGN(DBG_RESET, 0) /**< Initial State. */
-ENUM_VAL(DBG_INIT) /**< Debugger Initialized. */
-ENUM_VAL(DBG_CONFIGURED) /**< Debugger has been configured by GDB Server */
-ENUM_END(dbg_state_t)
-
-/** Breakpoint Type Enums
- *
- * Breakpoint Type.
- * The enums must be consecutive, starting from 0
- */
-ENUM_BEGIN
-ENUM_VALASSIGN(DBG_AUTO_BKPT,0) /**< RESERVED: Auto Breakpoint (Instruction resume after breakpoint). */
-ENUM_VAL(DBG_MANUAL_BKPT_ARM) /**< Manual ARM Breakpoint. */
-ENUM_VAL(DBG_NORMAL_BKPT_ARM) /**< Normal ARM Breakpoint (Single Step, Normal). */
-ENUM_VAL(DBG_MANUAL_BKPT_THUMB) /**< Manual Thumb Breakpoint. */
-ENUM_VAL(DBG_NORMAL_BKPT_THUMB) /**< Normal Thumb Breakpoint (Single Step, Normal). */
-ENUM_VAL(DBG_ABORT_PREFETCH) /**< Prefetch Abort. */
-ENUM_VAL(DBG_ABORT_DATA) /**< Data Abort. */
-ENUM_END(bkpt_type_t)
-
-/** Debugger Message Signal Enums
- *
- * Debugger Signal Message Enums.
- * The enums must be consecutive, starting from 0
- */
-/* Need to sync with the Signal enums in ecos-common-hal_stub.c */
-ENUM_BEGIN
-ENUM_VALASSIGN(MSG_SIG_DEFAULT, 0) /**< Default Signal Response. */
-ENUM_VAL(MSG_SIG_HUP) /**< Hangup Signal Response. */
-ENUM_VAL(MSG_SIG_INT) /**< Interrupt Signal Response. */
-ENUM_VAL(MSG_SIG_QUIT) /**< Quit Signal Response. */
-ENUM_VAL(MSG_SIG_ILL) /**< Illegal Instruction Signal Response (not reset when caught). */
-ENUM_VAL(MSG_SIG_TRAP) /**< Trace Trap Signal Response (not reset when caught). */
-ENUM_VAL(MSG_SIG_ABRT) /**< Abort Signal Response (replace SIGIOT). */
-ENUM_VAL(MSG_SIG_EMT) /**< EMT Instruciton Signal Response. */
-ENUM_VAL(MSG_SIG_FPE) /**< Floating Point Exception Signal Response. */
-ENUM_VAL(MSG_SIG_KILL) /**< Kill Signal Response (cannot be caught or ignored). */
-ENUM_VAL(MSG_SIG_BUS) /**< Bus Error Signal Response. */
-ENUM_VAL(MSG_SIG_SEGV) /**< Segmentation Violation Signal Response. */
-ENUM_VAL(MSG_SIG_SYS) /**< Bad Argument to System Call Signal Response. */
-ENUM_VAL(MSG_SIG_PIPE) /**< Write on a Pipe with No Reader Signal Response. */
-ENUM_VAL(MSG_SIG_ALRM) /**< Alarm Clock Signal Response. */
-ENUM_VAL(MSG_SIG_TERM) /**< Software Termination Signal from Kill Signal Response. */
-ENUM_END(dbg_msg_signo)
-
-/** Debugger Message Error Enums
- *
- * Debugger Error Message Enums.
- * The enums must be consecutive, starting from 1
- */
-/* FIXME: Need to validate against the ecos-generic-stub.c Error enums */
-ENUM_BEGIN
-ENUM_VALASSIGN(MSG_ERRIMPL, 0) /**< Stub (not implemented) Error. */
-ENUM_VAL(MSG_ERRINLENGTH) /**< Message Write Length Error. */
-ENUM_VAL(MSG_ERROUTLENGTH) /**< Message Read Length Error. */
-ENUM_VAL(MSG_ERRFORMAT) /**< Message Format Error. */
-ENUM_VAL(MSG_UNKNOWNCMD) /**< Unrecognized Command Error. */
-ENUM_VAL(MSG_UNKNOWNPARAM) /**< Unrecognized Parameter Error. */
-ENUM_VAL(MSG_UNKNOWNBRKPT) /**< Unrecognized Breakpoint Error. */
-ENUM_END(dbg_msg_errno)
-
-/** Register Enums
- *
- * Register Enums.
- * Refer to eCOS's arm_stub.h for enum values
- */
-ENUM_BEGIN
-ENUM_VALASSIGN(REG_R0, 0) /**< User Reg R0 */
-ENUM_VAL(REG_R1) /**< User Reg R1 */
-ENUM_VAL(REG_R2) /**< User Reg R2 */
-ENUM_VAL(REG_R3) /**< User Reg R3 */
-ENUM_VAL(REG_R4) /**< User Reg R4 */
-ENUM_VAL(REG_R5) /**< User Reg R5 */
-ENUM_VAL(REG_R6) /**< User Reg R6 */
-ENUM_VAL(REG_R7) /**< User Reg R7 */
-ENUM_VAL(REG_R8) /**< User Reg R8 */
-ENUM_VAL(REG_R9) /**< User Reg R9 */
-ENUM_VAL(REG_R10) /**< User Reg R10 */
-ENUM_VAL(REG_R11) /**< User Reg R11 */
-ENUM_VAL(REG_R12) /**< User Reg R12 */
-ENUM_VAL(REG_SP) /**< Previous Mode SP (R13) */
-ENUM_VAL(REG_LR) /**< Previous Mode LR (R14) */
-ENUM_VAL(REG_PC) /**< Program Counter (R15) */
-ENUM_VALASSIGN(REG_FPSCR, 24) /**< Previous Mode FPSCR (dummy) */
-ENUM_VAL(REG_CPSR) /**< Previous Mode CPSR */
-
-ENUM_END(register_enum_t)
-
-/** Abort Type Enums
- *
- * Abort Type used for interfacing with LCD Display routine.
- * The enums must be consecutive, starting from 0
- * Note: The values must align with those defined in NxOS's _abort.h
- */
-ENUM_BEGIN
-ENUM_VALASSIGN(DISP_ABORT_PREFETCH,0) /**< Prefetch Abort. */
-ENUM_VAL(DISP_ABORT_DATA) /**< Data Abort. */
-ENUM_VAL(DISP_ABORT_SPURIOUS) /**< Spurious IRQ. */
-ENUM_VAL(DISP_ABORT_ILLEGAL) /**< Illegal Instruction. */
-ENUM_END(abort_type_t)
-
-/*@}*/
-
-#endif /* __DEBUG_INTERNALS_H__ */
diff --git a/Debugger/debug_macros.h b/Debugger/debug_macros.h
deleted file mode 100644
index d852f38..0000000
--- a/Debugger/debug_macros.h
+++ /dev/null
@@ -1,463 +0,0 @@
-/** @file debug_macros.h
- * @brief internal macros used by debug_stub routines
- *
- */
-
-/* Copyright (C) 2007-2010 the NxOS developers
- *
- * Module Developed by: TC Wan <tcwan@cs.usm.my>
- *
- * See AUTHORS for a full list of the developers.
- *
- * See COPYING for redistribution license
- *
- */
-
-#ifndef __DEBUG_MACROS_H__
-#define __DEBUG_MACROS_H__
-
-
-
-
-/*@{*/
-
-/** _dbg_jumpTableHandler
- * Call Jump Table Routine based on Index
- * On entry:
- * @param jumptableaddr is the address (constant) of the Jump Table
- * @param jumpreg is the register used to perform the indirect jump
- * @param indexreg contains jump table index value
- */
- .macro _dbg_jumpTableHandler jumptableaddr, jumpreg, indexreg
-
- ldr \jumpreg, =\jumptableaddr
- ldr \jumpreg, [\jumpreg, \indexreg, lsl #2]
- mov lr, pc
- bx \jumpreg /* Call Command Handler Routine */
- .endm
-
-
-/** _dbg_thumbDecodeEntry
- * Load Thumb Instruction Decoder Entry
- * On entry:
- * @param instrreg is the register to load the instruction into
- * @param instrmask is the register to load the instruction mask into
- * @param codehandler is the register to load the code handling routine into
- * @param indexreg contains decode table index value
- * NOTE: instrreg, instrmask, codehandler must be in increasing register number order
- */
- .macro _dbg_thumbDecodeEntry instrreg, instrmask, codehandler, indexreg
-
- ldr \instrmask, =debug_thumbDecodeTable /* Temporary register */
- add \instrmask, \instrmask, \indexreg, lsl #3
- ldm \instrmask, {\instrreg, \codehandler} /* LSHW: IID, MSHW: IBM */
- mov \instrmask, \instrreg, lsr #16
- mov \instrreg, \instrreg, lsl #16
- mov \instrreg, \instrreg, lsr #16 /* Keep HLFWORD0 containing instruction */
- .endm
-
-/** _dbg_armDecodeEntry
- * Load ARM Instruction Decoder Entry
- * On entry:
- * @param instrreg is the register to load the instruction into
- * @param instrmask is the register to load the instruction mask into
- * @param codehandler is the register to load the code handling routine into
- * @param indexreg contains decode table index value
- * NOTE: instrreg, instrmask, codehandler must be in increasing register number order
- */
- .macro _dbg_armDecodeEntry instrreg, instrmask, codehandler, indexreg
-
- ldr \instrmask, =debug_armDecodeTable /* Temporary register */
- add \instrmask, \instrmask, \indexreg, lsl #3
- add \instrmask, \instrmask, \indexreg, lsl #2 /* 12 byte entries */
- ldm \instrmask, {\instrreg, \instrmask, \codehandler}
- .endm
-
-/** _asciiz
- * Terminate string given string buffer pointer in \strptr
- * scratchreg is used as a scratch register (destroyed)
- *
- */
- .macro _asciiz strptr, scratchreg
- mov \scratchreg, #0 /* ASCIIZ character */
- strb \scratchreg, [\strptr] /* Terminate ASCII string */
- .endm
-
-
-/** _dbg_stpcpy
- * _dbg_stpcpy macro
- * On entry:
- * deststrptr: Destination string
- * sourcestrptr: Source string
- * scratchreg: scratch register for copying
- * On exit:
- * deststrptr: Pointer to ASCIIZ character in destination string
- * sourcestrptr: Pointer to next character slot in source string (after ASCIIZ)
- * scratchreg: destroyed
- */
- .macro _dbg_stpcpy deststrptr, sourcestrptr, scratchreg
-1: ldrb \scratchreg, [\sourcestrptr], #1
- strb \scratchreg, [\deststrptr], #1
- teq \scratchreg, #0
- bne 1b
- sub \deststrptr, \deststrptr, #1 /* Adjust Destination string pointer to point at ASCIIZ character */
- .endm
-
-/** _dbg_memcpy
- * _dbg_stpcpy macro
- * On entry:
- * deststrptr: Destination string
- * sourcestrptr: Source string
- * sizereg: Number of bytes to copy
- * scratchreg: scratch register for copying
- * On exit:
- * deststrptr: Pointer to next character slot in destination string
- * sourcestrptr: Pointer to next character slot in source string
- * sizereg, scratchreg: destroyed
- */
- .macro _dbg_memcpy deststrptr, sourcestrptr, sizereg, scratchreg
-1: ldrb \scratchreg, [\sourcestrptr], #1
- strb \scratchreg, [\deststrptr], #1
- subs \sizereg, \sizereg, #1
- bne 1b
- .endm
-
-/** _dbg_CopyMsg2OutputBuf
- * Copies source message to output buffer
- * On entry:
- * R2: source message buffer (ASCIIZ terminated)
- * On exit:
- * R0: Pointer to Output Buffer ASCIIZ location
- * R2-R3: destroyed
- */
- .macro _dbg_CopyMsg2OutputBuf
- ldr r0, =debug_OutMsgBuf
- _dbg_stpcpy r0, r2, r3
- .endm
-
-/** _dbg_CopyMsg2OutputBuf_withParam
- * Internal Routine called to output message with parameters
- * Return Message with byte-sized parameter
- * On entry:
- * R1: byte-sized param
- * R2: source message buffer (ASCIIZ terminated)
- * On exit:
- * R0: Pointer to Output Buffer ASCIIZ location
- * R1-R3: destroyed
- */
- .macro _dbg_CopyMsg2OutputBuf_withParam
- _dbg_CopyMsg2OutputBuf /* R1 unchanged */
- bl byte2ascii /* R0 points to buffer position after byte value */
- _asciiz r0, r1
- .endm
-
-/** _dbg_outputAckOnlyFlag
- * Return Flag ('+') for Continue or Step
- * On exit:
- * R0: Pointer to Output Buffer ASCIIZ location
- * R2-R3: destroyed
- */
- .macro _dbg_outputAckOnlyFlag
- ldr r2, =debug_AckOnlyFlag /* ASCIIZ terminated */
- _dbg_CopyMsg2OutputBuf
- .endm
-
-
-/** _dbg_outputRetransmitFlag
- * Return Flag ('-') for Checksum Error (retransmission needed)
- * On exit:
- * R0: Pointer to Output Buffer ASCIIZ location
- * R2-R3: destroyed
- */
- .macro _dbg_outputRetransmitFlag
- ldr r2, =debug_RetransmitFlag /* ASCIIZ terminated */
- _dbg_CopyMsg2OutputBuf
- .endm
-
-/** _dbg_outputMsgValidResponse
- * Return Message with valid response ('+$')
- * On exit:
- * R0: Pointer to Output Buffer next character slot location
- * R2-R3: destroyed
- */
- .macro _dbg_outputMsgValidResponse
- ldr r2, =debug_ValidResponsePrefix
- _dbg_CopyMsg2OutputBuf
- .endm
-
-/** _dbg_outputMsgStatusOk
- * Return Message with Ok ('+$OK') status
- * On exit:
- * R0: Pointer to Output Buffer ASCIIZ location
- * R2-R3: destroyed
- */
- .macro _dbg_outputMsgStatusOk
- ldr r2, =debug_OkResponse /* ASCIIZ terminated */
- _dbg_CopyMsg2OutputBuf
- .endm
-
-/** _dbg_outputMsgCurrTID
- * Return Message with Default Thread ID ('+$QC0')
- * On exit:
- * R0: Pointer to Output Buffer ASCIIZ location
- * R2-R3: destroyed
- */
- .macro _dbg_outputMsgCurrTID
- ldr r2, =debug_ThreadIDResponse /* ASCIIZ terminated */
- _dbg_CopyMsg2OutputBuf
- .endm
-
-/** _dbg_outputMsgFirstThreadInfo
- * Return Message with Default Current Thread ID ('+$m0')
- * On exit:
- * R0: Pointer to Output Buffer ASCIIZ location
- * R2-R3: destroyed
- */
- .macro _dbg_outputMsgFirstThreadInfo
- ldr r2, =debug_FirstThreadInfoResponse /* ASCIIZ terminated */
- _dbg_CopyMsg2OutputBuf
- .endm
-
-/** _dbg_outputMsgSubsequentThreadInfo
- * Return Message with Default Current Thread ID ('+$m0')
- * On exit:
- * R0: Pointer to Output Buffer ASCIIZ location
- * R2-R3: destroyed
- */
- .macro _dbg_outputMsgSubsequentThreadInfo
- ldr r2, =debug_SubsequentThreadInfoResponse /* ASCIIZ terminated */
- _dbg_CopyMsg2OutputBuf
- .endm
-
-/** _dbg_outputMsgStatusErr
- * Return Message with Error ('+$ENN') status
- * On entry:
- * R1: error code
- * On exit:
- * R0: Pointer to Output Buffer ASCIIZ location
- * R1-R3: destroyed
- */
- .macro _dbg_outputMsgStatusErr
- ldr r2, =debug_ErrorResponsePrefix
- _dbg_CopyMsg2OutputBuf_withParam
- .endm
-
-/** _dbg_outputMsgStatusErrCode
- * Return Message with Error ('+$ENN') status
- * On exit:
- * R0: Pointer to Output Buffer ASCIIZ location
- * R1-R3: destroyed
- */
- .macro _dbg_outputMsgStatusErrCode errcode
- mov r1, #\errcode
- _dbg_outputMsgStatusErr
- .endm
-
-/** _dbg_outputMsgStatusSig
- * Return Message with Signal ('+$SNN') status
- * On entry:
- * R1: signal code
- * On exit:
- * R0: Pointer to Output Buffer ASCIIZ location
- * R1-R3: destroyed
- */
- .macro _dbg_outputMsgStatusSig
- ldr r2, =debug_SignalResponsePrefix
- _dbg_CopyMsg2OutputBuf_withParam
- .endm
-
-/** _dbg_outputMsgStatusSigCode
- * Return Message with Signal ('+$SNN') status
- * On exit:
- * R0: Pointer to Output Buffer ASCIIZ location
- * R1-R3: destroyed
- */
- .macro _dbg_outputMsgStatusSigCode statuscode
- mov r1, #\statuscode
- _dbg_outputMsgStatusSig
- .endm
-
-
-/** _regenum2index
- * Convert register enum to debugger stack index
- *
- * On entry:
- * @param indexenum: enum representing Register to access
- * @param indexreg: register to be used to store the debugger stack index value (0-max index)
- * On exit:
- * @param indexreg contains debugger stack index value (0-max index)
- */
- .macro _regenum2index indexenum, indexreg
- add \indexreg, \indexenum, #DBGSTACK_USERREG_INDEX /* Convert register index to Debug Stack index */
- .endm
-
-/** _getdbgregisterfromindex
- * Retrieve register contents from debugger stack given index
- *
- * On entry:
- * @param indexreg contains debugger stack index value (0-max index)
- * On exit:
- * @param indexreg: Breakpoint index (preserved)
- * @param contentsreg: Register Contents for given index
- */
- .macro _getdbgregisterfromindex indexreg, contentsreg
- ldr \contentsreg, =__debugger_stack_bottom__
- ldr \contentsreg, [\contentsreg, \indexreg, lsl #2]
- .endm
-
-/** _setdbgregisterfromindex
- * Store register contents to debugger stack given index
- *
- * On entry:
- * @param indexreg contains debugger stack index value (0-max index)
- * @param contentsreg: Register Contents for given index
- * @param addressreg: Scratch register for address pointer
- * On exit:
- * @param indexreg: Breakpoint index (preserved)
- * @param contentsreg: Register Contents for given index
- */
- .macro _setdbgregisterfromindex indexreg, contentsreg, addressreg
- ldr \addressreg, =__debugger_stack_bottom__
- str \contentsreg, [\addressreg, \indexreg, lsl #2]
- .endm
-
-/** _getdbgregister
- * Retrieve register contents from debugger stack given immediate index value
- *
- * On entry:
- * @param indexval contains debugger stack index value (0-max index)
- * On exit:
- * @param contentsreg: Register Contents for given index
- */
- .macro _getdbgregister indexval, contentsreg
- ldr \contentsreg, =__debugger_stack_bottom__
- ldr \contentsreg, [\contentsreg, #(\indexval << 2)]
- .endm
-
-/** _setdbgregister
- * Store register contents to debugger stack given immediate index value
- *
- * On entry:
- * @param indexval contains debugger stack index value (0-max index)
- * @param contentsreg: Register Contents for given index
- * @param addressreg: Scratch register for address pointer
- * On exit:
- * @param contentsreg: Register Contents for given index
- * @param addressreg: Destroyed
- */
- .macro _setdbgregister indexval, contentsreg, addressreg
- ldr \addressreg, =__debugger_stack_bottom__
- str \contentsreg, [\addressreg, #(\indexval << 2)]
- .endm
-
-/** _index2bkptindex_addr
- * Convert Breakpoint index to breakpoing entry address
- *
- * On entry:
- * @param indexreg contains breakpoint index value
- * On exit:
- * @param indexreg: Breakpoint index (preserved)
- * @param addrreg: Breakpoint Entry Address
- */
- .macro _index2bkptindex_addr indexreg, addrreg
- ldr \addrreg, =__breakpoints_start__
- add \addrreg, \addrreg, \indexreg, lsl #3 /* Calculate Breakpoint Entry Address */
- .endm
-
-/** _dbg_getstate
- * Get Debugger State
- * On exit:
- * @param reg: Debugger State enum
- */
- .macro _dbg_getstate reg
- ldr \reg, =debug_state
- ldrb \reg, [\reg]
- .endm
-
-/** _dbg_setstate
- * Set Debugger State to given value
- * On exit:
- * r0, r1: destroyed
- */
- .macro _dbg_setstate state
- mov r0, #\state
- ldr r1, =debug_state
- strb r0, [r1]
- .endm
-
-/** _dbg_getmode
- * Get Debugger Mode
- * On exit:
- * @param reg: Debugger Mode (Boolean)
- */
- .macro _dbg_getmode reg
- ldr \reg, =debug_mode
- ldrb \reg, [\reg]
- .endm
-
-/** _dbg_setmode
- * Set Debugger Mode to given value
- * On exit:
- * r0, r1: destroyed
- */
- .macro _dbg_setmode mode
- mov r0, #\mode
- ldr r1, =debug_mode
- strb r0, [r1]
- .endm
-
-/** _dbg_get_bkpt_type
- * Get Breakpoint Type
- * On exit:
- * @param reg: Breakpoint Type
- */
- .macro _dbg_get_bkpt_type reg
- ldr \reg, =debug_bkpt_type
- ldrb \reg, [\reg]
- .endm
-
-/** _dbg_set_bkpt_type
- * Set Breakpoint Type using value in reg
- * On exit:
- * @param reg: destroyed
- * r1: destroyed
- */
- .macro _dbg_set_bkpt_type reg
- ldr r1, =debug_bkpt_type
- strb \reg, [r1]
- .endm
-
-/** _dbg_set_bkpt_type_val
- * Set Breakpoint Type to given value
- * On exit:
- * r0, r1: destroyed
- */
- .macro _dbg_set_bkpt_type_val bkpt_type
- mov r0, #\bkpt_type
- ldr r1, =debug_bkpt_type
- strb r0, [r1]
- .endm
-
-/** _dbg_getcurrbkpt_index
- * Get current breakpoint index
- * On exit:
- * @param reg: Breakpoint index
- */
- .macro _dbg_getcurrbkpt_index reg
- ldr \reg, =debug_curr_breakpoint
- ldrb \reg, [\reg]
- .endm
-
-/** _dbg_setcurrbkpt_index
- * Set current breakpoint index
- * On exit:
- * r1: destroyed
- */
- .macro _dbg_setcurrbkpt_index reg
- ldr r1, =debug_curr_breakpoint
- strb \reg, [r1]
- .endm
-
- /*@}*/
-
-#endif /* __DEBUG_MACROS_H__ */
diff --git a/Debugger/debug_opcodes.S b/Debugger/debug_opcodes.S
deleted file mode 100644
index 307da8b..0000000
--- a/Debugger/debug_opcodes.S
+++ /dev/null
@@ -1,1499 +0,0 @@
-/** @file debug_opcodes.S
- * @brief ARM Debugger Opcode Parsing Routines
- *
- */
-
-/* Copyright (C) 2007-2011 the NxOS developers
- *
- * Module Developed by: TC Wan <tcwan@cs.usm.my>
- *
- * See AUTHORS for a full list of the developers.
- *
- * See COPYING for redistribution license
- *
- */
-
-/* WARNING: The following excepted code from eCos arm_stub.c has bugs in
- * the next instruction address calculation logic. The C code has not been
- * updated since it is only used for documentation purposes.
- *
- * Correct code behavior should be determined from the ARMDEBUG source code
- * whenever there is conflict in the algorithms.
- *
- * Of note: ARM and Thumb mode BX PC handling (missing PC+8/PC+4 adjustment).
- * LDM PC handling (missing Pre/Post Incr/Decr adjustment).
- */
-/****************************************************************************
-// Selected Routines from the eCos arm_stub.c related to next instruction address
-// determination in ARM processors.
-
-//========================================================================
-//
-// arm_stub.c
-//
-// Helper functions for stub, generic to all ARM processors
-//
-//========================================================================
-// ####ECOSGPLCOPYRIGHTBEGIN####
-// -------------------------------------------
-// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
-//
-// eCos is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 2 or (at your option) any later
-// version.
-//
-// eCos is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with eCos; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// As a special exception, if other files instantiate templates or use
-// macros or inline functions from this file, or you compile this file
-// and link it with other works to produce a work based on this file,
-// this file does not by itself cause the resulting work to be covered by
-// the GNU General Public License. However the source code for this file
-// must still be made available in accordance with section (3) of the GNU
-// General Public License v2.
-//
-// This exception does not invalidate any other reasons why a work based
-// on this file might be covered by the GNU General Public License.
-// -------------------------------------------
-// ####ECOSGPLCOPYRIGHTEND####
-//========================================================================
-//#####DESCRIPTIONBEGIN####
-//
-// Author(s): Red Hat, gthomas
-// Contributors: Red Hat, gthomas, jskov
-// Date: 1998-11-26
-// Purpose:
-// Description: Helper functions for stub, generic to all ARM processors
-// Usage:
-//
-//####DESCRIPTIONEND####
-//
-//========================================================================
-
-
-static int
-ins_will_execute(unsigned long ins)
-{
- unsigned long psr = get_register(PS); // condition codes
- int res = 0;
- switch ((ins & 0xF0000000) >> 28) {
- case 0x0: // EQ
- res = (psr & PS_Z) != 0;
- break;
- case 0x1: // NE
- res = (psr & PS_Z) == 0;
- break;
- case 0x2: // CS
- res = (psr & PS_C) != 0;
- break;
- case 0x3: // CC
- res = (psr & PS_C) == 0;
- break;
- case 0x4: // MI
- res = (psr & PS_N) != 0;
- break;
- case 0x5: // PL
- res = (psr & PS_N) == 0;
- break;
- case 0x6: // VS
- res = (psr & PS_V) != 0;
- break;
- case 0x7: // VC
- res = (psr & PS_V) == 0;
- break;
- case 0x8: // HI
- res = ((psr & PS_C) != 0) && ((psr & PS_Z) == 0);
- break;
- case 0x9: // LS
- res = ((psr & PS_C) == 0) || ((psr & PS_Z) != 0);
- break;
- case 0xA: // GE
- res = ((psr & (PS_N|PS_V)) == (PS_N|PS_V)) ||
- ((psr & (PS_N|PS_V)) == 0);
- break;
- case 0xB: // LT
- res = ((psr & (PS_N|PS_V)) == PS_N) ||
- ((psr & (PS_N|PS_V)) == PS_V);
- break;
- case 0xC: // GT
- res = ((psr & (PS_N|PS_V)) == (PS_N|PS_V)) ||
- ((psr & (PS_N|PS_V)) == 0);
- res = ((psr & PS_Z) == 0) && res;
- break;
- case 0xD: // LE
- res = ((psr & (PS_N|PS_V)) == PS_N) ||
- ((psr & (PS_N|PS_V)) == PS_V);
- res = ((psr & PS_Z) == PS_Z) || res;
- break;
- case 0xE: // AL
- res = TRUE;
- break;
- case 0xF: // NV
- if (((ins & 0x0E000000) >> 24) == 0xA)
- res = TRUE;
- else
- res = FALSE;
- break;
- }
- return res;
-}
-
-static unsigned long
-RmShifted(int shift)
-{
- unsigned long Rm = get_register(shift & 0x00F);
- int shift_count;
- if ((shift & 0x010) == 0) {
- shift_count = (shift & 0xF80) >> 7;
- } else {
- shift_count = get_register((shift & 0xF00) >> 8);
- }
- switch ((shift & 0x060) >> 5) {
- case 0x0: // Logical left
- Rm <<= shift_count;
- break;
- case 0x1: // Logical right
- Rm >>= shift_count;
- break;
- case 0x2: // Arithmetic right
- Rm = (unsigned long)((long)Rm >> shift_count);
- break;
- case 0x3: // Rotate right
- if (shift_count == 0) {
- // Special case, RORx
- Rm >>= 1;
- if (get_register(PS) & PS_C) Rm |= 0x80000000;
- } else {
- Rm = (Rm >> shift_count) | (Rm << (32-shift_count));
- }
- break;
- }
- return Rm;
-}
-
-// Decide the next instruction to be executed for a given instruction
-static unsigned long *
-target_ins(unsigned long *pc, unsigned long ins)
-{
- unsigned long new_pc, offset, op2;
- unsigned long Rn;
- int i, reg_count, c;
-
- switch ((ins & 0x0C000000) >> 26) {
- case 0x0:
- // BX or BLX
- if ((ins & 0x0FFFFFD0) == 0x012FFF10) {
- new_pc = (unsigned long)get_register(ins & 0x0000000F);
- return ((unsigned long *)new_pc);
- }
- // Data processing
- new_pc = (unsigned long)(pc+1);
- if ((ins & 0x0000F000) == 0x0000F000) {
- // Destination register is PC
- if ((ins & 0x0FBF0000) != 0x010F0000) {
- Rn = (unsigned long)get_register((ins & 0x000F0000) >> 16);
- if ((ins & 0x000F0000) == 0x000F0000) Rn += 8; // PC prefetch!
- if ((ins & 0x02000000) == 0) {
- op2 = RmShifted(ins & 0x00000FFF);
- } else {
- op2 = ins & 0x000000FF;
- i = (ins & 0x00000F00) >> 8; // Rotate count
- op2 = (op2 >> (i*2)) | (op2 << (32-(i*2)));
- }
- switch ((ins & 0x01E00000) >> 21) {
- case 0x0: // AND
- new_pc = Rn & op2;
- break;
- case 0x1: // EOR
- new_pc = Rn ^ op2;
- break;
- case 0x2: // SUB
- new_pc = Rn - op2;
- break;
- case 0x3: // RSB
- new_pc = op2 - Rn;
- break;
- case 0x4: // ADD
- new_pc = Rn + op2;
- break;
- case 0x5: // ADC
- c = (get_register(PS) & PS_C) != 0;
- new_pc = Rn + op2 + c;
- break;
- case 0x6: // SBC
- c = (get_register(PS) & PS_C) != 0;
- new_pc = Rn - op2 + c - 1;
- break;
- case 0x7: // RSC
- c = (get_register(PS) & PS_C) != 0;
- new_pc = op2 - Rn +c - 1;
- break;
- case 0x8: // TST
- case 0x9: // TEQ
- case 0xA: // CMP
- case 0xB: // CMN
- break; // PC doesn't change
- case 0xC: // ORR
- new_pc = Rn | op2;
- break;
- case 0xD: // MOV
- new_pc = op2;
- break;
- case 0xE: // BIC
- new_pc = Rn & ~op2;
- break;
- case 0xF: // MVN
- new_pc = ~op2;
- break;
- }
- }
- }
- return ((unsigned long *)new_pc);
- case 0x1:
- if ((ins & 0x02000010) == 0x02000010) {
- // Undefined!
- return (pc+1);
- } else {
- if ((ins & 0x00100000) == 0) {
- // STR
- return (pc+1);
- } else {
- // LDR
- if ((ins & 0x0000F000) != 0x0000F000) {
- // Rd not PC
- return (pc+1);
- } else {
- Rn = (unsigned long)get_register((ins & 0x000F0000) >> 16);
- if ((ins & 0x000F0000) == 0x000F0000) Rn += 8; // PC prefetch!
- if (ins & 0x01000000) {
- // Add/subtract offset before
- if ((ins & 0x02000000) == 0) {
- // Immediate offset
- if (ins & 0x00800000) {
- // Add offset
- Rn += (ins & 0x00000FFF);
- } else {
- // Subtract offset
- Rn -= (ins & 0x00000FFF);
- }
- } else {
- // Offset is in a register
- if (ins & 0x00800000) {
- // Add offset
- Rn += RmShifted(ins & 0x00000FFF);
- } else {
- // Subtract offset
- Rn -= RmShifted(ins & 0x00000FFF);
- }
- }
- }
- return ((unsigned long *)*(unsigned long *)Rn);
- }
- }
- }
- return (pc+1);
- case 0x2: // Branch, LDM/STM
- if ((ins & 0x02000000) == 0) {
- // LDM/STM
- if ((ins & 0x00100000) == 0) {
- // STM
- return (pc+1);
- } else {
- // LDM
- if ((ins & 0x00008000) == 0) {
- // PC not in list
- return (pc+1);
- } else {
- Rn = (unsigned long)get_register((ins & 0x000F0000) >> 16);
- if ((ins & 0x000F0000) == 0x000F0000) Rn += 8; // PC prefetch!
- offset = ins & 0x0000FFFF;
- reg_count = 0;
- for (i = 0; i < 15; i++) {
- if (offset & (1<<i)) reg_count++;
- }
- if (ins & 0x00800000) {
- // Add offset
- Rn += reg_count*4;
- } else {
- // Subtract offset
- Rn -= 4;
- }
- return ((unsigned long *)*(unsigned long *)Rn);
- }
- }
- } else {
- // Branch
- if (ins_will_execute(ins)) {
- offset = (ins & 0x00FFFFFF) << 2;
- if (ins & 0x00800000) offset |= 0xFC000000; // sign extend
- new_pc = (unsigned long)(pc+2) + offset;
- // If its BLX, make new_pc a thumb address.
- if ((ins & 0xFE000000) == 0xFA000000) {
- if ((ins & 0x01000000) == 0x01000000)
- new_pc |= 2;
- new_pc = MAKE_THUMB_ADDR(new_pc);
- }
- return ((unsigned long *)new_pc);
- } else {
- // Falls through
- return (pc+1);
- }
- }
- case 0x3: // Coprocessor & SWI
- if (((ins & 0x03000000) == 0x03000000) && ins_will_execute(ins)) {
- // SWI
- return (unsigned long *)(CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT * 4);
- } else {
- return (pc+1);
- }
- default:
- // Never reached - but fixes compiler warning.
- return 0;
- }
-}
-
-// FIXME: target_ins also needs to check for CPSR/THUMB being set and
-// set the thumb bit accordingly.
-
-static unsigned long
-target_thumb_ins(unsigned long pc, unsigned short ins)
-{
- unsigned long new_pc = MAKE_THUMB_ADDR(pc+2); // default is fall-through
- // to next thumb instruction
- unsigned long offset, arm_ins, sp;
- int i;
-
- switch ((ins & 0xf000) >> 12) {
- case 0x4:
- // Check for BX or BLX
- if ((ins & 0xff07) == 0x4700)
- new_pc = (unsigned long)get_register((ins & 0x00078) >> 3);
- break;
- case 0xb:
- // push/pop
- // Look for "pop {...,pc}"
- if ((ins & 0xf00) == 0xd00) {
- // find PC
- sp = (unsigned long)get_register(SP);
-
- for (offset = i = 0; i < 8; i++)
- if (ins & (1 << i))
- offset += 4;
-
- new_pc = *(cyg_uint32 *)(sp + offset);
-
- if (!v5T_semantics())
- new_pc = MAKE_THUMB_ADDR(new_pc);
- }
- break;
- case 0xd:
- // Bcc | SWI
- // Use ARM function to check condition
- arm_ins = ((unsigned long)(ins & 0x0f00)) << 20;
- if ((arm_ins & 0xF0000000) == 0xF0000000) {
- // SWI
- new_pc = CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT * 4;
- } else if (ins_will_execute(arm_ins)) {
- offset = (ins & 0x00FF) << 1;
- if (ins & 0x0080) offset |= 0xFFFFFE00; // sign extend
- new_pc = MAKE_THUMB_ADDR((unsigned long)(pc+4) + offset);
- }
- break;
- case 0xe:
- // check for B
- if ((ins & 0x0800) == 0) {
- offset = (ins & 0x07FF) << 1;
- if (ins & 0x0400) offset |= 0xFFFFF800; // sign extend
- new_pc = MAKE_THUMB_ADDR((unsigned long)(pc+4) + offset);
- }
- break;
- case 0xf:
- // BL/BLX (4byte instruction!)
- // First instruction (bit 11 == 0) holds top-part of offset
- if ((ins & 0x0800) == 0) {
- offset = (ins & 0x07FF) << 12;
- if (ins & 0x0400) offset |= 0xFF800000; // sign extend
- // Get second instruction
- // Second instruction (bit 11 == 1) holds bottom-part of offset
- ins = *(unsigned short*)(pc+2);
- // Check for BL/BLX
- if ((ins & 0xE800) == 0xE800) {
- offset |= (ins & 0x07ff) << 1;
- new_pc = (unsigned long)(pc+4) + offset;
- // If its BLX, force a full word alignment
- // Otherwise, its a thumb address.
- if (!(ins & 0x1000))
- new_pc &= ~3;
- else
- new_pc = MAKE_THUMB_ADDR(new_pc);
- }
- }
- break;
- }
-
- return new_pc;
-}
-
-void __single_step (void)
-{
- unsigned long pc = get_register(PC);
- unsigned long cpsr = get_register(PS);
-
- // Calculate address of next instruction to be executed
- if (cpsr & CPSR_THUMB_ENABLE) {
- // thumb
- ss_saved_pc = target_thumb_ins(pc, *(unsigned short*)pc);
- } else {
- // ARM
- unsigned long curins = *(unsigned long*)pc;
- if (ins_will_execute(curins)) {
- // Decode instruction to decide what the next PC will be
- ss_saved_pc = (unsigned long) target_ins((unsigned long*)pc,
- curins);
- } else {
- // The current instruction will not execute (the conditions
- // don't hold)
- ss_saved_pc = pc+4;
- }
- }
-
- // Set breakpoint according to type
- if (IS_THUMB_ADDR(ss_saved_pc)) {
- // Thumb instruction
- unsigned long t_pc = UNMAKE_THUMB_ADDR(ss_saved_pc);
- ss_saved_thumb_instr = *(unsigned short*)t_pc;
- *(unsigned short*)t_pc = HAL_BREAKINST_THUMB;
- } else {
- // ARM instruction
- ss_saved_instr = *(unsigned long*)ss_saved_pc;
- *(unsigned long*)ss_saved_pc = HAL_BREAKINST_ARM;
- }
-}
-
- ****************************************************************************/
-
-#define __ASSEMBLY__
-#include "debug_stub.h"
-#include "debug_internals.h"
-#include "debug_macros.h"
-
-.data
-.align 4
-/* Rm Shifted Shift Type Jump Table
- * On entry:
- * R0: Register Rm
- * R1: Shift/Rotate Amount
- * On exit:
- * R0: RmShifted result
- *
- */
-debug_regShiftJumpTable:
- .word _reg_lsl /* 00 */
- .word _reg_lsr /* 01 */
- .word _reg_asr /* 02 */
- .word _reg_ror /* 03 */
- .word _reg_rrx /* 04 */
-
-/* Data Processing Instruction Jump Table
- * On entry:
- * R0: Register Rn (Operand 1) value
- * R1: Operand 2 value
- * R2: Default Next Instruction Address
- * R5[3:0]: CPSR condition codes
- * On exit:
- * R0: Calculated result
- * R1, R2, R3: Destroyed
- *
- */
-debug_dataInstrJumpTable:
- .word _opcode_and /* 00 */
- .word _opcode_eor /* 01 */
- .word _opcode_sub /* 02 */
- .word _opcode_rsb /* 03 */
- .word _opcode_add /* 04 */
- .word _opcode_adc /* 05 */
- .word _opcode_sbc /* 06 */
- .word _opcode_rsc /* 07 */
- .word _opcode_tst /* 08 */
- .word _opcode_teq /* 09 */
- .word _opcode_cmp /* 0A */
- .word _opcode_cmn /* 0B */
- .word _opcode_orr /* 0C */
- .word _opcode_mov /* 0D */
- .word _opcode_bic /* 0E */
- .word _opcode_mvn /* 0F */
-
-
-/*
- * To determine the next instruction to execute, we need to check current (breakpointed) instruction
- * and determine whether it will be executed or not. This necessitates a mini instruction decoder
- * that can check the type of instruction, as well as if it'll affect the PC.
- * The instruction decoder used here is table based. Each entry in the table consists of:
- * Instruction Identifier (IID), Instruction Bitmask (IBM), Instruction Handler Address (IHA)
- * Null entries are placed at the end of the table.
- *
- * This allows for a flexible approach to handling instructions that we're interested in, at the expense
- * of memory usage.
- *
- * For ARM, the IID & IBM are both 4 bytes, whereas the Thumb IID & IBM are 2 bytes.
- * The IHA is always 4 bytes.
- */
-
-/* ARM Instruction Decode Table
- * .word IID, IBM, IHA (12 bytes)
- */
-
-/* WARNING: The sequence of matching instructions is important!
- * Always check from more specific to more general IBMs
- * for instructions sharing common opcode prefix bits.
- */
-debug_armDecodeTable:
- .word 0x012fff10, 0x0ffffff0, _arm_bx_blx_handler /* [Prefix:00] BX or BLX. Note v4t does not have BLX instr */
- .word 0x0000f000, 0x0c00f000, _arm_data_instr_handler /* [Prefix:00] Data Processing instr with Rd = R15 */
-/* .word 0x06000010, 0x0e000010, _arm_undef_handler */ /* [Prefix:01] Undefined instr: shouldn't occur, as it would've been trapped already. See _dbg_following_instruction_addr */
- .word 0x0410f000, 0x0410f000, _arm_ldr_pc_handler /* [Prefix:01] LDR with Rd = PC */
- .word 0x08108000, 0x0e108000, _arm_ldm_pc_handler /* [Prefix:10] LDM {pc} */
- .word 0x0a000000, 0x0e000000, _arm_b_bl_blx_handler /* [Prefix:10] B, BL or BLX. Note v4t does not have BLX instr */
- .word 0x0c000000, 0x0c000000, _arm_coproc_swi_handler /* [Prefix:11] Coprocessor instr or SWI */
- .word 0x0,0x0,0x0 /* Null Entry */
-
-/* Thumb Instruction Decode Table
- * .hword IID, IBM
- * .word IHA (8 bytes)
- */
-
-/* WARNING: The sequence of matching instructions is important!
- * Always check from more specific to more general IBMs
- * for instructions sharing common opcode prefix bits.
- */
-debug_thumbDecodeTable:
- .hword 0x4700, 0xff07
- .word _thumb_bx_blx_handler /* [Prefix:01] BX or BLX. Note: Link (L:b7) is not checked in the mask */
- .hword 0xbd00, 0xff00
- .word _thumb_poppc_handler /* [Prefix:10] PUSH/POP, specifically POP {Rlist,PC} */
- .hword 0xd000, 0xf000
- .word _thumb_bcond_swi_handler /* [Prefix:11] B<cond> or SWI */
- .hword 0xe000, 0xf800
- .word _thumb_b_handler /* [Prefix:11] B */
- .hword 0xf000, 0xf000
- .word _thumb_long_bl_blx_handler /* [Prefix:11] Long BL or BLX (4 bytes) Note: b11 (H) indicates 1st or 2nd instr */
- .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
- */
-
-
-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, 0xFF, 0xFF, 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 HI, LS, GE, LT, GT and LE instructions only
- * Condition Code stored in the following order:
- * b7 b6 b5 b4 b3 b2 b1 b0
- * AND CHKZ CHKC CHKNV - Z set C set N==V (bit set = 1)
- * OR - - - - Z clr C clr N!=V (bit clr = 0)
- *
- * HI: C set AND Z clr
- * LS: C clr OR Z set
- * GE: N == V
- * LT: N != V
- * GT: Z clr AND (N == V)
- * LE: Z set OR (N != V)
- */
-
-#define COMPLEX_CONDCODE_START 0x08
-#define COMPLEX_CONDCODE_NEQV_MASK 0x01
-#define COMPLEX_CONDCODE_CSET_MASK 0x02
-#define COMPLEX_CONDCODE_ZSET_MASK 0x04
-#define COMPLEX_CONDCODE_CHKNV_MASK 0x10
-#define COMPLEX_CONDCODE_CHKC_MASK 0x20
-#define COMPLEX_CONDCODE_CHKZ_MASK 0x40
-#define COMPLEX_CONDCODE_ANDOR_MASK 0x80
-
-#define COMPLEX_CONDCODE_NFLAG 0x08
-#define COMPLEX_CONDCODE_ZFLAG 0x04
-#define COMPLEX_CONDCODE_CFLAG 0x02
-#define COMPLEX_CONDCODE_VFLAG 0x01
-
-
-debug_armComplexCCTable:
- /* HI, LS, GE, LT, GT, LE */
- .byte 0xE2, 0x64, 0x11, 0x10, 0xD1, 0x54
-
-.code 32
-.text
-.align 4
-
-/* dbg_following_instruction_addr
- * Determine the address of the following instruction to execute.
- * On entry:
- * R0: Address of the instruction to be (re)executed
- * On exit:
- * R0: Destroyed
- * R1: Following Instruction Address (31 bits, b0 = THUMB flag)
- * R2-R7: Destroyed
- *
- * Here we make use of the Debugger Stack which contains the address of the aborted instruction that will be reexecuted
- * when we resume the program.
- *
- * If it is a Manual Breakpoint inserted into the code, then we will need to update the aborted instruction
- * address to skip the current aborted instruction and resume execution at the next instruction address,
- * and the next instruction address to be returned to the calling routine is the following instruction
- * address instead.
- *
- * We need to check the aborted instruction type, to see if it is a branch instruction, before we can determine
- * the next instruction address (for inserting a Breakpoint).
- */
- .global dbg_following_instruction_addr
-dbg_following_instruction_addr:
- stmfd sp!, {lr}
-/* We assume that any BKPT instructions in the code will be Manual Breakpoints,
- * i.e., the Debugger does not leave stray Single Step / Auto / Normal breakpoints in memory
- */
- mov r6, r0 /* Keep instruction address in R6 */
- _getdbgregister DBGSTACK_USERCPSR_INDEX, r1 /* Retrieve User CPSR into R1 */
- and r0, r1, #CPSR_THUMB /* store Thumb Mode status in R0 */
- mov r5, r1, lsr #28 /* store CPSR condition flags in R5[3:0] */
-
-_dbg_get_aborted_instr:
-1: teq r0, #0 /* Check if it is ARM or Thumb instruction */
- ldrneh r4, [r6] /* Load Thumb instruction opcode using Addr in R6 into R4 */
- ldrne r2, =(BKPT16_INSTR | BKPT16_MANUAL_BKPT) /* check for Thumb Manual Breakpoint Instruction */
- ldreq r4, [r6] /* Load ARM instruction opcode using Addr in R6 into R4 */
- ldreq r2, =(BKPT32_INSTR | BKPT32_MANUAL_BKPT) /* check for ARM Manual Breakpoint Instruction */
- teq r4, r2 /* Is instruction opcode (R4) == Manual Breakpoint opcode (R2)? */
- bne 2f /* Not Manual breakpoint */
- teq r0, #0 /* Check if it is ARM or Thumb Manual Breakpoint */
- addne r6, r6, #2 /* Is Manual Breakpoint, Skip to next Thumb instruction */
- addeq r6, r6, #4 /* Is Manual Breakpoint, Skip to next ARM instruction */
- b 1b /* To protect against a sequence of Manual Breakpoint Instructions */
-
-/* Here, R4 contains the instruction opcode which will be (re)executed when program resumes.
- * We need to dissect it to see if it is a branch instruction.
- * For ARM instructions, we also need to evaluate the current (breakpointed) instruction to see if it'll execute.
- * If not, then the following instruction is at the address following the address of the opcode in R4 (Default Following Instruction Address in R6).
- */
-2:
- teq r0, #0 /* Check if current instruction is ARM or Thumb instruction */
- beq _following_instr_addr_for_arm
-_following_instr_addr_for_thumb:
- add r6, r6, #2 /* Store default following Thumb instruction address to R6 */
-#if 0
- /* Flag Thumb instruction only within the instruction handler */
- orr r6, r6, #BKPT_STATE_THUMB_FLAG /* Set b0 to indicate Thumb instruction */
-#endif
- /* R4: Candidate Instruction Opcode
- * R5[3:0]: CPSR condition codes
- * R6: Default Following Instruction Address (PC+2)
- */
- bl _eval_thumb_instruction /* following address is either ARM or Thumb */
- /* We must set this the Thumb bit only within the instruction handler since BX would switch modes */
- b _exit_dbg_following_instruction_addr
-
-_following_instr_addr_for_arm:
- add r6, r6, #4 /* Store default following ARM instruction address to R6 */
- /* R4: Candidate Instruction Opcode
- * R5[3:0]: CPSR condition codes
- * R6: Default Following Instruction Address (PC+4)
- */
- bl _eval_arm_instruction
-
-_exit_dbg_following_instruction_addr:
- mov r1, r0 /* Return Actual Following Instruction Address in R1 (B0 set to indicate Thumb mode) */
- ldmfd sp!, {pc}
-
-
-/* _eval_arm_instruction
- * Evaluate ARM instruction to determine following instruction address
- * On entry:
- * R4: Opcode of instruction to be executed
- * R5[3:0]: CPSR condition codes
- * R6: Default Following Instruction Address (PC+4)
- * On exit:
- * R0: following instruction address (B0 set to indicate Thumb mode)
- * R1-R7: destroyed
- */
-_eval_arm_instruction:
- stmfd sp!, {lr}
- bl _dbg_check_arm_condcode /* Returns R0: will_execute (boolean) */
- teq r0, #FALSE
- moveq r0, r6 /* If False (don't execute), so use Default Following Instruction Address */
- beq _exit_eval_arm_instruction /* and Return to caller */
-
-_will_execute_arm_instr:
- mov r0, #0 /* initialize ARM Decode Entry Table index register */
-1:
- _dbg_armDecodeEntry r1, r2, r3, r0 /* instrreg (R1), instrmask (R2), codehandler (R3), indexreg (R0) */
- teq r1, #0 /* Check for Null Entry (End of Table marker) */
- moveq r0, r6 /* End of Table, no match found, so use Default Following Instruction Address */
- beq _exit_eval_arm_instruction
- and r7, r4, r2 /* Use R7 to check masked instruction opcode (from R4) to see if it matches template (in R1) */
- teq r7, r1
- addne r0, r0, #1 /* No match, so keep looking */
- bne 1b
-
-_call_arm_code_handler:
- mov lr, pc
- bx r3 /* Call Code Handler with R4: Instruction Opcode, R5[3:0]: CPSR, R6: Default Following Instruction Address */
-_exit_eval_arm_instruction:
- /* Returned Following Address Instruction in R0 (B0 set to indicate Thumb mode) */
- ldmfd sp!, {pc}
-
-/* _eval_thumb_instruction
- * Evaluate Thumb instruction to determine following instruction address
- * On entry:
- * R4: Opcode of instruction to be executed
- * R5[3:0]: CPSR condition codes
- * R6: Default Following Instruction Address (PC+2)
- * On exit:
- * R0: following instruction address (B0 set to indicate Thumb mode)
- * R1-R7: destroyed
- */
-_eval_thumb_instruction:
- stmfd sp!, {lr}
- /* Only B<cond> instructions are conditionally executed, deal with it in that Code Handler */
- mov r0, #0 /* initialize Thumb Decode Entry Table index register */
-1:
- _dbg_thumbDecodeEntry r1, r2, r3, r0 /* instrreg (R1), instrmask (R2), codehandler (R3), indexreg (R0) */
- teq r1, #0 /* Check for Null Entry (End of Table marker) */
- moveq r0, r6 /* End of Table, no match found, so use Default Following Instruction Address */
- orreq r0, r0, #BKPT_STATE_THUMB_FLAG /* Set R0[0] to flag Thumb mode */
- beq _exit_eval_thumb_instruction
-
- and r7, r4, r2 /* Use R5 to check masked instruction opcode (from R4) to see if it matches template (in R1) */
- teq r7, r1
- addne r0, r0, #1 /* No match, so keep looking */
- bne 1b
-
-_call_thumb_code_handler:
- mov lr, pc
- bx r3 /* Call Code Handler with R4: Instruction Opcode, R5[3:0]: CPSR, R6: Default Following Instruction Address */
-_exit_eval_thumb_instruction:
- /* Returned Following Address Instruction in R0 */
- ldmfd sp!, {pc}
-
-
-/****************************************************************************
- *
- * Instruction Decode Routines
- *
- ****************************************************************************/
-
-/* _dbg_check_arm_condcode
- * Check ARM conditional execution code
- * On entry:
- * R4: Opcode of instruction to be executed
- * R5[3:0]: CPSR condition codes
- * On exit:
- * R0: will_execute (boolean)
- * R1-R3: Destroyed
- */
-
-_dbg_check_arm_condcode:
- mov r0, #TRUE /* Default will_execute value */
- mov r3, r4, lsr #28 /* convert opcode's condition code to index (0-F) */
- ldr r2, =debug_armCondCodeTable
- ldrb r1, [r2, r3] /* Get condition code mask */
-/*
- * The following check is unnecessary as it is covered by the _dbg_cond_simple_checks checking algorithm
- teq r1, #0
- beq _dbg_check_arm_condcode_exit
-*/
- teq r1, #0xFF
- bne _dbg_cond_simple_checks
-
-
-/*
- * Complex Checks:
- * We assume that CHKNV and CHKC are mutually exclusive.
- * In addition, it is possible for CHKNV, CHKC and CHKZ to
- * be cleared, in which case it'll return True (default)
- *
- *
- * will_execute = TRUE [default condition]
- * If (CHKNV) set
- * // Only N/V, and Z flags are involved
- * NEQV_Flag = (N == V)
- * will_execute = (NEQV_Flag == NEQV_Mask)
- *
- * If (CHKC) set
- * // Only C and Z flags are involved
- * will_execute = (C_Flag == CSet_Mask)
- *
- * If (CHKZ) set
- * z_match = (Z_Flag == ZSet_Mask)
- * If (AND bit set)
- * will_execute = will_execute && z_match
- * else
- * will_execute = will_execute || z_match
- *
- */
-_dbg_cond_complex_checks:
- sub r3, r3, #COMPLEX_CONDCODE_START /* Convert complex condition code in R3 to new index (0-3) */
- ldr r2, =debug_armComplexCCTable
- ldrb r1, [r2, r3] /* Get complex condition code bitmap in R1 */
-
-_cond_check_nv:
- tst r1, #COMPLEX_CONDCODE_CHKNV_MASK
- beq _cond_check_c /* CHECKNV not set, so skip */
- ands r2, r5, #(COMPLEX_CONDCODE_NFLAG | COMPLEX_CONDCODE_VFLAG) /* Is (N == V == 0)? */
- teqne r2, #(COMPLEX_CONDCODE_NFLAG | COMPLEX_CONDCODE_VFLAG) /* No, Is (N == V == 1)? */
-
- moveq r2, #COMPLEX_CONDCODE_NEQV_MASK /* EQ: Either (N == V == 0) or (N == V == 1), set R2: COMPLEX_CONDCODE_NEQV_MASK */
- movne r2, #0 /* NE: N != V, clear R2 */
- and r3, r1, #COMPLEX_CONDCODE_NEQV_MASK /* R3: Extract NEQV Mask Value */
- teq r2, r3 /* Does N/V Condition match NEQV Mask value? */
- movne r0, #FALSE /* No, so will_execute = FALSE (for now) */
- b _cond_check_z
-
-#if 0
- bne _cond_nnev /* No, so (N != V) */
-
- /* EQ: Either (N == V == 0) or (N == V == 1) */
-_cond_neqv:
- tst r1, #COMPLEX_CONDCODE_NEQV_MASK /* Is (N == V) mask set? */
- moveq r0, #FALSE /* No, so will_execute = FALSE (for now) */
- b _cond_check_z
-
- /* Else, N != V */
-_cond_nnev:
- tst r1, #COMPLEX_CONDCODE_NEQV_MASK /* Is (N == V) mask set? */
- movne r0, #FALSE /* Yes, so will_execute = FALSE (for now) */
- b _cond_check_z
-#endif
-
-_cond_check_c:
- tst r1, #COMPLEX_CONDCODE_CHKC_MASK
- beq _cond_check_z /* CHECKC not set, so skip */
-
- /* Use R2 to store C Flag, R3 to store CSet Mask */
- and r2, r5, #COMPLEX_CONDCODE_CFLAG /* r2 = C flag */
- and r3, r1, #COMPLEX_CONDCODE_CSET_MASK /* r3 = CSet mask */
- teq r2, r3 /* Does C flag == CSet mask */
- movne r0, #FALSE /* No, so C flag failed match */
-
-_cond_check_z:
- tst r1, #COMPLEX_CONDCODE_CHKZ_MASK
- beq _dbg_check_arm_condcode_exit /* No additional checks needed, exit */
-
- /* Use R2 to store Z Flag, R3 to store ZSet Mask */
- and r2, r5, #COMPLEX_CONDCODE_ZFLAG /* r2 = Z flag */
- and r3, r1, #COMPLEX_CONDCODE_ZSET_MASK /* r3 = ZSet mask */
- teq r2, r3 /* Does Z flag == ZSet mask */
- moveq r3, #TRUE /* Zero, so z flag matched */
- movne r3, #FALSE /* Non-zero, so z flag failed match */
-
-_cond_andor:
- tst r1, #COMPLEX_CONDCODE_ANDOR_MASK /* Is ANDOR mask set? */
- andne r0, r0, r3 /* Yes, so AND with will_execute */
- orreq r0, r0, r3 /* No, so OR with will_execute */
- b _dbg_check_arm_condcode_exit /* Return will_execute (R0) */
-
-/*
- * Simple Checks:
- * We take advantage of the fact that only 1 bit would be set
- * in the bitmask, by generating the corresponding actual
- * CondSet[7:4], CondClr[3:0] value for comparison.
- *
- * will_execute = TRUE [default condition, equivalent to 0x00 (AL) ]
- * Generate CondSetClr[7:0] from CPSR[3:0]
- * will_execute = ((CondSetClr & BitMask) == BitMask)
- *
- */
-_dbg_cond_simple_checks:
- eor r2, r5, #NIBBLE0 /* R2: CondClr[3:0] = Invert CPSR[3:0] */
- orr r2, r2, r5, lsl #4 /* R2: CondSet[7:4] | CondClr[3:0] */
- and r2, r2, r1 /* R2: CondSetClr[7:0] & Bitmask */
- teq r2, r1 /* ((cond_code & SetBitMask) == SetBitMask)? */
- movne r0, #FALSE /* Not equal, check failed */
-
-_dbg_check_arm_condcode_exit:
- bx lr /* Return to caller */
-
-/* _arm_rmshifted_val
- * Calculate value of Shifted Rm (operand)
- * On entry:
- * R0[11:0]: Shifted Rm operand
- * On exit:
- * R0: value of Shifted Rm
- * R1, R2, R3: destroyed
- */
-_arm_rmshifted_val:
- stmfd sp!, {lr}
- ldr r3, =(NIBBLE2|BYTE0)
- and r3, r0, r3 /* 12 bit Shifted Register operand, copied to R3 */
- and r2, r3, #NIBBLE0 /* Register Rn Enum in R2 */
- _regenum2index r2, r2 /* Convert Enum into Index in R2 */
- _getdbgregisterfromindex r2, r0 /* Retrieve Register Rn contents from Index (R2) into R0 */
-
- tst r3, #0x10 /* B4: Immediate (0) or Register (1) shift count */
- /* check bitshift op */
- and r3, r3, #0x60 /* shift type */
- mov r3, r3, lsr #5 /* convert into shift type jumptable index */
- bne _arm_get_reg_shift /* Flags set previously via TST r3 (B4) */
-_arm_calc_const_shift:
- movs r1, r3, lsr #7 /* Immediate shift count, 5 bit unsigned value in R1 */
- bne _arm_calc_shifted_rm_val /* Non-zero shift count, process normally */
- /* Must check for RRX == ROR #0 */
- teq r3, #0x3 /* ROR == 0x3 */
- addeq r3, r3, #1
- b _arm_calc_shifted_rm_val
-
-_arm_get_reg_shift:
- mov r2, r3, lsr #8 /* Register-based shift count, 4 bit register enum in R2 */
- _regenum2index r2, r2 /* Convert Enum into Index in R2 */
- _getdbgregisterfromindex r2, r1 /* Retrieve Register value (shift count) from Index (R2) into R1 */
-
-_arm_calc_shifted_rm_val:
- _dbg_jumpTableHandler debug_regShiftJumpTable, r2, r3 /* Calculate RmShifted value from R0: Rn Register val, R1: Shift/Rotate val */
- ldmfd sp!, {pc}
-
-/* Rm Shifted Shift Type Jump Table Routines
- * On entry:
- * R0: Register Rm
- * R1: Shift/Rotate Amount
- * On exit:
- * R0: RmShifted result
- * R1: destroyed
- *
- */
-_reg_lsl:
- lsl r0, r0, r1
- bx lr
-
-_reg_lsr:
- lsr r0, r0, r1
- bx lr
-
-_reg_asr:
- asr r0, r0, r1
- bx lr
-
-_reg_ror:
- ror r0, r0, r1
- bx lr
-
-_reg_rrx:
- _getdbgregister DBGSTACK_USERCPSR_INDEX, r1 /* Retrieve CPSR contents into R1 */
- ands r1, r1, #CPSR_CFLAG /* Keep C Flag */
- movne r1, #0x80000000 /* Set B31 if C Flag set */
- lsr r0, r0, #1 /* Rm >> 1 */
- orr r0, r0, r1 /* Put C flag into B31 */
- bx lr
-
-
-/* _arm_data_instr_handler
- * ARM Data Processing Instruction with Rd == R15
- * On entry:
- * R4: Opcode of instruction to be executed
- * R5[3:0]: CPSR condition codes
- * R6: Default Following Instruction Address (PC+4)
- * On exit:
- * R0: following instruction address
- * R1-R7: Destroyed
- */
-_arm_data_instr_handler:
- stmfd sp!, {lr}
- ldr r1, =ARM_DATA_INSTR_MASK
- and r3, r4, r1 /* Keep base instruction Opcode in R3 */
- ldr r1, =ARM_DATA_INSTR_MSRMRS
- teq r3, r1 /* Check for MSR / MRS instruction */
-
-_arm_is_msr_mrs_instr:
- moveq r0, r6 /* Copy default next instruciton address to R0 */
- beq _exit_arm_data_instr_handler /* Return default next instruction address */
-
- /* Not MSR / MRS, so process normally */
-_arm_check_operand2_type:
- tst r4, #ARM_DATA_INSTR_IMMREG /* Check for Immediate (1) or Register (0) Operand 2 */
- beq _arm_op2_is_reg
-
-_arm_op2_is_imm:
- and r1, r4, #BYTE0 /* 8 bit unsigned constant in R1 */
- and r2, r4, #NIBBLE2 /* (rotate count / 2) in R2[11:8] */
- lsr r2, r2, #7 /* actual rotate count in R2[4:0] */
- ror r1, r1, r2 /* Rotated constant in R1 */
- b _arm_get_operand1_val
-
-_arm_op2_is_reg:
- ldr r1, =(NIBBLE2|BYTE0)
- and r0, r4, r1 /* 12 bit register operand in R1 */
- bl _arm_rmshifted_val /* R0 contains the Rm shifted val */
- mov r1, r0 /* R1: Operand2 val */
-
-_arm_get_operand1_val:
- bl _dbg_data_instr_retrieve_op1val /* R0: Register Rn (Operand1) val */
-
-_arm_calc_data_instr_val:
- and r3, r4, #ARM_DATA_INSTR_NORMAL /* Mask Instruction Opcode into R3[24:21] */
- lsr r3, r3, #21 /* Shift Data Processing Opcode into R3[3:0] */
- /* Calculate data instruction value from R0: Register Rn (Operand1) val, R1: Operand2 val, R5[3:0]: CPSR, R6: Default Next Instr Addr */
- _dbg_jumpTableHandler debug_dataInstrJumpTable, r2, r3 /* Next Instruction Address in R0 */
-_exit_arm_data_instr_handler:
- ldmfd sp!, {pc}
-
-/* _dbg_data_instr_retrieve_op1val
- * Retrieve Data Instruction Operand 1 value
- * On entry:
- * R4: Opcode of instruction to be executed
- * R5[3:0]: CPSR condition codes
- * R6: Default Next Instruction Address (PC+4)
- * On exit:
- * R0: Register Rn (Operand 1) value
- * R2, R3: Destroyed
- *
- */
-_dbg_data_instr_retrieve_op1val:
- and r3, r4, #NIBBLE4 /* Store Rn (Operand1) Register Enum into R3[19:16] */
- lsr r3, r3, #16 /* Shift into R3[3:0] */
- _regenum2index r3, r2 /* Convert Enum into Index in R2 */
- _getdbgregisterfromindex r2, r0 /* Retrieve Register contents from Index (R2) into R0 */
- teq r3, #REG_PC /* Check if it is PC relative */
- addeq r0, r0, #8 /* R0: Register Rn (Operand1) val; adjust for PC relative (+8) */
- bx lr
-
-/* Data Processing Instruction Jump Table Routines
- * On entry:
- * R0: Register Rn (Operand 1) value
- * R1: Operand 2 value
- * R5[3:0]: CPSR condition codes
- * R6: Default Next Instruction Address (PC+4)
- * On exit:
- * R0: Calculated result
- * R1, R2, R3: Destroyed
- *
- */
-_opcode_and:
- and r0, r0, r1
- bx lr
-
-_opcode_eor:
- eor r0, r0, r1
- bx lr
-
-_opcode_sub:
- sub r0, r0, r1
- bx lr
-
-_opcode_rsb:
- rsb r0, r0, r1
- bx lr
-
-_opcode_add:
- add r0, r0, r1
- bx lr
-
-_opcode_adc:
- /* Op1 + Op2 + C */
- tst r5, #(CPSR_CFLAG>> 28) /* R5[3:0] is shifted CPSR value: Test C Flag */
- add r0, r0, r1
- addne r0, r0, #1 /* Add C if set */
- bx lr
-
-_opcode_sbc:
- /* Op1 - Op2 + C - 1 */
- tst r5, #(CPSR_CFLAG>> 28) /* R5[3:0] is shifted CPSR value: Test C Flag */
- sub r0, r0, r1
- subeq r0, r0, #1 /* If C clear, subtract 1, else (C - 1) = 0 */
- bx lr
-
-_opcode_rsc:
- /* Op2 - Op1 + C - 1 */
- tst r5, #(CPSR_CFLAG>> 28) /* R5[3:0] is shifted CPSR value: Test C Flag */
- rsb r0, r0, r1
- subeq r0, r0, #1 /* If C clear, subtract 1, else (C - 1) = 0 */
- bx lr
-
-_opcode_tst:
-_opcode_teq:
-_opcode_cmp:
-_opcode_cmn:
- mov r0, r6 /* Next Instruction Address is not modified */
- bx lr
-
-_opcode_orr:
- orr r0, r0, r1
- bx lr
-
-_opcode_mov:
- mov r0, r1 /* Operand 1 is ignored */
- bx lr
-
-_opcode_bic:
- bic r0, r0, r1
- bx lr
-
-_opcode_mvn:
- mvn r0, r1 /* Operand 1 is ignored */
- bx lr
-
-/* _arm_bx_blx_handler
- * BX or BLX Rm Handler. Note v4t does not have BLX instr
- * On entry:
- * R4: Opcode of instruction to be executed
- * R5[3:0]: CPSR condition codes
- * R6: Default Following Instruction Address (PC+4)
- * On exit:
- * R0: following instruction address (B0 set to indicate Thumb mode)
- * R1,R2: destroyed
- */
-_arm_bx_blx_handler:
- stmfd sp!, {lr}
- and r2, r4, #NIBBLE0 /* Register Rn Enum in R2 */
- _regenum2index r2, r1 /* Convert Enum into Index in R1 */
- _getdbgregisterfromindex r1, r0 /* Retrieve Register contents from Index (R1) into R0 */
- teq r2, #REG_PC
- addeq r0, r0, #8 /* Adjust PC relative register value (for BX PC) */
- /* Here, the register value would have B0 set to indicate switch to Thumb mode */
- ldmfd sp!, {pc}
-
-/* _arm_ldr_pc_handler
- * LDR with Rd = PC
- * On entry:
- * R4: Opcode of instruction to be executed
- * R5[3:0]: CPSR condition codes
- * R6: Default Following Instruction Address (PC+4)
- * On exit:
- * R0: following instruction address
- * R1, R2, R3, R4, R5: destroyed
- */
-
-_arm_ldr_pc_handler:
- stmfd sp!, {lr}
-
- mov r1, #0 /* R1: Post-Indexed Offset (cleared) */
- tst r4, #ARM_LDR_INSTR_PREPOST /* Pre (1) or Post (0) Indexed */
- beq _get_rn_val /* If Post-Indexed, just use Rn directly */
-
- /* Pre-Indexed */
- ldr r0, =(NIBBLE2|BYTE0)
- and r0, r4, r0 /* R0: 12 bit Immediate value or Shifted Reg operand */
- tst r4, #ARM_LDR_INSTR_REGIMM /* Register (1) or Immediate (0) */
- beq _calc_ldr_pc_offset /* Immediate value is already in R0 */
-
-_get_shiftedreg_val:
- bl _arm_rmshifted_val /* Convert Rm shifted operand in R0 into value in R0 */
-
-_calc_ldr_pc_offset:
- mov r1, r0 /* Keep Offset in R1 */
-_get_rn_val:
- bl _dbg_data_instr_retrieve_op1val /* R0: Register Rn (Operand1) val */
-_calc_op1val_with_offset:
- tst r4, #ARM_LDR_INSTR_UPDOWN /* Add (1) or Subtract (0) */
- addne r0, r0, r1 /* If Add, R0 = Rn + Offset */
- subeq r0, r0, r1 /* If Sub, R0 = Rn - Offset */
-
-_get_ldr_pc_val_from_mem:
- ldr r0, [r0] /* Retrieve value from Memory at address given in R0 */
- ldmfd sp!, {pc}
-
-/* _arm_ldm_pc_handler
- * LDM {pc}
- * On entry:
- * R4: Opcode of instruction to be executed
- * R5[3:0]: CPSR condition codes
- * R6: Default Following Instruction Address (PC+4)
- * On exit:
- * R0: following instruction address
- * R2, R3: destroyed
- *
- * Note: The algorithm from eCos arm_stub.c does not deal with the Pre/Post-Indexed addressing (P) bit.
- * The algorithm here loads different content using LDM based on the value of the P bit.
- */
-_arm_ldm_pc_handler:
- stmfd sp!, {lr}
- bl _dbg_data_instr_retrieve_op1val /* R0: Register Rn (Operand1) val */
-
-_arm_get_regcount:
- mov r2, #0 /* Initialize reg_count (R2) to 0 */
- mov r3, r4, lsl #16 /* Keep HLFWORD0 containing vector bits in R3[31:16] */
- /* This shortens the checking to a max of 16 iterations, since the PC bit should be set */
-1: movs r3, r3, lsl #1 /* count number of '1' bits */
- addcs r2, r2, #1 /* increment reg_count (R2) if C Flag set */
- bne 1b /* continue until vector is empty */
-
- /* Pre-Incr: Rn += reg_count x 4
- * Post-Incr: Rn += (reg_count - 1) x 4
- * Pre-Decr: Rn -= 4
- * Post-Decr: Rn
- */
-
-_arm_check_updown_offset:
- tst r4, #ARM_LDM_INSTR_UPDOWN /* Check Up (1) or Down (0) */
- beq _arm_check_prepost_decr
-
-_arm_check_prepost_incr:
- tst r4, #ARM_LDM_INSTR_PREPOST /* Check Pre (1) or Post (0) */
- subeq r2, r2, #1 /* Post-Incr: Decrement reg_count in R2 */
- add r0, r0, r2, lsl #2 /* Increment Offset: Rn (R0) += reg_count (R2) x 4 */
- b _get_ldm_pc_val_from_mem
-
-_arm_check_prepost_decr:
- tst r4, #ARM_LDM_INSTR_PREPOST /* Check Pre (1) or Post (0) */
- /* Post-Decr: Rn unchanged */
- subne r0, r0, #4 /* Pre-Decr: Rn (R0) -= 4 */
-
-_get_ldm_pc_val_from_mem:
- ldr r0, [r0] /* Retrieve stack content for new PC value */
- ldmfd sp!, {pc}
-
-
-/* _arm_b_bl_blx_handler
- * B, BL or BLX <offset>. Note v4t does not have BLX instr
- * On entry:
- * R4: Opcode of instruction to be executed
- * R5[3:0]: CPSR condition codes
- * R6: Default Following Instruction Address (PC+4)
- * On exit:
- * R0: following instruction address
- * R1: destroyed
- */
-
-_arm_b_bl_blx_handler:
- stmfd sp!, {lr}
-
-_arm_b_bl_blx_get_offset:
- and r0, r4, #(BYTE2|BYTE1|BYTE0) /* Encoded Branch offset in R4[23:0] */
- lsl r0, r0, #(32-24) /* Shift to R0[31:8] */
- asr r0, r0, #(32-26) /* Actual Signed offset = Encode Offset x 4 in R0[25:0] */
- add r1, r6, #4 /* R1: (PC+4) + 4 */
- add r0, r0, r1 /* Calculate Branch Target Address R0: (PC+8) + signed offset */
-
-#ifndef __ARM6OR7__
- /* armv5t or later, has BLX support */
- and r1, r4, #ARM_BLX_INSTR_MASK /* Mask out Condition Code and Opcode */
- teq r1, #ARM_BLX_INSTR_BLX /* Look for BLX */
- bne _exit_arm_b_bl_blx_handler /* No, it is a B/BL instruction */
- tst r4, #ARM_BLX_INSTR_HBIT /* H bit for Thumb Halfword Address */
- orrne r0, r0, #0x02 /* Set Halfword Address R0[1] */
- orr r0, r0, #BKPT_STATE_THUMB_FLAG /* Set R0[0] since BLX instr used to switch to Thumb mode */
-#endif
-
-_exit_arm_b_bl_blx_handler:
- ldmfd sp!, {pc}
-
-/* _arm_coproc_swi_handler
- * SVC (SWI) or Coprocessor instruction
- * On entry:
- * R4: Opcode of instruction to be executed
- * R5[3:0]: CPSR condition codes
- * R6: Default Following Instruction Address (PC+4)
- * On exit:
- * R0: following instruction address
- */
-
-_arm_coproc_swi_handler:
- and r0, r4, #ARM_SWI_INSTR_MASK
- teq r0, #ARM_SWI_INSTR_VAL /* SVC (SWI) instruction */
-
- ldreq r0, =SVC_VECTOR /* SWI: Return SVC Vector Address */
- movne r0, r6 /* CoProc: Use default Following Instruction Address */
-_exit_arm_coproc_swi_handler:
- bx lr
-
-/* _thumb_bx_blx_handler
- * BX or BLX Handler. Note: Link (L:b7) is not checked in the mask; armv4t does not support BLX.
- * On entry:
- * R4: Opcode of instruction to be executed
- * R5[3:0]: CPSR condition codes
- * R6: Default Following Instruction Address (PC+2)
- * On exit:
- * R0: following instruction address (B0 set to indicate Thumb mode)
- * R1, R2: destroyed
- */
-_thumb_bx_blx_handler:
- stmfd sp!, {lr}
- and r2, r4, #THUMB_BLX_INSTR_REG_RNMASK /* Register Rn Enum in R2[6:3] (Hi-Reg indicated by B6) */
- mov r2, r2, lsr #3 /* Shift Rn Enum to R2[3:0] */
- _regenum2index r2, r1 /* Convert Enum into Index in R1 */
- _getdbgregisterfromindex r1, r0 /* Retrieve Register contents from Index (R1) into R0 */
- teq r2, #REG_PC
- addeq r0, r0, #4 /* Adjust PC relative register value (for BX PC) */
- /* Here, the register value would have R0[0] set to indicate switch to Thumb mode */
- ldmfd sp!, {pc}
-
-/* _thumb_poppc_handler
- * PUSH/POP, specifically POP {Rlist,PC}
- * On entry:
- * R4: Opcode of instruction to be executed
- * R5[3:0]: CPSR condition codes
- * R6: Default Following Instruction Address (PC+2)
- * On exit:
- * R0: following instruction address (B0 set to indicate Thumb mode)
- * R1-R3: destroyed
- */
-_thumb_poppc_handler:
- stmfd sp!, {lr}
-
-_thumb_get_SP_val:
- _getdbgregister DBGSTACK_USERSP_INDEX, r1 /* Retrieve SP contents into R1 */
-
-_thumb_get_regcount:
- mov r3, r4, lsl #24 /* Keep BYTE0 containing vector bits in R3[31:24] */
- /* POP is equivalent to LDMFD. Load PC is encoded in b8,
- * the 8-bit vector is for Lo registers.
- * This shortens the checking to a max of 8 iterations
- */
-1: movs r3, r3, lsl #1 /* count number of '1' bits */
- addcs r1, r1, #4 /* Walk the stack to locate the PUSHed LR (POP PC) value */
- bne 1b /* continue until vector is empty */
- ldr r0, [r1] /* Retrieve new PC value */
-#if 0
- /* PC Value should have B0 set */
- orr r0, r0, #BKPT_STATE_THUMB_FLAG /* Force R0[0] since it is used to indicates Thumb mode */
-#endif
- ldmfd sp!, {pc}
-
-/* _thumb_bcond_swi_handler
- * B<cond> or SWI (SVC)
- * On entry:
- * R4: Opcode of instruction to be executed
- * R5[3:0]: CPSR condition codes
- * R6: Default Following Instruction Address (PC+2)
- * On exit:
- * R0: following instruction address (B0 set to indicate Thumb mode)
- * R1-R3: destroyed
- */
-_thumb_bcond_swi_handler:
- stmfd sp!, {lr}
- and r2, r4, #THUMB_BCOND_SWI_INSTR_CONDMASK /* Keep Condition Code R2[11:8] */
- teq r2, #THUMB_BCOND_SWI_INSTR_SWI /* SVC (SWI) instruction */
-_thumb_swi_instr:
- ldreq r0, =SVC_VECTOR /* Return SVC Vector Address */
- beq _exit_thumb_bcond_swi_handler /* Switch to ARM mode for SVC */
-_thum_bcond_unused_instr:
- teq r2, #THUMB_BCOND_SWI_COND_UNUSED
- moveq r0, r6 /* False (don't execute), so use Default Following Instruction Address */
- beq _exit_thumb_bcond_instr
-
-_thumb_bcond_instr:
- stmfd sp!, {r4} /* Preserve Opcode in R4 */
- lsl r4, r2, #(32-12) /* Shift condition code in R2[11:8] to R0[31:28] to match ARM cond-code format */
- bl _dbg_check_arm_condcode /* Use ARM condition code checking routine to test (R4, R6 unchanged) */
- ldmfd sp!, {r4} /* Restore Opcode in R4 */
- teq r0, #FALSE
- moveq r0, r6 /* False (don't execute), so use Default Following Instruction Address */
- beq _exit_thumb_bcond_instr
-
-_thumb_calc_bcond_offset:
- lsl r0, r4, #(32-8) /* Shift 8-bit offset in R4[7:0] to R0[31:24] */
- asr r0, r0, #(32-9) /* Convert into 9-bit signed offset in R0[8:0] */
- add r0, r6, r0 /* PC+2 + signed offset */
- add r0, r0, #2 /* PC+4 + signed offset */
-_exit_thumb_bcond_instr:
- orr r0, r0, #BKPT_STATE_THUMB_FLAG /* Set R0[0] since it is used to indicates Thumb mode */
-_exit_thumb_bcond_swi_handler:
- ldmfd sp!, {pc}
-
-/* _thumb_b_handler
- * B
- * On entry:
- * R4: Opcode of instruction to be executed
- * R5[3:0]: CPSR condition codes
- * R6: Default Following Instruction Address (PC+2)
- * On exit:
- * R0: following instruction address (B0 set to indicate Thumb mode)
- * R1: destroyed
- * Note: The signed offset is 12-bits (encoded value x 2)
- */
-_thumb_b_handler:
- stmfd sp!, {lr}
- lsl r0, r4, #(32-11) /* Shift 11-bit offset in R4[10:0] to R0[31:21] */
- asr r0, r0, #(32-12) /* Convert into 12-bit signed offset in R0[11:0] */
- add r0, r6, r0 /* PC+2 + signed offset */
- add r0, r0, #2 /* PC+4 + signed offset */
- orr r0, r0, #BKPT_STATE_THUMB_FLAG /* Set R0[0] since it is used to indicates Thumb mode */
- ldmfd sp!, {pc}
-
-/* _thumb_long_bl_blx_handler
- * Long BL or BLX (4 bytes) Note: b11 (H) indicates 1st or 2nd instr; armv4t does not support BLX.
- * On entry:
- * R4: Opcode of instruction to be executed
- * R5[3:0]: CPSR condition codes
- * R6: Default Following Instruction Address (PC+2)
- * On exit:
- * R0: following instruction address (B0 set to indicate Thumb mode)
- * R1, R2, R3: destroyed
- * R6: Subseqent Instruction Address (PC+4) if first instruction is valid, else unchanged (PC+2)
- * Note: The BL instruction (0xFxxx) should be in pairs (Dual 16-bit instructions).
- * The first instruction should have (H=0) to indicate the upper 11 bits of the encoded offset
- * The second instruction should have (H=1) to indicate the lower 11 bits of the encoded offset
- * The signed offset is 23 bits (encoded value x 2)
- *
- * Note2: The BLX instruction (0xExxx) encodes the first instruciton using BL (0xFxxx) with H=0,
- * while the second instruction has a different opcode value (0xExxx), with H=1.
- * BLX is only used to switch to an ARM target.
- */
-_thumb_long_bl_blx_handler:
- stmfd sp!, {lr}
-_thumb_check_1st_bl_blx_instruction:
- tst r4, #THUMB_BLX_INSTR_IMM_HBIT /* Check H bit */
- bne _return_default_thumb_following_instr /* H=1 as first instruction shouldn't happen */
-_thumb_check_2nd_bl_blx_instruction:
- ldrh r3, [r6] /* Get second instruction in pair at PC+2 into R3 */
- add r6, r6, #2 /* Skip to Subsequent Instruction (PC+4) */
- tst r3, #THUMB_BLX_INSTR_IMM_HBIT /* Check H bit */
- beq _return_default_thumb_following_instr /* H=0 as second instruction shouldn't happen */
-
-_thumb_concat_branch_offset:
- lsl r0, r4, #(32-11) /* Shift first instruction 11-bit offset in R4[10:0] to R0[31:21] */
- asr r0, r0, #(32-23) /* Convert into 12-bit signed offset in R0[22:12] */
- lsl r2, r3, #(32-11) /* Shift second instruction 11-bit offset in R3[10:0] to R2[31:21] */
- lsr r2, r2, #(32-12) /* Convert into 12-bit unsigned offset in R2[11:0] */
- orr r0, r0, r2 /* Combine offsets */
- add r0, r6, r0 /* PC+4 + signed offset */
-
-_thumb_check_bl_blx_pair:
- and r3, r3, #THUMB_BLX_INSTR_IMM_MASK /* Keep second instruction opcode in R3 */
- teq r3, #THUMB_BLX_INSTR_IMM_BL /* Look for BL */
- beq _flag_thumb_instr_addr /* Return BL target address in R0 */
-
-#ifndef __ARM6OR7__
- /* v5t or higher architecture */
- teq r3, #THUMB_BLX_INSTR_IMM_BLX /* Look for BLX */
- biceq r0, r0, #0x03 /* Match, Force ARM address */
- beq _exit_thumb_long_bl_blx_handler
-#endif
-
-_return_default_thumb_following_instr:
- /* FIXME: This assumes that once the 4-byte sequence check fails, it will return PC+4,
- * regardless of whether the second instruction is a valid BL/BLX instruction or not.
- */
- mov r0, r6 /* Return default Following/Subsequent Instruction Address */
-_flag_thumb_instr_addr:
- orr r0, r0, #BKPT_STATE_THUMB_FLAG /* Set R0[0] since it is used to indicates Thumb mode */
-
-_exit_thumb_long_bl_blx_handler:
- ldmfd sp!, {pc}
-
diff --git a/Debugger/debug_runlooptasks.S b/Debugger/debug_runlooptasks.S
deleted file mode 100644
index a9eb50a..0000000
--- a/Debugger/debug_runlooptasks.S
+++ /dev/null
@@ -1,411 +0,0 @@
-/** @file debug_runlooptasks.S
- * @brief GDB Server platform Run Loop
- *
- */
-
-/* Copyright (C) 2007-2011 the NxOS developers
- *
- * Module Developed by: TC Wan <tcwan@cs.usm.my>
- *
- * See AUTHORS for a full list of the developers.
- *
- * See COPYING for redistribution license
- *
- */
-
-/*
- * This file contains platform specific code.
- * This include ABORT Mode Debugger Run Loop operation,
- * as well as Debugger Interfacing code to the platform code.
- */
-
-/*
- * The Debugger has to implement a Run Loop in ABORT mode
- * since the hardware is still running. Consequently,
- * the communications subsystems such as USB (and Bluetooth?)
- * which is used to communicate with the Host needs to be
- * serviced in order for actual data transmission and reception
- * to take place. Currently we're reusing the platform's
- * communication routines to do the actual tx/rx, so it means
- * that it is not possible to set breakpoints in those modules.
- * In addition, since the platform communication modules may
- * handle other tasks, it is currently possible to enter an
- * indeterminate state where certain communication messages trigger
- * a platform response which cannot be handled by the Debugger Run Loop.
- * The alternative is to implement our own communications routines, but
- * that will take even more code.
- *
- * FIXME: It may become necessary to hack the platform communications
- * routines to detect that we're in the Debugger Run Loop and not the
- * normal run loop to avoid system crashes, but the current goal is to
- * have as minimal changes to the platform code as possible.
- *
- * Since there are two Run Loops for the platform, the way in which
- * they interact is as follows:
- *
- * [Platform Run Loop] - DBG_INIT/ GDB Cmd/ BKPT -> [Debugger Run Loop]
- * \ <------ GO/ STEP/ CONT ----- /
- * ... ...
- * ... Handle GDB Cmd/Resp
- * ... ...
- * {normal runloop {communications /
- * processing} watchdog routines}
- * ^-------v v-------^
- *
- * The Platform will invoke dbg__bkpt_init() after hardware and system initialization,
- * before entering the Platform Run Loop. This configures the Debugger, but does not
- * invoke the Debugger Run Loop unless a Manual Breakpoint is found in the platform code.
- *
- * Subsequently, the Debugger Run Loop will be triggered by Breakpoints, or
- * when the communications subsystem receives a GDB Command.
- *
- * The Debugger Run Loop is actually dbg__bkpt_waitCMD(), this file contains
- * the Run Loop Tasks which needs to be invoked periodically by the Run Loop,
- * to minimize the coupling between the ARMDEBUG modules and the Platform.
- *
- * Note: The Debugger Run Loop does not handle Hardware Shutdown, it is
- * assumed that we wouldn't need to do so in Debug Mode.
- *
- */
-#define __ASSEMBLY__
-
-#define REBOOT_POWERDOWN
-#include "debug_runlooptasks.h"
-
-#include "debug_internals.h"
-#include "debug_macros.h"
-#include "debug_stub.h"
-
- .code 32
- .align 4
-
-#ifdef __NXOS__
-/****************************************************************************
- *
- * NxOS Run Loop
- *
- ****************************************************************************/
- dbg_interwork dbg__runloopTasks
-/* Currently, there's nothing that needs to be done in the NxOS Run Loop */
- push {lr}
- mov r0, #1 /* 1 ms delay */
- bl nx_systick_wait_ms
- pop {pc}
-
-#else
-/****************************************************************************
- *
- * NXT Firmware Run Loop
- *
- ****************************************************************************/
- dbg_interwork dbg__runloopTasks
- push {lr}
- /* FIXME: Add necessary cXXXCtrl calls here */
- bl cCommCtrl
- /* OSWatchdogWrite is a NULL function in the NXT Firmware?! */
- pop {pc}
-#endif
-
-#ifdef __NXOS__
-/****************************************************************************
- *
- * NxOS Reboot Routine
- *
- ****************************************************************************/
- dbg_interwork dbg__reboot
-#ifdef REBOOT_POWERDOWN
- b nx_core_halt /* Shutdown Brick, won't return */
-#else
- b nx_core_reset /* Reboot Brick, won't return */
-#endif
-
-#else
-/****************************************************************************
- *
- * NXT Firmware Reboot Routine
- *
- ****************************************************************************/
- dbg_interwork dbg__reboot
- /* Powerdown Sequence
- dIOCtrlSetPower((POWERDOWN>>8));
- dIOCtrlTransfer();
-
- Reboot Sequence
- dIOCtrlSetPower((UBYTE)(BOOT>>8));
- dIOCtrlSetPwm((UBYTE)BOOT);
- dIOCtrlTransfer();
- */
-
- /* We implement the powerdown sequence for now */
-
-#ifdef REBOOT_POWERDOWN
- /* Powerdown sequence */
- ldr r0, =((POWERDOWN >> 8) & 0xFF)
- ldr r1, =dIOCtrlSetPower
- mov lr,pc
- bx r1
-#else
- /* Reboot sequence: this forces SAMBA mode??!! */
- ldr r0, =((BOOT >> 8) & 0xFF)
- ldr r1, =dIOCtrlSetPower
- mov lr,pc
- bx r1
-
- ldr r0, =(BOOT & 0xFF)
- ldr r1, =dIOCtrlSetPwm
- mov lr,pc
- bx r1
-#endif
-
-_dbg__reboot_wait:
- ldr r1, =dIOCtrlTransfer
- mov lr,pc
- bx r1
-
- b _dbg__reboot_wait /* Wait for AVR... */
-#endif
-
-#ifdef __NXOS__
-/****************************************************************************
- *
- * NxOS Abort Info LCD Display Routine
- *
- ****************************************************************************/
-/* On entry:
- * r0: abort type
- * On exit:
- * r0-r3: destroyed
- */
- dbg_interwork dbg__display_abort_info
- push {lr}
- _getdbgregister DBGSTACK_USERPC_INDEX, r1 /* Retrieve User PC into R2 */
- _getdbgregister DBGSTACK_USERCPSR_INDEX, r2 /* Retrieve User CPSR into R2 */
- bl nx__abort_info /* void nx__abort_info(U32 data, U32 pc, U32 cpsr); */
- pop {pc}
-
-#else
-/****************************************************************************
- *
- * NXT Firmware Abort Info LCD Display Routine
- *
- ****************************************************************************/
- dbg_interwork dbg__display_abort_info
-/* FIXME: Inteface with NXT Firmware LCD Display routines */
- push {lr}
- pop {pc}
-#endif
-
-#ifdef __NXOS__
- .extern debug_OutCommBuf
-/****************************************************************************
- *
- * NxOS Communications Driver Interface Routine
- *
- ****************************************************************************/
-/* dbg__sendCommMsg
- * Internal send routine (interfaces with drivers).
- * On entry:
- * R0: Total Message Buffer length
- * On exit:
- * R0: Tx Status (TRUE if data sent)
- * R1-R3: Destroyed
- */
- dbg_interwork dbg__sendCommMsg
- stmfd sp!, {r4, lr}
- mov r4, r0 /* Keep Comm Buffer length in R4 */
- /* Check USB bus status, transmit message if possible */
- bl nx_usb_is_connected /* R0 = TRUE (#1) if USB is ready */
- teq r0, #0 /* FALSE == #0;
- We can't check for True condition since values
- used by C-Compiler & ARMDEBUG are different */
- beq dbg__sendCommMsgFailed
-
- /* Actual transmission (blocking) */
- ldr r0, =debug_OutCommBuf /* data pointer parameter */
- mov r1, r4 /* Comm buffer length */
- bl nx_usb_write
-
-1: bl nx_usb_data_written /* R0 = True if data has been sent */
- teq r0, #0 /* FALSE == #0;
- We can't check for True condition since values
- used by C-Compiler & ARMDEBUG are different */
- /* FIXME: implement timeout */
- beq 1b /* Busy Wait Loop */
-
- mov r0, #TRUE
- b exit_dbg__sendCommMsg
-dbg__sendCommMsgFailed:
- mov r0, #FALSE
-
-exit_dbg__sendCommMsg:
- ldmfd sp!, {r4, pc}
-
-
-#else
-/****************************************************************************
- *
- * NXT Firmware Communications Driver Interface Routine
- *
- ****************************************************************************/
-/* dbg__sendCommMsg
- * Internal send routine (interfaces with drivers).
- * On entry:
- * R0: Total Message Buffer length
- * On exit:
- R0: Tx Status (TRUE if data sent)
- */
- dbg_interwork dbg__sendCommMsg
- stmfd sp!, {r4, lr}
- mov r4, r0 /* Keep Comm Buffer length in R4 */
- ldr r0, =debug_nxtCommChannel
- ldr r0, [r0] /* Get Channel Enum */
- teq r0, #BT_CMD_READY
- beq dbg__sendBTMsg
- teq r0, #USB_CMD_READY
- beq dbg__sendUSBMsg
- b dbg__sendCommMsgFailed /* Channel Enum Doesn't Match, shouldn't happen? */
-
-dbg__sendBTMsg:
- /* NXT BT routines do not have any configuration checks */
- ldr r0, =debug_OutCommBuf /* data pointer parameter */
- mov r1, r4 /* BT Bytes to Send */
- mov r2, r4 /* BT Message Size */
- bl dBtSendMsg /* Send it via Bluetooth (complete message) */
- mov r0, #TRUE /* Always flag Success */
- b exit_dbg__sendCommMsg
-
-dbg__sendUSBMsg:
- /* Check USB bus status, transmit message if possible */
- bl dUsbIsConfigured /* R0: UByte status, TRUE / FALSE */
- teq r0, #nxt_UBYTE_TRUE
- bne dbg__sendCommMsgFailed
-
- /* Actual transmission (blocking) */
- ldr r0, =debug_OutCommBuf /* data pointer parameter */
- mov r1, r4 /* Comm buffer length */
- bl dUsbWrite /* call NXT Firmware USB driver, return 0: done, !0: remaining chars */
- teq r0, #0 /* Tx done if returned length is 0 */
- moveq r0, #TRUE /* Convert NXT firmware return value to our Status (TRUE/FALSE) */
- beq exit_dbg__sendCommMsg
-dbg__sendCommMsgFailed:
- mov r0, #FALSE
-
-exit_dbg__sendCommMsg:
- ldmfd sp!, {r4, pc}
-#endif
-
-
-#ifdef __NXOS__
-/****************************************************************************
- *
- * GDB Debugger Invocation Routine for NxOS
- *
- ****************************************************************************/
- .code 32
- .align 4
-
- .extern dbg__install_singlestep
- .extern dbg__activate_singlestep
- .extern irq_stack_frame_address
-/* nxos__handleDebug
- * Prepare to switch to Debug Mode
- * int nxos__handleDebug(U8 *buffer, comm_chan_t channel, U32 length);
- *
- * This routine is called from NxOS Fantom library to setup
- * Single Step Breakpoint in preparation for Debugger invocation if we're in
- * normal execution mode.
- *
- * It returns to complete the IRQ handling normally, after which the single
- * step breakpoint will be triggered, and the incoming GDB message will then
- * be processed in the dbg__bkpt_waitCMD() loop.
- *
- * If we're in Debugger Mode already, then just return and let the
- * dbg__bkpt_waitCMD() loop handle it normally.
- *
- * If we're operating in normal NxOS mode, return True (!0)
- * If we're already in Debugger Mode, return False (0)
- */
- dbg_interwork nxos__handleDebug
- push {lr}
- /* This routine is called from nx__irq_handler() via fantom_filter_packet().
- * The operating mode should already have been configured by the IRQ interrupt handler.
- *
- * The IRQ Stack Frame Pointer will contains the LR and SPSR from the topmost interrupted task
- * if it is non-zero (NxOS supports nested IRQs)
- */
- bl dbg__copyNxtDebugMsg /* Copy to Debugger Message Buffer, Remember Comm Channel */
- mov r0, #FALSE /* Setup Default Return value (False) */
- _dbg_getmode r1 /* Get Debug Mode */
- cmp r1, #(TRUE & BYTE0) /* Confine it to Byte size */
- /* If Debug Mode is TRUE, this means that we're already running the Debugger */
- beq exit_nxos__handleDebug /* Yes, return False */
-
- /* Retrieve ISR Return Address */
- ldr r3, =irq_stack_frame_address
- ldr r3, [r3] /* Get Interrupt Stack Pointer */
- teq r3, #0
- beq exit_nxos__handleDebug /* NULL Interrupt Stack Frame Pointer, exit (status: False) */
-
-nxos_switch2debug:
- /* Since the Interrupt Stack Frame Pointer points to the top of the stack frame,
- * we'll have to use Load Empty Ascending Stack (LDMEA == LDMDB) to access the variables
- */
- ldmdb r3, {r1,r2} /* R1: LR, R2: SPSR */
- tst r2, #CPSR_THUMB /* Check for Thumb Mode */
- orrne r1, r1, #1 /* Configure for Thumb Single Step Breakpoint */
- bl dbg__install_singlestep /* Setup Single Step, next instruction address returned in r1 */
- bl dbg__activate_singlestep
- mov r0, #TRUE /* We're going to switch to Debug Mode (via Single Step Breakpoint) */
-
-exit_nxos__handleDebug:
- pop {r1}
- bx r1 /* In case we have Interworking from different caller mode */
-
-#else
-
-/****************************************************************************
- *
- * GDB Debugger Invocation Routine for NXT Firmware
- *
- ****************************************************************************/
- .code 16
- .align 2
-
- .extern dbg__copyNxtDebugMsg
- .global cCommHandleDebug
- .thumb_func
- .type cCommHandleDebug, %function
-/* cCommHandleDebug
- * Switch Mode to Debugger.
- * Used by NXT Firmware only
- *
- * UWORD cCommHandleDebug(UBYTE *pInBuf, UBYTE CmdBit, UWORD MsgLength);
- *
- * This routine is called from cCommInterprete either in normal operation mode (SVC)
- * or else when we're in debug mode (ABORT) which uses the cCommCtrl() routine to handle
- * I/O with the Host.
- *
- * On entry, the message is copied from the NXT buffer into our own buffers.
- *
- * If this is accessed from normal operation mode, we need to switch mode to
- * ABORT mode to handle the incoming message using a Manual Breakpoint instruction.
- * When DEBUG is exited, the execution resumes from the instruction following the Breakpoint.
- */
-cCommHandleDebug:
-/* Arg Registers are not preserved since this is invoked explicitly */
- push {lr} /* store arg registers */
- bl dbg__copyNxtDebugMsg /* Copy to Debugger Message Buffer, Remember Comm Channel */
- _dbg_getmode r0 /* Get Debug Mode */
- cmp r0, #(TRUE & BYTE0) /* Confine it to Byte size */
-
- /* If Debug Mode is TRUE, this means that we're already running the Debugger */
- beq _cCommHandleDebug_cont
- /* Else, we're in normal operation mode (SVC), or other mode (??!) and need to force a switch to Debug mode */
- dbg__bkpt_thumb
-_cCommHandleDebug_cont:
- mov r0, #0 /* FIXME: Return Status */
- pop {r1} /* Can't Pop LR directly */
- bx r1 /* Safe code: actually we should be able to Pop PC since the caller is Thumb Mode */
-
- .ltorg
-#endif
diff --git a/Debugger/debug_runlooptasks.h b/Debugger/debug_runlooptasks.h
deleted file mode 100644
index a2ae956..0000000
--- a/Debugger/debug_runlooptasks.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/** @file debug_runlooptasks.h
- * @brief Shared C/ASM header file for debugger communications
- *
- */
-
-/* Copyright (C) 2007-2011 the NxOS developers
- *
- * Module Developed by: TC Wan <tcwan@cs.usm.my>
- *
- * See AUTHORS for a full list of the developers.
- *
- * See COPYING for redistribution license
- *
- */
-
-#ifndef __DEBUG_RUNLOOPTASKS_H__
-#define __DEBUG_RUNLOOPTASKS_H__
-
-#include "_c_arm_macros.h"
-
-/* This is a place holder header file to allow for interfacing with C Routines in either
- * NxOS or NXT Firmware.
- *
- * Since the header files from the original source trees were meant for C programs, we can't
- * include them directly. Here we just use .extern to reference the routines.
- */
-
-#ifdef __NXOS__
- .extern nx__abort_info
- .extern nx_systick_wait_ms
-
- .extern nx_usb_is_connected
- .extern nx_usb_can_write
- .extern nx_usb_write
- .extern nx_usb_data_written
- .extern nx_usb_read
- .extern nx_usb_data_read
- .extern nx_core_reset
- .extern nx_core_halt
-
-#else /* NXT Firmware */
-
- .extern cCommInit
- .extern cCommCtrl
- .extern cCommExit
- .extern dUsbWrite
- .extern dUsbRead
- .extern dUsbIsConfigured
- .extern dBtSendMsg
- /**
- * True value used by Thumb mode in NXT
- */
- .equ nxt_UBYTE_TRUE, 1
- /**
- * False value used by Thumb mode in NXT
- */
- .equ nxt_UBYTE_FALSE, 0
- /**
- * USB Command Indicator
- */
- .equ USB_CMD_READY, 0x01 /* From c_comm.iom */
- /**
- * BT Command Indicator
- */
- .equ BT_CMD_READY, 0x02 /* From c_comm.iom */
-
- .extern dIOCtrlSetPower
- .extern dIOCtrlSetPwm
- .extern dIOCtrlTransfer
- /**
- * NXT Boot Magic Value
- */
- .equ BOOT, 0xA55A /* from c_ioctrl.iom */
- /**
- * NXT Powerdown Magic Value
- */
- .equ POWERDOWN, 0x5A00 /* from c_ioctrl.iom */
-
-#endif
-
-#endif
diff --git a/Debugger/debug_stack.ld b/Debugger/debug_stack.ld
deleted file mode 100644
index 8fc4cb7..0000000
--- a/Debugger/debug_stack.ld
+++ /dev/null
@@ -1,15 +0,0 @@
-/* The following linker definitions should be placed in the stack section */
-
- /* debugger state */
- __debugger_stack_bottom__ = . ;
- . += 0x48; /* 16 previous mode registers + SPSR + UNDEF Next Instruction Address */
- __debugger_stack__ = .;
- __debugger_stack_top__ = . ;
-
- /* breakpoints */
- __breakpoints_start__ = . ;
- . += 0x40; /* Single Stepping Breakpoint + 7 Breakpoints */
- __breakpoints_end__ = . ;
-
-/* Symbols */
- __breakpoints_num__ = (__breakpoints_end__ - __breakpoints_start__) / 8;
diff --git a/Debugger/debug_stub.S b/Debugger/debug_stub.S
deleted file mode 100644
index a7b2d56..0000000
--- a/Debugger/debug_stub.S
+++ /dev/null
@@ -1,1579 +0,0 @@
-/** @file debug_stub.S
- * @brief ARM Breakpoint Debugger support routines
- *
- */
-
-/* Copyright (C) 2007-2011 the NxOS developers
- *
- * Module Developed by: TC Wan <tcwan@cs.usm.my>
- *
- * See AUTHORS for a full list of the developers.
- *
- * See COPYING for redistribution license
- *
- */
-
- /* GDB sparc-stub.c comments header included below to document GDB Server Remote protocol */
- /* This header has been modified to include additional commands not documented in the header stub */
-
- /****************************************************************************
-
- THIS SOFTWARE IS NOT COPYRIGHTED
-
- HP offers the following for use in the public domain. HP makes no
- warranty with regard to the software or it's performance and the
- user accepts the software "AS IS" with all faults.
-
- HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
- TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-
-****************************************************************************/
-
-/****************************************************************************
- * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
- *
- * Module name: remcom.c $
- * Revision: 1.34 $
- * Date: 91/03/09 12:29:49 $
- * Contributor: Lake Stevens Instrument Division$
- *
- * Description: low level support for gdb debugger. $
- *
- * Considerations: only works on target hardware $
- *
- * Written by: Glenn Engel $
- * ModuleState: Experimental $
- *
- * NOTES: See Below $
- *
- * Modified for SPARC by Stu Grossman, Cygnus Support.
- *
- * This code has been extensively tested on the Fujitsu SPARClite demo board.
- *
- * To enable debugger support, two things need to happen. One, a
- * call to set_debug_traps() is necessary in order to allow any breakpoints
- * or error conditions to be properly intercepted and reported to gdb.
- * Two, a breakpoint needs to be generated to begin communication. This
- * is most easily accomplished by a call to breakpoint(). Breakpoint()
- * simulates a breakpoint by executing a trap #1.
- *
- *************
- *
- * The following gdb commands are supported:
- *
- * command function Return value
- *
- * g return the value of the CPU registers hex data or ENN
- * 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 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.
- * x = ['0','F'] for R0-R15, ['10','17'] for F0-F7 (dummy)
- * '18' for FPSCR (dummy), '19' for User CPSR
- *
- * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
- * MAA..AA,LLLL:bb..bb
- * Write LLLL bytes at address AA.AA OK or ENN
- *
- * D Detach (equivalent to continue Ack Only
- * at current address)
- * c Resume at current address SNN ( signal NN)
- * cAA..AA Continue at address AA..AA SNN
- *
- * s Step one instruction SNN
- * sAA..AA Step one instruction from AA..AA SNN
- *
- * k kill
- *
- * ? What was the last sigval ? SNN (signal NN)
- *
- * zt,AA..AA,k Remove a Breakpoint of type t at addr OK or ENN
- * AA..AA of kind k
- * Zt,AA..AA,k Insert a Breakpoint of type t at addr OK or ENN
- * AA..AA of kind k
- * t 0: memory breakpoint
- * 1: hardware breakpoint
- * 2: write watchpoint
- * 3: read watchpoint
- * 4: access watchpoint
- * k: 2 (16-bit Thumb), 3 (32-bit Thumb2)
- * or 4 (32-bit ARM) for t=[0,1]
- * Num. bytes to watch for t=[2,4]
- *
- * All commands and responses are sent with a packet which includes a
- * checksum. A packet consists of
- *
- * $<packet info>#<checksum>.
- *
- * where
- * <packet info> :: <characters representing the command or response>
- * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
- *
- * When a packet is received, it is first acknowledged with either '+' or '-'.
- * '+' indicates a successful transfer. '-' indicates a failed transfer.
- *
- * Example:
- *
- * Host: Reply:
- * $m0,10#2a +$00010203040506070809101112131415#42
- *
- ****************************************************************************/
- /* Modified GDB Server Remote Protocol definition from GDB's sparc-stub.c Comment Header included above
- * Additional commands from GDB Reference Appendix D.2
- *
- * 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_internals.h"
-#include "debug_macros.h"
-
- /* Opcode Parser function reference */
- .extern dbg_following_instruction_addr
-
- /* Hexutils function references */
- .extern hex2char
- .extern char2hex
- .extern byte2ascii
- .extern halfword2ascii_be
- .extern halfword2ascii_le
- .extern word2ascii_be
- .extern word2ascii_le
- .extern ascii2hex_varlen_be
- .extern ascii2byte
- .extern ascii2halfword_be
- .extern ascii2halfword_le
- .extern ascii2word_be
- .extern ascii2word_le
-
-/* Macro definitions */
-
-/* _check_msgseparator
- * Look for separator ','
- * On entry:
- * bufferptr: points to the parameter buffer [can't be R0]
- * On exit:
- * R0: destroyed
- * bufferptr: points to the next character location in the parameter buffer
- * Flags: Updated
- */
-
- .macro _check_msgseparator bufferptr
- ldrb r0, [\bufferptr], #1 /* get separator */
- cmp r0, #MSGBUF_SEPCHAR
- .endm
-
-/* _check_msgargument
- * Look for argument ':'
- * On entry:
- * bufferptr: points to the parameter buffer [can't be R0]
- * On exit:
- * R0: destroyed
- * bufferptr: points to the next character location in the parameter buffer
- * Flags: Updated
- */
-
- .macro _check_msgargument bufferptr
- ldrb r0, [\bufferptr], #1 /* get separator */
- cmp r0, #MSGBUF_ARGCHAR
- .endm
-
-/* _check_msgassignment
- * Look for assignment '='
- * On entry:
- * bufferptr: points to the parameter buffer [can't be R0]
- * On exit:
- * R0: destroyed
- * bufferptr: points to the next character location in the parameter buffer
- * Flags: Updated
- */
-
- .macro _check_msgassignment bufferptr
- ldrb r0, [\bufferptr], #1 /* get separator */
- cmp r0, #MSGBUF_SETCHAR
- .endm
-
-.bss
-.align 4
-debug_InMsgBuf:
- .space MSGBUF_SIZE,0
-debug_OutMsgBuf:
- .space MSGBUF_SIZE,0
-
- /* Make Debugger State accessible from other modules */
- .global debug_state
- .global debug_mode
- .global debug_bkpt_type
- .global debug_curr_breakpoint
-
-debug_state:
- .byte 0x0 /* dbg_state_t variable */
-debug_mode:
- .byte 0x0 /* Boolean variable */
-debug_bkpt_type:
- .byte 0x0 /* bkpt_type_t variable */
-debug_curr_breakpoint:
- .byte 0x0
-
-.data
-.align 4
-debug_RetransmitFlag:
- .byte '-',0
-
-debug_AckOnlyFlag:
- .byte '+',0
-
-debug_ValidResponsePrefix:
- .byte '+','$',0
-
-debug_ErrorResponsePrefix:
- .byte '+','$','E',0
-
-debug_SignalResponsePrefix:
- .byte '+','$','S',0
-
-debug_OkResponse:
- .byte '+','$','O','K',0
-
-debug_ThreadIDResponse:
- .byte '+','$','Q','C','0',0 /* 0: Any thread */
-
-debug_FirstThreadInfoResponse:
- .byte '+','$','m','0',0 /* 0: One default thread */
-debug_SubsequentThreadInfoResponse:
- .byte '+','$','l',0 /* End of Thread List */
-
-/* The CmdIndexTable and CmdJumpTable must be kept in sync */
-debug_cmdIndexTable:
- .byte 'g','G','p','P','m','M','D','c','s','k','z','Z','?','q','Q',0
-
-/* Command Handlers
- * On entry:
- * R0: Input Message Parameter Buffer address pointer (points to contents after '$' and '<cmdchar>')
- */
-.align 4
-debug_cmdJumpTable:
- .word _dbg__cmd_GetAllRegs /* 'g' */
- .word _dbg__cmd_SetAllRegs /* 'G' */
- .word _dbg__cmd_GetOneReg /* 'p' */
- .word _dbg__cmd_SetOneReg /* 'P' */
- .word _dbg__cmd_ReadMem /* 'm' */
- .word _dbg__cmd_WriteMem /* 'M' */
- .word _dbg__cmd_Detach /* 'D' */
- .word _dbg__cmd_Continue /* 'c' */
-#ifdef __NXOS__
- .word _dbg__cmd_Step /* 's' */
-#else
- /* NXT Firmware does not support Stepping */
- .word _dbg__nop /* 's' */
-#endif
- .word _dbg__cmd_Kill /* 'k' */
- .word _dbg__cmd_RemoveBreakpoint /* 'z' */
- .word _dbg__cmd_InsertBreakpoint /* 'Z' */
- .word _dbg__cmd_Status /* '?' */
- .word _dbg__cmd_Query /* 'q' */
- .word _dbg__nop /* 'Q' */
- .word 0
-
-.code 32
-.text
-.align 4
- .extern __breakpoints_num__
- .extern dbg__getDebugMsg /* Read a message from the communications link */
- .extern dbg__putDebugMsg /* Write a message to the communications link */
- .extern dbg__sendAckOrNak /* Send Ack or Nak to indicate success/failure of message receipt */
- .extern dbg__runloopTasks /* Platform specific Run Loop processing */
-
-
-/* The Debugger Interface can handle a total of (n-1) Breakpoint States and 1 Single Stepping State,
- * where n is a power of 2. The value of n is given by __breakpoints_num__ defined in the linker file.
- *
- * In addition, a Debugger Stack contains the User Mode Register Stack Frame + SPSR + Bkpt Instr Addr.
- * These are currently stored in the .stack area in RAM, so there is no fixed address
- * location that is used for this purpose.
- *
- * The Breakpoint feature assumes that the program is executed in RAM. It is not possible
- * to set dynamic breakpoints for programs executed from Flash in the AT91SAM7S which lacks
- * instruction breakpointing support in hardware without using JTAG. The only type of breakpoints
- * that can be supported in Flash based programs are Static (predefined) breakpoints inserted into
- * the code.
- *
- * Each Breakpoint State i is a struct comprising the Breakpoint Address + Memory Contents
- * stored in 8 bytes as:
- * [High Memory Address]
- * ADDR [i*8+4]: Memory Contents (32 bits)
- * ADDR [i*8]: Breakpoint Address (31 bits, b0 = THUMB flag [not implemented yet])
- * [Low Memory Address]
- *
- * A Non-zero Breakpoint Address means that the breakpoint is active, whereas the memory contents
- * contains the instruction which resided at that address initially (now replaced by a BKPT <index>
- * instruction).
- * Note: Currently it is not possible to resume execution of a program with breakpoints enabled
- * after a RESET, since the RESET will clear all contents of the stack, destroying the instruction
- * contained in a given breakpoint.
- * Fortunately the NXT will also need to reload the program into RAM so this is not expected to be
- * an issue.
- *
- * The Memory Map for the Debugger State is as follows:
- *
- * [High Memory Address] __breakpoints_end__
- * Breakpoint 07 State
- * Breakpoint 06 State
- * ...
- * Breakpoint 02 State
- * Breakpoint 01 State
- * Single Step State __debugger_stack__ / __breakpoints_start__
- * Previous Mode R15
- * Previous Mode R14
- * Previous Mode R13
- * ...
- * User Mode R02
- * User Mode R01
- * User Mode R00
- * Previous Mode CPSR (UNDEF SPSR)
- * UNDEF Next Instr Addr __debugger_stack_bottom__
- * [Low Memory Address]
- *
- * Each Breakpoint State will initially be zeroed.
- *
- */
- /* FIXME: The Debugger Stack Frame is probably not 100% consistent with the order that
- GDB expects in the g/G messages. CSPR is probably located above R15 */
-
-/****************************************************************************
- *
- * GDB Debugger Init and Breakpoint Handler Routines
- *
- ****************************************************************************/
- .code 32
- .align 4
-/* dbg__bkpt_init
- * GDB set_debug_traps() routine
- * On entry:
- * None
- * On exit:
- * r0-r3: destroyed
- */
- dbg_interwork dbg__bkpt_init
- push {lr}
- bl _dbg__clear_breakpoints
- mov r2, #0
- ldr r1, =debug_curr_breakpoint
- strb r2, [r1]
- ldr r0, =debug_InMsgBuf
- strb r2, [r0]
- ldr r1, =debug_OutMsgBuf
- strb r2, [r1]
- bl dbg__comm_init /* Pass R0: Rx Buffer, R1: Tx Buffer to comm submodule */
-
-/* FIXME: Initialize other stuff here */
- _dbg_setstate DBG_INIT
- _dbg_setmode FALSE /* Debug Mode = False */
- pop {lr}
- bx lr /* Must return via BX; may have been called from Thumb mode (NXT Firmware) */
-
-
-/* _dbg__flush_icache
- * Flush the Instruction cache
- * Defined by GDB Stub, but not needed for ARMv4T architecture
- */
-_dbg__flush_icache:
- /* nop */
- bx lr
-
-/* _dbg__switch2undefmode
- * Common internal routine to return execution to user program
- */
-_dbg__switch2undefmode:
- bl _dbg__flush_icache
- 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__abort_exception_handler
- * Handle Abort Exceptions
- * On entry:
- * r0: Abort Type Enum
- * On exit:
- * routine does not 'exit' in the normal sense
- */
- dbg_interwork dbg__abort_exception_handler
- _dbg_set_bkpt_type r0 /* Set Breakpoint Type given value in R0 */
- b dbg__bkpt_waitCMD
-
-/* dbg__thumb_bkpt_handler
- * GDB handle_exception() routine (Thumb Mode)
- * On entry:
- * r0: Breakpoint index value
- * On exit:
- * routine does not 'exit' in the normal sense
- */
- dbg_interwork dbg__thumb_bkpt_handler
- /* On entry, r0 contains breakpoint index value */
- _dbg_setcurrbkpt_index r0 /* keep current breakpoint index in memory */
- ldr r1, =BKPT16_MANUAL_BKPT
- teq r0, r1
- moveq r0, #DBG_MANUAL_BKPT_THUMB /* Manual Thumb Breakpoint, process it */
- beq _restore_normal_breakpoints
-
-_process_normal_breakpoint_thumb:
- ldr r1, =__breakpoints_num__
- cmp r0, r1 /* Sanity check that index is in range */
- bhs dbg__bkpt_offset_outofrange /* Exceeded Offset Range */
- mov r0, #DBG_NORMAL_BKPT_THUMB /* It is a valid normal breakpoint */
- b _restore_normal_breakpoints
-
-/* dbg__arm_bkpt_handler
- * GDB handle_exception() routine (ARM Mode)
- * On entry:
- * r0: breakpoint index value
- * On exit:
- * routine does not 'exit' in the normal sense
- */
- dbg_interwork dbg__arm_bkpt_handler
- /* On entry, r0 contains breakpoint index value */
- _dbg_setcurrbkpt_index r0 /* keep current breakpoint index in memory */
- ldr r1, =BKPT32_MANUAL_BKPT
- teq r0, r1
- moveq r0, #DBG_MANUAL_BKPT_ARM /* Manual ARM Breakpoint, process it */
- beq _restore_normal_breakpoints
-
-_process_normal_breakpoint_arm:
- ldr r1, =__breakpoints_num__
- cmp r0, r1 /* Sanity check that index is in range */
- bhs dbg__bkpt_offset_outofrange /* Exceeded Offset Range */
- mov r0, #DBG_NORMAL_BKPT_ARM /* It is a valid normal breakpoint */
-/* b _restore_normal_breakpoints */
-
-_restore_normal_breakpoints:
- _dbg_set_bkpt_type r0 /* Set Breakpoint Type given value in R0 */
- bl _dbg__restore_breakpoints /* includes restoring single step */
- bl _dbg__clear_singlestep
- bl _dbg__flush_icache
-/* b dbg__bkpt_waitCMD */
-
-dbg__bkpt_inactive:
-/* b dbg__bkpt_waitCMD */
-
-dbg__bkpt_offset_outofrange:
-/* b dbg__bkpt_waitCMD */
-
-/* dbg__bkpt_waitCMD
- * GDB Stub Remote Command Handler
- */
-
-/****************************************************************************
- *
- * GDB Server Command Processing Routines
- *
- ****************************************************************************/
- dbg_interwork dbg__bkpt_waitCMD
- /* We enter this code section when a Breakpoint Triggers */
- _dbg_setmode TRUE /* Debug Mode = True */
- msr cpsr_c, #(MODE_ABT) /* Re-enable Interrupts */
-
- _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__bkpt_waitCMD_cont /* No message yet, do housekeeping tasks */
- bgt _proc_command /* valid message, process it */
- bl __dbg__procChecksumError /* Message invalid, checksum error? */
- b dbg__bkpt_waitCMD_cont
-
-_proc_command:
-/* Message now has Ctrl-C or $<packet info>\0 */
- mov r4, r1 /* Use R4 as buffer pointer */
- ldrb r0, [r4], #1 /* Look for Ctrl-C or '$' */
- teq r0, #MSGBUF_CTRLC
- bne _dbg_check_gdb_command
- /* Ctrl-C detected, do nothing (wait for next command from GDB) */
-#if 0
- /* On entering the Debugger via Ctrl-C, _dbg__cmd_Status has already sent a reply, so just keep quiet */
- bl __dbg__procAckOnly /* send Ack */
-#endif
- b dbg__bkpt_waitCMD_cont
-
-_dbg_check_gdb_command:
- teq r0, #MSGBUF_STARTCHAR
- movne r1, #MSG_ERRFORMAT /* Message Format invalid (not '$') */
- bne _dbg__cmdError /* Shouldn't happen */
- ldrb r0, [r4], #1 /* Look for command char */
- 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 r1, #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__bkpt_waitCMD_cont
-
-_dbg__cmdError:
- _dbg_outputMsgStatusErr
- bl dbg__putDebugMsg /* Send error response to the GDB server */
- b dbg__bkpt_waitCMD_cont
-
-
-/* __dbg__procOkOnly
- * Send OK to GDB due to Detach
- * On entry:
- * None
- * On exit:
- * r0-r3: destroyed
- */
-__dbg__procOkOnly:
- stmfd sp!, {lr}
- _dbg_outputMsgStatusOk /* Acknowledge Detach command from GDB server */
-_cont_procOkOnly:
- bl dbg__putDebugMsg /* Send OK response to the GDB server */
- cmp r0, #0
- beq _cont_procOkOnly_exit /* Sending of OK succeeded */
- bl dbg__runloopTasks /* Service run loop tasks */
- b _cont_procOkOnly /* Retry OK transmission */
-_cont_procOkOnly_exit:
- ldmfd sp!, {pc}
-
-
-/* __dbg__procAckOnly
- * Send Ack to GDB due to Continue or Step
- * On entry:
- * None
- * On exit:
- * r0-r3: destroyed
- */
-__dbg__procAckOnly:
- stmfd sp!, {lr}
- _dbg_outputAckOnlyFlag
- b _cont_sendAckOrNak /* Acknowledge Continue or Step command from GDB server */
-
-/* __dbg__procChecksumError
- * Request Retransmission from GDB due to Checksum error
- * On entry:
- * None
- * On exit:
- * r0-r3: destroyed
- */
-__dbg__procChecksumError:
- stmfd sp!, {lr}
- _dbg_outputRetransmitFlag
- /* b _cont_sendAckOrNak */ /* Acknowledge Continue or Step command from GDB server */
-
-_cont_sendAckOrNak:
- bl dbg__sendAckOrNak /* send Ack or Nak to GDB server */
- cmp r0, #0
- beq _cont_sendAckOrNak_exit /* Sending of Ack or Nak succeeded */
- bl dbg__runloopTasks /* Service run loop tasks */
- b _cont_sendAckOrNak /* Retry Ack or Nak transmission */
-_cont_sendAckOrNak_exit:
- ldmfd sp!, {pc}
-
-/* _dbg__cmdChar2Index
- * Convert Command Character to Jump Table Index
- * On entry:
- * r0: command character
- * On exit:
- * r0: jump table index (-1 for command not found)
- * R1: destroyed
- * R2: destroyed
- * R3: destroyed
- */
-_dbg__cmdChar2Index:
- mov r1, r0 /* Copy command character to r1 */
- mov r0, #0 /* Clear return value */
- ldr r3, =debug_cmdIndexTable /* Convert command to index using r3 as Index Lookup Address Pointer */
-1: ldrb r2, [r3, r0] /* Get table entry */
- teq r2, #0
- moveq r0, #CMDINDEX_OUTOFRANGE /* End of Index Table, Not found */
- beq _exit_cmdIndexTable
- teq r1, r2
- addne r0, #1 /* Increment Index */
- bne 1b /* No match, skip to next command char */
-_exit_cmdIndexTable:
- bx lr
-
-/* __dbg__cmdParamLen
- * Determines the length of the parameter buffer for a given command
- * On entry:
- * R0: parameter buffer pointer (contents after '$' and '<cmdchar>')
- * On exit:
- * R0: Address of parameter buffer (preserved)
- * R1: length
- */
-__dbg__cmdParamLen:
- stmfd sp!, {r0,r2,lr} /* R2: scratch register */
- mov r1, #0
-1: ldrb r2, [r0], #1
- teq r2, #0
- addne r1, r1, #1
- bne 1b
- ldmfd sp!, {r0,r2,pc}
-
-/* __dbg__procCmdOk
- * Common subroutine exit stub to return Command Ok Status for Command Handlers
- * DO NOT CALL THIS STUB DIRECTLY! It Assumes that the return address is in the stack.
- *
- */
-__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.
- *
- */
-__dbg__procCmdParamError:
- mov r1, #MSG_UNKNOWNPARAM
- b __dbg__procErrorMsg
-
-/* __dbg__procCmdReturnInputLengthError
- * Common subroutine exit stub to handle Command Input Length Error for Command Handlers
- * DO NOT CALL THIS STUB DIRECTLY! It Assumes that the return address is in the stack.
- *
- */
-__dbg__procCmdReturnInputLengthError:
- mov r1, #MSG_ERRINLENGTH
- b __dbg__procErrorMsg
-
-/* __dbg__procCmdReturnOutputLengthError
- * Common subroutine exit stub to handle Command Return Output Error for Command Handlers
- * DO NOT CALL THIS STUB DIRECTLY! It Assumes that the return address is in the stack.
- *
- */
-__dbg__procCmdReturnOutputLengthError:
- mov r1, #MSG_ERROUTLENGTH
- b __dbg__procErrorMsg
-
-/* __dbg__procBreakpointAddrError
- * Common subroutine exit stub to handle Breakpoint Address Error for Breakpoint Insert/Remove Handlers
- * DO NOT CALL THIS STUB DIRECTLY! It Assumes that the return address is in the stack.
- *
- */
-__dbg__procBreakpointAddrError:
- mov r1, #MSG_UNKNOWNBRKPT
-/* b __dbg__procErrorMsg */
-
-
-__dbg__procErrorMsg:
- _dbg_outputMsgStatusErr
- /* b __dbg__sendDebugMsgExit */
-
-__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_get_bkpt_type r0
-_check_data_abort_exception:
- teq r0, #DBG_ABORT_DATA
- moveq r1, #MSG_SIG_BUS /* Bus Error */
- beq _exit_dmg__cmd_Status
-_check_prefetch_abort_exception:
- teq r0, #DBG_ABORT_PREFETCH
- moveq r1, #MSG_SIG_ABRT /* FIMXE: Look for a better Signal number */
- beq _exit_dmg__cmd_Status
-_default_breakpoint_exception:
- mov r1, #MSG_SIG_DEFAULT /* Dummy Signal number */
-
-_exit_dmg__cmd_Status:
- _dbg_outputMsgStatusSig
- 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!, {r0,r1, lr}
- _dbg_setstate DBG_CONFIGURED /* We have exchanged query messages with the GDB server */
- ldmfd sp!, {r0, r1} /* Restore parameters needed for subsequent processing */
- bl __dbg__cmdParamLen
- cmp r1, #CMD_QUERY_MINPARAMLEN
- beq _dbg__cmd_Query_default
-
- ldrb r2, [r0] /* Get First Query Param Char */
-_dbg__cmd_Query_check_C:
- teq r2, #CMD_QUERY_CURRTID_CHAR /* Handle Current Thread ID Query */
- bne _dbg__cmd_Query_check_fThreadInfo
- cmp r1, #CMD_QUERY_CURRTID_PARAMLEN
- bne _dbg__cmd_Query_default
- _dbg_outputMsgCurrTID
- b __dbg__sendDebugMsgExit
-_dbg__cmd_Query_check_fThreadInfo:
- teq r2, #CMD_QUERY_FTINFO_CHAR /* Handle fThreadInfo Query */
- bne _dbg__cmd_Query_check_sThreadInfo
- cmp r1, #CMD_QUERY_FTINFO_PARAMLEN
- bne _dbg__cmd_Query_default
- _dbg_outputMsgFirstThreadInfo
- b __dbg__sendDebugMsgExit
-_dbg__cmd_Query_check_sThreadInfo:
- teq r2, #CMD_QUERY_STINFO_CHAR /* Handle sThreadInfo ID Query */
- bne _dbg__cmd_Query_default
- cmp r1, #CMD_QUERY_STINFO_PARAMLEN
- bne _dbg__cmd_Query_default
- _dbg_outputMsgSubsequentThreadInfo
- b __dbg__sendDebugMsgExit
-
-_dbg__cmd_Query_default:
- b __dbg__procUnimplementedError /* FIXME: return an empty message to GDB (no modifiable settings) */
-
-
-/* _dbg__cmd_GetOneReg
- * Get One Register Value Command Handler
- * Valid command parameter x is from '0' to 'F' for User Mode Registers R0-R15,
- * '18' for FPSCR (dummy), and '19' for CPSR
- * On entry:
- * r0: parameter buffer pointer (contents after '$' and '<cmdchar>')
- * x
- * On exit:
- * r0, r1, r2, r3, r4: destroyed
- *
- */
-_dbg__cmd_GetOneReg:
- stmfd sp!, {lr}
- bl __dbg__cmdParamLen
- cmp r1, #CMD_REG_GETONE_MINPARAMLEN /* Check for correct length */
- blo __dbg__procCmdParamError /* Unexpected input, report error */
- cmp r1, #CMD_REG_GETONE_MAXPARAMLEN /* Check for correct length */
- bhi __dbg__procCmdParamError /* Unexpected input, report error */
- bl ascii2hex_varlen_be /* convert ASCII reg enum to Hex (in R0), R1 has address of next buffer char */
-
-_dbg__proc_getRegister:
- mov r4, r0 /* Keep register index safe */
- _dbg_outputMsgValidResponse /* R0: address of output message buffer data pointer (after response prefix) */
- mov r1, r4 /* Move register index value to R1 */
- bl _dbg_outputOneRegValue /* update output buffer */
- _asciiz r0, r1
- bl dbg__putDebugMsg /* Send response to the GDB server */
- ldmfd sp!, {pc}
-
-/* _dbg_outputOneRegValue
- * Given Register Enum (0-F: R0-R15, 0x19: CPSR, OtherVal: dummy), output hex char to buffer
- * On entry:
- * r0: output message buffer pointer
- * r1: register enum (0-F, 0x19)
- * On exit:
- * r0: updated (points to next character slot at end of Output Buffer)
- * r1: original output message buffer pointer
- * r2: destroyed
- */
-_dbg_outputOneRegValue:
- stmfd sp!, {lr}
- cmp r1, #REG_PC
- addls r2, r1, #DBGSTACK_USERREG_INDEX /* Convert register enum to Debug Stack index */
- bls _retrieve_RegVal
-
- cmp r1, #REG_CPSR
- moveq r2, #DBGSTACK_USERCPSR_INDEX /* convert register enum to Debug Stack index */
- beq _retrieve_RegVal
-
- bhi _exit_dbg_outputOneRegValue /* No match (reg enum > REG_CPSR), skip */
-
-#if 0
- cmp r1, #REG_FPSCR
- bne _exit_dbg_outputOneRegValue /* No match, skip */
-#endif
-
-_output_dummy_regval:
- /* Output Dummy Register value (for F0-F7, FPSR) */
- /* FIXME: F0-F7 expects output value that is more than 32-bits */
- mov r1, #0
- b _output2buffer /* Output all zeros for F0-F7, FPSCR */
-
-_retrieve_RegVal:
- _getdbgregisterfromindex r2, r1 /* Retrieve Register contents into R1 */
-
-_output2buffer:
-
-#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
-
-_exit_dbg_outputOneRegValue:
- ldmfd sp!, {pc}
-
-/* _dbg__cmd_GetAllRegs
- * Get All Register Values Command Handler
- * Output Buffer returns register values in the order: User R0, R1, R2, ..., R15
- * On entry:
- * r0: parameter buffer pointer (contents after '$' and '<cmdchar>')
- * <NULL> (no parameters)
- * On exit:
- * r0, r1, r2, r3: destroyed
- */
-_dbg__cmd_GetAllRegs:
- stmfd sp!, {lr}
- bl __dbg__cmdParamLen
- teq r1, #CMD_REG_GETALL_PARAMLEN /* Check for correct length */
- bne __dbg__procCmdParamError /* Unexpected input, report error */
-
- _dbg_outputMsgValidResponse /* R0: address of output message buffer data pointer (after response prefix) */
-
- /* We must return R0-R15, then CPSR */
- mov r3, #REG_R0 /* Output User Register Values first */
-1: mov r1, r3
- bl _dbg_outputOneRegValue /* update output buffer */
- add r3, r3, #1 /* increment index */
- cmp r3, #REG_PC
- bls 1b /* process all the registers */
-#if 0
-_get_cpsr:
- /* GDB will query for CPSR value specifically */
- mov r1, #REG_CPSR /* Output User CPSR Value last */
- bl _dbg_outputOneRegValue /* update output buffer */
-#endif
- _asciiz r0, r1
- bl dbg__putDebugMsg /* Send response to the GDB server */
- ldmfd sp!, {pc}
-
-/* _dbg_setOneRegValue
- * Given Register Enum (0-F: R0-R15, 0x19: CPSR, OtherVal: dummy), output hex char to buffer
- * On entry:
- * r0: parameter buffer pointer
- * r1: register enum (0-F, 0x19)
- * On exit:
- * r0: (Updated) Address of parameter in buffer
- * r1, r2, r3: destroyed
- *
- * FIXME: This routine assumes that the input buffer contains exactly 8-Hex digits for each register value.
- */
-_dbg_setOneRegValue:
- stmfd sp!, {lr}
- cmp r1, #REG_PC
- addls r2, r1, #DBGSTACK_USERREG_INDEX /* Convert register enum to Debug Stack index */
- bls _store_RegVal
-
- cmp r1, #REG_CPSR
- moveq r2, #DBGSTACK_USERCPSR_INDEX /* convert register enum to Debug Stack index */
- beq _store_RegVal
-
- bhi _exit_dbg_setOneRegValue /* No match (reg enum > REG_CPSR), skip */
-
-#if 0
- cmp r1, #REG_FPSCR
- bne _exit_dbg_setOneRegValue /* No match, skip */
-#endif
-
-_set_dummy_regval:
- /* FIXME: This assumes that we will never get FP reg values (96-bits) in this routine */
- /* Set dummy FPSCR value (ignored) */
- add r1, r0, #CMD_REG_REGPARAMLEN /* Just increment the pointer */
- b _done_store_RegVal
-
-_store_RegVal:
-#ifdef __BIG_ENDIAN__
- bl ascii2word_be
-#else
- bl ascii2word_le
-#endif
- /* 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 */
-_done_store_RegVal:
- mov r0, r1 /* Copy buffer pointer to next parameter to R0 for return value */
-_exit_dbg_setOneRegValue:
- ldmfd sp!, {pc}
-
-
-/* _dbg__cmd_SetOneReg
- * Set One Register Value Command Handler
- * Valid command parameter x is from '0' to 'F' for User Mode Registers R0-R15,
- * '18' for FPSCR (dummy), and '19' for CPSR
- * On entry:
- * r0: parameter buffer pointer (contents after '$' and '<cmdchar>')
- * x=rrrr
- * On exit:
- * r0, r1, r2, r3, r4: destroyed
- *
- */
-_dbg__cmd_SetOneReg:
- stmfd sp!, {lr}
- bl __dbg__cmdParamLen
- cmp r1, #CMD_REG_SETONE_MINPARAMLEN /* Check for correct length */
- blo __dbg__procCmdParamError /* Unexpected input, report error */
- cmp r1, #CMD_REG_SETONE_MAXPARAMLEN /* Check for correct length */
- bhi __dbg__procCmdParamError /* Unexpected input, report error */
-
- /* FIXME: We can't set FP regs.
- * Fortunately the values required by FP regs are 96 bits (24 nibbles)
- * so it fails the CMD_REG_SETONE_MAXPARAMLEN check
- */
-
- bl ascii2hex_varlen_be /* convert ASCII reg enum to Hex (in R0), R1 has address of next buffer char */
- cmp r0, #REG_FPSCR
- beq __dbg__procCmdParamError /* Don't allow setting of FPSCR */
- mov r4, r0 /* Keep enum in R4 */
- _check_msgassignment r1 /* R1 points to next char in buffer */
- bne __dbg__procCmdParamError /* Can't find '=' */
-
-_dbg__proc_setRegister:
- mov r0, r1 /* move parameter buffer pointer to R0 */
- mov r1, r4 /* and retrieve enum to R1 to call _dbg_setOneRegValue */
- bl _dbg_setOneRegValue
- b __dbg__procCmdOk
-
-/* _dbg__cmd_SetAllReg
- * Set All Register Values Command Handler
- * On entry:
- * r0: parameter buffer pointer (contents after '$' and '<cmdchar>')
- * rrrrRRRRrrrr... (17 registers)
- * On exit:
- * r0, r1, r2, r3, r4: destroyed
- *
- */
-_dbg__cmd_SetAllRegs:
- /* Assumes that the registers are in the sequence R0, R1, ... R15 */
- 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 r4, #REG_R0 /* R4: register enum, starting with enum for R0 */
-1: mov r1, r4 /* Copy enum to R1; R0 already points to current parameter */
- bl _dbg_setOneRegValue /* R0: next parameter address pointer */
- add r4, r4, #1 /* increment index */
- cmp r4, #REG_PC
- bls 1b
-
- ldrb r0, [r0]
- teq r0, #0 /* Look for ASCIIZ character to terminate loop */
- beq __dbg__procCmdOk
- bne __dbg__procCmdParamError /* Unexpected input, report error */
-
-/* _dbg__nop
- * NOP Command Handler (placeholder)
- * On entry:
- * r0: parameter buffer (contents after '$' and '<cmdchar>')
- * On exit:
- * r0, r1, r2, r3: destroyed
- */
-_dbg__nop:
- stmfd sp!, {lr}
- b __dbg__procUnimplementedError
-
-/* _dbg__cmd_ReadMem
- * Read Memory Contents Command Handler
- * Output Buffer returns memory contents
- * On entry:
- * r0: parameter buffer pointer (contents after '$' and '<cmdchar>')
- * AA..AA,LLLL
- * On exit:
- * r0, r1, r2, r3, r4, r5: destroyed
- */
-_dbg__cmd_ReadMem:
- stmfd sp!, {lr}
- bl __dbg__cmdParamLen
-#if 0
- teq r1, #CMD_MEM_READ_PARAMLEN /* Check for correct length */
- bne __dbg__procCmdParamError /* Unexpected input, report error */
- bl ascii2word_be /* convert ASCII address location to Hex (in R0), R1 has address of next buffer char */
-#endif
- bl ascii2hex_varlen_be /* convert ASCII address to Hex (in R0), R1 has address of next buffer char */
- mov r5, r0 /* Keep Address location in R5 */
- _check_msgseparator r1
- bne __dbg__procCmdParamError /* Can't find ',' */
- mov r0, r1 /* move buffer pointer to R0 for subsequent processing */
- bl ascii2hex_varlen_be /* convert ASCII length to Hex (in R0), R1 has address of next buffer char */
- cmp r0, #CMD_MEM_MAXREADBYTES /* Don't overflow our buffer (2 x CMD_MEM_MAXREADBYTES) */
- bhi __dbg__procCmdReturnOutputLengthError /* Requested Length greater than buffer size, return error */
- mov r4, r0 /* Keep numbytes in R4 */
- /* FIXME: Should validate the address? */
-
- _dbg_outputMsgValidResponse /* R0: address of output message buffer data pointer (after response prefix) */
-1: ldrb r1, [r5], #1
- bl byte2ascii /* update output buffer */
- subs r4, r4, #1
- bne 1b
-
- _asciiz r0, r1
- bl dbg__putDebugMsg /* Send response to the GDB server */
- ldmfd sp!, {pc}
-
-
-/* _dbg__cmd_WriteMem
- * Write Memory Contents Command Handler
- * On entry:
- * r0: parameter buffer pointer (contents after '$' and '<cmdchar>')
- * AA..AA,LLLL::bb..bb
- * On exit:
- * r0, r1, r2, r3, r4: destroyed
- */
-_dbg__cmd_WriteMem:
- stmfd sp!, {lr}
- bl __dbg__cmdParamLen
-#if 0
- cmp r1, #CMD_MEM_WRITE_MINPARAMLEN /* Check for correct (minimum) length */
- blo __dbg__procCmdParamError /* Unexpected input, report error */
- sub r4, r1, #CMD_MEM_WRITE_MINPARAMLEN /* R4: Number of ASCII Hex chars for byte writes */
- bl ascii2word_be /* convert ASCII address location to Hex (in R0), R1 has address of next buffer char */
-#endif
- bl ascii2hex_varlen_be /* convert ASCII address to Hex (in R0), R1 has address of next buffer char */
- mov r3, r0 /* Keep Address location in R3 */
- _check_msgseparator r1
- bne __dbg__procCmdParamError /* Can't find ',' */
- mov r0, r1 /* move buffer pointer to R0 for subsequent processing */
- bl ascii2hex_varlen_be /* convert ASCII length to Hex (in R0), R1 has address of next buffer char */
- cmp r0, r4, asr #1 /* is Number of bytes to write == (number of ASCII Hex Chars / 2)? */
- bne __dbg__procCmdParamError /* Number of bytes does not match argument length */
- cmp r0, #CMD_MEM_MAXWRITEBYTES /* Don't overflow our buffer (2 x CMD_MEM_MAXWRITEBYTES) */
- bhi __dbg__procCmdReturnInputLengthError /* Requested Length greater than buffer size, return error */
- mov r4, r0 /* Keep numbytes in R4 */
- /* FIXME: Should validate the address? */
- _check_msgargument r1
- bne __dbg__procCmdParamError /* Can't find ':' */
-
-1: mov r0, r1
- bl ascii2byte /* convert ASCII Hex value into byte value */
- strb r0, [r3], #1 /* Store into memory location */
- subs r4, r4, #1
- bne 1b
- b __dbg__procCmdOk
-
-/* _dbg__cmd_Detach
- * Detach User Program Execution Command Handler
- * Treat this as being equivalent to 'Continue' without any arguments
- *
- * On entry:
- * r0: parameter buffer pointer (contents after '$' and '<cmdchar>')
- * <NULL> (No Parameters)
- * On exit:
- * r0-r7: destroyed
- * Note: This routine does not return to caller. Instead it switches
- * operating mode to UNDEF and returns to previously active program
- */
-_dbg__cmd_Detach:
- stmfd sp!, {lr} /* In case unexpected parameters were received */
- bl __dbg__cmdParamLen
- teq r1, #CMD_DETACH_PARAMLEN /* Check for correct length */
- bne __dbg__procCmdParamError /* Unexpected input, report error */
-
- ldmfd sp!, {lr} /* Cleanup stack, since we won't return to the Debugger Run Loop */
- _dbg_setstate DBG_INIT /* Reset the Debug State */
- bl __dbg__procOkOnly /* send OK to keep GDB server happy */
- b _dbg__cont_check_breakpoint_type /* Continue from current PC */
-
-/* _dbg__cmd_Continue
- * Continue User Program Execution Command Handler
- * Setup breakpoints before resuming execution of program.
- *
- * If Address is specified, update the next instruction address to specified address
- *
- * If this is a Normal Breakpoint, then we resume from current (Breakpoint) exception address
- * Else (it is a Manual Breakpoint or Address Specified)
- * We need to resume from the next instruction address
- * On entry:
- * r0: parameter buffer pointer (contents after '$' and '<cmdchar>')
- * Optional: AA..AA
- * On exit:
- * r0-r7: 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:
- /* Don't put anything on the stack, we won't return to the Debugger Run Loop */
- bl __dbg__cmdParamLen
- cmp r1, #CMD_CONTINUE_MINPARAMLEN /* Check for correct parameter length */
- bne _dbg__cont_fromAddr /* Address is specified */
- bl __dbg__procAckOnly /* send Ack to keep GDB server happy */
- b _dbg__cont_check_breakpoint_type /* Continue from current PC */
-
-_dbg__cont_fromAddr:
- bl ascii2hex_varlen_be /* convert ASCII address to Hex (in R0), R1 has address of next buffer char */
- /* Continue from Specified Address */
- _setdbgregister DBGSTACK_NEXTINSTR_INDEX, r0, r1 /* Set Next Instruction Pointer for Resume using contents of R0, and scratch register R1 */
- bl __dbg__procAckOnly /* send Ack to keep GDB server happy */
- b _dbg__cont_is_manual_bkpt_or_address_specified
-
-_dbg__cont_check_breakpoint_type:
- _dbg_get_bkpt_type r0
- teq r0, #DBG_MANUAL_BKPT_ARM
- beq _dbg__cont_is_manual_bkpt_or_address_specified
- teq r0, #DBG_MANUAL_BKPT_THUMB
- beq _dbg__cont_is_manual_bkpt_or_address_specified
-
-_dbg__cont_is_normal_breakpoint:
- _getdbgregister DBGSTACK_USERPC_INDEX, r0 /* Retrieve Aborted Instruction PC from the Debug Stack into R0 */
- _setdbgregister DBGSTACK_NEXTINSTR_INDEX, r0, r1 /* Set Next Instruction Pointer for Resume using contents of R0, and scratch register R1 */
- /* GDB knows to Step from a breakpointed instruction before continuing when
- * Continue is issued, so it is safe to activate all defined breakpoints and continue.
- */
-_dbg__cont_is_manual_bkpt_or_address_specified:
- bl _dbg__activate_breakpoints /* Restore exisiting breakpoints */
- b _dbg__switch2undefmode
-
-/* _dbg__cmd_Step
- * Step User Program Execution Command Handler
- * Setup breakpoints before resuming execution of program.
- *
- * If Address is specified, update the next instruction address to specified address
- *
- * If this is a Normal Breakpoint, then we need to install a Step Breakpoint at next instruction address
- * and resume from current (Breakpoint) exception address
- * Else (it is a Manual Breakpoint or Address specified)
- * We need to install a Step Breakpoint at the following instruction address (after the next instruction address)
- * and resume from the next instruction address
- * On entry:
- * r0: parameter buffer pointer (contents after '$' and '<cmdchar>')
- * Optional: AA..AA
- * On exit:
- * r0-r7: destroyed
- * Note: This routine does not return to caller. Instead it switches
- * operating mode to UNDEF and returns to previously active program
- */
-_dbg__cmd_Step:
- /* Don't put anything on the stack, we won't return to the Debugger Run Loop */
- bl __dbg__cmdParamLen
- cmp r1, #CMD_STEP_MINPARAMLEN /* Check for correct parameter length */
- beq _dbg__step_check_breakpoint_type /* Step from current PC */
-
-_dbg__step_fromAddr:
- bl ascii2hex_varlen_be /* convert ASCII address to Hex (in R0), R1 has address of next buffer char */
- /* Step from Specified Address */
- _setdbgregister DBGSTACK_NEXTINSTR_INDEX, r0, r1 /* Set Next Instruction Pointer for Resume using contents of R0, and scratch register R1 */
- b _dbg__step_is_manual_bkpt_or_address_specified
-
-_dbg__step_check_breakpoint_type:
- _dbg_get_bkpt_type r0
- teq r0, #DBG_MANUAL_BKPT_ARM
- beq _dbg__step_is_manual_bkpt
- teq r0, #DBG_MANUAL_BKPT_THUMB
- beq _dbg__step_is_manual_bkpt
-
-_dbg__step_is_normal_breakpoint:
- _getdbgregister DBGSTACK_USERPC_INDEX, r0 /* Retrieve Aborted Instruction PC from the Debug Stack into R0 */
- _setdbgregister DBGSTACK_NEXTINSTR_INDEX, r0, r1 /* Set Next Instruction Pointer for Resume usinh contents in R0, and scratch register R1 */
- b _dbg__step_is_manual_bkpt_or_address_specified
-
-_dbg__step_is_manual_bkpt:
- _getdbgregister DBGSTACK_NEXTINSTR_INDEX, r0 /* Retrieve Next Instruction Pointer for Resume into R1 */
- /* b _dbg__step_is_manual_bkpt_or_address_specified */
-
-_dbg__step_is_manual_bkpt_or_address_specified:
- bl dbg_following_instruction_addr /* following instruction address returned in r1 */
- bl dbg__install_singlestep /* Setup Single Step, next instruction address returned in r1 */
- bl dbg__activate_singlestep
-#if 0
- /* Disable ACK transmit, let the next Breakpoint generate the Signal Response */
- bl __dbg__procAckOnly /* send Ack to keep GDB server happy */
-#endif
- b _dbg__switch2undefmode
-
-/* _dbg__cmd_Kill
- * Kill User Program Execution Command Handler
- * Kill Program, this is accomplished by rebooting the Brick
- *
- * On entry:
- * r0: parameter buffer pointer (contents after '$' and '<cmdchar>')
- * <NULL> (No Parameters)
- * On exit:
- * r0-r7: destroyed
- * Note: This routine does not return to caller. Instead it calls
- * the relevant system routine to reboot the Brick
- */
-_dbg__cmd_Kill:
- stmfd sp!, {lr} /* In case unexpected parameters were received */
- bl __dbg__cmdParamLen
- teq r1, #CMD_KILL_PARAMLEN /* Check for correct length */
- bne __dbg__procCmdParamError /* Unexpected input, report error */
-
- bl __dbg__procAckOnly /* send Ack to keep GDB server happy */
- b dbg__reboot /* Goodbye.... */
-
-/* _dbg__proc_brkpt_params
- * Process Breakpoint Parameters
- * On entry:
- * r0: parameter buffer pointer (contents after '$' and '<cmdchar>')
- * t,AA..AA,k
- * On exit:
- * r0: non-zero = breakpoint address; 0 = parameter error
- * r1: destroyed
- * r2: destroyed
- * r3: destroyed
- */
-_dbg__proc_brkpt_params:
- /* FIXME: Add support for watchpoints */
- stmfd sp!, {lr}
- mov r3, r0 /* Keep parameter buffer address in R3 */
- ldrb r0, [r3], #1 /* get breakpoint type t */
- bl char2hex
- cmp r0, #CMD_BKPT_TYPE_BREAK_MEMORY
- bne _dbg__proc_brkpt_params_error /* We only support memory breakpoints for now */
- _check_msgseparator r3
- bne _dbg__proc_brkpt_params_error /* Something wrong with the parameters */
- mov r0, r3 /* Check Address */
- bl ascii2hex_varlen_be /* convert ASCII address to Hex (in R0), R1 has address of next buffer char */
- mov r3, r0 /* Keep breakpoint address in R3 */
- _check_msgseparator r1
- bne _dbg__proc_brkpt_params_error /* Something wrong with the parameters */
- ldrb r0, [r1], #1 /* get breakpoint kind k */
- bl char2hex
- cmp r0, #CMD_BKPT_KIND_THUMB
- orreq r3, r3, #1 /* Mark Thumb breakpoints */
- beq _exit_dbg__proc_brkpt_params
- cmp r0, #CMD_BKPT_KIND_ARM
- beq _exit_dbg__proc_brkpt_params /* ARM breakpoint */
-
-_dbg__proc_brkpt_params_error:
- mov r3, #0 /* Unrecognized breakpoint type */
-_exit_dbg__proc_brkpt_params:
- mov r0, r3 /* return breakpoint address */
- ldmfd sp!, {pc}
-
-/* _dbg__cmd_InsertBreakpoint
- * Add Breakpoint
- * On entry:
- * r0: parameter buffer pointer (contents after '$' and '<cmdchar>')
- * t,AA..AA,k
- * On exit:
- * r0, r1, r2, r3: destroyed
- */
-_dbg__cmd_InsertBreakpoint:
- stmfd sp!, {lr}
- bl __dbg__cmdParamLen
- teq r1, #CMD_BKPT_INSERT_MINPARAMLEN /* Check for correct length */
- blo __dbg__procCmdParamError /* Unexpected input, report error */
- bl _dbg__proc_brkpt_params /* R0: Breakpoint Address */
- teq r0, #0
- beq __dbg__procBreakpointAddrError /* Thumb2 instructions, or unknown kind */
- mov r3, r0 /* Keep breakpoint address in R3 */
- mov r0, #0 /* Empty Breakpoint entry */
- bl _dbg_find_breakpoint_slot /* Look for an available breakpoint slot, return index in R0 */
- cmp r0, #CMD_BKPT_NOTFOUND
- beq __dbg__procBreakpointAddrError /* No empty slot! */
- mov r1, r3 /* Move breakpoint address to R1 */
- bl _dbg__install_one_breakpoint /* r0: index, r1: instruction address */
- b __dbg__procCmdOk
-
-/* _dbg__cmd_RemoveBreakpoint
- * Remove Breakpoint
- * On entry:
- * r0: parameter buffer pointer (contents after '$' and '<cmdchar>')
- * t,AA..AA,k
- * On exit:
- * r0, r1, r2, r3: destroyed
- */
-_dbg__cmd_RemoveBreakpoint:
- stmfd sp!, {lr}
- bl __dbg__cmdParamLen
- teq r1, #CMD_BKPT_REMOVE_MINPARAMLEN /* Check for correct length */
- blo __dbg__procCmdParamError /* Unexpected input, report error */
- bl _dbg__proc_brkpt_params /* R0: Breakpoint Address */
- teq r0, #0
- beq __dbg__procBreakpointAddrError /* Thumb2 instructions, or unknown kind */
- bl _dbg_find_breakpoint_slot /* Look for matching breakpoint slot, return index in R0 */
- cmp r0, #CMD_BKPT_NOTFOUND
- beq __dbg__procBreakpointAddrError /* Specified Breakpoint not found! */
- _index2bkptindex_addr r0, r1 /* Calculate Breakpoint Entry Address */
- mov r0, r1 /* Move it to R0 for subroutine call */
- bl _dbg__clear_one_breakpoint /* R0: address of breakpoint to clear */
- b __dbg__procCmdOk
-
-/****************************************************************************
- *
- * Breakpoint Manipulation Routines
- *
- ****************************************************************************/
-/* _dbg_find_breakpoint_slot
- * Find the matching Breakpoint Slot.
- * This is both used to find empty slots (pass R0=0x0000) or
- * occupied slots (pass R0=<brkpt addr>)
- *
- * On Entry:
- * R0: Breakpoint Address
- * On Exit:
- * R0: Matching Index (-1: not found)
- *
- * NOTE: This routine performs exact match, i.e., breakpoint address MUST be configured
- * for ARM or Thumb (bit 0 clear/set) as appropriate
- */
-
-_dbg_find_breakpoint_slot:
- stmfd sp!, {r1,r2,r3, lr}
- mov r1, #1 /* Only consider Breakpoints 1-7 */
- ldr r3, =__breakpoints_num__
-1:
- _index2bkptindex_addr r1, r2 /* Calculate Breakpoint Entry Address */
- ldr r2, [r2] /* Get actual breakpoint entry (instruction address) */
- cmp r0, r2
- beq _found_breakpoint_slot
- add r1, r1, #1 /* no match, check next */
- cmp r1, r3
- blo 1b /* continue checking only if we don't exceed __breakpoints_num__ */
-
-_notfound_breakpoint_slot:
- mov r1, #CMD_BKPT_NOTFOUND
-_found_breakpoint_slot:
- mov r0, r1 /* Return value in R0 */
- ldmfd sp!, {r1,r2,r3, pc}
-
-/* _dbg__clear_singlestep
- * Clear the Single Step Breakpoint
- */
-_dbg__clear_singlestep:
- ldr r0, =__breakpoints_start__ /* Single Step Breakpoint is at the beginning of the Breakpoint State Struct */
-/* b _dbg__clear_one_breakpoint */
-
-/* _dbg__clear_one_breakpoint
- * On entry, R0 contains the Breakpoint State slot address to be cleared
- *
- */
-_dbg__clear_one_breakpoint:
- mov r1, #0
- mov r2, #0
- stmea r0!, {r1, r2} /* clear Breakpoint state */
- bx lr
-
-/* _dbg__clear_breakpoints
- * Routine iterates through the array of breakpoints (incl single step breakpoint) and clears the breakpoint
- */
-_dbg__clear_breakpoints:
- stmfd sp!, {lr}
- ldr r0, =__breakpoints_start__ /* Single Step Breakpoint is at the beginning of the Breakpoint State Struct */
- ldr r3, =__breakpoints_end__ /* start from top of the table */
-3: bl _dbg__clear_one_breakpoint
- cmp r0, r3
- blo 3b
- ldmfd sp!, {pc}
-
-/* dbg__install_singlestep
- * Install the Single Step Breakpoint
- *
- * On entry:
- * R1: Instruction Address (31 bits, b0 = THUMB flag)
- * On exit:
- * R0: Breakpoint index (preserved)
- * R1: Instruction Address (preserved)
- * R2: Breakpoint Instruction
- * R3: Breakpoint Entry address
- */
- dbg_interwork dbg__install_singlestep
- mov r0, #0
-/* b _dbg__install_one_breakpoint */
-
-/* _dbg__install_one_breakpoint
- * Install breakpoint entry into Breakpoint State Table
- *
- * On entry:
- * R0: Breakpoint index (assumed valid)
- * R1: Instruction Address (31 bits, b0 = THUMB flag)
- * On exit:
- * R0: Breakpoint index (preserved)
- * R1: Instruction Address (preserved)
- * R2: Breakpoint Instruction
- * R3: Breakpoint Entry address
- */
-_dbg__install_one_breakpoint:
-/* Check for Thumb bit */
- tst r1, #BKPT_STATE_THUMB_FLAG /* 1: Thumb instruction */
-/* Assume that the address entry is valid, otherwise we should sanitize it (mask out b1) */
- bic r2, r1, #BKPT_STATE_THUMB_FLAG /* R2: Instruction Address; clear Thumb Flag for accessing Memory */
- ldreq r2, [r2] /* if 0: load ARM instruction from address location */
- ldrneh r2, [r2] /* else load Thumb instruction */
- _index2bkptindex_addr r0, r3 /* Calculate Breakpoint Entry Address */
- stm r3, {r1, r2}
- bx lr
-
-
-/* _dbg__restore_singlestep
- * Restores the contents of the single step breakpoint to memory
- *
- * On entry:
- * None
- * On exit:
- * R0-R2: Destroyed
- */
-_dbg__restore_singlestep:
- mov r0, #0 /* single step breakpoint index */
- _index2bkptindex_addr r0, r1 /* Calculate Single Step Breakpoint Entry Address */
- ldm r1, {r1, r2} /* r1: Breakpoint Address, r2: Breakpoint Instruction */
- teq r1, #0
- bxeq lr /* Exit if not active */
-/* b _dbg__restore_one_breakpoint */
-
-/* _dbg__restore_one_breakpoint
- * Restores the contents to memory for one breakpoint
- *
- * On entry:
- * R0: Breakpoint index (assumed valid) [not used -- can be used for validating BKPT]
- * R1: Breakpoint Address (assumed valid)
- * R2: Breakpoint Instruction (assumed valid)
- * On exit:
- * R0: Breakpoint index (preserved)
- * R1: B0 cleared if Thumb Instruction Address
- * R2: Breakpoint Instruction (preserved)
- */
-_dbg__restore_one_breakpoint:
-/* Check for Thumb bit */
- tst r1, #BKPT_STATE_THUMB_FLAG /* 1: Thumb instruction */
-/* Assume that the address entry is valid, otherwise we should sanitize it (mask out b1) */
- streq r2, [r1] /* if 0: restore ARM instruction to address location */
- bicne r1, #BKPT_STATE_THUMB_FLAG /* else, clear Thumb Flag */
- strneh r2, [r1] /* store Thumb instruction */
- bx lr
-
-/* _dbg__restore_breakpoints
- * Routine iterates through the array of breakpoints (incl single step breakpoint) and restores the contents to memory
- * Only Active breakpoints (i.e., Non-zero Address) are processed.
- *
- * On entry:
- * None
- * On exit:
- * R0-R6: Destroyed
- */
-_dbg__restore_breakpoints:
- stmfd sp!, {lr}
- ldr r6, =_dbg__restore_one_breakpoint
- b __dbg__iterate_breakpoint_array
-
-/* dbg__activate_singlestep
- * Activate the single step breakpoint to memory
- *
- * On entry:
- * None
- * On exit:
- * R0-R3: Destroyed
- */
- dbg_interwork dbg__activate_singlestep
- mov r0, #0 /* single step breakpoint index */
- _index2bkptindex_addr r0, r1 /* Calculate Single Step Breakpoint Entry Address */
- ldm r1, {r1, r2} /* r1: Breakpoint Address, r2: Breakpoint Instruction */
- teq r1, #0
- bxeq lr /* Exit if not active */
-/* b _dbg__activate_one_breakpoint */
-
-/* _dbg__activate_one_breakpoint
- * Activate one breakpoint to memory
- *
- * On entry:
- * R0: Breakpoint index (assumed valid)
- * R1: Breakpoint Address (assumed valid)
- * R2: Breakpoint Instruction (assumed valid)
- * On exit:
- * R0: Breakpoint index (preserved)
- * R1-R3: Destroyed
- */
-_dbg__activate_one_breakpoint:
-/* Check for Thumb bit */
- tst r1, #BKPT_STATE_THUMB_FLAG /* 1: Thumb instruction */
- bne _nx_is_thumb_bp
-_nx_is_arm_bp:
-/* Assume that the address entry is valid, otherwise we should sanitize it (mask out b1) */
- ldr r3, [r1] /* if 0: load ARM instruction from address location */
- teq r2, r3 /* check that the two instructions are identical */
- bne _dbg__breakpoint_invalid_arm
- ldr r2, =BKPT32_INSTR /* ARM BKPT instruction */
- orr r2, r2, r0 /* Merge Breakpoint index */
- str r2, [r1] /* Store it into memory location */
-_dbg__breakpoint_invalid_arm:
- bx lr
-_nx_is_thumb_bp:
- bic r1, #BKPT_STATE_THUMB_FLAG /* else, clear Thumb Flag */
- ldrh r3, [r1] /* load Thumb instruction from address location */
- teq r2, r3 /* check that the two instructions are identical */
- bne _dbg__breakpoint_invalid_thumb
- ldr r2, =BKPT16_INSTR /* Thumb BKPT instruction */
- orr r2, r2, r0 /* Merge Breakpoint index */
- strh r2, [r1] /* Store it into memory location */
-_dbg__breakpoint_invalid_thumb:
- bx lr
-
-/* _dbg__activate_breakpoints
- * Routine iterates through the array of breakpoints (incl single step breakpoint) and activates them
- * Only Active breakpoints (i.e., Non-zero Address) are processed.
- *
- * On entry:
- * None
- * On exit:
- * R0-R6: Destroyed
- */
-_dbg__activate_breakpoints:
- stmfd sp!, {lr}
- ldr r6, =_dbg__activate_one_breakpoint
- b __dbg__iterate_breakpoint_array
-
-
-/* __dbg__iterate_breakpoint_array
- * WARNING: DO NOT CALL THIS ROUTINE DIRECTLY.
- * Internal Routine, assumes that lr has been push to stack
- *
- * Common routine to iterate through the array of breakpoints (incl single step breakpoint)
- * Only Active breakpoints (i.e., Non-zero Address entries) are processed.
- *
- * On Entry:
- * R0: Breakpoint index
- * R1: Breakpoint Address
- * R2: Breakpoint Instruction
- * R6: Handler Routine
- * On exit:
- * R0-R5: Destroyed
- * R6: Handler routine (preserved)
- *
- */
-__dbg__iterate_breakpoint_array:
- ldr r5, =__breakpoints_end__ /* start from top of the table (Assume __breakpoints_end__ > __breakpoints_start__) */
- ldr r4, =__breakpoints_start__ /* end address check */
- ldr r0, =__breakpoints_num__ /* Number of Breakpoints (incl Single Step) (Assume Non-Zero) */
-4: sub r0, r0, #1 /* Decrement breakpoint index in r0 */
- ldmea r5!, {r1, r2} /* r1: Breakpoint Address, r2: Breakpoint Instruction */
- teq r1, #0 /* Is it active? */
- movne lr, pc
- bxne r6 /* active entry */
- cmp r5, r4
- bhi 4b /* if (pointer > start of Breakpoint Table address), get next slot */
- ldmfd sp!, {pc}
-
diff --git a/Debugger/debug_stub.h b/Debugger/debug_stub.h
deleted file mode 100644
index 2430e77..0000000
--- a/Debugger/debug_stub.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/** @file debug_stub.h
- * @brief Shared C/ASM header file for debugger stub
- *
- */
-
-/* Copyright (C) 2007-2010 the NxOS developers
- *
- * Module Developed by: TC Wan <tcwan@cs.usm.my>
- *
- * See AUTHORS for a full list of the developers.
- *
- * See COPYING for redistribution license
- *
- */
-
-#ifndef __DEBUG_STUB_H__
-#define __DEBUG_STUB_H__
-
-#include "_c_arm_macros.h"
-
-/** @name BKPT suppport constants
- *
- * ARM and Thumb Breakpoint Instructions.
- */
-/*@{*/
-
-#define __ARM6OR7__
-
-#ifdef __ARM6OR7__
-#define BKPT32_INSTR 0xE7200070 /* ARM6 and ARM7 does not trap unused opcodes (BKPT overlap with control instructions), \
- CPU has unpredictable behavior. Ref: Steve Furber, ARM SoC Architecture 2nd Ed, pg. 143 */
-#else
-#define BKPT32_INSTR 0xE1200070 /* ARM BKPT instruction, will work in ARMv5T and above */
-#endif
-
-#define BKPT32_ENUM_MASK 0x000FFF0F /* ARM BKPT Enum Mask */
-#define BKPT32_AUTO_BKPT 0x00080000 /* RESERVED: ARM BKPT Auto-Step Flag (for CONT support) */
-#define BKPT32_MANUAL_BKPT 0x0007FF0F /* Manually inserted ARM Breakpoint */
-
-#define BKPT16_INSTR 0xBE00 /* Thumb BKPT instruction */
-#define BKPT16_ENUM_MASK 0x00FF /* Thumb BKPT Enum Mask */
-#define BKPT16_AUTO_BKPT 0x0080 /* RESERVED: Thumb BKPT Auto-Step Flag (for CONT support) */
-#define BKPT16_MANUAL_BKPT 0x007F /* Manually inserted Thumb Breakpoint */
-/*@}*/
-
-#ifndef __ASSEMBLY__
-
-/* Define C stuff */
-/** @defgroup debug_public */
-/*@{*/
-
-
-/** Initialize Debugger.
- * Equivalent to GDB set_debug_traps() routine
- */
-FUNCDEF void dbg__bkpt_init(void);
-
-#ifdef __NXOS__
-
-/** Communication Channel Enums
- *
- * Communication Channel Enums.
- */
-ENUM_BEGIN
-ENUM_VALASSIGN(COMM_USB, 1) /**< USB Communications */
-ENUM_VAL(COMM_BT) /**< Bluetooth Communications */
-ENUM_END(comm_chan_t)
-
-/** Enable switch to Debugger Mode from NxOS operational mode
- * Returns 0 if no mode switch needed (already in Debug mode)
- * !0 if mode switch will happen
- * Used by NxOS only
- */
-/* Note: This platform specific routine is found in debug_runlooptasks.S */
-FUNCDEF int nxos__handleDebug(U8 *buffer, comm_chan_t channel, U32 length);
-#else
-/** Switch Mode to Debugger.
- * Used by NXT Firmware only
- */
-/* Note: This platform specific routine is found in debug_runlooptasks.S */
-FUNCDEF UWORD cCommHandleDebug(UBYTE *pInBuf, UBYTE CmdBit, UWORD MsgLength);
-#endif
-
-/** Debugger Handler Routine (called by Exception Handler Trap).
- * Equivalent to GDB handle_exception() routine
- */
-FUNCDEF void dbg__bkpt_handler(void);
-
-/** dbg_breakpoint_arm.
- * Equivalent to GDB breakpoint() routine for ARM code
- */
-/* FUNCDEF void dbg_breakpoint_arm(void); */
-static inline void dbg_breakpoint_arm(void)
-{
- asm volatile (".word %a0"
- : /* Output (empty) */
- : "X" (BKPT32_INSTR | BKPT32_MANUAL_BKPT)
- );
-}
-
-#if 0 /* Old asm definitions, in case gas does not recognize %a0 operand */
-
-#ifdef __ARM6OR7__
-static inline void dbg_breakpoint_arm(void) { asm volatile (".word 0xE727FF7F" /* (BKPT32_INSTR | BKPT32_MANUAL_BKPT) */ ); }
-#else
-static inline void dbg_breakpoint_arm(void) { asm volatile (".word 0xE127FF7F" /* (BKPT32_INSTR | BKPT32_MANUAL_BKPT) */ ); }
-#endif
-
-#endif
-
-/** dbg_breakpoint_thumb.
- * Equivalent to GDB breakpoint() routine for Thumb code
- */
-/* FUNCDEF void dbg_breakpoint_thumb(void); */
-static inline void dbg_breakpoint_thumb(void)
-{
- asm volatile (".hword %a0"
- : /* Output (empty) */
- : "X" (BKPT16_INSTR | BKPT16_MANUAL_BKPT)
- );
-}
-
-#if 0 /* Old asm definitions, in case gas does not recognize %a0 operand */
-
-static inline void dbg_breakpoint_thumb(void) { asm volatile (".hword 0xBE7F" /* (BKPT16_INSTR | BKPT16_MANUAL_BKPT) */); }
-
-#endif
-
-/*@}*/
-
-#else
-/* Define Assembly stuff */
-
-/* dbg__bkpt_arm
- * GDB breakpoint() for ARM mode
- */
- .macro dbg__bkpt_arm
- .word (BKPT32_INSTR | BKPT32_MANUAL_BKPT)
- .endm
-
-/* dbg__bkpt_thumb
- * GDB breakpoint() for Thumb mode
- */
- .macro dbg__bkpt_thumb
- .hword (BKPT16_INSTR | BKPT16_MANUAL_BKPT)
- .endm
-
-/** Macro to declare Interworking ARM Routine
- *
- * dbg_interwork <arm_routine_name>
- *
- * Note: declared as a private macro since ARMDEBUG is also used by NIF
- */
- .macro dbg_interwork arm_routine
- .align 4
- .arm
- .type \arm_routine, %function @ Needed by new binutils (>2.21)
- .global \arm_routine
-\arm_routine:
- .endm
-
-#endif
- /*@}*/
-
-#endif /* __DEBUG_STUB_H__ */
diff --git a/Debugger/debug_test.S b/Debugger/debug_test.S
deleted file mode 100644
index 2cb87a0..0000000
--- a/Debugger/debug_test.S
+++ /dev/null
@@ -1,161 +0,0 @@
-/** @file debug_test.S
- * @brief Test Routines to trigger ARM and Thumb Manual Breakpoints
- *
- */
-
-/* Copyright (C) 2007-2011 the NxOS developers
- *
- * Module Developed by: TC Wan <tcwan@cs.usm.my>
- *
- * See AUTHORS for a full list of the developers.
- *
- * See COPYING for redistribution license
- *
- */
-#define __ASSEMBLY__
-#include "debug_stub.h"
-
-.text
-.align 4
-.code 32
-
-/**********************************************
- * dbg__test_arm_bkpt Test Routine
- *
- */
- dbg_interwork dbg__test_arm_bkpt
- stmfd sp!,{lr}
- dbg__bkpt_arm /* Trigger ARM Manual Breakpoint */
- ldmfd sp!,{pc}
-
-
-/**********************************************
- * dbg__test_arm_instrstep Test Routine
- * Used to test GDB Stepping command
- * This routine exercises the mov, add, ldr, ldm, b, bl,
- * and bx instructions which modify the PC (R15)
- * In addition, conditional instructions are also evaluated.
- *
- */
- dbg_interwork dbg__test_arm_instrstep
- stmfd sp!, {lr}
- bl dbg__test_arm_instr_sub1
- ldr r1, =test_arm_3 /* R1: pointer to test_arm_3 */
- ldr r2, =test_arm_2 /* R2: pointer to test_arm_2 */
- mov pc, r1
-
-test_arm_1:
- subs r0, r0, #1
- addne pc, r2, #4 /* If R0 > 0, keep branching to a new location */
- /* else R0 == 0 */
- b exit_dbg__test_arm_instrstep
-
-test_arm_2:
- sub r0, r0, #1
- cmp r0, #5
- bgt test_arm_1
- ldrle pc, =exit_dbg__test_arm_instrstep
- b exit_dbg__test_arm_instrstep
-
-test_arm_3:
- sub r0, r0, #1
- teq r0, #8
- beq test_arm_1
- ldrne r3, =test_arm_3
- bx r3
-
-exit_dbg__test_arm_instrstep:
- bl dbg__test_thumb_instr_sub1
- ldmfd sp!, {pc}
-
- .global dbg__test_arm_instr_sub1
-dbg__test_arm_instr_sub1:
- mov r0, #10
- bx lr
-
- .global dbg__test_arm_instr_sub1
-dbg__test_arm_instr_sub2:
- stmfd sp!, {r4, lr}
- mov r0, #TRUE
- ldmfd sp!, {r4, pc}
-
-/**********************************************
- * dbg__test_thumb_bkpt Test Routine
- *
- */
- dbg_interwork dbg__test_thumb_bkpt
- stmfd sp!,{lr}
-/* ldr r0, =_thumb_entry
- orr r0, r0, #1 @ Set Thumb mode
- mov lr, pc
- bx r0
-*/
- bl _thumb_entry
- ldmfd sp!,{pc}
-
-.code 16
- .thumb_func
- .type _thumb_entry, %function
-_thumb_entry:
- dbg__bkpt_thumb
- bx lr
-
-
-/**********************************************
- * dbg__test_thumb_instrstep Test Routine
- * Used to test GDB Stepping command
- *
- */
- .global dbg__test_thumb_instrstep
- .thumb_func
- .type dbg__test_thumb_instrstep, %function
-dbg__test_thumb_instrstep:
- push {lr}
- bl dbg__test_thumb_instr_sub1
- bl dbg__test_thumb_instr_sub2
-
-test_thumb_1:
- sub r0, #1
- bne test_thumb_2
- /* else R0 == 0 */
- b exit_dbg__test_thumb_instrstep
-
-test_thumb_2:
- sub r0, #1
- cmp r0, #5
- bls test_thumb_1
- bhi test_thumb_3
- beq test_thumb_2
- b test_thumb_1
-
-test_thumb_3:
- sub r0, #1
- cmp r0, #0xB
- blo load_test_thumb_1
- ldr r2, =test_thumb_3+1 /* Need to set Thumb bit */
- b exit_test_thumb_3
-load_test_thumb_1:
- ldr r2, =test_thumb_1+1 /* Need to set Thumb bit */
-exit_test_thumb_3:
- bx r2
-
-exit_dbg__test_thumb_instrstep:
- bl dbg__test_arm_instr_sub1
- pop {r1}
- bx r1
-
- .thumb_func
- .type dbg__test_thumb_instr_sub1, %function
-dbg__test_thumb_instr_sub1:
- mov r0, #0x0F
- bx lr
-
- .thumb_func
- .type dbg__test_thumb_instr_sub2, %function
-dbg__test_thumb_instr_sub2:
- push {lr}
- mov r1, #FALSE
- pop {pc}
-
-
-.end
diff --git a/Debugger/debug_test.h b/Debugger/debug_test.h
deleted file mode 100644
index b8e6634..0000000
--- a/Debugger/debug_test.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/** @file debug_test.h
- * @brief C header file for debugger test routines
- *
- */
-
-/* Copyright (C) 2007-2010 the NxOS developers
- *
- * Module Developed by: TC Wan <tcwan@cs.usm.my>
- *
- * See AUTHORS for a full list of the developers.
- *
- * See COPYING for redistribution license
- *
- */
-
-#ifndef __DEBUG_TEST_H__
-#define __DEBUG_TEST_H__
-
-#include "_c_arm_macros.h"
-
-#ifndef __ASSEMBLY__
-
-/* Define C stuff */
-/** @defgroup debug_public */
-/*@{*/
-
-/**
- * Insert ARM Breakpoint instruction into code stream
- */
-FUNCDEF void dbg__test_arm_bkpt(void);
-/**
- * Insert Thumb Breakpoint instruction into code stream
- */
-FUNCDEF void dbg__test_thumb_bkpt(void);
-
-/**
- * Dummy function for testing ARM instruction stepping
- */
-FUNCDEF void dbg__test_arm_instrstep(void);
-/**
- * Dummy function for testing Thumb instruction stepping
- */
-FUNCDEF void dbg__test_thumb_instrstep(void);
-
- /*@}*/
-
-#endif
-
-
-#endif /* __DEBUG_TEST_H__ */
diff --git a/Debugger/undef_handler.S b/Debugger/undef_handler.S
deleted file mode 100644
index cfbaae3..0000000
--- a/Debugger/undef_handler.S
+++ /dev/null
@@ -1,144 +0,0 @@
-
-/* Copyright (C) 2007-2010 the NxOS developers
- *
- * Module Developed by: TC Wan <tcwan@cs.usm.my>
- *
- * See AUTHORS for a full list of the developers.
- *
- * Redistribution of this file is permitted under
- * the terms of the GNU Public License (GPL) version 2.
- */
-#define __ASSEMBLY__
-#include "debug_stub.h"
-#include "debug_internals.h"
-
-
-.text
-.code 32
-.align 0
-
- .extern dbg__thumb_bkpt_handler
- .extern dbg__arm_bkpt_handler
- .extern default_undef_handler
-
-/* Remote GDB Debugger relies on BKPT instruction being trapped here
- * In ARMv4t, it is an Illegal (Undefined) Instruction.
- * On triggering, lr (R14) contains the previous mode's pc (R15).
- * Based on example in Hohl, "ARM Assembly Language: Fundamentals and Techniques"
- * Chapter 11, Example 11.1.
- */
- /** undef_handler
- * We assume that the DEBUG stack holds only one stack frame and we will overwrite it.
- * On entry, LR_undef points to one instruction past the UNDEF instruction.
- *
- * For the purpose of Debugging, the stack frame should present the PC (R15) as the address
- * of the instruction that triggered the Breakpoint. Hence we need to adjust R15
- * to point to the address of the UNDEF instruction. This is what the JTAG debugger
- * does.
- *
- * We will also store UNDEF LR (next instruction pointer) and UNDEF SPSR to the stack.
- *
- * For the handler, once the user registers have been stored in the DEBUG stack, the
- * registers will be used as follows:
- *
- * R0: UNDEF LR, then UNDEF instruction address, finally UNDEF instruction word / BKPT index
- * R1: SPSR
- * R2: Mode
- * R3: Debug Stack Pointer (for Banked R13-R14 update)
- */
- dbg_interwork undef_handler
- ldr sp, =__debugger_stack__
- stmfd sp, {r0-r15}^ /* Save workspace, previous mode's pc via 'S' flag, R13-R15: placeholders */
- mov r3, sp /* Use R3 to write Banked R13-R14, and actual PC of UNDEF instruction */
- sub sp, sp, #(4*16) /* Need to manually update SP(undef) */
-
- mov r0, lr /* Keep Next Instruction address after UNDEF instruction in R0 */
- mrs r1, spsr /* Copy SPSR to r1 */
- stmfd sp!, {r0,r1} /* Save User's Next Instr Pointer (in UNDEF LR) and previous mode's CPSR to stack */
-
- tst r1, #CPSR_THUMB /* Check for Thumb Mode */
- subne r0, r0, #2 /* Is Thumb instruction, adjust PC for UNDEF instruction address */
- subeq r0, r0, #4 /* Is ARM instruction, adjust PC for UNDEF instruction address */
- str r0, [r3, #-4]! /* Save PC to stack (R15 slot) */
-
- and r2, r1, #CPSR_MODE /* Get previous mode */
- teq r2, #MODE_USR
- beq _skip_banked_registers /* Can't switch back if we're in User mode! */
-
-_store_prev_mode_banked_regs:
- /* FIXME: We don't handle FIQ properly! */
-
- orr r2, #(CPSR_FIQ | CPSR_IRQ) /* Disable Interrupts */
- msr cpsr_c, r2 /* Switch to previous mode */
- stmfd r3!, {sp, lr} /* Store Previous Mode's LR (R14), SP (R13) via R3 */
- msr cpsr_c, #(MODE_UND | CPSR_FIQ | CPSR_IRQ) /* Revert to Undef Mode */
-
-_skip_banked_registers:
- tst r1, #CPSR_THUMB /* Check for Thumb Mode */
- beq _is_arm /* Clear, so it's ARM mode */
-_is_thumb:
- ldrh r0, [r0] /* load UNDEF instruction into r0 */
- ldr r1, =BKPT16_ENUM_MASK /* Thumb BKPT enum mask */
- bic r2, r0, r1 /* leave only opcode */
- ldr r1, =BKPT16_INSTR /* check for Thumb Breakpoint Instruction */
- teq r2, r1
- bne default_undef_handler
- ldr r1, =BKPT16_ENUM_MASK /* get Thumb BKPT Enum Mask */
- ldr r2, =dbg__thumb_bkpt_handler /* handle BKPT, BKPT index in r0 */
- b _exit_undef_handler
-_is_arm:
- ldr r0, [r0] /* load UNDEF instruction into r0 */
- ldr r1, =BKPT32_ENUM_MASK /* ARM BKPT enum mask */
- bic r2, r0, r1 /* leave only opcode */
- ldr r1, =BKPT32_INSTR /* check for ARM Breakpoint Instruction */
- teq r2, r1
- bne default_undef_handler
- ldr r1, =BKPT32_ENUM_MASK /* get ARM BKPT Enum Mask */
- ldr r2, =dbg__arm_bkpt_handler /* handle BKPT, BKPT index in r0 */
-_exit_undef_handler:
- and r0, r1, r0 /* Keep index value */
- msr cpsr_c, #(MODE_ABT | CPSR_FIQ | CPSR_IRQ) /* Switch to Abort Mode, Disable Interrupts */
- ldr sp, =__abort_stack__ /* Reinitialize stack pointer each time a Breakpoint happens */
- bic sp, sp, #7
- mov pc, r2 /* Invoke Debugger */
-
-/** resume_execution
- * This routine is called by the Debugger prior to returning control to
- * the executing program.
- * It updates the SPSR_UNDEF with the Debug Stack value, and
- * restores all registers R0-R14 to the previously active mode.
- * Then, it uses the Next Instruction Address Pointer to return
- * execution control to the previously executing program.
- */
-/* On Entry, SP(undef) points to the Next Instruction Address.
- * If the instruction which triggered the Breakpoint need to be
- * reexecuted, it should be placed in the Next Instruction Address slot
- * by ABORT mode before coming here
- */
- dbg_interwork resume_execution
- ldr lr, =__debugger_stack_bottom__ /* Use LR(undef) for Debug Stack Access */
- add r1, lr, #(DBGSTACK_USERSP_INDEX*4) /* Use R1 for Previous Mode SP (R13) and LR (R14) access */
- ldr r0, [lr, #(DBGSTACK_USERCPSR_INDEX*4)]! /* LR updated, Retrieve SPSR into R0 */
- msr spsr, r0 /* Update SPSR for return to program being debugged */
- and r0, r0, #CPSR_MODE /* Get previous mode */
- teq r0, #MODE_USR
- bne _restore_prev_mode_banked_regs /* Can't switch back if we're in User mode! */
-
- /* Previous mode was User Mode */
- ldmed lr, {r0-r14}^ /* We use LDMED since LR is pointing to USERCPSR not R0 */
- b _really_resume_execution
-
-_restore_prev_mode_banked_regs:
- /* FIXME: We don't handle FIQ properly! */
- orr r0, #(CPSR_FIQ | CPSR_IRQ) /* Disable Interrupts */
- msr cpsr_c, r0 /* Switch to previous mode */
- ldmfd r1, {sp, lr} /* Restore Previous Mode's LR (R14), SP (R13) via R1 */
- msr cpsr_c, #(MODE_UND | CPSR_FIQ | CPSR_IRQ) /* Revert to Undef Mode */
- ldmed lr, {r0-r12} /* We use LDMED since LR is pointing to USERCPSR not R0 */
-
-_really_resume_execution:
- ldmfd sp, {pc}^ /* Exit to Previous Mode using Next Instruction Address */
-
-
-
-