flash: add error messages upon incorrect arguments to flash iteration
[openocd.git] / src / target / cortex_m3.c
index 556928f826044954916fe21e45c46930fe82729c..48f811489f870929b396f31c0613d60d42268b7a 100644 (file)
@@ -42,6 +42,9 @@
 
 /* NOTE:  most of this should work fine for the Cortex-M1 and
  * Cortex-M0 cores too, although they're ARMv6-M not ARMv7-M.
+ * Some differences:  M0/M1 doesn't have FBP remapping or the
+ * DWT tracing/profiling support.  (So the cycle counter will
+ * not be usable; the other stuff isn't currently used here.)
  *
  * Although there are some workarounds for errata seen only in r0p0
  * silicon, such old parts are hard to find and thus not much tested
@@ -182,11 +185,12 @@ static int cortex_m3_endreset_event(struct target *target)
        int i;
        uint32_t dcb_demcr;
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
+       struct armv7m_common *armv7m = &cortex_m3->armv7m;
        struct swjdp_common *swjdp = &cortex_m3->armv7m.swjdp_info;
        struct cortex_m3_fp_comparator *fp_list = cortex_m3->fp_comparator_list;
        struct cortex_m3_dwt_comparator *dwt_list = cortex_m3->dwt_comparator_list;
 
-       /* FIXME handling of DEMCR clobbers vector_catch config ... */
+       /* REVISIT The four debug monitor bits are currently ignored... */
        mem_ap_read_atomic_u32(swjdp, DCB_DEMCR, &dcb_demcr);
        LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32 "",dcb_demcr);
 
@@ -201,21 +205,14 @@ static int cortex_m3_endreset_event(struct target *target)
        /* clear any interrupt masking */
        cortex_m3_write_debug_halt_mask(target, 0, C_MASKINTS);
 
-       /* Enable trace and DWT; trap hard and bus faults.
+       /* Enable features controlled by ITM and DWT blocks, and catch only
+        * the vectors we were told to pay attention to.
         *
-        * REVISIT why trap those two?  And why trash the vector_catch
-        * config, instead of preserving it?  Catching HARDERR and BUSERR
-        * will interfere with code that handles those itself...
+        * Target firmware is responsible for all fault handling policy
+        * 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 | VC_HARDERR | VC_BUSERR);
-
-       /* Monitor bus faults as such (instead of as generic HARDERR), but
-        * leave memory management and usage faults disabled.
-        *
-        * REVISIT setting BUSFAULTENA interferes with code which relies
-        * on the default setting.  Why do it?
-        */
-       mem_ap_write_u32(swjdp, NVIC_SHCSR, SHCSR_BUSFAULTENA);
+       mem_ap_write_u32(swjdp, DCB_DEMCR, TRCENA | armv7m->demcr);
 
        /* Paranoia: evidently some (early?) chips don't preserve all the
         * debug state (including FBP, DWT, etc) across reset...
@@ -530,7 +527,7 @@ static int cortex_m3_soft_reset_halt(struct target *target)
        uint32_t dcb_dhcsr = 0;
        int retval, timeout = 0;
 
-       /* Enter debug state on reset; see end_reset_event() */
+       /* Enter debug state on reset; restore DEMCR in endreset_event() */
        mem_ap_write_u32(swjdp, DCB_DEMCR,
                        TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
 
@@ -579,7 +576,7 @@ static void cortex_m3_enable_breakpoints(struct target *target)
        /* set any pending breakpoints */
        while (breakpoint)
        {
-               if (breakpoint->set == 0)
+               if (!breakpoint->set)
                        cortex_m3_set_breakpoint(target, breakpoint);
                breakpoint = breakpoint->next;
        }
@@ -779,14 +776,15 @@ static int cortex_m3_assert_reset(struct target *target)
 
                /* clear C_HALT in dhcsr reg */
                cortex_m3_write_debug_halt_mask(target, 0, C_HALT);
-
-               /* Enter debug state on reset, cf. end_reset_event() */
-               mem_ap_write_u32(swjdp, DCB_DEMCR,
-                               TRCENA | VC_HARDERR | VC_BUSERR);
        }
        else
        {
-               /* Enter debug state on reset, cf. end_reset_event() */
+               /* Halt in debug on reset; endreset_event() restores DEMCR.
+                *
+                * REVISIT catching BUSERR presumably helps to defend against
+                * bad vector table entries.  Should this include MMERR or
+                * other flags too?
+                */
                mem_ap_write_atomic_u32(swjdp, DCB_DEMCR,
                                TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
        }
@@ -936,16 +934,25 @@ cortex_m3_set_breakpoint(struct target *target, struct breakpoint *breakpoint)
        else if (breakpoint->type == BKPT_SOFT)
        {
                uint8_t code[4];
+
+               /* NOTE: on ARMv6-M and ARMv7-M, BKPT(0xab) is used for
+                * semihosting; don't use that.  Otherwise the BKPT
+                * parameter is arbitrary.
+                */
                buf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11));
-               if ((retval = target_read_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, breakpoint->orig_instr)) != ERROR_OK)
-               {
+               retval = target_read_memory(target,
+                               breakpoint->address & 0xFFFFFFFE,
+                               breakpoint->length, 1,
+                               breakpoint->orig_instr);
+               if (retval != ERROR_OK)
                        return retval;
-               }
-               if ((retval = target_write_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, code)) != ERROR_OK)
-               {
+               retval = target_write_memory(target,
+                               breakpoint->address & 0xFFFFFFFE,
+                               breakpoint->length, 1,
+                               code);
+               if (retval != ERROR_OK)
                        return retval;
-               }
-               breakpoint->set = 0x11; /* Any nice value but 0 */
+               breakpoint->set = true;
        }
 
        LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)",
@@ -1008,7 +1015,7 @@ cortex_m3_unset_breakpoint(struct target *target, struct breakpoint *breakpoint)
                        }
                }
        }
-       breakpoint->set = 0;
+       breakpoint->set = false;
 
        return ERROR_OK;
 }
@@ -1187,7 +1194,7 @@ cortex_m3_unset_watchpoint(struct target *target, struct watchpoint *watchpoint)
        target_write_u32(target, comparator->dwt_comparator_address + 8,
                        comparator->function);
 
-       watchpoint->set = 0;
+       watchpoint->set = false;
 
        return ERROR_OK;
 }
@@ -1273,7 +1280,7 @@ static void cortex_m3_enable_watchpoints(struct target *target)
        /* set any pending watchpoints */
        while (watchpoint)
        {
-               if (watchpoint->set == 0)
+               if (!watchpoint->set)
                        cortex_m3_set_watchpoint(target, watchpoint);
                watchpoint = watchpoint->next;
        }
@@ -1647,7 +1654,8 @@ static int cortex_m3_examine(struct target *target)
                        return retval;
 
                if (((cpuid >> 4) & 0xc3f) == 0xc23)
-                       LOG_DEBUG("CORTEX-M3 processor detected");
+                       LOG_DEBUG("Cortex-M3 r%dp%d processor detected",
+                               (cpuid >> 20) & 0xf, (cpuid >> 0) & 0xf);
                LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid);
 
                /* NOTE: FPB and DWT are both optional. */
@@ -1925,12 +1933,20 @@ COMMAND_HANDLER(handle_cortex_m3_vector_catch_command)
                        }
                }
 write:
+               /* For now, armv7m->demcr only stores vector catch flags. */
+               armv7m->demcr = catch;
+
                demcr &= ~0xffff;
                demcr |= catch;
 
-               /* write, but don't assume it stuck */
+               /* 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);
+
+               /* FIXME be sure to clear DEMCR on clean server shutdown.
+                * Otherwise the vector catch hardware could fire when there's
+                * no debugger hooked up, causing much confusion...
+                */
        }
 
        for (unsigned i = 0; i < ARRAY_SIZE(vec_ids); i++)
@@ -1976,24 +1992,24 @@ COMMAND_HANDLER(handle_cortex_m3_mask_interrupts_command)
 static const struct command_registration cortex_m3_exec_command_handlers[] = {
        {
                .name = "disassemble",
-               .handler = &handle_cortex_m3_disassemble_command,
+               .handler = handle_cortex_m3_disassemble_command,
                .mode = COMMAND_EXEC,
                .help = "disassemble Thumb2 instructions",
-               .usage = "<address> [<count>]",
+               .usage = "address [count]",
        },
        {
                .name = "maskisr",
-               .handler = &handle_cortex_m3_mask_interrupts_command,
+               .handler = handle_cortex_m3_mask_interrupts_command,
                .mode = COMMAND_EXEC,
                .help = "mask cortex_m3 interrupts",
                .usage = "['on'|'off']",
        },
        {
                .name = "vector_catch",
-               .handler = &handle_cortex_m3_vector_catch_command,
+               .handler = handle_cortex_m3_vector_catch_command,
                .mode = COMMAND_EXEC,
-               .help = "catch hardware vectors",
-               .usage = "['all'|'none'|<list>]",
+               .help = "configure hardware vectors to trigger debug entry",
+               .usage = "['all'|'none'|('bus_err'|'chk_err'|...)*]",
        },
        COMMAND_REGISTRATION_DONE
 };

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)