From fae838b025f11aca2c8835ec3b27f9d567a52226 Mon Sep 17 00:00:00 2001 From: Tat-Chee Wan (USM) Date: Tue, 22 Mar 2011 20:55:58 +0800 Subject: continue execution wip Work in Progress to implement GDB Continue Execution --- Debugger/debug_stub.S | 24 ++++++++++++++++++------ Debugger/debug_stub.h | 1 + Debugger/undef_handler.S | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 6 deletions(-) (limited to 'Debugger') 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 */ + + + -- cgit v1.2.3