This updates three aspects of debugger/exception interactions:
- Save the user's "vector_catch" setting, and restore it after reset.
Previously, it was obliterated (rather annoyingly) each time.
- Don't catch BusFault and HardFault exceptions unless the user says
to do so. Target firmware may need to handle them.
- Don't modify SHCSR to prevent escalating BusFault to HardFault.
Target firmware may expect to handle it as a HardFault.
Those simplifications fix several bugs. In one annoying case, OpenOCD
would cause the target to lock up on ome faults which triggered after
the debugger disconnected.
NOTE: a known remaining issue is that OpenOCD can still leave DEMCR
set after an otherwise-clean OpenOCD shutdown.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
- watchpoint support
Cortex-M3
- Exposed DWT registers like cycle counter
- watchpoint support
Cortex-M3
- Exposed DWT registers like cycle counter
+ - vector_catch settings not clobbered by resets
+ - no longer interferes with firmware's fault handling
ETM, ETB
- "trigger_percent" command moved ETM --> ETB
- "etm trigger_debug" command added
ETM, ETB
- "trigger_percent" command moved ETM --> ETB
- "etm trigger_debug" command added
int exception_number;
struct swjdp_common swjdp_info;
int exception_number;
struct swjdp_common swjdp_info;
/* Direct processor core register read and writes */
/* Direct processor core register read and writes */
- int (*load_core_reg_u32)(struct target *target, enum armv7m_regtype type, uint32_t num, uint32_t *value);
- int (*store_core_reg_u32)(struct target *target, enum armv7m_regtype type, uint32_t num, uint32_t value);
+ int (*load_core_reg_u32)(struct target *target,
+ enum armv7m_regtype type, uint32_t num, uint32_t *value);
+ int (*store_core_reg_u32)(struct target *target,
+ enum armv7m_regtype type, uint32_t num, uint32_t value);
+
/* register cache to processor synchronization */
int (*read_core_reg)(struct target *target, unsigned num);
int (*write_core_reg)(struct target *target, unsigned num);
/* register cache to processor synchronization */
int (*read_core_reg)(struct target *target, unsigned num);
int (*write_core_reg)(struct target *target, unsigned num);
int i;
uint32_t dcb_demcr;
struct cortex_m3_common *cortex_m3 = target_to_cm3(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;
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);
mem_ap_read_atomic_u32(swjdp, DCB_DEMCR, &dcb_demcr);
LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32 "",dcb_demcr);
/* 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);
- /* 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...
/* Paranoia: evidently some (early?) chips don't preserve all the
* debug state (including FBP, DWT, etc) across reset...
uint32_t dcb_dhcsr = 0;
int retval, timeout = 0;
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);
mem_ap_write_u32(swjdp, DCB_DEMCR,
TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
/* clear C_HALT in dhcsr reg */
cortex_m3_write_debug_halt_mask(target, 0, C_HALT);
/* 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);
- /* 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);
}
mem_ap_write_atomic_u32(swjdp, DCB_DEMCR,
TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
}
+ /* For now, armv7m->demcr only stores vector catch flags. */
+ armv7m->demcr = catch;
+
demcr &= ~0xffff;
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);
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++)
}
for (unsigned i = 0; i < ARRAY_SIZE(vec_ids); i++)
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)