This is an automated email from Gerrit.

Antonio Borneo ([email protected]) just uploaded a new patch set to 
Gerrit, which you can find at http://openocd.zylin.com/6434

-- gerrit

commit ef9a7eee3da0791483ad0e482b3daeaa83aa3c2f
Author: Antonio Borneo <[email protected]>
Date:   Fri Aug 13 18:52:20 2021 +0200

    cortex_m: fix command 'step address'
    
    The command 'step' accepts an optional parameter 'address' to run
    the step-by-step execution from an address different from current
    program counter.
    When OpenOCD sets the new program counter value in the register
    cache, it doesn't flag it as dirty. The following call to function
    armv7m_restore_context() does not propagate the new value of the
    program counter to the target. This cause the target to continue
    from the old program counter value, ignoring the user's request.
    
    It is hard to notice the issue if the target is halted in an idle
    loop! In fact the default mode to operate step-by-step is to set a
    breakpoint to the following instruction and resume execution. In
    the idle loop the CPU will pass through the breakpoint whatever
    the resume address is. User will find the target halting at the
    instruction following 'address' which is consistent with the
    expected behaviour of command 'step address'.
    
    To verify the issue on an STM32F4, use a dummy code in SRAM:
        halt
        mww 0x20000000 0xbf00bf00
        mww 0x20000004 0xbf00bf00
        mww 0x20000008 0xe7fcbf00
        arm disassemble 0x20000000 6
                0x20000000  bf00    nop
                0x20000002  bf00    nop
                0x20000004  bf00    nop
           +--> 0x20000006  bf00    nop
           |    0x20000008  bf00    nop
           +-<- 0x2000000a  e7fc    b   #0x20000006
        resume 0x20000006
        halt
        step 0x20000000
    the target doesn't halt because it is in the loop from 0x20000006
    to 0x2000000a. The 'step 0x20000000' did not changed the program
    counter so the temporary breakpoint at 0x20000002 is never hit.
    Then:
        halt
        step 0x20000008
                target halted ...
                ... pc: 0x2000000a
    gives the feeling that only the instruction at 0x20000008 has been
    executed, but actually the whole loop has been executed from the
    place 'halt' stopped the execution till the breakpoint at the
    instruction following 0x20000008.
    
    Flag the program counter cached value as 'valid' and 'dirty' to
    force armv7m_restore_context() to update the target's register.
    
    Change-Id: I49bd8bb95b2f5429ec38ed016f2ad706618ae68a
    Signed-off-by: Antonio Borneo <[email protected]>

diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c
index 9f035a0..f3c8527 100644
--- a/src/target/cortex_m.c
+++ b/src/target/cortex_m.c
@@ -975,8 +975,11 @@ static int cortex_m_step(struct target *target, int 
current,
        }
 
        /* current = 1: continue on current pc, otherwise continue at <address> 
*/
-       if (!current)
+       if (!current) {
                buf_set_u32(pc->value, 0, 32, address);
+               pc->dirty = true;
+               pc->valid = true;
+       }
 
        uint32_t pc_value = buf_get_u32(pc->value, 0, 32);
 

-- 

Reply via email to