]> git.sur5r.net Git - openocd/blobdiff - src/target/cortex_m3.c
cortex_m3: add BKPT_TYPE_BY_ADDR define
[openocd] / src / target / cortex_m3.c
index 7f6cbafa522b3f2ccd062a933bfe9211e2932c50..9c3d2d9d691ffa9b13f1fd9bbbaa4518f5cc43c5 100644 (file)
  * 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);
@@ -68,16 +73,22 @@ 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 */
 
-       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); */
-       dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR & 0xFFFFFFF0);
+       retval = dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR & 0xFFFFFFF0);
+       if (retval != ERROR_OK)
+               return retval;
        retval = dap_queue_ap_write(swjdp, AP_REG_BD0 | (DCB_DCRSR & 0xC), regnum);
        if (retval != ERROR_OK)
                return retval;
 
        /* mem_ap_read_u32(swjdp, DCB_DCRDR, value); */
-       dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR & 0xFFFFFFF0);
+       retval = dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR & 0xFFFFFFF0);
+       if (retval != ERROR_OK)
+               return retval;
        retval = dap_queue_ap_read(swjdp, AP_REG_BD0 | (DCB_DCRDR & 0xC), value);
        if (retval != ERROR_OK)
                return retval;
@@ -103,15 +114,21 @@ 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 */
 
-       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]); */
-       dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR & 0xFFFFFFF0);
+       retval = dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR & 0xFFFFFFF0);
+       if (retval != ERROR_OK)
+               return retval;
        retval = dap_queue_ap_write(swjdp, AP_REG_BD0 | (DCB_DCRDR & 0xC), value);
        // XXX check retval
 
        /* mem_ap_write_u32(swjdp, DCB_DCRSR, i | DCRSR_WnR); */
-       dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR & 0xFFFFFFF0);
+       retval = dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR & 0xFFFFFFF0);
+       if (retval != ERROR_OK)
+               return retval;
        retval = dap_queue_ap_write(swjdp, AP_REG_BD0 | (DCB_DCRSR & 0xC), regnum | DCRSR_WnR);
        // XXX check retval
 
@@ -143,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;
+       int retval;
 
        /* 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 */
-       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;
@@ -162,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;
+       int retval;
 
        /* backup dhcsr reg */
        dhcsr_save = cortex_m3->dcb_dhcsr;
@@ -171,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))
-               mem_ap_write_atomic_u32(swjdp, DCB_DHCSR,
+       {
+               retval = mem_ap_write_atomic_u32(swjdp, DCB_DHCSR,
                                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);
+       if (retval != ERROR_OK)
+               return retval;
        LOG_DEBUG(" ");
 
        /* restore dhcsr reg */
@@ -196,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... */
-       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 */
-       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 */
-       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))
-               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);
@@ -217,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.
         */
-       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 */
-       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++)
        {
-               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++)
        {
-               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);
-               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);
-               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);
+               if (retval != ERROR_OK)
+                       return retval;
        }
        retval = dap_run(swjdp);
        if (retval != ERROR_OK)
@@ -250,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 */
-       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;
 }
@@ -289,33 +341,51 @@ static int cortex_m3_examine_exception_reason(struct target *target)
        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 */
-                       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)
                        {
-                               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 */
-                       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 */
-                       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 */
-                       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 */
-                       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;
@@ -366,7 +436,9 @@ static int cortex_m3_debug_entry(struct target *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;
@@ -442,14 +514,19 @@ static int cortex_m3_debug_entry(struct target *target)
                target_state_name(target));
 
        if (armv7m->post_debug_entry)
-               armv7m->post_debug_entry(target);
+       {
+               retval = armv7m->post_debug_entry(target);
+               if (retval != ERROR_OK)
+                       return retval;
+       }
 
        return ERROR_OK;
 }
 
 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;
@@ -464,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".
-        *
-        * REVISIT Is there a better way to report and handle this?
         */
        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;
 
+               /* We have to execute the rest (the "finally" equivalent, but
+                * still throw this exception again).
+                */
+               detected_failure = ERROR_FAIL;
+
                /* 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 */
-               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)
                {
@@ -535,11 +619,14 @@ static int cortex_m3_poll(struct target *target)
                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)
@@ -592,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() */
-       mem_ap_write_u32(swjdp, DCB_DEMCR,
+       retval = mem_ap_write_u32(swjdp, DCB_DEMCR,
                        TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* 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);
+       if (retval != ERROR_OK)
+               return retval;
        target->state = TARGET_RESET;
 
        /* registers are now invalid */
@@ -608,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)
                {
-                       mem_ap_read_atomic_u32(swjdp, NVIC_DFSR,
+                       retval = mem_ap_read_atomic_u32(swjdp, NVIC_DFSR,
                                        &cortex_m3->nvic_dfsr);
+                       if (retval != ERROR_OK)
+                               return retval;
                        if ((dcb_dhcsr & S_HALT)
                                        && (cortex_m3->nvic_dfsr & DFSR_VCATCH))
                        {
@@ -776,10 +869,11 @@ static int cortex_m3_step(struct target *target, int current,
        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) {
-               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);
        }
@@ -801,7 +895,10 @@ static int cortex_m3_step(struct target *target, int current,
                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);
@@ -813,7 +910,9 @@ static int cortex_m3_step(struct target *target, int current,
                        " nvic_icsr = 0x%" PRIx32,
                        cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr);
 
-       cortex_m3_debug_entry(target);
+       retval = cortex_m3_debug_entry(target);
+       if (retval != ERROR_OK)
+               return retval;
        target_call_event_callbacks(target, TARGET_EVENT_HALTED);
 
        LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
@@ -827,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;
-       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();
 
-       /*
-        * 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 */
-       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))
-               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)
-                       mem_ap_write_atomic_u32(swjdp, DCB_DHCSR,
+               {
+                       retval = mem_ap_write_atomic_u32(swjdp, DCB_DHCSR,
                                        DBGKEY | C_DEBUGEN | C_HALT);
+                       if (retval != ERROR_OK)
+                               return retval;
+               }
 
                /* clear any debug flags before resuming */
                cortex_m3_clear_halt(target);
@@ -870,53 +984,13 @@ static int cortex_m3_assert_reset(struct target *target)
                 * 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);
+               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)
@@ -931,13 +1005,23 @@ static int cortex_m3_assert_reset(struct target *target)
        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
@@ -945,7 +1029,9 @@ static int cortex_m3_assert_reset(struct target *target)
                         * 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;
                }
        }
 
@@ -956,7 +1042,6 @@ static int cortex_m3_assert_reset(struct target *target)
 
        if (target->reset_halt)
        {
-               int retval;
                if ((retval = target_halt(target)) != ERROR_OK)
                        return retval;
        }
@@ -992,7 +1077,7 @@ cortex_m3_set_breakpoint(struct target *target, struct breakpoint *breakpoint)
 
        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)
@@ -1112,7 +1197,7 @@ cortex_m3_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
 
        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
@@ -1123,16 +1208,18 @@ cortex_m3_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
 #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))
@@ -1149,9 +1236,8 @@ cortex_m3_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
 
        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
@@ -1168,7 +1254,7 @@ cortex_m3_remove_breakpoint(struct target *target, struct breakpoint *breakpoint
 
        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)
@@ -1465,7 +1551,7 @@ static int cortex_m3_store_core_reg_u32(struct target *target,
                {
                        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;
@@ -1540,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,
-               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;
@@ -1564,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,
-               uint32_t count, uint8_t *buffer)
+               uint32_t count, const uint8_t *buffer)
 {
        return cortex_m3_write_memory(target, address, 4, count, buffer);
 }
@@ -1776,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;
+       int retval;
 
        mem_ap_read_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
        *ctrl = (uint8_t)dcrdr;
@@ -1788,7 +1875,9 @@ static int cortex_m3_dcc_read(struct adiv5_dap *swjdp, uint8_t *value, uint8_t *
        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;
@@ -1862,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;
 
+       /* 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(); */
@@ -1945,7 +2038,9 @@ COMMAND_HANDLER(handle_cortex_m3_vector_catch_command)
        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;
@@ -1981,8 +2076,12 @@ write:
                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
@@ -2030,6 +2129,45 @@ COMMAND_HANDLER(handle_cortex_m3_mask_interrupts_command)
        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",
@@ -2045,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'|...)*]",
        },
+       {
+               .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[] = {