aboutsummaryrefslogtreecommitdiff
path: root/AT91SAM7S256/armdebug/Debugger/debug_runlooptasks.S
diff options
context:
space:
mode:
Diffstat (limited to 'AT91SAM7S256/armdebug/Debugger/debug_runlooptasks.S')
-rw-r--r--AT91SAM7S256/armdebug/Debugger/debug_runlooptasks.S174
1 files changed, 166 insertions, 8 deletions
diff --git a/AT91SAM7S256/armdebug/Debugger/debug_runlooptasks.S b/AT91SAM7S256/armdebug/Debugger/debug_runlooptasks.S
index fd17412..48b7e5a 100644
--- a/AT91SAM7S256/armdebug/Debugger/debug_runlooptasks.S
+++ b/AT91SAM7S256/armdebug/Debugger/debug_runlooptasks.S
@@ -1,4 +1,4 @@
-/** @file debug_runloop.S
+/** @file debug_runlooptasks.S
* @brief GDB Server platform Run Loop
*
*/
@@ -13,6 +13,11 @@
*
*/
+/*
+ * 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
@@ -48,11 +53,10 @@
* ^-------v v-------^
*
* The Platform will invoke dbg__bkpt_init() after hardware and system initialization,
- * before entering the Platform Run Loop. This switches processing over to the
- * Debugger Run Loop which will wait for the GDB command to Go/Step/Cont before
- * returning control to the Platform Run Loop.
+ * 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, Debugger Run Loop will be triggered by Breakpoints, or
+ * 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
@@ -65,17 +69,31 @@
*/
#define __ASSEMBLY__
- .global dbg__runloopTasks
+#include "debug_internals.h"
+#include "debug_macros.h"
+#include "debug_stub.h"
+ .code 32
+ .align 4
+ .global dbg__runloopTasks
+ .global dbg__reboot
#ifdef __NXOS__
-/* NxOS Run Loop */
+/****************************************************************************
+ *
+ * NxOS Run Loop
+ *
+ ****************************************************************************/
dbg__runloopTasks:
/* Currently, there's nothing that needs to be done in the NxOS Run Loop */
bx lr
#else
-/* NXT Firmware Run Loop */
+/****************************************************************************
+ *
+ * NXT Firmware Run Loop
+ *
+ ****************************************************************************/
.extern cCommCtrl
dbg__runloopTasks:
@@ -85,3 +103,143 @@ dbg__runloopTasks:
/* OSWatchdogWrite is a NULL function in the NXT Firmware?! */
pop {pc}
#endif
+
+#ifdef __NXOS__
+ .extern nx_core_reset
+/****************************************************************************
+ *
+ * NxOS Reboot Routine
+ *
+ ****************************************************************************/
+ dbg__reboot:
+ b nx_core_reset /* Reboot Brick, won't return */
+
+#else
+/****************************************************************************
+ *
+ * NXT Firmware Reboot Routine
+ *
+ ****************************************************************************/
+dbg__reboot:
+ bx lr
+#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
+ .global nxos__handleDebug
+/* nxos__handleDebug
+ * Prepare to switch to Debug Mode
+ * int nxos__handleDebug(comm_chan_t channel);
+ *
+ * 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)
+ */
+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)
+ */
+
+ ldr r3, =debug_nxtCommChannel
+ str r0, [r3] /* Keep track of which communications link was used (USB/Bluetooth) */
+
+ /* Check our current operating mode */
+ mov r0, #FALSE /* Setup Default Return value (False) */
+ mrs r3, cpsr /* Copy CPSR to r3 */
+ and r3, r3, #CPSR_MODE /* Get current mode */
+ teq r3, #MODE_ABT /* Are we in Abort (Debug) mode? */
+ 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
+/* 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 /* setup Debugger Message Buffers, validate input, CPSR returned in R0 */
+ _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