This is an automated email from Gerrit. Tomas Vanek ([email protected]) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/4862
-- gerrit commit 00bc2806aedc5cf05c1dad97ec49aaa5a8d54f3c Author: Tomas Vanek <[email protected]> Date: Sun Jan 20 20:03:44 2019 +0100 armv7m, cortex_m: fix debug execution if IT/ICI bits are set If a Cortex-M3, 4 or 7 target was stopped in the middle of IT block or in the load/store multiple instruction, target_resume() with debug_execution flag cleared only some IT/ICI bits and therefore service algo failed too. Clearing IT bits in cortex_m_debug_entry() cleared wrong bits and also made xPSR dirty if some IT bits was set - it prevented reliable external resume. Move all algo related initialization to armv7m_start_algorithm() and set all bits of xPSR: T=1, all others to zero. armv7m_start_algorithm() ensures registers are saved and restored later. The change may break flash/nor/ambiqmicro.c - the only flash driver which uses target_resume() with debug_execution flag instead of armv7m algo functions. Change-Id: I895abcf7ce029e4fea13e6630d9c527218768727 Signed-off-by: Tomas Vanek <[email protected]> diff --git a/src/target/armv7m.c b/src/target/armv7m.c index a1962fe..1a6e1b7 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -443,6 +443,24 @@ int armv7m_start_algorithm(struct target *target, /* save previous core mode */ armv7m_algorithm_info->core_mode = core_mode; + /* Disable interrupts */ + /* We disable interrupts in the PRIMASK register instead of + * masking with C_MASKINTS. This is probably the same issue + * as Cortex-M3 Erratum 377493 (fixed in r1p0): C_MASKINTS + * in parallel with disabled interrupts can cause local faults + * to not be taken. + */ + struct reg *reg = &armv7m->arm.core_cache->reg_list[ARMV7M_PRIMASK]; + buf_set_u32(reg->value, 0, 1, 1); + reg->dirty = true; + reg->valid = true; + + /* Make sure we start in Thumb mode and reset ICI/IT bits */ + reg = armv7m->arm.cpsr; + buf_set_u32(reg->value, 0, 32, 1ul << 24); + reg->dirty = true; + reg->valid = true; + retval = target_resume(target, 0, entry_point, 1, 1); return retval; diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 06e1c1c..776a8a0 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -427,12 +427,6 @@ static int cortex_m_debug_entry(struct target *target) r = arm->cpsr; xPSR = buf_get_u32(r->value, 0, 32); - /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */ - if (xPSR & 0xf00) { - r->dirty = r->valid; - cortex_m_store_core_reg_u32(target, 16, xPSR & ~0xff); - } - /* Are we in an exception handler */ if (xPSR & 0x1FF) { armv7m->exception_number = (xPSR & 0x1FF); @@ -704,31 +698,6 @@ static int cortex_m_resume(struct target *target, int current, cortex_m_enable_watchpoints(target); } - if (debug_execution) { - r = armv7m->arm.core_cache->reg_list + ARMV7M_PRIMASK; - - /* Disable interrupts */ - /* We disable interrupts in the PRIMASK register instead of - * masking with C_MASKINTS. This is probably the same issue - * as Cortex-M3 Erratum 377493 (fixed in r1p0): C_MASKINTS - * in parallel with disabled interrupts can cause local faults - * to not be taken. - * - * REVISIT this clearly breaks non-debug execution, since the - * PRIMASK register state isn't saved/restored... workaround - * by never resuming app code after debug execution. - */ - buf_set_u32(r->value, 0, 1, 1); - r->dirty = true; - r->valid = true; - - /* Make sure we are in Thumb mode */ - r = armv7m->arm.cpsr; - buf_set_u32(r->value, 24, 1, 1); - r->dirty = true; - r->valid = true; - } - /* current = 1: continue on current pc, otherwise continue at <address> */ r = armv7m->arm.pc; if (!current) { -- _______________________________________________ OpenOCD-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openocd-devel
