diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 67a3fcc57..e64f8ac37 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -1112,7 +1112,9 @@ bool is_ap_num_valid(struct adiv5_dap *dap, uint64_t ap_num) * This function checks the ID for each access port to find the requested Access Port type * It also calls dap_get_ap() to increment the AP refcount */ -int dap_find_get_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_ap **ap_out) +int dap_find_by_types_get_ap(struct adiv5_dap *dap, + const enum ap_type *types_to_find, unsigned int num_types, + struct adiv5_ap **ap_out) { if (is_adiv6(dap)) { /* TODO: scan the ROM table and detect the AP available */ @@ -1120,6 +1122,8 @@ int dap_find_get_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adi return ERROR_FAIL; } + assert(num_types > 0); + /* Maximum AP number is 255 since the SELECT register is 8 bits */ for (unsigned int ap_num = 0; ap_num <= DP_APSEL_MAX; ap_num++) { struct adiv5_ap *ap = dap_get_ap(dap, ap_num); @@ -1140,18 +1144,39 @@ int dap_find_get_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adi /* Reading register for a non-existent AP should not cause an error, * but just to be sure, try to continue searching if an error does happen. */ - if (retval == ERROR_OK && (id_val & AP_TYPE_MASK) == type_to_find) { - LOG_DEBUG("Found %s at AP index: %d (IDR=0x%08" PRIX32 ")", - ap_type_to_description(type_to_find), + if (retval == ERROR_OK) { + for (unsigned int i = 0; i < num_types; i++) { + if ((id_val & AP_TYPE_MASK) == types_to_find[i]) { + LOG_DEBUG("Found %s at AP index: %d (IDR=0x%08" PRIX32 ")", + ap_type_to_description(types_to_find[i]), ap_num, id_val); - *ap_out = ap; - return ERROR_OK; + *ap_out = ap; + return ERROR_OK; + } + } } dap_put_ap(ap); } - LOG_DEBUG("No %s found", ap_type_to_description(type_to_find)); + char *types_str = NULL; + for (unsigned int i = 0; i < num_types; i++) { + if (!types_str) { + types_str = strdup(ap_type_to_description(types_to_find[i])); + } else { + char *next_str = alloc_printf("%s, %s", types_str, + ap_type_to_description(types_to_find[i])); + free(types_str); + types_str = next_str; + } + if (!types_str) { + LOG_ERROR("No memory"); + return ERROR_FAIL; + } + } + LOG_DEBUG("No %s found", types_str); + free(types_str); + return ERROR_FAIL; } diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index ebd2752bd..b7472510b 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -738,11 +738,22 @@ int adiv6_dap_read_baseptr(struct command_invocation *cmd, struct adiv5_dap *dap /* test if ap_num is valid, based on current knowledge of dap */ bool is_ap_num_valid(struct adiv5_dap *dap, uint64_t ap_num); -/* Probe Access Ports to find a particular type. Increment AP refcount */ -int dap_find_get_ap(struct adiv5_dap *dap, - enum ap_type type_to_find, +/* Probe Access Ports to find any type from array. + * Increment AP refcount */ +int dap_find_by_types_get_ap(struct adiv5_dap *dap, + const enum ap_type *types_to_find, + unsigned int num_types, struct adiv5_ap **ap_out); +/* Probe Access Ports to find a particular type. Increment AP refcount */ +static inline int dap_find_get_ap(struct adiv5_dap *dap, + enum ap_type type_to_find, + struct adiv5_ap **ap_out) +{ + const enum ap_type types[1] = { type_to_find }; + return dap_find_by_types_get_ap(dap, types, 1, ap_out); +} + /* Return AP with specified ap_num. Increment AP refcount */ struct adiv5_ap *dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num); diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index fc12a1770..c4eee8c07 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -2775,10 +2775,12 @@ int cortex_m_security_restore(struct target *target, struct cortex_m_saved_secur static int cortex_m_find_mem_ap(struct adiv5_dap *swjdp, struct adiv5_ap **debug_ap) { - if (dap_find_get_ap(swjdp, AP_TYPE_AHB3_AP, debug_ap) == ERROR_OK) - return ERROR_OK; + const enum ap_type types[] = { + AP_TYPE_AHB3_AP, + AP_TYPE_AHB5_AP + }; - return dap_find_get_ap(swjdp, AP_TYPE_AHB5_AP, debug_ap); + return dap_find_by_types_get_ap(swjdp, types, ARRAY_SIZE(types), debug_ap); } int cortex_m_examine(struct target *target)