]> git.gag.com Git - fw/openocd/commitdiff
target/smp: use a struct list_head to hold the smp targets
authorAntonio Borneo <borneo.antonio@gmail.com>
Thu, 16 Dec 2021 00:59:14 +0000 (01:59 +0100)
committerAntonio Borneo <borneo.antonio@gmail.com>
Mon, 14 Feb 2022 15:10:10 +0000 (15:10 +0000)
Instead of reinventing a simply linked list, reuse the list helper
for the list of targets in a smp cluster.
Using the existing helper, that implements a double linked list,
makes trivial going through the list in reverse order.

Change-Id: Ib36ad2955f15cd2a601b0b9e36ca6d948b12d00f
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/6783
Tested-by: jenkins
16 files changed:
src/rtos/hwthread.c
src/rtos/linux.c
src/server/gdb_server.c
src/target/aarch64.c
src/target/armv7a.c
src/target/armv7a_cache.c
src/target/armv7a_cache_l2x.c
src/target/armv8_cache.c
src/target/breakpoints.c
src/target/cortex_a.c
src/target/mips_m4k.c
src/target/riscv/riscv.c
src/target/smp.c
src/target/smp.h
src/target/target.c
src/target/target.h

index 3702b0b4762d6976ba548286ba4c62cc72580855..7c998861f7554408e882a18a1bc4b7a8bd77fa51 100644 (file)
@@ -23,6 +23,7 @@
 #include "target/target.h"
 #include "target/target_type.h"
 #include "target/register.h"
+#include <target/smp.h>
 #include "rtos.h"
 #include "helper/log.h"
 #include "helper/types.h"
@@ -107,7 +108,7 @@ static int hwthread_update_threads(struct rtos *rtos)
 
        /* determine the number of "threads" */
        if (target->smp) {
-               for (head = target->head; head; head = head->next) {
+               foreach_smp_target(head, target->smp_targets) {
                        struct target *curr = head->target;
 
                        if (!target_was_examined(curr))
@@ -123,7 +124,7 @@ static int hwthread_update_threads(struct rtos *rtos)
 
        if (target->smp) {
                /* loop over all threads */
-               for (head = target->head; head; head = head->next) {
+               foreach_smp_target(head, target->smp_targets) {
                        struct target *curr = head->target;
 
                        if (!target_was_examined(curr))
@@ -218,7 +219,8 @@ static struct target *hwthread_find_thread(struct target *target, int64_t thread
        if (!target)
                return NULL;
        if (target->smp) {
-               for (struct target_list *head = target->head; head; head = head->next) {
+               struct target_list *head;
+               foreach_smp_target(head, target->smp_targets) {
                        if (thread_id == threadid_from_target(head->target))
                                return head->target;
                }
index 84b4c6524d8abfd1e374fcf7001997cb05fc8326..d147c1cf0e97f4e6b8bdcac5ef764a14e842a38b 100644 (file)
@@ -30,6 +30,7 @@
 #include "rtos.h"
 #include "rtos_standard_stackings.h"
 #include <target/register.h>
+#include <target/smp.h>
 #include "server/gdb_server.h"
 
 #define LINUX_USER_KERNEL_BORDER 0xc0000000
@@ -191,16 +192,14 @@ static int linux_os_thread_reg_list(struct rtos *rtos,
        /*  search target to perform the access  */
        struct reg **gdb_reg_list;
        struct target_list *head;
-       head = target->head;
        found = 0;
-       do {
+       foreach_smp_target(head, target->smp_targets) {
                if (head->target->coreid == next->core_id) {
                        target = head->target;
                        found = 1;
                        break;
                }
-               head = head->next;
-       } while (head);
+       }
 
        if (found == 0) {
                LOG_ERROR
@@ -397,7 +396,6 @@ static int get_name(struct target *target, struct threads *t)
 static int get_current(struct target *target, int create)
 {
        struct target_list *head;
-       head = target->head;
        uint8_t *buf;
        uint32_t val;
        uint32_t ti_addr;
@@ -413,7 +411,7 @@ static int get_current(struct target *target, int create)
                ctt = ctt->next;
        }
 
-       while (head) {
+       foreach_smp_target(head, target->smp_targets) {
                struct reg **reg_list;
                int reg_list_size;
                int retval;
@@ -474,7 +472,6 @@ static int get_current(struct target *target, int create)
                }
 
                free(reg_list);
-               head = head->next;
        }
 
        free(buffer);
@@ -1394,9 +1391,8 @@ static int linux_os_smp_init(struct target *target)
        struct linux_os *os_linux =
                (struct linux_os *)rtos->rtos_specific_params;
        struct current_thread *ct;
-       head = target->head;
 
-       while (head) {
+       foreach_smp_target(head, target->smp_targets) {
                if (head->target->rtos != rtos) {
                        struct linux_os *smp_os_linux =
                                (struct linux_os *)head->target->rtos->rtos_specific_params;
@@ -1413,8 +1409,6 @@ static int linux_os_smp_init(struct target *target)
                        os_linux->nr_cpus++;
                        free(smp_os_linux);
                }
-
-               head = head->next;
        }
 
        return ERROR_OK;
index b6f4a82647a60cc07c8b81be525f1d04931a1cd9..537670c52f139a891d49e5740fef269ca851f4f7 100644 (file)
@@ -2280,7 +2280,7 @@ static int smp_reg_list_noread(struct target *target,
        *combined_list_size = 0;
 
        struct target_list *head;
-       foreach_smp_target(head, target->head) {
+       foreach_smp_target(head, target->smp_targets) {
                struct reg **reg_list = NULL;
                int reg_list_size;
                int result = target_get_gdb_reg_list_noread(head->target, &reg_list,
@@ -2330,7 +2330,7 @@ static int smp_reg_list_noread(struct target *target,
        }
 
        /* Now warn the user about any registers that weren't found in every target. */
-       foreach_smp_target(head, target->head) {
+       foreach_smp_target(head, target->smp_targets) {
                struct reg **reg_list = NULL;
                int reg_list_size;
                int result = target_get_gdb_reg_list_noread(head->target, &reg_list,
@@ -3659,13 +3659,10 @@ static int gdb_target_start(struct target *target, const char *port)
        /* initialize all targets gdb service with the same pointer */
        {
                struct target_list *head;
-               struct target *curr;
-               head = target->head;
-               while (head) {
-                       curr = head->target;
+               foreach_smp_target(head, target->smp_targets) {
+                       struct target *curr = head->target;
                        if (curr != target)
                                curr->gdb_service = gdb_service;
-                       head = head->next;
                }
        }
        return ret;
index d11fd943bd1b9354acb5cd2c880093a205f552b2..a45322d2f586e6725cc5b910f80f637279db807f 100644 (file)
@@ -333,15 +333,14 @@ static int aarch64_wait_halt_one(struct target *target)
 static int aarch64_prepare_halt_smp(struct target *target, bool exc_target, struct target **p_first)
 {
        int retval = ERROR_OK;
-       struct target_list *head = target->head;
+       struct target_list *head;
        struct target *first = NULL;
 
        LOG_DEBUG("target %s exc %i", target_name(target), exc_target);
 
-       while (head) {
+       foreach_smp_target(head, target->smp_targets) {
                struct target *curr = head->target;
                struct armv8_common *armv8 = target_to_armv8(curr);
-               head = head->next;
 
                if (exc_target && curr == target)
                        continue;
@@ -430,7 +429,7 @@ static int aarch64_halt_smp(struct target *target, bool exc_target)
                struct target_list *head;
                struct target *curr;
 
-               foreach_smp_target(head, target->head) {
+               foreach_smp_target(head, target->smp_targets) {
                        int halted;
 
                        curr = head->target;
@@ -480,7 +479,7 @@ static int update_halt_gdb(struct target *target, enum target_debug_reason debug
        }
 
        /* poll all targets in the group, but skip the target that serves GDB */
-       foreach_smp_target(head, target->head) {
+       foreach_smp_target(head, target->smp_targets) {
                curr = head->target;
                /* skip calling context */
                if (curr == target)
@@ -745,7 +744,7 @@ static int aarch64_prep_restart_smp(struct target *target, int handle_breakpoint
        struct target *first = NULL;
        uint64_t address;
 
-       foreach_smp_target(head, target->head) {
+       foreach_smp_target(head, target->smp_targets) {
                struct target *curr = head->target;
 
                /* skip calling target */
@@ -800,7 +799,7 @@ static int aarch64_step_restart_smp(struct target *target)
                struct target *curr = target;
                bool all_resumed = true;
 
-               foreach_smp_target(head, target->head) {
+               foreach_smp_target(head, target->smp_targets) {
                        uint32_t prsr;
                        int resumed;
 
@@ -888,7 +887,7 @@ static int aarch64_resume(struct target *target, int current,
                        struct target_list *head;
                        bool all_resumed = true;
 
-                       foreach_smp_target(head, target->head) {
+                       foreach_smp_target(head, target->smp_targets) {
                                uint32_t prsr;
                                int resumed;
 
index 2259fa560212b1d71c7e2c9469498d4b0d4279b1..d564f19ae79052e912a0eb61977fc88de16e53bb 100644 (file)
@@ -38,6 +38,7 @@
 #include "arm_opcodes.h"
 #include "target.h"
 #include "target_type.h"
+#include "smp.h"
 
 static void armv7a_show_fault_registers(struct target *target)
 {
@@ -193,8 +194,7 @@ done:
 static int armv7a_l2x_cache_init(struct target *target, uint32_t base, uint32_t way)
 {
        struct armv7a_l2x_cache *l2x_cache;
-       struct target_list *head = target->head;
-       struct target *curr;
+       struct target_list *head;
 
        struct armv7a_common *armv7a = target_to_armv7a(target);
        l2x_cache = calloc(1, sizeof(struct armv7a_l2x_cache));
@@ -207,15 +207,14 @@ static int armv7a_l2x_cache_init(struct target *target, uint32_t base, uint32_t
        armv7a->armv7a_mmu.armv7a_cache.outer_cache = l2x_cache;
        /*  initialize all target in this cluster (smp target)
         *  l2 cache must be configured after smp declaration */
-       while (head) {
-               curr = head->target;
+       foreach_smp_target(head, target->smp_targets) {
+               struct target *curr = head->target;
                if (curr != target) {
                        armv7a = target_to_armv7a(curr);
                        if (armv7a->armv7a_mmu.armv7a_cache.outer_cache)
                                LOG_ERROR("smp target : outer cache already initialized\n");
                        armv7a->armv7a_mmu.armv7a_cache.outer_cache = l2x_cache;
                }
-               head = head->next;
        }
        return JIM_OK;
 }
index 4078fdde20607c5a2eb9de2e4f5f4ef4a287b289..ba6f076f0fc8e0fba68348473e172000d6700e34 100644 (file)
@@ -26,6 +26,7 @@
 #include "armv7a_cache.h"
 #include <helper/time_support.h>
 #include "arm_opcodes.h"
+#include "smp.h"
 
 static int armv7a_l1_d_cache_sanity_check(struct target *target)
 {
@@ -138,14 +139,10 @@ int armv7a_cache_auto_flush_all_data(struct target *target)
 
        if (target->smp) {
                struct target_list *head;
-               struct target *curr;
-               head = target->head;
-               while (head) {
-                       curr = head->target;
+               foreach_smp_target(head, target->smp_targets) {
+                       struct target *curr = head->target;
                        if (curr->state == TARGET_HALTED)
                                retval = armv7a_l1_d_cache_clean_inval_all(curr);
-
-                       head = head->next;
                }
        } else
                retval = armv7a_l1_d_cache_clean_inval_all(target);
index 6b42fae53aa47a14497ab9db03aa477821bb6215..c26d051734cb14543949512dd7fd7f117fd5f2c0 100644 (file)
@@ -27,6 +27,7 @@
 #include <helper/time_support.h>
 #include "target.h"
 #include "target_type.h"
+#include "smp.h"
 
 static int arm7a_l2x_sanity_check(struct target *target)
 {
@@ -194,8 +195,7 @@ static int arm7a_handle_l2x_cache_info_command(struct command_invocation *cmd,
 static int armv7a_l2x_cache_init(struct target *target, uint32_t base, uint32_t way)
 {
        struct armv7a_l2x_cache *l2x_cache;
-       struct target_list *head = target->head;
-       struct target *curr;
+       struct target_list *head;
 
        struct armv7a_common *armv7a = target_to_armv7a(target);
        if (armv7a->armv7a_mmu.armv7a_cache.outer_cache) {
@@ -210,8 +210,8 @@ static int armv7a_l2x_cache_init(struct target *target, uint32_t base, uint32_t
 
        /*  initialize all targets in this cluster (smp target)
         *  l2 cache must be configured after smp declaration */
-       while (head) {
-               curr = head->target;
+       foreach_smp_target(head, target->smp_targets) {
+               struct target *curr = head->target;
                if (curr != target) {
                        armv7a = target_to_armv7a(curr);
                        if (armv7a->armv7a_mmu.armv7a_cache.outer_cache) {
@@ -220,7 +220,6 @@ static int armv7a_l2x_cache_init(struct target *target, uint32_t base, uint32_t
                        }
                        armv7a->armv7a_mmu.armv7a_cache.outer_cache = l2x_cache;
                }
-               head = head->next;
        }
        return ERROR_OK;
 }
index f05ac07cd6dca2c6b705008138fc9097bcac02ce..5b58d3f9fde3852e5163d40399e8eb39a3735a44 100644 (file)
@@ -23,6 +23,7 @@
 #include "armv8_cache.h"
 #include "armv8_dpm.h"
 #include "armv8_opcodes.h"
+#include "smp.h"
 
 /* CLIDR cache types */
 #define CACHE_LEVEL_HAS_UNIFIED_CACHE  0x4
@@ -250,15 +251,12 @@ static int  armv8_flush_all_data(struct target *target)
                /*  look if all the other target have been flushed in order to flush level
                 *  2 */
                struct target_list *head;
-               struct target *curr;
-               head = target->head;
-               while (head) {
-                       curr = head->target;
+               foreach_smp_target(head, target->smp_targets) {
+                       struct target *curr = head->target;
                        if (curr->state == TARGET_HALTED) {
                                LOG_INFO("Wait flushing data l1 on core %" PRId32, curr->coreid);
                                retval = _armv8_flush_all_data(curr);
                        }
-                       head = head->next;
                }
        } else
                retval = _armv8_flush_all_data(target);
index dd901ef25ba2b5e27ca56a62e75bc070e28bed8f..8439ff395ea4f366be90bdce26dc7733f4d82341 100644 (file)
@@ -26,6 +26,7 @@
 #include "target.h"
 #include <helper/log.h>
 #include "breakpoints.h"
+#include "smp.h"
 
 static const char * const breakpoint_type_strings[] = {
        "hardware",
@@ -216,22 +217,22 @@ int breakpoint_add(struct target *target,
        uint32_t length,
        enum breakpoint_type type)
 {
-       int retval = ERROR_OK;
        if (target->smp) {
                struct target_list *head;
-               struct target *curr;
-               head = target->head;
-               if (type == BKPT_SOFT)
+
+               if (type == BKPT_SOFT) {
+                       head = list_first_entry(target->smp_targets, struct target_list, lh);
                        return breakpoint_add_internal(head->target, address, length, type);
+               }
 
-               while (head) {
-                       curr = head->target;
-                       retval = breakpoint_add_internal(curr, address, length, type);
+               foreach_smp_target(head, target->smp_targets) {
+                       struct target *curr = head->target;
+                       int retval = breakpoint_add_internal(curr, address, length, type);
                        if (retval != ERROR_OK)
                                return retval;
-                       head = head->next;
                }
-               return retval;
+
+               return ERROR_OK;
        } else {
                return breakpoint_add_internal(target, address, length, type);
        }
@@ -242,19 +243,17 @@ int context_breakpoint_add(struct target *target,
        uint32_t length,
        enum breakpoint_type type)
 {
-       int retval = ERROR_OK;
        if (target->smp) {
                struct target_list *head;
-               struct target *curr;
-               head = target->head;
-               while (head) {
-                       curr = head->target;
-                       retval = context_breakpoint_add_internal(curr, asid, length, type);
+
+               foreach_smp_target(head, target->smp_targets) {
+                       struct target *curr = head->target;
+                       int retval = context_breakpoint_add_internal(curr, asid, length, type);
                        if (retval != ERROR_OK)
                                return retval;
-                       head = head->next;
                }
-               return retval;
+
+               return ERROR_OK;
        } else {
                return context_breakpoint_add_internal(target, asid, length, type);
        }
@@ -266,19 +265,17 @@ int hybrid_breakpoint_add(struct target *target,
        uint32_t length,
        enum breakpoint_type type)
 {
-       int retval = ERROR_OK;
        if (target->smp) {
                struct target_list *head;
-               struct target *curr;
-               head = target->head;
-               while (head) {
-                       curr = head->target;
-                       retval = hybrid_breakpoint_add_internal(curr, address, asid, length, type);
+
+               foreach_smp_target(head, target->smp_targets) {
+                       struct target *curr = head->target;
+                       int retval = hybrid_breakpoint_add_internal(curr, address, asid, length, type);
                        if (retval != ERROR_OK)
                                return retval;
-                       head = head->next;
                }
-               return retval;
+
+               return ERROR_OK;
        } else
                return hybrid_breakpoint_add_internal(target, address, asid, length, type);
 }
@@ -345,12 +342,10 @@ void breakpoint_remove(struct target *target, target_addr_t address)
        if (target->smp) {
                unsigned int num_breakpoints = 0;
                struct target_list *head;
-               struct target *curr;
-               head = target->head;
-               while (head) {
-                       curr = head->target;
+
+               foreach_smp_target(head, target->smp_targets) {
+                       struct target *curr = head->target;
                        num_breakpoints += breakpoint_remove_internal(curr, address);
-                       head = head->next;
                }
                if (!num_breakpoints)
                        LOG_ERROR("no breakpoint at address " TARGET_ADDR_FMT " found", address);
@@ -363,12 +358,10 @@ void breakpoint_remove_all(struct target *target)
 {
        if (target->smp) {
                struct target_list *head;
-               struct target *curr;
-               head = target->head;
-               while (head) {
-                       curr = head->target;
+
+               foreach_smp_target(head, target->smp_targets) {
+                       struct target *curr = head->target;
                        breakpoint_remove_all_internal(curr);
-                       head = head->next;
                }
        } else {
                breakpoint_remove_all_internal(target);
@@ -387,12 +380,10 @@ void breakpoint_clear_target(struct target *target)
 {
        if (target->smp) {
                struct target_list *head;
-               struct target *curr;
-               head = target->head;
-               while (head) {
-                       curr = head->target;
+
+               foreach_smp_target(head, target->smp_targets) {
+                       struct target *curr = head->target;
                        breakpoint_clear_target_internal(curr);
-                       head = head->next;
                }
        } else {
                breakpoint_clear_target_internal(target);
@@ -482,21 +473,17 @@ bye:
 int watchpoint_add(struct target *target, target_addr_t address,
                uint32_t length, enum watchpoint_rw rw, uint32_t value, uint32_t mask)
 {
-       int retval = ERROR_OK;
        if (target->smp) {
                struct target_list *head;
-               struct target *curr;
-               head = target->head;
 
-               while (head != (struct target_list *)NULL) {
-                       curr = head->target;
-                       retval = watchpoint_add_internal(curr, address, length, rw, value,
-                                       mask);
+               foreach_smp_target(head, target->smp_targets) {
+                       struct target *curr = head->target;
+                       int retval = watchpoint_add_internal(curr, address, length, rw, value, mask);
                        if (retval != ERROR_OK)
                                return retval;
-                       head = head->next;
                }
-               return retval;
+
+               return ERROR_OK;
        } else {
                return watchpoint_add_internal(target, address, length, rw, value,
                                mask);
@@ -549,12 +536,10 @@ void watchpoint_remove(struct target *target, target_addr_t address)
        if (target->smp) {
                unsigned int num_watchpoints = 0;
                struct target_list *head;
-               struct target *curr;
-               head = target->head;
-               while (head) {
-                       curr = head->target;
+
+               foreach_smp_target(head, target->smp_targets) {
+                       struct target *curr = head->target;
                        num_watchpoints += watchpoint_remove_internal(curr, address);
-                       head = head->next;
                }
                if (num_watchpoints == 0)
                        LOG_ERROR("no watchpoint at address " TARGET_ADDR_FMT " num_watchpoints", address);
index bf65544f51afa133d33a458ccd51c4adcbc5c6d4..272411359b05557ca792e9c7511543451b2aaa2e 100644 (file)
@@ -639,14 +639,11 @@ static int cortex_a_dpm_setup(struct cortex_a_common *a, uint32_t didr)
 static struct target *get_cortex_a(struct target *target, int32_t coreid)
 {
        struct target_list *head;
-       struct target *curr;
 
-       head = target->head;
-       while (head) {
-               curr = head->target;
+       foreach_smp_target(head, target->smp_targets) {
+               struct target *curr = head->target;
                if ((curr->coreid == coreid) && (curr->state == TARGET_HALTED))
                        return curr;
-               head = head->next;
        }
        return target;
 }
@@ -656,14 +653,12 @@ static int cortex_a_halt_smp(struct target *target)
 {
        int retval = 0;
        struct target_list *head;
-       struct target *curr;
-       head = target->head;
-       while (head) {
-               curr = head->target;
+
+       foreach_smp_target(head, target->smp_targets) {
+               struct target *curr = head->target;
                if ((curr != target) && (curr->state != TARGET_HALTED)
                        && target_was_examined(curr))
                        retval += cortex_a_halt(curr);
-               head = head->next;
        }
        return retval;
 }
@@ -684,7 +679,7 @@ static int update_halt_gdb(struct target *target)
        if (target->gdb_service)
                gdb_target = target->gdb_service->target;
 
-       foreach_smp_target(head, target->head) {
+       foreach_smp_target(head, target->smp_targets) {
                curr = head->target;
                /* skip calling context */
                if (curr == target)
@@ -951,11 +946,10 @@ static int cortex_a_restore_smp(struct target *target, int handle_breakpoints)
 {
        int retval = 0;
        struct target_list *head;
-       struct target *curr;
        target_addr_t address;
-       head = target->head;
-       while (head) {
-               curr = head->target;
+
+       foreach_smp_target(head, target->smp_targets) {
+               struct target *curr = head->target;
                if ((curr != target) && (curr->state != TARGET_RUNNING)
                        && target_was_examined(curr)) {
                        /*  resume current address , not in step mode */
@@ -963,8 +957,6 @@ static int cortex_a_restore_smp(struct target *target, int handle_breakpoints)
                                        handle_breakpoints, 0);
                        retval += cortex_a_internal_restart(curr);
                }
-               head = head->next;
-
        }
        return retval;
 }
index ca4416981029932b2dd1b9d0a0e9360791bbdd64..8627bce6e7ae6145b3f7a709cc0385040d32103c 100644 (file)
@@ -128,14 +128,11 @@ static int mips_m4k_debug_entry(struct target *target)
 static struct target *get_mips_m4k(struct target *target, int32_t coreid)
 {
        struct target_list *head;
-       struct target *curr;
 
-       head = target->head;
-       while (head) {
-               curr = head->target;
+       foreach_smp_target(head, target->smp_targets) {
+               struct target *curr = head->target;
                if ((curr->coreid == coreid) && (curr->state == TARGET_HALTED))
                        return curr;
-               head = head->next;
        }
        return target;
 }
@@ -144,11 +141,10 @@ static int mips_m4k_halt_smp(struct target *target)
 {
        int retval = ERROR_OK;
        struct target_list *head;
-       struct target *curr;
-       head = target->head;
-       while (head) {
+
+       foreach_smp_target(head, target->smp_targets) {
                int ret = ERROR_OK;
-               curr = head->target;
+               struct target *curr = head->target;
                if ((curr != target) && (curr->state != TARGET_HALTED))
                        ret = mips_m4k_halt(curr);
 
@@ -156,7 +152,6 @@ static int mips_m4k_halt_smp(struct target *target)
                        LOG_ERROR("halt failed target->coreid: %" PRId32, curr->coreid);
                        retval = ret;
                }
-               head = head->next;
        }
        return retval;
 }
@@ -414,12 +409,10 @@ static int mips_m4k_restore_smp(struct target *target, uint32_t address, int han
 {
        int retval = ERROR_OK;
        struct target_list *head;
-       struct target *curr;
 
-       head = target->head;
-       while (head) {
+       foreach_smp_target(head, target->smp_targets) {
                int ret = ERROR_OK;
-               curr = head->target;
+               struct target *curr = head->target;
                if ((curr != target) && (curr->state != TARGET_RUNNING)) {
                        /*  resume current address , not in step mode */
                        ret = mips_m4k_internal_restore(curr, 1, address,
@@ -431,7 +424,6 @@ static int mips_m4k_restore_smp(struct target *target, uint32_t address, int han
                                retval = ret;
                        }
                }
-               head = head->next;
        }
        return retval;
 }
index c9840fe50f9db6b94d2fcc6a88d0b3cf5249545f..931f7629092690c5ccf249c1379d3b7508426ce4 100644 (file)
@@ -13,6 +13,7 @@
 #include "target/target.h"
 #include "target/algorithm.h"
 #include "target/target_type.h"
+#include <target/smp.h>
 #include "jtag/jtag.h"
 #include "target/register.h"
 #include "target/breakpoints.h"
@@ -1232,13 +1233,14 @@ int riscv_halt(struct target *target)
 
        int result = ERROR_OK;
        if (target->smp) {
-               for (struct target_list *tlist = target->head; tlist; tlist = tlist->next) {
+               struct target_list *tlist;
+               foreach_smp_target(tlist, target->smp_targets) {
                        struct target *t = tlist->target;
                        if (halt_prep(t) != ERROR_OK)
                                result = ERROR_FAIL;
                }
 
-               for (struct target_list *tlist = target->head; tlist; tlist = tlist->next) {
+               foreach_smp_target(tlist, target->smp_targets) {
                        struct target *t = tlist->target;
                        riscv_info_t *i = riscv_info(t);
                        if (i->prepped) {
@@ -1247,7 +1249,7 @@ int riscv_halt(struct target *target)
                        }
                }
 
-               for (struct target_list *tlist = target->head; tlist; tlist = tlist->next) {
+               foreach_smp_target(tlist, target->smp_targets) {
                        struct target *t = tlist->target;
                        if (halt_finish(t) != ERROR_OK)
                                return ERROR_FAIL;
@@ -1469,14 +1471,15 @@ int riscv_resume(
        LOG_DEBUG("handle_breakpoints=%d", handle_breakpoints);
        int result = ERROR_OK;
        if (target->smp && !single_hart) {
-               for (struct target_list *tlist = target->head; tlist; tlist = tlist->next) {
+               struct target_list *tlist;
+               foreach_smp_target(tlist, target->smp_targets) {
                        struct target *t = tlist->target;
                        if (resume_prep(t, current, address, handle_breakpoints,
                                                debug_execution) != ERROR_OK)
                                result = ERROR_FAIL;
                }
 
-               for (struct target_list *tlist = target->head; tlist; tlist = tlist->next) {
+               foreach_smp_target(tlist, target->smp_targets) {
                        struct target *t = tlist->target;
                        riscv_info_t *i = riscv_info(t);
                        if (i->prepped) {
@@ -1486,7 +1489,7 @@ int riscv_resume(
                        }
                }
 
-               for (struct target_list *tlist = target->head; tlist; tlist = tlist->next) {
+               foreach_smp_target(tlist, target->smp_targets) {
                        struct target *t = tlist->target;
                        if (resume_finish(t) != ERROR_OK)
                                return ERROR_FAIL;
@@ -2180,9 +2183,8 @@ int riscv_openocd_poll(struct target *target)
                unsigned halts_discovered = 0;
                unsigned should_remain_halted = 0;
                unsigned should_resume = 0;
-               unsigned i = 0;
-               for (struct target_list *list = target->head; list;
-                               list = list->next, i++) {
+               struct target_list *list;
+               foreach_smp_target(list, target->smp_targets) {
                        struct target *t = list->target;
                        riscv_info_t *r = riscv_info(t);
                        enum riscv_poll_hart out = riscv_poll_hart(t, r->current_hartid);
@@ -2242,8 +2244,7 @@ int riscv_openocd_poll(struct target *target)
                }
 
                /* Sample memory if any target is running. */
-               for (struct target_list *list = target->head; list;
-                               list = list->next, i++) {
+               foreach_smp_target(list, target->smp_targets) {
                        struct target *t = list->target;
                        if (t->state == TARGET_RUNNING) {
                                sample_memory(target);
index 518f6e458531ab687e119d08c95c19695ed9b119..3e1ded8bc3e0b5e128f5f559ddcf720946556119 100644 (file)
@@ -111,18 +111,18 @@ COMMAND_HANDLER(default_handle_smp_command)
        }
 
        if (!strcmp(CMD_ARGV[0], "on")) {
-               foreach_smp_target(head, target->head)
+               foreach_smp_target(head, target->smp_targets)
                        head->target->smp = 1;
 
                return ERROR_OK;
        }
 
        if (!strcmp(CMD_ARGV[0], "off")) {
-               foreach_smp_target(head, target->head)
+               foreach_smp_target(head, target->smp_targets)
                        head->target->smp = 0;
 
                /* fixes the target display to the debugger */
-               if (target->head)
+               if (!list_empty(target->smp_targets))
                        target->gdb_service->target = target;
 
                return ERROR_OK;
@@ -135,9 +135,7 @@ COMMAND_HANDLER(handle_smp_gdb_command)
 {
        struct target *target = get_current_target(CMD_CTX);
        int retval = ERROR_OK;
-       struct target_list *head;
-       head = target->head;
-       if (head) {
+       if (!list_empty(target->smp_targets)) {
                if (CMD_ARGC == 1) {
                        int coreid = 0;
                        COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], coreid);
index 3338240adf6d2a3a1e2736c8885ace604b480cc0..46fc55f750870c061cef602bdd1ed7fa76531f5d 100644 (file)
 #ifndef OPENOCD_TARGET_SMP_H
 #define OPENOCD_TARGET_SMP_H
 
+#include <helper/list.h>
 #include "server/server.h"
 
 #define foreach_smp_target(pos, head) \
-       for (pos = head; (pos); pos = pos->next)
+       list_for_each_entry(pos, head, lh)
 
 extern const struct command_registration smp_command_handlers[];
 
index acfbd3df5c85a0e1e56e182d9e2e27dcff6e98e4..6250d303115847b2b911b9062c3bb1525abdc1cb 100644 (file)
@@ -56,6 +56,7 @@
 #include "rtos/rtos.h"
 #include "transport/transport.h"
 #include "arm_cti.h"
+#include "smp.h"
 
 /* default halt wait timeout (ms) */
 #define DEFAULT_HALT_TIMEOUT 5000
@@ -159,6 +160,7 @@ static int64_t target_timer_next_event_value;
 static LIST_HEAD(target_reset_callback_list);
 static LIST_HEAD(target_trace_callback_list);
 static const int polling_interval = TARGET_DEFAULT_POLLING_INTERVAL;
+static LIST_HEAD(empty_smp_targets);
 
 static const struct jim_nvp nvp_assert[] = {
        { .name = "assert", NVP_ASSERT },
@@ -2272,13 +2274,15 @@ static void target_destroy(struct target *target)
 
        /* release the targets SMP list */
        if (target->smp) {
-               struct target_list *head = target->head;
-               while (head) {
-                       struct target_list *pos = head->next;
+               struct target_list *head, *tmp;
+
+               list_for_each_entry_safe(head, tmp, target->smp_targets, lh) {
+                       list_del(&head->lh);
                        head->target->smp = 0;
                        free(head);
-                       head = pos;
                }
+               if (target->smp_targets != &empty_smp_targets)
+                       free(target->smp_targets);
                target->smp = 0;
        }
 
@@ -5786,6 +5790,9 @@ static int target_create(struct jim_getopt_info *goi)
                return JIM_ERR;
        }
 
+       /* set empty smp cluster */
+       target->smp_targets = &empty_smp_targets;
+
        /* set target number */
        target->target_number = new_target_number();
 
@@ -5998,9 +6005,7 @@ static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
        const char *targetname;
        int retval, len;
        struct target *target = NULL;
-       struct target_list *head, *curr, *new;
-       curr = NULL;
-       head = NULL;
+       struct target_list *head, *new;
 
        retval = 0;
        LOG_DEBUG("%d", argc);
@@ -6009,6 +6014,13 @@ static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
         * argv[3] ...
         */
 
+       struct list_head *lh = malloc(sizeof(*lh));
+       if (!lh) {
+               LOG_ERROR("Out of memory");
+               return JIM_ERR;
+       }
+       INIT_LIST_HEAD(lh);
+
        for (i = 1; i < argc; i++) {
 
                targetname = Jim_GetString(argv[i], &len);
@@ -6017,24 +6029,14 @@ static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
                if (target) {
                        new = malloc(sizeof(struct target_list));
                        new->target = target;
-                       new->next = NULL;
-                       if (!head) {
-                               head = new;
-                               curr = head;
-                       } else {
-                               curr->next = new;
-                               curr = new;
-                       }
+                       list_add_tail(&new->lh, lh);
                }
        }
        /*  now parse the list of cpu and put the target in smp mode*/
-       curr = head;
-
-       while (curr) {
-               target = curr->target;
+       foreach_smp_target(head, lh) {
+               target = head->target;
                target->smp = 1;
-               target->head = head;
-               curr = curr->next;
+               target->smp_targets = lh;
        }
 
        if (target && target->rtos)
index 974630f178555016dbbdf4c683d634f2b08067ae..1f1a3542077f72e11c3db9c60feae0c95a26cf4f 100644 (file)
@@ -201,7 +201,9 @@ struct target {
                                                                                 * and must be detected when symbols are offered */
        struct backoff_timer backoff;
        int smp;                                                        /* add some target attributes for smp support */
-       struct target_list *head;
+       struct list_head *smp_targets;          /* list all targets in this smp group/cluster
+                                                                                * The head of the list is shared between the
+                                                                                * cluster, thus here there is a pointer */
        /* the gdb service is there in case of smp, we have only one gdb server
         * for all smp target
         * the target attached to the gdb is changing dynamically by changing
@@ -220,8 +222,8 @@ struct target {
 };
 
 struct target_list {
+       struct list_head lh;
        struct target *target;
-       struct target_list *next;
 };
 
 struct gdb_fileio_info {