Revert "cortex_m3: add auto maskisr"
[openocd.git] / src / target / cortex_m3.c
index d6090f55b98b90f46c7ed04b32623fc433bc4d79..9c3d2d9d691ffa9b13f1fd9bbbaa4518f5cc43c5 100644 (file)
  * any longer.
  */
 
  * any longer.
  */
 
+/**
+ * Returns the type of a break point required by address location
+ */
+#define BKPT_TYPE_BY_ADDR(addr) ((addr) < 0x20000000 ? BKPT_HARD : BKPT_SOFT)
+
 
 /* forward declarations */
 static int cortex_m3_set_breakpoint(struct target *target, struct breakpoint *breakpoint);
 
 /* forward declarations */
 static int cortex_m3_set_breakpoint(struct target *target, struct breakpoint *breakpoint);
@@ -68,7 +73,9 @@ static int cortexm3_dap_read_coreregister_u32(struct adiv5_dap *swjdp,
        /* because the DCB_DCRDR is used for the emulated dcc channel
         * we have to save/restore the DCB_DCRDR when used */
 
        /* because the DCB_DCRDR is used for the emulated dcc channel
         * we have to save/restore the DCB_DCRDR when used */
 
-       mem_ap_read_u32(swjdp, DCB_DCRDR, &dcrdr);
+       retval = mem_ap_read_u32(swjdp, DCB_DCRDR, &dcrdr);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* mem_ap_write_u32(swjdp, DCB_DCRSR, regnum); */
        retval = dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR & 0xFFFFFFF0);
 
        /* mem_ap_write_u32(swjdp, DCB_DCRSR, regnum); */
        retval = dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR & 0xFFFFFFF0);
@@ -107,7 +114,9 @@ static int cortexm3_dap_write_coreregister_u32(struct adiv5_dap *swjdp,
        /* because the DCB_DCRDR is used for the emulated dcc channel
         * we have to save/restore the DCB_DCRDR when used */
 
        /* because the DCB_DCRDR is used for the emulated dcc channel
         * we have to save/restore the DCB_DCRDR when used */
 
-       mem_ap_read_u32(swjdp, DCB_DCRDR, &dcrdr);
+       retval = mem_ap_read_u32(swjdp, DCB_DCRDR, &dcrdr);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* mem_ap_write_u32(swjdp, DCB_DCRDR, core_regs[i]); */
        retval = dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR & 0xFFFFFFF0);
 
        /* mem_ap_write_u32(swjdp, DCB_DCRDR, core_regs[i]); */
        retval = dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR & 0xFFFFFFF0);
@@ -151,15 +160,20 @@ static int cortex_m3_clear_halt(struct target *target)
 {
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
        struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
 {
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
        struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
+       int retval;
 
        /* clear step if any */
        cortex_m3_write_debug_halt_mask(target, C_HALT, C_STEP);
 
        /* Read Debug Fault Status Register */
 
        /* clear step if any */
        cortex_m3_write_debug_halt_mask(target, C_HALT, C_STEP);
 
        /* Read Debug Fault Status Register */
-       mem_ap_read_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
+       retval = mem_ap_read_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* Clear Debug Fault Status */
 
        /* Clear Debug Fault Status */
-       mem_ap_write_atomic_u32(swjdp, NVIC_DFSR, cortex_m3->nvic_dfsr);
+       retval = mem_ap_write_atomic_u32(swjdp, NVIC_DFSR, cortex_m3->nvic_dfsr);
+       if (retval != ERROR_OK)
+               return retval;
        LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32 "", cortex_m3->nvic_dfsr);
 
        return ERROR_OK;
        LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32 "", cortex_m3->nvic_dfsr);
 
        return ERROR_OK;
@@ -170,6 +184,7 @@ static int cortex_m3_single_step_core(struct target *target)
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
        struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
        uint32_t dhcsr_save;
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
        struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
        uint32_t dhcsr_save;
+       int retval;
 
        /* backup dhcsr reg */
        dhcsr_save = cortex_m3->dcb_dhcsr;
 
        /* backup dhcsr reg */
        dhcsr_save = cortex_m3->dcb_dhcsr;
@@ -179,10 +194,16 @@ static int cortex_m3_single_step_core(struct target *target)
         * HALT can put the core into an unknown state.
         */
        if (!(cortex_m3->dcb_dhcsr & C_MASKINTS))
         * HALT can put the core into an unknown state.
         */
        if (!(cortex_m3->dcb_dhcsr & C_MASKINTS))
-               mem_ap_write_atomic_u32(swjdp, DCB_DHCSR,
+       {
+               retval = mem_ap_write_atomic_u32(swjdp, DCB_DHCSR,
                                DBGKEY | C_MASKINTS | C_HALT | C_DEBUGEN);
                                DBGKEY | C_MASKINTS | C_HALT | C_DEBUGEN);
-       mem_ap_write_atomic_u32(swjdp, DCB_DHCSR,
+               if (retval != ERROR_OK)
+                       return retval;
+       }
+       retval = mem_ap_write_atomic_u32(swjdp, DCB_DHCSR,
                                DBGKEY | C_MASKINTS | C_STEP | C_DEBUGEN);
                                DBGKEY | C_MASKINTS | C_STEP | C_DEBUGEN);
+       if (retval != ERROR_OK)
+               return retval;
        LOG_DEBUG(" ");
 
        /* restore dhcsr reg */
        LOG_DEBUG(" ");
 
        /* restore dhcsr reg */
@@ -204,16 +225,26 @@ static int cortex_m3_endreset_event(struct target *target)
        struct cortex_m3_dwt_comparator *dwt_list = cortex_m3->dwt_comparator_list;
 
        /* REVISIT The four debug monitor bits are currently ignored... */
        struct cortex_m3_dwt_comparator *dwt_list = cortex_m3->dwt_comparator_list;
 
        /* REVISIT The four debug monitor bits are currently ignored... */
-       mem_ap_read_atomic_u32(swjdp, DCB_DEMCR, &dcb_demcr);
+       retval = mem_ap_read_atomic_u32(swjdp, DCB_DEMCR, &dcb_demcr);
+       if (retval != ERROR_OK)
+               return retval;
        LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32 "",dcb_demcr);
 
        /* this register is used for emulated dcc channel */
        LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32 "",dcb_demcr);
 
        /* this register is used for emulated dcc channel */
-       mem_ap_write_u32(swjdp, DCB_DCRDR, 0);
+       retval = mem_ap_write_u32(swjdp, DCB_DCRDR, 0);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* Enable debug requests */
 
        /* Enable debug requests */
-       mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
+       retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
+       if (retval != ERROR_OK)
+               return retval;
        if (!(cortex_m3->dcb_dhcsr & C_DEBUGEN))
        if (!(cortex_m3->dcb_dhcsr & C_DEBUGEN))
-               mem_ap_write_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN);
+       {
+               retval = mem_ap_write_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN);
+               if (retval != ERROR_OK)
+                       return retval;
+       }
 
        /* clear any interrupt masking */
        cortex_m3_write_debug_halt_mask(target, 0, C_MASKINTS);
 
        /* clear any interrupt masking */
        cortex_m3_write_debug_halt_mask(target, 0, C_MASKINTS);
@@ -225,31 +256,44 @@ static int cortex_m3_endreset_event(struct target *target)
         * choices *EXCEPT* explicitly scripted overrides like "vector_catch"
         * or manual updates to the NVIC SHCSR and CCR registers.
         */
         * choices *EXCEPT* explicitly scripted overrides like "vector_catch"
         * or manual updates to the NVIC SHCSR and CCR registers.
         */
-       mem_ap_write_u32(swjdp, DCB_DEMCR, TRCENA | armv7m->demcr);
+       retval = mem_ap_write_u32(swjdp, DCB_DEMCR, TRCENA | armv7m->demcr);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* Paranoia: evidently some (early?) chips don't preserve all the
         * debug state (including FBP, DWT, etc) across reset...
         */
 
        /* Enable FPB */
 
        /* Paranoia: evidently some (early?) chips don't preserve all the
         * debug state (including FBP, DWT, etc) across reset...
         */
 
        /* Enable FPB */
-       target_write_u32(target, FP_CTRL, 3);
+       retval = target_write_u32(target, FP_CTRL, 3);
+       if (retval != ERROR_OK)
+               return retval;
+
        cortex_m3->fpb_enabled = 1;
 
        /* Restore FPB registers */
        for (i = 0; i < cortex_m3->fp_num_code + cortex_m3->fp_num_lit; i++)
        {
        cortex_m3->fpb_enabled = 1;
 
        /* Restore FPB registers */
        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);
+               retval = target_write_u32(target, fp_list[i].fpcr_address, fp_list[i].fpcr_value);
+               if (retval != ERROR_OK)
+                       return retval;
        }
 
        /* Restore DWT registers */
        for (i = 0; i < cortex_m3->dwt_num_comp; i++)
        {
        }
 
        /* Restore DWT registers */
        for (i = 0; i < cortex_m3->dwt_num_comp; i++)
        {
-               target_write_u32(target, dwt_list[i].dwt_comparator_address + 0,
+               retval = target_write_u32(target, dwt_list[i].dwt_comparator_address + 0,
                                dwt_list[i].comp);
                                dwt_list[i].comp);
-               target_write_u32(target, dwt_list[i].dwt_comparator_address + 4,
+               if (retval != ERROR_OK)
+                       return retval;
+               retval = target_write_u32(target, dwt_list[i].dwt_comparator_address + 4,
                                dwt_list[i].mask);
                                dwt_list[i].mask);
-               target_write_u32(target, dwt_list[i].dwt_comparator_address + 8,
+               if (retval != ERROR_OK)
+                       return retval;
+               retval = target_write_u32(target, dwt_list[i].dwt_comparator_address + 8,
                                dwt_list[i].function);
                                dwt_list[i].function);
+               if (retval != ERROR_OK)
+                       return retval;
        }
        retval = dap_run(swjdp);
        if (retval != ERROR_OK)
        }
        retval = dap_run(swjdp);
        if (retval != ERROR_OK)
@@ -258,7 +302,7 @@ static int cortex_m3_endreset_event(struct target *target)
        register_cache_invalidate(cortex_m3->armv7m.core_cache);
 
        /* make sure we have latest dhcsr flags */
        register_cache_invalidate(cortex_m3->armv7m.core_cache);
 
        /* make sure we have latest dhcsr flags */
-       mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
+       retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
 
        return retval;
 }
 
        return retval;
 }
@@ -297,33 +341,51 @@ static int cortex_m3_examine_exception_reason(struct target *target)
        struct adiv5_dap *swjdp = &armv7m->dap;
        int retval;
 
        struct adiv5_dap *swjdp = &armv7m->dap;
        int retval;
 
-       mem_ap_read_u32(swjdp, NVIC_SHCSR, &shcsr);
+       retval = mem_ap_read_u32(swjdp, NVIC_SHCSR, &shcsr);
+       if (retval != ERROR_OK)
+               return retval;
        switch (armv7m->exception_number)
        {
                case 2: /* NMI */
                        break;
                case 3: /* Hard Fault */
        switch (armv7m->exception_number)
        {
                case 2: /* NMI */
                        break;
                case 3: /* Hard Fault */
-                       mem_ap_read_atomic_u32(swjdp, NVIC_HFSR, &except_sr);
+                       retval = mem_ap_read_atomic_u32(swjdp, NVIC_HFSR, &except_sr);
+                       if (retval != ERROR_OK)
+                               return retval;
                        if (except_sr & 0x40000000)
                        {
                        if (except_sr & 0x40000000)
                        {
-                               mem_ap_read_u32(swjdp, NVIC_CFSR, &cfsr);
+                               retval = mem_ap_read_u32(swjdp, NVIC_CFSR, &cfsr);
+                               if (retval != ERROR_OK)
+                                       return retval;
                        }
                        break;
                case 4: /* Memory Management */
                        }
                        break;
                case 4: /* Memory Management */
-                       mem_ap_read_u32(swjdp, NVIC_CFSR, &except_sr);
-                       mem_ap_read_u32(swjdp, NVIC_MMFAR, &except_ar);
+                       retval = mem_ap_read_u32(swjdp, NVIC_CFSR, &except_sr);
+                       if (retval != ERROR_OK)
+                               return retval;
+                       retval = mem_ap_read_u32(swjdp, NVIC_MMFAR, &except_ar);
+                       if (retval != ERROR_OK)
+                               return retval;
                        break;
                case 5: /* Bus Fault */
                        break;
                case 5: /* Bus Fault */
-                       mem_ap_read_u32(swjdp, NVIC_CFSR, &except_sr);
-                       mem_ap_read_u32(swjdp, NVIC_BFAR, &except_ar);
+                       retval = mem_ap_read_u32(swjdp, NVIC_CFSR, &except_sr);
+                       if (retval != ERROR_OK)
+                               return retval;
+                       retval = mem_ap_read_u32(swjdp, NVIC_BFAR, &except_ar);
+                       if (retval != ERROR_OK)
+                               return retval;
                        break;
                case 6: /* Usage Fault */
                        break;
                case 6: /* Usage Fault */
-                       mem_ap_read_u32(swjdp, NVIC_CFSR, &except_sr);
+                       retval = mem_ap_read_u32(swjdp, NVIC_CFSR, &except_sr);
+                       if (retval != ERROR_OK)
+                               return retval;
                        break;
                case 11:        /* SVCall */
                        break;
                case 12:        /* Debug Monitor */
                        break;
                case 11:        /* SVCall */
                        break;
                case 12:        /* Debug Monitor */
-                       mem_ap_read_u32(swjdp, NVIC_DFSR, &except_sr);
+                       retval = mem_ap_read_u32(swjdp, NVIC_DFSR, &except_sr);
+                       if (retval != ERROR_OK)
+                               return retval;
                        break;
                case 14:        /* PendSV */
                        break;
                        break;
                case 14:        /* PendSV */
                        break;
@@ -374,7 +436,9 @@ static int cortex_m3_debug_entry(struct target *target)
        LOG_DEBUG(" ");
 
        cortex_m3_clear_halt(target);
        LOG_DEBUG(" ");
 
        cortex_m3_clear_halt(target);
-       mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
+       retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
+       if (retval != ERROR_OK)
+               return retval;
 
        if ((retval = armv7m->examine_debug_reason(target)) != ERROR_OK)
                return retval;
 
        if ((retval = armv7m->examine_debug_reason(target)) != ERROR_OK)
                return retval;
@@ -461,7 +525,8 @@ static int cortex_m3_debug_entry(struct target *target)
 
 static int cortex_m3_poll(struct target *target)
 {
 
 static int cortex_m3_poll(struct target *target)
 {
-       int retval;
+       int detected_failure = ERROR_OK;
+       int retval = ERROR_OK;
        enum target_state prev_target_state = target->state;
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
        struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
        enum target_state prev_target_state = target->state;
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
        struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
@@ -476,23 +541,30 @@ static int cortex_m3_poll(struct target *target)
 
        /* Recover from lockup.  See ARMv7-M architecture spec,
         * section B1.5.15 "Unrecoverable exception cases".
 
        /* Recover from lockup.  See ARMv7-M architecture spec,
         * section B1.5.15 "Unrecoverable exception cases".
-        *
-        * REVISIT Is there a better way to report and handle this?
         */
        if (cortex_m3->dcb_dhcsr & S_LOCKUP) {
         */
        if (cortex_m3->dcb_dhcsr & S_LOCKUP) {
-               LOG_WARNING("%s -- clearing lockup after double fault",
+               LOG_ERROR("%s -- clearing lockup after double fault",
                                target_name(target));
                cortex_m3_write_debug_halt_mask(target, C_HALT, 0);
                target->debug_reason = DBG_REASON_DBGRQ;
 
                                target_name(target));
                cortex_m3_write_debug_halt_mask(target, C_HALT, 0);
                target->debug_reason = DBG_REASON_DBGRQ;
 
+               /* We have to execute the rest (the "finally" equivalent, but
+                * still throw this exception again).
+                */
+               detected_failure = ERROR_FAIL;
+
                /* refresh status bits */
                /* refresh status bits */
-               mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
+               retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
+               if (retval != ERROR_OK)
+                       return retval;
        }
 
        if (cortex_m3->dcb_dhcsr & S_RESET_ST)
        {
                /* check if still in reset */
        }
 
        if (cortex_m3->dcb_dhcsr & S_RESET_ST)
        {
                /* check if still in reset */
-               mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
+               retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
+               if (retval != ERROR_OK)
+                       return retval;
 
                if (cortex_m3->dcb_dhcsr & S_RESET_ST)
                {
 
                if (cortex_m3->dcb_dhcsr & S_RESET_ST)
                {
@@ -547,11 +619,14 @@ static int cortex_m3_poll(struct target *target)
                if (cortex_m3->dcb_dhcsr & S_RETIRE_ST)
                {
                        target->state = TARGET_RUNNING;
                if (cortex_m3->dcb_dhcsr & S_RETIRE_ST)
                {
                        target->state = TARGET_RUNNING;
-                       return ERROR_OK;
+                       retval = ERROR_OK;
                }
        }
 
                }
        }
 
-       return ERROR_OK;
+       /* Did we detect a failure condition that we cleared? */
+       if (detected_failure != ERROR_OK)
+               retval = detected_failure;
+       return retval;
 }
 
 static int cortex_m3_halt(struct target *target)
 }
 
 static int cortex_m3_halt(struct target *target)
@@ -604,12 +679,16 @@ static int cortex_m3_soft_reset_halt(struct target *target)
        int retval, timeout = 0;
 
        /* Enter debug state on reset; restore DEMCR in endreset_event() */
        int retval, timeout = 0;
 
        /* Enter debug state on reset; restore DEMCR in endreset_event() */
-       mem_ap_write_u32(swjdp, DCB_DEMCR,
+       retval = mem_ap_write_u32(swjdp, DCB_DEMCR,
                        TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
                        TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* Request a core-only reset */
 
        /* Request a core-only reset */
-       mem_ap_write_atomic_u32(swjdp, NVIC_AIRCR,
+       retval = mem_ap_write_atomic_u32(swjdp, NVIC_AIRCR,
                        AIRCR_VECTKEY | AIRCR_VECTRESET);
                        AIRCR_VECTKEY | AIRCR_VECTRESET);
+       if (retval != ERROR_OK)
+               return retval;
        target->state = TARGET_RESET;
 
        /* registers are now invalid */
        target->state = TARGET_RESET;
 
        /* registers are now invalid */
@@ -620,8 +699,10 @@ static int cortex_m3_soft_reset_halt(struct target *target)
                retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &dcb_dhcsr);
                if (retval == ERROR_OK)
                {
                retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &dcb_dhcsr);
                if (retval == ERROR_OK)
                {
-                       mem_ap_read_atomic_u32(swjdp, NVIC_DFSR,
+                       retval = mem_ap_read_atomic_u32(swjdp, NVIC_DFSR,
                                        &cortex_m3->nvic_dfsr);
                                        &cortex_m3->nvic_dfsr);
+                       if (retval != ERROR_OK)
+                               return retval;
                        if ((dcb_dhcsr & S_HALT)
                                        && (cortex_m3->nvic_dfsr & DFSR_VCATCH))
                        {
                        if ((dcb_dhcsr & S_HALT)
                                        && (cortex_m3->nvic_dfsr & DFSR_VCATCH))
                        {
@@ -788,10 +869,11 @@ static int cortex_m3_step(struct target *target, int current,
        if (!current)
                buf_set_u32(pc->value, 0, 32, address);
 
        if (!current)
                buf_set_u32(pc->value, 0, 32, address);
 
+       uint32_t pc_value = buf_get_u32(pc->value, 0, 32);
+
        /* the front-end may request us not to handle breakpoints */
        if (handle_breakpoints) {
        /* the front-end may request us not to handle breakpoints */
        if (handle_breakpoints) {
-               breakpoint = breakpoint_find(target,
-                               buf_get_u32(pc->value, 0, 32));
+               breakpoint = breakpoint_find(target, pc_value);
                if (breakpoint)
                        cortex_m3_unset_breakpoint(target, breakpoint);
        }
                if (breakpoint)
                        cortex_m3_unset_breakpoint(target, breakpoint);
        }
@@ -813,7 +895,10 @@ static int cortex_m3_step(struct target *target, int current,
                cortex_m3_write_debug_halt_mask(target, C_STEP, C_HALT);
        }
 
                cortex_m3_write_debug_halt_mask(target, C_STEP, C_HALT);
        }
 
-       mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
+       int retval;
+       retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* registers are now invalid */
        register_cache_invalidate(cortex_m3->armv7m.core_cache);
 
        /* registers are now invalid */
        register_cache_invalidate(cortex_m3->armv7m.core_cache);
@@ -825,7 +910,6 @@ static int cortex_m3_step(struct target *target, int current,
                        " nvic_icsr = 0x%" PRIx32,
                        cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr);
 
                        " nvic_icsr = 0x%" PRIx32,
                        cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr);
 
-       int retval;
        retval = cortex_m3_debug_entry(target);
        if (retval != ERROR_OK)
                return retval;
        retval = cortex_m3_debug_entry(target);
        if (retval != ERROR_OK)
                return retval;
@@ -842,34 +926,49 @@ static int cortex_m3_assert_reset(struct target *target)
 {
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
        struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
 {
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
        struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
-       int assert_srst = 1;
+       enum cortex_m3_soft_reset_config reset_config = cortex_m3->soft_reset_config;
 
        LOG_DEBUG("target->state: %s",
                target_state_name(target));
 
        enum reset_types jtag_reset_config = jtag_get_reset_config();
 
 
        LOG_DEBUG("target->state: %s",
                target_state_name(target));
 
        enum reset_types jtag_reset_config = jtag_get_reset_config();
 
-       /*
-        * We can reset Cortex-M3 targets using just the NVIC without
-        * requiring SRST, getting a SoC reset (or a core-only reset)
-        * instead of a system reset.
-        */
-       if (!(jtag_reset_config & RESET_HAS_SRST))
-               assert_srst = 0;
+       if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT)) {
+               /* allow scripts to override the reset event */
+
+               target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
+               register_cache_invalidate(cortex_m3->armv7m.core_cache);
+               target->state = TARGET_RESET;
+
+               return ERROR_OK;
+       }
 
        /* Enable debug requests */
 
        /* Enable debug requests */
-       mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
+       int retval;
+       retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
+       if (retval != ERROR_OK)
+               return retval;
        if (!(cortex_m3->dcb_dhcsr & C_DEBUGEN))
        if (!(cortex_m3->dcb_dhcsr & C_DEBUGEN))
-               mem_ap_write_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN);
+       {
+               retval = mem_ap_write_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN);
+               if (retval != ERROR_OK)
+                       return retval;
+       }
 
 
-       mem_ap_write_u32(swjdp, DCB_DCRDR, 0);
+       retval = mem_ap_write_u32(swjdp, DCB_DCRDR, 0);
+       if (retval != ERROR_OK)
+               return retval;
 
        if (!target->reset_halt)
        {
                /* Set/Clear C_MASKINTS in a separate operation */
                if (cortex_m3->dcb_dhcsr & C_MASKINTS)
 
        if (!target->reset_halt)
        {
                /* Set/Clear C_MASKINTS in a separate operation */
                if (cortex_m3->dcb_dhcsr & C_MASKINTS)
-                       mem_ap_write_atomic_u32(swjdp, DCB_DHCSR,
+               {
+                       retval = mem_ap_write_atomic_u32(swjdp, DCB_DHCSR,
                                        DBGKEY | C_DEBUGEN | C_HALT);
                                        DBGKEY | C_DEBUGEN | C_HALT);
+                       if (retval != ERROR_OK)
+                               return retval;
+               }
 
                /* clear any debug flags before resuming */
                cortex_m3_clear_halt(target);
 
                /* clear any debug flags before resuming */
                cortex_m3_clear_halt(target);
@@ -885,53 +984,13 @@ static int cortex_m3_assert_reset(struct target *target)
                 * bad vector table entries.  Should this include MMERR or
                 * other flags too?
                 */
                 * bad vector table entries.  Should this include MMERR or
                 * other flags too?
                 */
-               mem_ap_write_atomic_u32(swjdp, DCB_DEMCR,
+               retval = mem_ap_write_atomic_u32(swjdp, DCB_DEMCR,
                                TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
                                TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
+               if (retval != ERROR_OK)
+                       return retval;
        }
 
        }
 
-       /*
-        * When nRST is asserted on most Stellaris devices, it clears some of
-        * the debug state.  The ARMv7M and Cortex-M3 TRMs say that's wrong;
-        * and OpenOCD depends on those TRMs.  So we won't use SRST on those
-        * chips.  (Only power-on reset should affect debug state, beyond a
-        * few specified bits; not the chip's nRST input, wired to SRST.)
-        *
-        * REVISIT current errata specs don't seem to cover this issue.
-        * Do we have more details than this email?
-        *   https://lists.berlios.de/pipermail
-        *      /openocd-development/2008-August/003065.html
-        */
-       if (strcmp(target->variant, "lm3s") == 0)
-       {
-               /* Check for silicon revisions with the issue. */
-               uint32_t did0;
-
-               if (target_read_u32(target, 0x400fe000, &did0) == ERROR_OK)
-               {
-                       switch ((did0 >> 16) & 0xff)
-                       {
-                               case 0:
-                                       /* all Sandstorm suffer issue */
-                                       assert_srst = 0;
-                                       break;
-
-                               case 1:
-                               case 3:
-                                       /* Fury and DustDevil rev A have
-                                        * this nRST problem.  It should
-                                        * be fixed in rev B silicon.
-                                        */
-                                       if (((did0 >> 8) & 0xff) == 0)
-                                               assert_srst = 0;
-                                       break;
-                               case 4:
-                                       /* Tempest should be fine. */
-                                       break;
-                       }
-               }
-       }
-
-       if (assert_srst)
+       if (jtag_reset_config & RESET_HAS_SRST)
        {
                /* default to asserting srst */
                if (jtag_reset_config & RESET_SRST_PULLS_TRST)
        {
                /* default to asserting srst */
                if (jtag_reset_config & RESET_SRST_PULLS_TRST)
@@ -946,13 +1005,23 @@ static int cortex_m3_assert_reset(struct target *target)
        else
        {
                /* Use a standard Cortex-M3 software reset mechanism.
        else
        {
                /* Use a standard Cortex-M3 software reset mechanism.
-                * SYSRESETREQ will reset SoC peripherals outside the
-                * core, like watchdog timers, if the SoC wires it up
-                * correctly.  Else VECRESET can reset just the core.
+                * We default to using VECRESET as it is supported on all current cores.
+                * This has the disadvantage of not resetting the peripherals, so a
+                * reset-init event handler is needed to perform any peripheral resets.
                 */
                 */
-               mem_ap_write_atomic_u32(swjdp, NVIC_AIRCR,
-                               AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
-               LOG_DEBUG("Using Cortex-M3 SYSRESETREQ");
+               retval = mem_ap_write_atomic_u32(swjdp, NVIC_AIRCR,
+                               AIRCR_VECTKEY | ((reset_config == CORTEX_M3_RESET_SYSRESETREQ)
+                               ? AIRCR_SYSRESETREQ : AIRCR_VECTRESET));
+               if (retval != ERROR_OK)
+                       return retval;
+
+               LOG_DEBUG("Using Cortex-M3 %s", (reset_config == CORTEX_M3_RESET_SYSRESETREQ)
+                               ? "SYSRESETREQ" : "VECTRESET");
+
+               if (reset_config == CORTEX_M3_RESET_VECTRESET) {
+                       LOG_WARNING("Only resetting the Cortex-M3 core, use a reset-init event "
+                                       "handler to reset any peripherals");
+               }
 
                {
                        /* I do not know why this is necessary, but it
 
                {
                        /* I do not know why this is necessary, but it
@@ -960,7 +1029,9 @@ static int cortex_m3_assert_reset(struct target *target)
                         * after reset) on LM3S6918 -- Michael Schwingen
                         */
                        uint32_t tmp;
                         * after reset) on LM3S6918 -- Michael Schwingen
                         */
                        uint32_t tmp;
-                       mem_ap_read_atomic_u32(swjdp, NVIC_AIRCR, &tmp);
+                       retval = mem_ap_read_atomic_u32(swjdp, NVIC_AIRCR, &tmp);
+                       if (retval != ERROR_OK)
+                               return retval;
                }
        }
 
                }
        }
 
@@ -971,7 +1042,6 @@ static int cortex_m3_assert_reset(struct target *target)
 
        if (target->reset_halt)
        {
 
        if (target->reset_halt)
        {
-               int retval;
                if ((retval = target_halt(target)) != ERROR_OK)
                        return retval;
        }
                if ((retval = target_halt(target)) != ERROR_OK)
                        return retval;
        }
@@ -1007,7 +1077,7 @@ cortex_m3_set_breakpoint(struct target *target, struct breakpoint *breakpoint)
 
        if (cortex_m3->auto_bp_type)
        {
 
        if (cortex_m3->auto_bp_type)
        {
-               breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
+               breakpoint->type = BKPT_TYPE_BY_ADDR(breakpoint->address);
        }
 
        if (breakpoint->type == BKPT_HARD)
        }
 
        if (breakpoint->type == BKPT_HARD)
@@ -1127,7 +1197,7 @@ cortex_m3_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
 
        if (cortex_m3->auto_bp_type)
        {
 
        if (cortex_m3->auto_bp_type)
        {
-               breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
+               breakpoint->type = BKPT_TYPE_BY_ADDR(breakpoint->address);
 #ifdef ARMV7_GDB_HACKS
                if (breakpoint->length != 2) {
                        /* XXX Hack: Replace all breakpoints with length != 2 with
 #ifdef ARMV7_GDB_HACKS
                if (breakpoint->length != 2) {
                        /* XXX Hack: Replace all breakpoints with length != 2 with
@@ -1138,16 +1208,18 @@ cortex_m3_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
 #endif
        }
 
 #endif
        }
 
-       if ((breakpoint->type == BKPT_HARD) && (breakpoint->address >= 0x20000000))
-       {
-               LOG_INFO("flash patch comparator requested outside code memory region");
-               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
-       }
+       if(breakpoint->type != BKPT_TYPE_BY_ADDR(breakpoint->address)) {
+               if (breakpoint->type == BKPT_HARD)
+               {
+                       LOG_INFO("flash patch comparator requested outside code memory region");
+                       return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+               }
 
 
-       if ((breakpoint->type == BKPT_SOFT) && (breakpoint->address < 0x20000000))
-       {
-               LOG_INFO("soft breakpoint requested in code (flash) memory region");
-               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+               if (breakpoint->type == BKPT_SOFT)
+               {
+                       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))
        }
 
        if ((breakpoint->type == BKPT_HARD) && (cortex_m3->fp_code_available < 1))
@@ -1164,9 +1236,8 @@ cortex_m3_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
 
        if (breakpoint->type == BKPT_HARD)
                cortex_m3->fp_code_available--;
 
        if (breakpoint->type == BKPT_HARD)
                cortex_m3->fp_code_available--;
-       cortex_m3_set_breakpoint(target, breakpoint);
 
 
-       return ERROR_OK;
+       return cortex_m3_set_breakpoint(target, breakpoint);
 }
 
 static int
 }
 
 static int
@@ -1183,7 +1254,7 @@ cortex_m3_remove_breakpoint(struct target *target, struct breakpoint *breakpoint
 
        if (cortex_m3->auto_bp_type)
        {
 
        if (cortex_m3->auto_bp_type)
        {
-               breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
+               breakpoint->type = BKPT_TYPE_BY_ADDR(breakpoint->address);
        }
 
        if (breakpoint->set)
        }
 
        if (breakpoint->set)
@@ -1480,7 +1551,7 @@ static int cortex_m3_store_core_reg_u32(struct target *target,
                {
                        struct reg *r;
 
                {
                        struct reg *r;
 
-                       LOG_ERROR("JTAG failure %i", retval);
+                       LOG_ERROR("JTAG failure");
                        r = armv7m->core_cache->reg_list + num;
                        r->dirty = r->valid;
                        return ERROR_JTAG_DEVICE_ERROR;
                        r = armv7m->core_cache->reg_list + num;
                        r->dirty = r->valid;
                        return ERROR_JTAG_DEVICE_ERROR;
@@ -1555,7 +1626,7 @@ static int cortex_m3_read_memory(struct target *target, uint32_t address,
 }
 
 static int cortex_m3_write_memory(struct target *target, uint32_t address,
 }
 
 static int cortex_m3_write_memory(struct target *target, uint32_t address,
-               uint32_t size, uint32_t count, uint8_t *buffer)
+               uint32_t size, uint32_t count, const uint8_t *buffer)
 {
        struct armv7m_common *armv7m = target_to_armv7m(target);
        struct adiv5_dap *swjdp = &armv7m->dap;
 {
        struct armv7m_common *armv7m = target_to_armv7m(target);
        struct adiv5_dap *swjdp = &armv7m->dap;
@@ -1579,7 +1650,7 @@ static int cortex_m3_write_memory(struct target *target, uint32_t address,
 }
 
 static int cortex_m3_bulk_write_memory(struct target *target, uint32_t address,
 }
 
 static int cortex_m3_bulk_write_memory(struct target *target, uint32_t address,
-               uint32_t count, uint8_t *buffer)
+               uint32_t count, const uint8_t *buffer)
 {
        return cortex_m3_write_memory(target, address, 4, count, buffer);
 }
 {
        return cortex_m3_write_memory(target, address, 4, count, buffer);
 }
@@ -1791,6 +1862,7 @@ static int cortex_m3_examine(struct target *target)
 static int cortex_m3_dcc_read(struct adiv5_dap *swjdp, uint8_t *value, uint8_t *ctrl)
 {
        uint16_t dcrdr;
 static int cortex_m3_dcc_read(struct adiv5_dap *swjdp, uint8_t *value, uint8_t *ctrl)
 {
        uint16_t dcrdr;
+       int retval;
 
        mem_ap_read_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
        *ctrl = (uint8_t)dcrdr;
 
        mem_ap_read_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
        *ctrl = (uint8_t)dcrdr;
@@ -1803,7 +1875,9 @@ static int cortex_m3_dcc_read(struct adiv5_dap *swjdp, uint8_t *value, uint8_t *
        if (dcrdr & (1 << 0))
        {
                dcrdr = 0;
        if (dcrdr & (1 << 0))
        {
                dcrdr = 0;
-               mem_ap_write_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
+               retval = mem_ap_write_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
+               if (retval != ERROR_OK)
+                       return retval;
        }
 
        return ERROR_OK;
        }
 
        return ERROR_OK;
@@ -1877,6 +1951,10 @@ static int cortex_m3_init_arch_info(struct target *target,
        cortex_m3->jtag_info.tap = tap;
        cortex_m3->jtag_info.scann_size = 4;
 
        cortex_m3->jtag_info.tap = tap;
        cortex_m3->jtag_info.scann_size = 4;
 
+       /* default reset mode is to use srst if fitted
+        * if not it will use CORTEX_M3_RESET_VECTRESET */
+       cortex_m3->soft_reset_config = CORTEX_M3_RESET_VECTRESET;
+
        armv7m->arm.dap = &armv7m->dap;
 
        /* Leave (only) generic DAP stuff for debugport_init(); */
        armv7m->arm.dap = &armv7m->dap;
 
        /* Leave (only) generic DAP stuff for debugport_init(); */
@@ -1960,7 +2038,9 @@ COMMAND_HANDLER(handle_cortex_m3_vector_catch_command)
        if (retval != ERROR_OK)
                return retval;
 
        if (retval != ERROR_OK)
                return retval;
 
-       mem_ap_read_atomic_u32(swjdp, DCB_DEMCR, &demcr);
+       retval = mem_ap_read_atomic_u32(swjdp, DCB_DEMCR, &demcr);
+       if (retval != ERROR_OK)
+               return retval;
 
        if (CMD_ARGC > 0) {
                unsigned catch = 0;
 
        if (CMD_ARGC > 0) {
                unsigned catch = 0;
@@ -1996,8 +2076,12 @@ write:
                demcr |= catch;
 
                /* write, but don't assume it stuck (why not??) */
                demcr |= catch;
 
                /* write, but don't assume it stuck (why not??) */
-               mem_ap_write_u32(swjdp, DCB_DEMCR, demcr);
-               mem_ap_read_atomic_u32(swjdp, DCB_DEMCR, &demcr);
+               retval = mem_ap_write_u32(swjdp, DCB_DEMCR, demcr);
+               if (retval != ERROR_OK)
+                       return retval;
+               retval = mem_ap_read_atomic_u32(swjdp, DCB_DEMCR, &demcr);
+               if (retval != ERROR_OK)
+                       return retval;
 
                /* FIXME be sure to clear DEMCR on clean server shutdown.
                 * Otherwise the vector catch hardware could fire when there's
 
                /* FIXME be sure to clear DEMCR on clean server shutdown.
                 * Otherwise the vector catch hardware could fire when there's
@@ -2045,6 +2129,45 @@ COMMAND_HANDLER(handle_cortex_m3_mask_interrupts_command)
        return ERROR_OK;
 }
 
        return ERROR_OK;
 }
 
+COMMAND_HANDLER(handle_cortex_m3_reset_config_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+       struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
+       int retval;
+       char *reset_config;
+
+       retval = cortex_m3_verify_pointer(CMD_CTX, cortex_m3);
+       if (retval != ERROR_OK)
+               return retval;
+
+       if (CMD_ARGC > 0)
+       {
+               if (strcmp(*CMD_ARGV, "sysresetreq") == 0)
+                       cortex_m3->soft_reset_config = CORTEX_M3_RESET_SYSRESETREQ;
+               else if (strcmp(*CMD_ARGV, "vectreset") == 0)
+                       cortex_m3->soft_reset_config = CORTEX_M3_RESET_VECTRESET;
+       }
+
+       switch (cortex_m3->soft_reset_config)
+       {
+               case CORTEX_M3_RESET_SYSRESETREQ:
+                       reset_config = "sysresetreq";
+                       break;
+
+               case CORTEX_M3_RESET_VECTRESET:
+                       reset_config = "vectreset";
+                       break;
+
+               default:
+                       reset_config = "unknown";
+                       break;
+       }
+
+       command_print(CMD_CTX, "cortex_m3 reset_config %s", reset_config);
+
+       return ERROR_OK;
+}
+
 static const struct command_registration cortex_m3_exec_command_handlers[] = {
        {
                .name = "maskisr",
 static const struct command_registration cortex_m3_exec_command_handlers[] = {
        {
                .name = "maskisr",
@@ -2060,6 +2183,13 @@ static const struct command_registration cortex_m3_exec_command_handlers[] = {
                .help = "configure hardware vectors to trigger debug entry",
                .usage = "['all'|'none'|('bus_err'|'chk_err'|...)*]",
        },
                .help = "configure hardware vectors to trigger debug entry",
                .usage = "['all'|'none'|('bus_err'|'chk_err'|...)*]",
        },
+       {
+               .name = "reset_config",
+               .handler = handle_cortex_m3_reset_config_command,
+               .mode = COMMAND_ANY,
+               .help = "configure software reset handling",
+               .usage = "['srst'|'sysresetreq'|'vectreset']",
+       },
        COMMAND_REGISTRATION_DONE
 };
 static const struct command_registration cortex_m3_command_handlers[] = {
        COMMAND_REGISTRATION_DONE
 };
 static const struct command_registration cortex_m3_command_handlers[] = {

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)