Harden cortexm_reset() and remove double reset(#601)
Thanks to Dave Marples <dave@marples.net> for input. - Issue only one reset. Start with SRST. Only if not seen, use SYSRESETREQ - Wait for release of DHCSR_S_RESET_ST before issuing more commands - Add timeout to catch reset line stuck low - Remove AP errors
This commit is contained in:
parent
bc84d803ea
commit
effd43ce38
|
@ -598,36 +598,43 @@ static void cortexm_pc_write(target *t, const uint32_t val)
|
|||
* using the core debug registers in the NVIC. */
|
||||
static void cortexm_reset(target *t)
|
||||
{
|
||||
/* Read DHCSR here to clear S_RESET_ST bit before reset */
|
||||
target_mem_read32(t, CORTEXM_DHCSR);
|
||||
platform_timeout to;
|
||||
if ((t->target_options & CORTEXM_TOPT_INHIBIT_SRST) == 0) {
|
||||
platform_srst_set_val(true);
|
||||
platform_srst_set_val(false);
|
||||
/* Some NRF52840 users saw invalid SWD transaction with
|
||||
* native/firmware without this delay.*/
|
||||
platform_delay(10);
|
||||
}
|
||||
uint32_t dhcsr = target_mem_read32(t, CORTEXM_DHCSR);
|
||||
if ((dhcsr & CORTEXM_DHCSR_S_RESET_ST) == 0) {
|
||||
/* No reset seen yet, maybe as SRST is not connected, or device has
|
||||
* CORTEXM_TOPT_INHIBIT_SRST set.
|
||||
* Trigger reset by AIRCR.*/
|
||||
target_mem_write32(t, CORTEXM_AIRCR,
|
||||
CORTEXM_AIRCR_VECTKEY | CORTEXM_AIRCR_SYSRESETREQ);
|
||||
}
|
||||
|
||||
/* Read DHCSR here to clear S_RESET_ST bit before reset */
|
||||
target_mem_read32(t, CORTEXM_DHCSR);
|
||||
|
||||
/* Request system reset from NVIC: SRST doesn't work correctly */
|
||||
/* This could be VECTRESET: 0x05FA0001 (reset only core)
|
||||
* or SYSRESETREQ: 0x05FA0004 (system reset)
|
||||
*/
|
||||
target_mem_write32(t, CORTEXM_AIRCR,
|
||||
CORTEXM_AIRCR_VECTKEY | CORTEXM_AIRCR_SYSRESETREQ);
|
||||
|
||||
/* If target needs to do something extra (see Atmel SAM4L for example) */
|
||||
if (t->extended_reset != NULL) {
|
||||
t->extended_reset(t);
|
||||
}
|
||||
|
||||
/* Poll for release from reset */
|
||||
while (target_mem_read32(t, CORTEXM_DHCSR) & CORTEXM_DHCSR_S_RESET_ST);
|
||||
|
||||
/* Wait for CORTEXM_DHCSR_S_RESET_ST to read 0, meaning reset released.*/
|
||||
platform_timeout_set(&to, 1000);
|
||||
while ((target_mem_read32(t, CORTEXM_DHCSR) & CORTEXM_DHCSR_S_RESET_ST) &&
|
||||
!platform_timeout_is_expired(&to));
|
||||
#if defined(PLATFORM_HAS_DEBUG)
|
||||
if (platform_timeout_is_expired(&to))
|
||||
DEBUG("Reset seem to be stuck low!\n");
|
||||
#endif
|
||||
/* 10 ms delay to ensure that things such as the STM32 HSI clock
|
||||
* have started up fully. */
|
||||
platform_delay(10);
|
||||
/* Reset DFSR flags */
|
||||
target_mem_write32(t, CORTEXM_DFSR, CORTEXM_DFSR_RESETALL);
|
||||
|
||||
/* 1ms delay to ensure that things such as the stm32f1 HSI clock have started
|
||||
* up fully.
|
||||
*/
|
||||
platform_delay(1);
|
||||
/* Make sure we ignore any initial DAP error */
|
||||
target_check_error(t);
|
||||
}
|
||||
|
||||
static void cortexm_halt_request(target *t)
|
||||
|
|
Loading…
Reference in New Issue