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:
Tomas Vanek 2016-07-27 16:50:25 +02:00 committed by Andreas Fritiofson
parent 607edefb53
commit 7d2ad65c64
2 changed files with 17 additions and 7 deletions

View File

@ -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;

View File

@ -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 */
}