summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTat-Chee Wan (USM)2011-03-22 20:55:58 +0800
committerTat-Chee Wan (USM)2011-03-22 20:55:58 +0800
commitfae838b025f11aca2c8835ec3b27f9d567a52226 (patch)
tree412392c86339bf65315d3bec24848586724a4527
parentb66fd09e34c9a720acd5367eb7658456417a8c3b (diff)
continue execution wip
Work in Progress to implement GDB Continue Execution
-rw-r--r--Debugger/debug_stub.S24
-rw-r--r--Debugger/debug_stub.h1
-rw-r--r--Debugger/undef_handler.S41
3 files changed, 60 insertions, 6 deletions
diff --git a/Debugger/debug_stub.S b/Debugger/debug_stub.S
index b0d7fed..ffb6062 100644
--- a/Debugger/debug_stub.S
+++ b/Debugger/debug_stub.S
@@ -964,15 +964,27 @@ _dbg__cmd_Continue:
bne __dbg__procCmdParamError /* Unexpected input, report error */
/* Continue from Specified Address */
bl ascii2word /* convert ASCII address location to Hex (in R0), R1 has address of next buffer char */
- mov r1, #DBGSTACK_NEXTINSTR_INDEX /* The Next Instruction Pointer for Resume is in index 0 of the Debug Stack */
- _setdbgregisterfromindex r1, r0, r2 /* Set Register contents in R0, using index in R2, and scratch register R3 */
+ mov r2, #DBGSTACK_NEXTINSTR_INDEX /* The Next Instruction Pointer for Resume is in index 0 of the Debug Stack */
+ _setdbgregisterfromindex r2, r0, r1 /* Set Register contents in R0, using index in R2, and scratch register R1 */
_dbg__cmd_processContinue:
-@@@@@
- /* Switch mode to Previous Mode, reload all the registers (except for PC) */
- /* Switch back to ABORT, resume with PC and SPSR */
- b __dbg__procCmdOk
+/* FIXME: Currently we assume that the trigger is a Manual Breakpoint, i.e., no need to
+ restore instructions to memory, and handle auto-breakpoints (needed to reenable the memory
+ breakpoint that was triggered) */
+@@@@@
+__dbg__sendOkBeforeResume:
+ _dbg_outputMsgStatusOk
+ bl dbg__putDebugMsg /* Send Ok response to the GDB server */
+ cmp r0, #0
+ beq _dbg__switch2undefmode /* Sending of retransmission request succeeded */
+ bl dbg__runloopTasks /* Service run loop tasks */
+ b __dbg__sendOkBeforeResume /* Retry retransmission */
+
+_dbg__switch2undefmode:
+ msr cpsr_c, #(MODE_UND | CPSR_FIQ | CPSR_IRQ) /* Configure Undef Mode */
+ ldr lr, =resume_execution
+ mov pc, lr /* Exit via UNDEF mode */
/* _dbg__proc_brkpt_params
diff --git a/Debugger/debug_stub.h b/Debugger/debug_stub.h
index 85ff22a..dd71a16 100644
--- a/Debugger/debug_stub.h
+++ b/Debugger/debug_stub.h
@@ -147,6 +147,7 @@
#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 + 13) /* SP is R13 */
#define DBGSTACK_USERCPSR_OFFSET (DBGSTACK_USERCPSR_INDEX-DBGSTACK_USERREG_INDEX) /* = -1, offset for calculating Debug Stack index */
/*@}*/
diff --git a/Debugger/undef_handler.S b/Debugger/undef_handler.S
index f040219..8d33e13 100644
--- a/Debugger/undef_handler.S
+++ b/Debugger/undef_handler.S
@@ -101,4 +101,45 @@ _exit_undef_handler:
ldr lr, =dbg__arm_bkpt_handler /* handle BKPT, BKPT index in r0 */
mov pc, lr /* Invoke Debugger State (Supervisor Mode) */
+ .global resume_execution
+
+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
+ */
+ 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 r0, spsr /* 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 */
+
+
+