flash at91samd, at91sam4l: fix improper use of mem_ap_ call
Since merge of #3149 OpenOCD start with an unresponsive SAMD or SAM4L resulted in segfaults. First was in cortex_m_assert_reset (fixed by #3552), second was in samd_handle_reset_deassert() /sam4l_handle_reset_deassert(). The change replaces mem_ap_write_u32/8 by target_write_u32/8. It also takes better care about examining and polling target before debug control registers are set. It prevents lockup when 'reset halt' is issued on unresponsive cpu. Change-Id: I2516489f4771aebfc1118d174f527497b8a201ad Signed-off-by: Tomas Vanek <vanekt@fbl.cz> Reviewed-on: http://openocd.zylin.com/3603 Tested-by: jenkins Reviewed-by: Andreas Fritiofson <andreas.fritiofson@gmail.com>
This commit is contained in:
parent
607edefb53
commit
7d2ad65c64
|
@ -645,10 +645,15 @@ static int sam4l_write(struct flash_bank *bank, const uint8_t *buffer,
|
|||
COMMAND_HANDLER(sam4l_handle_reset_deassert)
|
||||
{
|
||||
struct target *target = get_current_target(CMD_CTX);
|
||||
struct armv7m_common *armv7m = target_to_armv7m(target);
|
||||
int retval = ERROR_OK;
|
||||
enum reset_types jtag_reset_config = jtag_get_reset_config();
|
||||
|
||||
/* If the target has been unresponsive before, try to re-establish
|
||||
* communication now - CPU is held in reset by DSU, DAP is working */
|
||||
if (!target_was_examined(target))
|
||||
target_examine_one(target);
|
||||
target_poll(target);
|
||||
|
||||
/* In case of sysresetreq, debug retains state set in cortex_m_assert_reset()
|
||||
* so we just release reset held by SMAP
|
||||
*
|
||||
|
@ -657,14 +662,14 @@ COMMAND_HANDLER(sam4l_handle_reset_deassert)
|
|||
* After vectreset SMAP release is not needed however makes no harm
|
||||
*/
|
||||
if (target->reset_halt && (jtag_reset_config & RESET_HAS_SRST)) {
|
||||
retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN);
|
||||
retval = target_write_u32(target, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN);
|
||||
if (retval == ERROR_OK)
|
||||
retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DEMCR,
|
||||
retval = target_write_u32(target, DCB_DEMCR,
|
||||
TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
|
||||
/* do not return on error here, releasing SMAP reset is more important */
|
||||
}
|
||||
|
||||
int retval2 = mem_ap_write_atomic_u32(armv7m->debug_ap, SMAP_SCR, SMAP_SCR_HCR);
|
||||
int retval2 = target_write_u32(target, SMAP_SCR, SMAP_SCR_HCR);
|
||||
if (retval2 != ERROR_OK)
|
||||
return retval2;
|
||||
|
||||
|
|
|
@ -1018,10 +1018,15 @@ COMMAND_HANDLER(samd_handle_bootloader_command)
|
|||
COMMAND_HANDLER(samd_handle_reset_deassert)
|
||||
{
|
||||
struct target *target = get_current_target(CMD_CTX);
|
||||
struct armv7m_common *armv7m = target_to_armv7m(target);
|
||||
int retval = ERROR_OK;
|
||||
enum reset_types jtag_reset_config = jtag_get_reset_config();
|
||||
|
||||
/* If the target has been unresponsive before, try to re-establish
|
||||
* communication now - CPU is held in reset by DSU, DAP is working */
|
||||
if (!target_was_examined(target))
|
||||
target_examine_one(target);
|
||||
target_poll(target);
|
||||
|
||||
/* In case of sysresetreq, debug retains state set in cortex_m_assert_reset()
|
||||
* so we just release reset held by DSU
|
||||
*
|
||||
|
@ -1030,9 +1035,9 @@ COMMAND_HANDLER(samd_handle_reset_deassert)
|
|||
* After vectreset DSU release is not needed however makes no harm
|
||||
*/
|
||||
if (target->reset_halt && (jtag_reset_config & RESET_HAS_SRST)) {
|
||||
retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN);
|
||||
retval = target_write_u32(target, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN);
|
||||
if (retval == ERROR_OK)
|
||||
retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DEMCR,
|
||||
retval = target_write_u32(target, DCB_DEMCR,
|
||||
TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
|
||||
/* do not return on error here, releasing DSU reset is more important */
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue