This is an automated email from Gerrit.

Antonio Borneo (borneo.anto...@gmail.com) just uploaded a new patch set to 
Gerrit, which you can find at http://openocd.zylin.com/4622

-- gerrit

commit 4117e8bc0558e33996c6642b0ec61f6b987c8c46
Author: Antonio Borneo <borneo.anto...@gmail.com>
Date:   Mon Jul 23 15:20:40 2018 +0200

    target/cortex_a: poll all targets in SMP node after halt
    
    The periodic poll scans all the targets in the same order they
    have been declared in the configuration file.
    When one target in a SMP node halts, the transition is detected
    in the following poll and this triggers a halt request to all the
    other cores of the SMP node.
    The targets that will be polled afterwards will be identified as
    "halted", but the targets already scanned will remain as
    "running" until the next periodic poll.
    This creates a race condition with GDB; GDB sets the breakpoints
    when runs the target and removes them as soon as the target is
    halted. When it receives the halt event, it starts removing the
    breakpoints and fails on the targets that are still reported as
    "running".
    
    Fixed by polling all the targets in the SMP node before informing
    GDB about the halt event.
    This implementation is almost copy/paste from the one in aarch64.
    
    Change-Id: Id2bd99f1e56b014e48e9e34ccb891b4219c518f8
    Signed-off-by: Antonio Borneo <borneo.anto...@gmail.com>

diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c
index e4d8331..08b6ef9 100644
--- a/src/target/cortex_a.c
+++ b/src/target/cortex_a.c
@@ -57,6 +57,9 @@
 #include "transport/transport.h"
 #include <helper/time_support.h>
 
+#define foreach_smp_target(pos, head) \
+       for (pos = head; (pos != NULL); pos = pos->next)
+
 static int cortex_a_poll(struct target *target);
 static int cortex_a_debug_entry(struct target *target);
 static int cortex_a_restore_context(struct target *target, bool bpwp);
@@ -806,12 +809,43 @@ static int cortex_a_halt_smp(struct target *target)
 
 static int update_halt_gdb(struct target *target)
 {
+       struct target *gdb_target = NULL;
+       struct target_list *head;
+       struct target *curr;
        int retval = 0;
+
        if (target->gdb_service && target->gdb_service->core[0] == -1) {
                target->gdb_service->target = target;
                target->gdb_service->core[0] = target->coreid;
                retval += cortex_a_halt_smp(target);
        }
+
+       if (target->gdb_service)
+               gdb_target = target->gdb_service->target;
+
+       foreach_smp_target(head, target->head) {
+               curr = head->target;
+               /* skip calling context */
+               if (curr == target)
+                       continue;
+               if (!target_was_examined(curr))
+                       continue;
+               /* skip targets that were already halted */
+               if (curr->state == TARGET_HALTED)
+                       continue;
+               /* Skip gdb_target; it alerts GDB so has to be polled as last 
one */
+               if (curr == gdb_target)
+                       continue;
+
+               /* avoid recursion in cortex_a_poll() */
+               curr->smp = 0;
+               cortex_a_poll(curr);
+               curr->smp = 1;
+       }
+
+       /* after all targets were updated, poll the gdb serving target */
+       if (gdb_target != NULL && gdb_target != target)
+               cortex_a_poll(gdb_target);
        return retval;
 }
 

-- 

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to