armv4_5: add algorithms instruction breakpoint support
[openocd.git] / src / target / cortex_m3.c
index d6090f55b98b90f46c7ed04b32623fc433bc4d79..2a58f5bf0d6201f801737acbb584d7665bb7b52e 100644 (file)
@@ -68,7 +68,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 */
 
-       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);
@@ -107,7 +109,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 */
 
-       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);
@@ -151,15 +155,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;
@@ -170,6 +179,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;
@@ -179,10 +189,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 */
@@ -204,16 +220,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);
@@ -225,31 +251,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)
@@ -258,7 +297,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;
 }
@@ -297,33 +336,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;
@@ -374,7 +431,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;
@@ -486,13 +545,17 @@ static int cortex_m3_poll(struct target *target)
                target->debug_reason = DBG_REASON_DBGRQ;
 
                /* 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)
                {
@@ -604,12 +667,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 */
@@ -620,8 +687,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))
                        {
@@ -813,7 +882,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);
@@ -825,7 +897,6 @@ static int cortex_m3_step(struct target *target, int current,
                        " 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;
@@ -858,18 +929,31 @@ static int cortex_m3_assert_reset(struct target *target)
                assert_srst = 0;
 
        /* 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);
@@ -885,8 +969,10 @@ 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;
        }
 
        /*
@@ -950,8 +1036,10 @@ static int cortex_m3_assert_reset(struct target *target)
                 * core, like watchdog timers, if the SoC wires it up
                 * correctly.  Else VECRESET can reset just the core.
                 */
-               mem_ap_write_atomic_u32(swjdp, NVIC_AIRCR,
+               retval = mem_ap_write_atomic_u32(swjdp, NVIC_AIRCR,
                                AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
+               if (retval != ERROR_OK)
+                       return retval;
                LOG_DEBUG("Using Cortex-M3 SYSRESETREQ");
 
                {
@@ -960,7 +1048,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;
                }
        }
 
@@ -971,7 +1061,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;
        }
@@ -1791,6 +1880,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;
@@ -1803,7 +1893,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;
@@ -1960,7 +2052,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;
@@ -1996,8 +2090,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

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)