X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Fcortex_m3.c;h=e3ed4cfbb81dcbaf0875246844241b99b6364b41;hp=f1513c7a360a2810fd192e782184436c923e5fb7;hb=dfbb9f3e89ae;hpb=e27696f6b04459e935a0a5f65f7f668cb02970dd diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c index f1513c7a36..e3ed4cfbb8 100644 --- a/src/target/cortex_m3.c +++ b/src/target/cortex_m3.c @@ -1,6 +1,7 @@ /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * + * * * Copyright (C) 2006 by Magnus Lundin * * lundin@mlu.mine.nu * * * @@ -30,6 +31,7 @@ #include "register.h" #include "target.h" +#include "target_request.h" #include "log.h" #include "jtag.h" #include "arm_jtag.h" @@ -41,16 +43,21 @@ int cortex_m3_register_commands(struct command_context_s *cmd_ctx); /* forward declarations */ -void cortex_m3_unset_all_breakpoints_and_watchpoints(struct target_s *target); void cortex_m3_enable_breakpoints(struct target_s *target); void cortex_m3_enable_watchpoints(struct target_s *target); -void cortex_m3_disable_bkpts_and_wpts(struct target_s *target); int cortex_m3_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target); int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *target); int cortex_m3_quit(); int cortex_m3_load_core_reg_u32(target_t *target, enum armv7m_regtype type, u32 num, u32 *value); int cortex_m3_store_core_reg_u32(target_t *target, enum armv7m_regtype type, u32 num, u32 value); - +int cortex_m3_target_request_data(target_t *target, u32 size, u8 *buffer); +int cortex_m3_examine(struct command_context_s *cmd_ctx, struct target_s *target); + +#ifdef ARMV7_GDB_HACKS +extern u8 armv7m_gdb_dummy_cpsr_value[]; +extern reg_t armv7m_gdb_dummy_cpsr_reg; +#endif + target_type_t cortexm3_target = { .name = "cortex_m3", @@ -58,8 +65,8 @@ target_type_t cortexm3_target = .poll = cortex_m3_poll, .arch_state = armv7m_arch_state, - .target_request_data = NULL, - + .target_request_data = cortex_m3_target_request_data, + .halt = cortex_m3_halt, .resume = cortex_m3_resume, .step = cortex_m3_step, @@ -67,7 +74,6 @@ target_type_t cortexm3_target = .assert_reset = cortex_m3_assert_reset, .deassert_reset = cortex_m3_deassert_reset, .soft_reset_halt = cortex_m3_soft_reset_halt, - .prepare_reset_halt = cortex_m3_prepare_reset_halt, .get_gdb_reg_list = armv7m_get_gdb_reg_list, @@ -75,6 +81,7 @@ target_type_t cortexm3_target = .write_memory = cortex_m3_write_memory, .bulk_write_memory = cortex_m3_bulk_write_memory, .checksum_memory = armv7m_checksum_memory, + .blank_check_memory = armv7m_blank_check_memory, .run_algorithm = armv7m_run_algorithm, @@ -86,6 +93,7 @@ target_type_t cortexm3_target = .register_commands = cortex_m3_register_commands, .target_command = cortex_m3_target_command, .init_target = cortex_m3_init_target, + .examine = cortex_m3_examine, .quit = cortex_m3_quit }; @@ -100,7 +108,7 @@ int cortex_m3_clear_halt(target_t *target) ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr); /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */ ahbap_write_system_atomic_u32(swjdp, NVIC_DFSR, cortex_m3->nvic_dfsr); - DEBUG(" NVIC_DFSR 0x%x", cortex_m3->nvic_dfsr); + LOG_DEBUG(" NVIC_DFSR 0x%x", cortex_m3->nvic_dfsr); return ERROR_OK; } @@ -116,7 +124,7 @@ int cortex_m3_single_step_core(target_t *target) ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_MASKINTS | C_HALT | C_DEBUGEN ); ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_MASKINTS | C_STEP | C_DEBUGEN ); cortex_m3->dcb_dhcsr |= C_MASKINTS; - DEBUG(" "); + LOG_DEBUG(" "); cortex_m3_clear_halt(target); return ERROR_OK; @@ -135,12 +143,13 @@ int cortex_m3_exec_opcode(target_t *target,u32 opcode, int len /* MODE, r0_inval ahbap_write_system_u32(swjdp, 0x20000000, opcode); ahbap_write_coreregister_u32(swjdp, 0x20000000, 15); cortex_m3_single_step_core(target); - armv7m->core_cache->reg_list[15].dirty = 1; + armv7m->core_cache->reg_list[15].dirty = armv7m->core_cache->reg_list[15].valid; retvalue = ahbap_write_system_atomic_u32(swjdp, 0x20000000, savedram); return retvalue; } +#if 0 /* Enable interrupts */ int cortex_m3_cpsie(target_t *target, u32 IF) { @@ -152,6 +161,7 @@ int cortex_m3_cpsid(target_t *target, u32 IF) { return cortex_m3_exec_opcode(target, ARMV7M_T_CPSID(IF), 2); } +#endif int cortex_m3_endreset_event(target_t *target) { @@ -166,14 +176,16 @@ int cortex_m3_endreset_event(target_t *target) cortex_m3_dwt_comparator_t *dwt_list = cortex_m3->dwt_comparator_list; ahbap_read_system_atomic_u32(swjdp, DCB_DEMCR, &dcb_demcr); - DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr); + LOG_DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr); + + ahbap_write_system_u32(swjdp, DCB_DCRDR, 0 ); /* Enable debug requests */ ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr); if (!(cortex_m3->dcb_dhcsr & C_DEBUGEN)) ahbap_write_system_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN ); /* Enable trace and dwt */ - ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET ); + ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR ); /* Monitor bus faults */ ahbap_write_system_u32(swjdp, NVIC_SHCSR, SHCSR_BUSFAULTENA ); @@ -181,13 +193,13 @@ int cortex_m3_endreset_event(target_t *target) target_write_u32(target, FP_CTRL, 3); /* Restore FPB registers */ - for ( i = 0; i < cortex_m3->fp_num_code + cortex_m3->fp_num_lit; i++) + for (i = 0; i < cortex_m3->fp_num_code + cortex_m3->fp_num_lit; i++) { target_write_u32(target, fp_list[i].fpcr_address, fp_list[i].fpcr_value); } /* Restore DWT registers */ - for ( i = 0; i < cortex_m3->dwt_num_comp; i++) + for (i = 0; i < cortex_m3->dwt_num_comp; i++) { target_write_u32(target, dwt_list[i].dwt_comparator_address, dwt_list[i].comp); target_write_u32(target, dwt_list[i].dwt_comparator_address | 0x4, dwt_list[i].mask); @@ -195,11 +207,6 @@ int cortex_m3_endreset_event(target_t *target) } swjdp_transaction_endcheck(swjdp); - /* Make sure working_areas are all free */ - target_free_all_working_areas(target); - - /* We are in process context */ - armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT); armv7m_invalidate_core_regs(target); return ERROR_OK; } @@ -216,16 +223,15 @@ int cortex_m3_examine_debug_reason(target_t *target) if ((target->debug_reason != DBG_REASON_DBGRQ) && (target->debug_reason != DBG_REASON_SINGLESTEP)) { + /* INCOMPLETE */ - /* INCOPMPLETE */ - - if (cortex_m3->nvic_dfsr & 0x2) + if (cortex_m3->nvic_dfsr & DFSR_BKPT) { target->debug_reason = DBG_REASON_BREAKPOINT; - if (cortex_m3->nvic_dfsr & 0x4) + if (cortex_m3->nvic_dfsr & DFSR_DWTTRAP) target->debug_reason = DBG_REASON_WPTANDBKPT; } - else if (cortex_m3->nvic_dfsr & 0x4) + else if (cortex_m3->nvic_dfsr & DFSR_DWTTRAP) target->debug_reason = DBG_REASON_WATCHPOINT; } @@ -278,7 +284,7 @@ int cortex_m3_examine_exception_reason(target_t *target) break; } swjdp_transaction_endcheck(swjdp); - DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m->exception_number), \ + LOG_DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m->exception_number), \ shcsr, except_sr, cfsr, except_ar); return ERROR_OK; } @@ -294,7 +300,7 @@ int cortex_m3_debug_entry(target_t *target) cortex_m3_common_t *cortex_m3 = armv7m->arch_info; swjdp_common_t *swjdp = &cortex_m3->swjdp_info; - DEBUG(" "); + LOG_DEBUG(" "); if (armv7m->pre_debug_entry) armv7m->pre_debug_entry(target); @@ -305,39 +311,56 @@ int cortex_m3_debug_entry(target_t *target) return retval; /* Examine target state and mode */ - /* First load register acessible through core debug port*/ + /* First load register acessible through core debug port*/ for (i = 0; i < ARMV7M_PRIMASK; i++) { if (!armv7m->core_cache->reg_list[i].valid) - armv7m->read_core_reg(target, i); + armv7m->read_core_reg(target, i); } xPSR = buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32); - - /* For IT instructions xPSR must be reloaded on resume and clear on debug exec*/ + +#ifdef ARMV7_GDB_HACKS + /* copy real xpsr reg for gdb, setting thumb bit */ + buf_set_u32(armv7m_gdb_dummy_cpsr_value, 0, 32, xPSR); + buf_set_u32(armv7m_gdb_dummy_cpsr_value, 5, 1, 1); + armv7m_gdb_dummy_cpsr_reg.valid = armv7m->core_cache->reg_list[ARMV7M_xPSR].valid; + armv7m_gdb_dummy_cpsr_reg.dirty = armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty; +#endif + + /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */ if (xPSR & 0xf00) { - armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = 1; + armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = armv7m->core_cache->reg_list[ARMV7M_xPSR].valid; cortex_m3_store_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 16, xPSR &~ 0xff); } - - /* Now we can load SP core registers */ + /* Now we can load SP core registers */ for (i = ARMV7M_PRIMASK; i < ARMV7NUMCOREREGS; i++) { if (!armv7m->core_cache->reg_list[i].valid) - armv7m->read_core_reg(target, i); + armv7m->read_core_reg(target, i); } /* Are we in an exception handler */ - armv7m->core_mode = (xPSR & 0x1FF) ? ARMV7M_MODE_HANDLER : ARMV7M_MODE_THREAD; - armv7m->exception_number = xPSR & 0x1FF; + if (xPSR & 0x1FF) + { + armv7m->core_mode = ARMV7M_MODE_HANDLER; + armv7m->exception_number = (xPSR & 0x1FF); + } + else + { + armv7m->core_mode = buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_CONTROL].value, 0, 1); + armv7m->exception_number = 0; + } + if (armv7m->exception_number) { cortex_m3_examine_exception_reason(target); } - DEBUG("entered debug state at PC 0x%x, target->state: %s ", *(u32*)(armv7m->core_cache->reg_list[15].value), target_state_strings[target->state]); + LOG_DEBUG("entered debug state in core mode: %s at PC 0x%x, target->state: %s", armv7m_mode_strings[armv7m->core_mode], \ + *(u32*)(armv7m->core_cache->reg_list[15].value), target_state_strings[target->state]); if (armv7m->post_debug_entry) armv7m->post_debug_entry(target); @@ -345,7 +368,7 @@ int cortex_m3_debug_entry(target_t *target) return ERROR_OK; } -enum target_state cortex_m3_poll(target_t *target) +int cortex_m3_poll(target_t *target) { int retval; u32 prev_target_state = target->state; @@ -360,18 +383,25 @@ enum target_state cortex_m3_poll(target_t *target) if (retval != ERROR_OK) { target->state = TARGET_UNKNOWN; - return TARGET_UNKNOWN; + return retval; } if (cortex_m3->dcb_dhcsr & S_RESET_ST) { - target->state = TARGET_RESET; - return target->state; + /* check if still in reset */ + ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr); + + if (cortex_m3->dcb_dhcsr & S_RESET_ST) + { + target->state = TARGET_RESET; + return ERROR_OK; + } } - else if (target->state == TARGET_RESET) + + if (target->state == TARGET_RESET) { /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */ - DEBUG("Exit from reset with dcb_dhcsr 0x%x", cortex_m3->dcb_dhcsr); + LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%x", cortex_m3->dcb_dhcsr); cortex_m3_endreset_event(target); target->state = TARGET_RUNNING; prev_target_state = TARGET_RUNNING; @@ -384,15 +414,15 @@ enum target_state cortex_m3_poll(target_t *target) if ((prev_target_state == TARGET_RUNNING) || (prev_target_state == TARGET_RESET)) { if ((retval = cortex_m3_debug_entry(target)) != ERROR_OK) - return TARGET_UNKNOWN; + return retval; target_call_event_callbacks(target, TARGET_EVENT_HALTED); } if (prev_target_state == TARGET_DEBUG_RUNNING) { - DEBUG(" "); + LOG_DEBUG(" "); if ((retval = cortex_m3_debug_entry(target)) != ERROR_OK) - return TARGET_UNKNOWN; + return retval; target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); } @@ -403,10 +433,13 @@ enum target_state cortex_m3_poll(target_t *target) target->state = TARGET_SLEEP; */ +#if 0 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */ - ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr); - DEBUG("dcb_dhcsr 0x%x, nvic_dfsr 0x%x, target->state: %s", cortex_m3->dcb_dhcsr, cortex_m3->nvic_dfsr, target_state_strings[target->state]); - return target->state; + ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr); + LOG_DEBUG("dcb_dhcsr 0x%x, nvic_dfsr 0x%x, target->state: %s", cortex_m3->dcb_dhcsr, cortex_m3->nvic_dfsr, target_state_strings[target->state]); +#endif + + return ERROR_OK; } int cortex_m3_halt(target_t *target) @@ -416,24 +449,24 @@ int cortex_m3_halt(target_t *target) cortex_m3_common_t *cortex_m3 = armv7m->arch_info; swjdp_common_t *swjdp = &cortex_m3->swjdp_info; - DEBUG("target->state: %s", target_state_strings[target->state]); + LOG_DEBUG("target->state: %s", target_state_strings[target->state]); if (target->state == TARGET_HALTED) { - WARNING("target was already halted"); - return ERROR_TARGET_ALREADY_HALTED; + LOG_DEBUG("target was already halted"); + return ERROR_OK; } if (target->state == TARGET_UNKNOWN) { - WARNING("target was in unknown state when halt was requested"); + LOG_WARNING("target was in unknown state when halt was requested"); } if (target->state == TARGET_RESET) { if ((jtag_reset_config & RESET_SRST_PULLS_TRST) && jtag_srst) { - ERROR("can't request a halt while in reset if nSRST pulls nTRST"); + LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST"); return ERROR_TARGET_FAILURE; } else @@ -463,13 +496,6 @@ int cortex_m3_soft_reset_halt(struct target_s *target) swjdp_common_t *swjdp = &cortex_m3->swjdp_info; u32 dcb_dhcsr = 0; int retval, timeout = 0; - - /* Check that we are using process_context, or change and print warning */ - if (armv7m_get_context(target) != ARMV7M_PROCESS_CONTEXT) - { - DEBUG("Changing to process contex registers"); - armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT); - } /* Enter debug state on reset, cf. end_reset_event() */ ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET ); @@ -489,12 +515,12 @@ int cortex_m3_soft_reset_halt(struct target_s *target) ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr); if ((dcb_dhcsr & S_HALT) && (cortex_m3->nvic_dfsr & DFSR_VCATCH)) { - DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr, cortex_m3->nvic_dfsr); + LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr, cortex_m3->nvic_dfsr); cortex_m3_poll(target); return ERROR_OK; } else - DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr, timeout); + LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr, timeout); } timeout++; usleep(1000); @@ -503,28 +529,6 @@ int cortex_m3_soft_reset_halt(struct target_s *target) return ERROR_OK; } -int cortex_m3_prepare_reset_halt(struct target_s *target) -{ - armv7m_common_t *armv7m = target->arch_info; - cortex_m3_common_t *cortex_m3 = armv7m->arch_info; - swjdp_common_t *swjdp = &cortex_m3->swjdp_info; - u32 dcb_demcr, dcb_dhcsr; - - /* Enable debug requests */ - ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr); - if (!(cortex_m3->dcb_dhcsr & C_DEBUGEN)) - ahbap_write_system_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN ); - - /* Enter debug state on reset, cf. end_reset_event() */ - ahbap_write_system_atomic_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET ); - - ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &dcb_dhcsr); - ahbap_read_system_atomic_u32(swjdp, DCB_DEMCR, &dcb_demcr); - DEBUG("dcb_dhcsr 0x%x, dcb_demcr 0x%x, ", dcb_dhcsr, dcb_demcr); - - return ERROR_OK; -} - int cortex_m3_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution) { /* get pointers to arch-specific information */ @@ -536,35 +540,22 @@ int cortex_m3_resume(struct target_s *target, int current, u32 address, int hand if (target->state != TARGET_HALTED) { - WARNING("target not halted"); + LOG_WARNING("target not halted"); return ERROR_TARGET_NOT_HALTED; } if (!debug_execution) { - /* Check that we are using process_context, or change and print warning */ - if (armv7m_get_context(target) != ARMV7M_PROCESS_CONTEXT) - { - WARNING("Incorrect context in resume"); - armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT); - } - target_free_all_working_areas(target); cortex_m3_enable_breakpoints(target); cortex_m3_enable_watchpoints(target); - /* TODOLATER Interrupt handling/disable for debug execution, cache ... ... */ + /* TODOLATER Interrupt handling/disable for debug execution, cache ... ... */ } dcb_dhcsr = DBGKEY | C_DEBUGEN; if (debug_execution) { - /* Check that we are using debug_context, or change and print warning */ - if (armv7m_get_context(target) != ARMV7M_DEBUG_CONTEXT) - { - WARNING("Incorrect context in debug_exec resume"); - armv7m_use_context(target, ARMV7M_DEBUG_CONTEXT); - } /* Disable interrupts */ /* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS, @@ -595,10 +586,10 @@ int cortex_m3_resume(struct target_s *target, int current, u32 address, int hand /* Single step past breakpoint at current address */ if ((breakpoint = breakpoint_find(target, resume_pc))) { - DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address); - cortex_m3_unset_breakpoint(target, breakpoint); - cortex_m3_single_step_core(target); - cortex_m3_set_breakpoint(target, breakpoint); + LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address); + cortex_m3_unset_breakpoint(target, breakpoint); + cortex_m3_single_step_core(target); + cortex_m3_set_breakpoint(target, breakpoint); } } @@ -616,19 +607,19 @@ int cortex_m3_resume(struct target_s *target, int current, u32 address, int hand { target->state = TARGET_RUNNING; target_call_event_callbacks(target, TARGET_EVENT_RESUMED); - DEBUG("target resumed at 0x%x",resume_pc); + LOG_DEBUG("target resumed at 0x%x",resume_pc); } else { target->state = TARGET_DEBUG_RUNNING; target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED); - DEBUG("target debug resumed at 0x%x",resume_pc); + LOG_DEBUG("target debug resumed at 0x%x",resume_pc); } return ERROR_OK; } -//int irqstepcount=0; +/* int irqstepcount=0; */ int cortex_m3_step(struct target_s *target, int current, u32 address, int handle_breakpoints) { /* get pointers to arch-specific information */ @@ -639,16 +630,9 @@ int cortex_m3_step(struct target_s *target, int current, u32 address, int handle if (target->state != TARGET_HALTED) { - WARNING("target not halted"); + LOG_WARNING("target not halted"); return ERROR_TARGET_NOT_HALTED; } - - /* Check that we are using process_context, or change and print warning */ - if (armv7m_get_context(target) != ARMV7M_PROCESS_CONTEXT) - { - WARNING("Incorrect context in step, must be process"); - armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT); - } /* current = 1: continue on current pc, otherwise continue at
*/ if (!current) @@ -670,82 +654,112 @@ int cortex_m3_step(struct target_s *target, int current, u32 address, int handle ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY| C_STEP | C_DEBUGEN); ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr); - /* If we run in process context then registers are now invalid */ - if (armv7m_get_context(target) == ARMV7M_PROCESS_CONTEXT) - armv7m_invalidate_core_regs(target); + /* registers are now invalid */ + armv7m_invalidate_core_regs(target); if (breakpoint) cortex_m3_set_breakpoint(target, breakpoint); - DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr); + LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr); cortex_m3_debug_entry(target); target_call_event_callbacks(target, TARGET_EVENT_HALTED); - DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr); + LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr); return ERROR_OK; } int cortex_m3_assert_reset(target_t *target) { - int retval; + armv7m_common_t *armv7m = target->arch_info; + cortex_m3_common_t *cortex_m3 = armv7m->arch_info; + swjdp_common_t *swjdp = &cortex_m3->swjdp_info; + int assert_srst = 1; + + LOG_DEBUG("target->state: %s", target_state_strings[target->state]); + + if (!(jtag_reset_config & RESET_HAS_SRST)) + { + LOG_ERROR("Can't assert SRST"); + return ERROR_FAIL; + } + + /* Enable debug requests */ + ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr); + if (!(cortex_m3->dcb_dhcsr & C_DEBUGEN)) + ahbap_write_system_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN ); - DEBUG("target->state: %s", target_state_strings[target->state]); + ahbap_write_system_u32(swjdp, DCB_DCRDR, 0 ); + + if (!target->reset_halt) + { + /* Set/Clear C_MASKINTS in a separate operation */ + if (cortex_m3->dcb_dhcsr & C_MASKINTS) + ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT ); - if (target->state == TARGET_HALTED || target->state == TARGET_UNKNOWN) + cortex_m3_clear_halt(target); + + /* Enter debug state on reset, cf. end_reset_event() */ + ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR); + } + else { - /* assert SRST and TRST */ - /* system would get ouf sync if we didn't reset test-logic, too */ - if ((retval = jtag_add_reset(1, 1)) != ERROR_OK) + /* Enter debug state on reset, cf. end_reset_event() */ + ahbap_write_system_atomic_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET ); + } + + /* following hack is to handle luminary reset + * when srst is asserted the luminary device seesm to also clear the debug registers + * which does not match the armv7 debug TRM */ + + if (strcmp(cortex_m3->variant, "lm3s") == 0) + { + /* get revision of lm3s target, only early silicon has this issue + * Fury Rev B, DustDevil Rev B, Tempest all ok */ + + u32 did0; + + if (target_read_u32(target, 0x400fe000, &did0) == ERROR_OK) { - if (retval == ERROR_JTAG_RESET_CANT_SRST) + switch ((did0 >> 16) & 0xff) { - WARNING("can't assert srst"); - return retval; - } - else - { - ERROR("unknown error"); - exit(-1); + case 0: + /* all Sandstorm suffer issue */ + assert_srst = 0; + break; + + case 1: + case 3: + /* only Fury/DustDevil rev A suffer reset problems */ + if (((did0 >> 8) & 0xff) == 0) + assert_srst = 0; + break; } } - jtag_add_sleep(5000); - if ((retval = jtag_add_reset(0, 1)) != ERROR_OK) + } + + if (assert_srst) + { + /* default to asserting srst */ + if (jtag_reset_config & RESET_SRST_PULLS_TRST) + { + jtag_add_reset(1, 1); + } + else { - if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST) - { - WARNING("srst resets test logic, too"); - retval = jtag_add_reset(1, 1); - } + jtag_add_reset(0, 1); } } else { - if ((retval = jtag_add_reset(0, 1)) != ERROR_OK) - { - if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST) - { - WARNING("srst resets test logic, too"); - retval = jtag_add_reset(1, 1); - } - - if (retval == ERROR_JTAG_RESET_CANT_SRST) - { - WARNING("can't assert srsrt"); - return retval; - } - else if (retval != ERROR_OK) - { - ERROR("unknown error"); - exit(-1); - } - } + /* this causes the luminary device to reset using the watchdog */ + ahbap_write_system_atomic_u32(swjdp, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ ); + LOG_DEBUG("Using Luminary Reset: SYSRESETREQ"); } target->state = TARGET_RESET; jtag_add_sleep(50000); - armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT); armv7m_invalidate_core_regs(target); return ERROR_OK; @@ -753,7 +767,7 @@ int cortex_m3_assert_reset(target_t *target) int cortex_m3_deassert_reset(target_t *target) { - DEBUG("target->state: %s", target_state_strings[target->state]); + LOG_DEBUG("target->state: %s", target_state_strings[target->state]); /* deassert reset lines */ jtag_add_reset(0, 0); @@ -761,11 +775,6 @@ int cortex_m3_deassert_reset(target_t *target) return ERROR_OK; } -void cortex_m3_unset_all_breakpoints_and_watchpoints(struct target_s *target) -{ - -} - void cortex_m3_enable_breakpoints(struct target_s *target) { breakpoint_t *breakpoint = target->breakpoints; @@ -792,10 +801,10 @@ int cortex_m3_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint) if (breakpoint->set) { - WARNING("breakpoint already set"); + LOG_WARNING("breakpoint already set"); return ERROR_OK; } - + if (cortex_m3->auto_bp_type) { breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT; @@ -807,8 +816,8 @@ int cortex_m3_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint) fp_num++; if (fp_num >= cortex_m3->fp_num_code) { - DEBUG("ERROR Can not find free FP Comparator"); - WARNING("ERROR Can not find free FP Comparator"); + LOG_DEBUG("ERROR Can not find free FP Comparator"); + LOG_WARNING("ERROR Can not find free FP Comparator"); exit(-1); } breakpoint->set = fp_num + 1; @@ -816,7 +825,7 @@ int cortex_m3_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint) comparator_list[fp_num].used = 1; comparator_list[fp_num].fpcr_value = (breakpoint->address & 0x1FFFFFFC) | hilo | 1; target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value); - DEBUG("fpc_num %i fpcr_value 0x%x", fp_num, comparator_list[fp_num].fpcr_value); + LOG_DEBUG("fpc_num %i fpcr_value 0x%x", fp_num, comparator_list[fp_num].fpcr_value); } else if (breakpoint->type == BKPT_SOFT) { @@ -839,7 +848,7 @@ int cortex_m3_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint if (!breakpoint->set) { - WARNING("breakpoint not set"); + LOG_WARNING("breakpoint not set"); return ERROR_OK; } @@ -848,7 +857,7 @@ int cortex_m3_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint int fp_num = breakpoint->set - 1; if ((fp_num < 0) || (fp_num >= cortex_m3->fp_num_code)) { - DEBUG("Invalid FP Comparator number in breakpoint"); + LOG_DEBUG("Invalid FP Comparator number in breakpoint"); return ERROR_OK; } comparator_list[fp_num].used = 0; @@ -877,33 +886,41 @@ int cortex_m3_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint) /* get pointers to arch-specific information */ armv7m_common_t *armv7m = target->arch_info; cortex_m3_common_t *cortex_m3 = armv7m->arch_info; - + if (cortex_m3->auto_bp_type) { breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT; +#ifdef ARMV7_GDB_HACKS + if (breakpoint->length != 2) { + /* XXX Hack: Replace all breakpoints with length != 2 with + * a hardware breakpoint. */ + breakpoint->type = BKPT_HARD; + breakpoint->length = 2; + } +#endif } if ((breakpoint->type == BKPT_HARD) && (breakpoint->address >= 0x20000000)) { - INFO("flash patch comparator requested outside code memory region"); + LOG_INFO("flash patch comparator requested outside code memory region"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } if ((breakpoint->type == BKPT_SOFT) && (breakpoint->address < 0x20000000)) { - INFO("soft breakpoint requested in code (flash) memory region"); + LOG_INFO("soft breakpoint requested in code (flash) memory region"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } if ((breakpoint->type == BKPT_HARD) && (cortex_m3->fp_code_available < 1)) { - INFO("no flash patch comparator unit available for hardware breakpoint"); + LOG_INFO("no flash patch comparator unit available for hardware breakpoint"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } if ((breakpoint->length != 2)) { - INFO("only breakpoints of two bytes length supported"); + LOG_INFO("only breakpoints of two bytes length supported"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } @@ -922,7 +939,7 @@ int cortex_m3_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoin if (target->state != TARGET_HALTED) { - WARNING("target not halted"); + LOG_WARNING("target not halted"); return ERROR_TARGET_NOT_HALTED; } @@ -954,7 +971,7 @@ int cortex_m3_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint) if (watchpoint->set) { - WARNING("watchpoint already set"); + LOG_WARNING("watchpoint already set"); return ERROR_OK; } @@ -964,8 +981,8 @@ int cortex_m3_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint) dwt_num++; if (dwt_num >= cortex_m3->dwt_num_comp) { - DEBUG("ERROR Can not find free DWT Comparator"); - WARNING("ERROR Can not find free DWT Comparator"); + LOG_DEBUG("ERROR Can not find free DWT Comparator"); + LOG_WARNING("ERROR Can not find free DWT Comparator"); return -1; } watchpoint->set = dwt_num + 1; @@ -983,11 +1000,11 @@ int cortex_m3_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint) target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address, comparator_list[dwt_num].comp); target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x4, comparator_list[dwt_num].mask); target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x8, comparator_list[dwt_num].function); - DEBUG("dwt_num %i 0x%x 0x%x 0x%x", dwt_num, comparator_list[dwt_num].comp, comparator_list[dwt_num].mask, comparator_list[dwt_num].function); + LOG_DEBUG("dwt_num %i 0x%x 0x%x 0x%x", dwt_num, comparator_list[dwt_num].comp, comparator_list[dwt_num].mask, comparator_list[dwt_num].function); } else { - WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */ + LOG_WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */ return ERROR_OK; } @@ -1005,7 +1022,7 @@ int cortex_m3_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint if (!watchpoint->set) { - WARNING("watchpoint not set"); + LOG_WARNING("watchpoint not set"); return ERROR_OK; } @@ -1013,7 +1030,7 @@ int cortex_m3_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint if ((dwt_num < 0) || (dwt_num >= cortex_m3->dwt_num_comp)) { - DEBUG("Invalid DWT Comparator number in watchpoint"); + LOG_DEBUG("Invalid DWT Comparator number in watchpoint"); return ERROR_OK; } comparator_list[dwt_num].used = 0; @@ -1033,7 +1050,7 @@ int cortex_m3_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint) if (target->state != TARGET_HALTED) { - WARNING("target not halted"); + LOG_WARNING("target not halted"); return ERROR_TARGET_NOT_HALTED; } @@ -1060,7 +1077,7 @@ int cortex_m3_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoin if (target->state != TARGET_HALTED) { - WARNING("target not halted"); + LOG_WARNING("target not halted"); return ERROR_TARGET_NOT_HALTED; } @@ -1102,32 +1119,41 @@ int cortex_m3_load_core_reg_u32(struct target_s *target, enum armv7m_regtype typ if (retval != ERROR_OK) { - ERROR("JTAG failure %i",retval); + LOG_ERROR("JTAG failure %i",retval); return ERROR_JTAG_DEVICE_ERROR; } - //DEBUG("load from core reg %i value 0x%x",num,*value); + LOG_DEBUG("load from core reg %i value 0x%x",num,*value); } else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */ { /* read other registers */ - /* cortex_m3_MRS(struct target_s *target, int num, u32* value) */ - u32 savedram; - u32 SYSm; - u32 instr; - SYSm = num & 0x1F; - ahbap_read_system_u32(swjdp, 0x20000000, &savedram); - instr = ARMV7M_T_MRS(0, SYSm); - ahbap_write_system_u32(swjdp, 0x20000000, ARMV7M_T_MRS(0, SYSm)); - ahbap_write_coreregister_u32(swjdp, 0x20000000, 15); - cortex_m3_single_step_core(target); - ahbap_read_coreregister_u32(swjdp, value, 0); - armv7m->core_cache->reg_list[0].dirty = 1; - armv7m->core_cache->reg_list[15].dirty = 1; - ahbap_write_system_u32(swjdp, 0x20000000, savedram); - swjdp_transaction_endcheck(swjdp); - DEBUG("load from special reg %i value 0x%x", SYSm, *value); + ahbap_read_coreregister_u32(swjdp, value, 20); + + switch (num) + { + case 19: + *value = buf_get_u32((u8*)value, 0, 8); + break; + + case 20: + *value = buf_get_u32((u8*)value, 8, 8); + break; + + case 21: + *value = buf_get_u32((u8*)value, 16, 8); + break; + + case 22: + *value = buf_get_u32((u8*)value, 24, 8); + break; + } + + LOG_DEBUG("load from special reg %i value 0x%x", num, *value); + } + else + { + return ERROR_INVALID_ARGUMENTS; } - else return ERROR_INVALID_ARGUMENTS; return ERROR_OK; } @@ -1135,44 +1161,68 @@ int cortex_m3_load_core_reg_u32(struct target_s *target, enum armv7m_regtype typ int cortex_m3_store_core_reg_u32(struct target_s *target, enum armv7m_regtype type, u32 num, u32 value) { int retval; + u32 reg; /* get pointers to arch-specific information */ armv7m_common_t *armv7m = target->arch_info; cortex_m3_common_t *cortex_m3 = armv7m->arch_info; swjdp_common_t *swjdp = &cortex_m3->swjdp_info; +#ifdef ARMV7_GDB_HACKS + /* If the LR register is being modified, make sure it will put us + * in "thumb" mode, or an INVSTATE exception will occur. This is a + * hack to deal with the fact that gdb will sometimes "forge" + * return addresses, and doesn't set the LSB correctly (i.e., when + * printing expressions containing function calls, it sets LR=0.) */ + + if (num == 14) + value |= 0x01; +#endif + if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP)) { retval = ahbap_write_coreregister_u32(swjdp, value, num); if (retval != ERROR_OK) { - ERROR("JTAG failure %i", retval); - armv7m->core_cache->reg_list[num].dirty = 1; + LOG_ERROR("JTAG failure %i", retval); + armv7m->core_cache->reg_list[num].dirty = armv7m->core_cache->reg_list[num].valid; return ERROR_JTAG_DEVICE_ERROR; } - DEBUG("write core reg %i value 0x%x", num, value); + LOG_DEBUG("write core reg %i value 0x%x", num, value); } else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */ { /* write other registers */ - u32 savedram , tempr0; - u32 SYSm; - u32 instr; - SYSm = num & 0x1F; - ahbap_read_system_u32(swjdp, 0x20000000, &savedram); - instr = ARMV7M_T_MSR(SYSm, 0); - ahbap_write_system_u32(swjdp, 0x20000000, ARMV7M_T_MSR(SYSm, 0)); - ahbap_read_coreregister_u32(swjdp, &tempr0, 0); - ahbap_write_coreregister_u32(swjdp, value, 0); - ahbap_write_coreregister_u32(swjdp, 0x20000000, 15); - cortex_m3_single_step_core(target); - ahbap_write_coreregister_u32(swjdp, tempr0, 0); - armv7m->core_cache->reg_list[15].dirty = 1; - ahbap_write_system_u32(swjdp, 0x20000000, savedram); - swjdp_transaction_endcheck(swjdp); - DEBUG("write special reg %i value 0x%x ", SYSm, value); + + ahbap_read_coreregister_u32(swjdp, ®, 20); + + switch (num) + { + case 19: + buf_set_u32((u8*)®, 0, 8, value); + break; + + case 20: + buf_set_u32((u8*)®, 8, 8, value); + break; + + case 21: + buf_set_u32((u8*)®, 16, 8, value); + break; + + case 22: + buf_set_u32((u8*)®, 24, 8, value); + break; + } + + ahbap_write_coreregister_u32(swjdp, reg, 20); + + LOG_DEBUG("write special reg %i value 0x%x ", num, value); + } + else + { + return ERROR_INVALID_ARGUMENTS; } - else return ERROR_INVALID_ARGUMENTS; return ERROR_OK; } @@ -1183,39 +1233,31 @@ int cortex_m3_read_memory(struct target_s *target, u32 address, u32 size, u32 co armv7m_common_t *armv7m = target->arch_info; cortex_m3_common_t *cortex_m3 = armv7m->arch_info; swjdp_common_t *swjdp = &cortex_m3->swjdp_info; + int retval; /* sanitize arguments */ if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer)) return ERROR_INVALID_ARGUMENTS; - - if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) - return ERROR_TARGET_UNALIGNED_ACCESS; - /* Is not optimal, autoincrement of tar should be used ( ahbap_block_read and CSW_ADDRINC_SINGLE ) */ + /* cortex_m3 handles unaligned memory access */ + switch (size) { case 4: - /* TODOLATER Check error return value ! */ - { - ahbap_read_buf(swjdp, buffer, 4 * count, address); - } + retval = ahbap_read_buf_u32(swjdp, buffer, 4 * count, address); break; case 2: - { - ahbap_read_buf_u16(swjdp, buffer, 2 * count, address); - } + retval = ahbap_read_buf_u16(swjdp, buffer, 2 * count, address); break; case 1: - { - ahbap_read_buf(swjdp, buffer, count, address); - } + retval = ahbap_read_buf_u8(swjdp, buffer, count, address); break; default: - ERROR("BUG: we shouldn't get here"); + LOG_ERROR("BUG: we shouldn't get here"); exit(-1); } - return ERROR_OK; + return retval; } int cortex_m3_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer) @@ -1224,45 +1266,34 @@ int cortex_m3_write_memory(struct target_s *target, u32 address, u32 size, u32 c armv7m_common_t *armv7m = target->arch_info; cortex_m3_common_t *cortex_m3 = armv7m->arch_info; swjdp_common_t *swjdp = &cortex_m3->swjdp_info; + int retval; /* sanitize arguments */ if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer)) return ERROR_INVALID_ARGUMENTS; - - if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) - return ERROR_TARGET_UNALIGNED_ACCESS; - + switch (size) { case 4: - /* TODOLATER Check error return value ! */ - { - ahbap_write_buf(swjdp, buffer, 4 * count, address); - } + retval = ahbap_write_buf_u32(swjdp, buffer, 4 * count, address); break; case 2: - { - ahbap_write_buf_u16(swjdp, buffer, 2 * count, address); - } + retval = ahbap_write_buf_u16(swjdp, buffer, 2 * count, address); break; case 1: - { - ahbap_write_buf(swjdp, buffer, count, address); - } + retval = ahbap_write_buf_u8(swjdp, buffer, count, address); break; default: - ERROR("BUG: we shouldn't get here"); + LOG_ERROR("BUG: we shouldn't get here"); exit(-1); } - return ERROR_OK; + return retval; } int cortex_m3_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer) { - cortex_m3_write_memory(target, address, 4, count, buffer); - - return ERROR_OK; + return cortex_m3_write_memory(target, address, 4, count, buffer); } void cortex_m3_build_reg_cache(target_t *target) @@ -1272,6 +1303,13 @@ void cortex_m3_build_reg_cache(target_t *target) int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *target) { + cortex_m3_build_reg_cache(target); + return ERROR_OK; +} + +int cortex_m3_examine(struct command_context_s *cmd_ctx, struct target_s *target) +{ + int retval; u32 cpuid, fpcr, dwtcr, ictr; int i; @@ -1279,15 +1317,19 @@ int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *ta armv7m_common_t *armv7m = target->arch_info; cortex_m3_common_t *cortex_m3 = armv7m->arch_info; swjdp_common_t *swjdp = &cortex_m3->swjdp_info; + + target->type->examined = 1; - cortex_m3_build_reg_cache(target); - ahbap_debugport_init(swjdp); + if ((retval=ahbap_debugport_init(swjdp))!=ERROR_OK) + return retval; /* Read from Device Identification Registers */ - target_read_u32(target, CPUID, &cpuid); + if ((retval=target_read_u32(target, CPUID, &cpuid))!=ERROR_OK) + return retval; + if (((cpuid >> 4) & 0xc3f) == 0xc23) - DEBUG("CORTEX-M3 processor detected"); - DEBUG("cpuid: 0x%8.8x", cpuid); + LOG_DEBUG("CORTEX-M3 processor detected"); + LOG_DEBUG("cpuid: 0x%8.8x", cpuid); target_read_u32(target, NVIC_ICTR, &ictr); cortex_m3->intlinesnum = (ictr & 0x1F) + 1; @@ -1295,7 +1337,7 @@ int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *ta for (i = 0; i < cortex_m3->intlinesnum; i++) { target_read_u32(target, NVIC_ISE0 + 4 * i, cortex_m3->intsetenable + i); - DEBUG("interrupt enable[%i] = 0x%8.8x", i, cortex_m3->intsetenable[i]); + LOG_DEBUG("interrupt enable[%i] = 0x%8.8x", i, cortex_m3->intsetenable[i]); } /* Setup FPB */ @@ -1310,7 +1352,7 @@ int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *ta cortex_m3->fp_comparator_list[i].type = (i < cortex_m3->fp_num_code) ? FPCR_CODE : FPCR_LITERAL; cortex_m3->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i; } - DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr, cortex_m3->fp_num_code, cortex_m3->fp_num_lit); + LOG_DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr, cortex_m3->fp_num_code, cortex_m3->fp_num_lit); /* Setup DWT */ target_read_u32(target, DWT_CTRL, &dwtcr); @@ -1331,6 +1373,84 @@ int cortex_m3_quit() return ERROR_OK; } +int cortex_m3_dcc_read(swjdp_common_t *swjdp, u8 *value, u8 *ctrl) +{ + u16 dcrdr; + + ahbap_read_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR); + *ctrl = (u8)dcrdr; + *value = (u8)(dcrdr >> 8); + + LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl); + + /* write ack back to software dcc register + * signify we have read data */ + if (dcrdr & (1 << 0)) + { + dcrdr = 0; + ahbap_write_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR); + } + + return ERROR_OK; +} + +int cortex_m3_target_request_data(target_t *target, u32 size, u8 *buffer) +{ + armv7m_common_t *armv7m = target->arch_info; + cortex_m3_common_t *cortex_m3 = armv7m->arch_info; + swjdp_common_t *swjdp = &cortex_m3->swjdp_info; + u8 data; + u8 ctrl; + int i; + + for (i = 0; i < (size * 4); i++) + { + cortex_m3_dcc_read(swjdp, &data, &ctrl); + buffer[i] = data; + } + + return ERROR_OK; +} + +int cortex_m3_handle_target_request(void *priv) +{ + target_t *target = priv; + if (!target->type->examined) + return ERROR_OK; + armv7m_common_t *armv7m = target->arch_info; + cortex_m3_common_t *cortex_m3 = armv7m->arch_info; + swjdp_common_t *swjdp = &cortex_m3->swjdp_info; + + if (!target->dbg_msg_enabled) + return ERROR_OK; + + if (target->state == TARGET_RUNNING) + { + u8 data; + u8 ctrl; + + cortex_m3_dcc_read(swjdp, &data, &ctrl); + + /* check if we have data */ + if (ctrl & (1 << 0)) + { + u32 request; + + /* we assume target is quick enough */ + request = data; + cortex_m3_dcc_read(swjdp, &data, &ctrl); + request |= (data << 8); + cortex_m3_dcc_read(swjdp, &data, &ctrl); + request |= (data << 16); + cortex_m3_dcc_read(swjdp, &data, &ctrl); + request |= (data << 24); + target_request(target, request); + } + } + + return ERROR_OK; +} + int cortex_m3_init_arch_info(target_t *target, cortex_m3_common_t *cortex_m3, int chain_pos, char *variant) { armv7m_common_t *armv7m; @@ -1359,11 +1479,21 @@ int cortex_m3_init_arch_info(target_t *target, cortex_m3_common_t *cortex_m3, in armv7m->pre_restore_context = NULL; armv7m->post_restore_context = NULL; + if (variant) + { + cortex_m3->variant = strdup(variant); + } + else + { + cortex_m3->variant = strdup(""); + } + armv7m_init_arch_info(target, armv7m); armv7m->arch_info = cortex_m3; armv7m->load_core_reg_u32 = cortex_m3_load_core_reg_u32; armv7m->store_core_reg_u32 = cortex_m3_store_core_reg_u32; -// armv7m->full_context = cortex_m3_full_context; + + target_register_timer_callback(cortex_m3_handle_target_request, 1, 1, target); return ERROR_OK; } @@ -1374,10 +1504,11 @@ int cortex_m3_target_command(struct command_context_s *cmd_ctx, char *cmd, char int chain_pos; char *variant = NULL; cortex_m3_common_t *cortex_m3 = malloc(sizeof(cortex_m3_common_t)); + memset(cortex_m3, 0, sizeof(*cortex_m3)); if (argc < 4) { - ERROR("'target cortex_m3' requires at least one additional argument"); + LOG_ERROR("'target cortex_m3' requires at least one additional argument"); exit(-1); } @@ -1387,7 +1518,6 @@ int cortex_m3_target_command(struct command_context_s *cmd_ctx, char *cmd, char variant = args[4]; cortex_m3_init_arch_info(target, cortex_m3, chain_pos, variant); - cortex_m3_register_commands(cmd_ctx); return ERROR_OK; }