This is an automated email from Gerrit.

"Tomas Vanek <[email protected]>" just uploaded a new patch set to Gerrit, which 
you can find at https://review.openocd.org/c/openocd/+/9439

-- gerrit

commit 81cb2fd3e1f0751ab42461a4accb9c3180a9851b
Author: Tomas Vanek <[email protected]>
Date:   Wed Feb 4 12:45:41 2026 +0100

    target/arm_adi_v5: search for multiple AP types much more effective way
    
    Cortex-M debug AP could be on AHB3 or AHB5.
    Finding AHB3 is fast as AP usually has a low address.
    On the other hand, finding AP on the AHB5 equipped device is weird
    without this patch. cortex_m_find_mem_ap()
    first tries to read IDR from all possible 256 ADIv5 APs and checks
    for AHB3 ID and if that fails, starts over and search for AHB5.
    It takes long time (74 msec on fast USB HS based STLINK V3J15M7)
    and logs lot of rubbish:
    
    Debug: 168 117  target_examine_one(): [stm32u3x.cpu] Examination started
    Debug: 169 117  target_call_event_callbacks(): event 19 (examine-start)
    Debug: 170 117 arm_adi_v5.c:1201 dap_get_ap(): refcount AP#0x0 get 1
    Debug: 171 118 arm_adi_v5.c:1226 dap_put_ap(): refcount AP#0x0 put 0
    Debug: 172 118 arm_adi_v5.c:1201 dap_get_ap(): refcount AP#0x1 get 1
    Debug: 173 118 arm_adi_v5.c:1226 dap_put_ap(): refcount AP#0x1 put 0
    Debug: 174 118 arm_adi_v5.c:1201 dap_get_ap(): refcount AP#0x2 get 1
    Debug: 175 119 arm_adi_v5.c:1226 dap_put_ap(): refcount AP#0x2 put 0
    ...
    Debug: 188 123 arm_adi_v5.c:1201 dap_get_ap(): refcount AP#0x9 get 1
    Debug: 189 123  stlink_usb_error_check(): STLINK_BAD_AP_ERROR
    Debug: 190 123 arm_adi_v5.c:1226 dap_put_ap(): refcount AP#0x9 put 0
    Debug: 191 123 arm_adi_v5.c:1201 dap_get_ap(): refcount AP#0xa get 1
    Debug: 192 123  stlink_usb_error_check(): STLINK_BAD_AP_ERROR
    Debug: 193 123 arm_adi_v5.c:1226 dap_put_ap(): refcount AP#0xa put 0
    ...
    Debug: 926 190 arm_adi_v5.c:1201 dap_get_ap(): refcount AP#0xff get 1
    Debug: 927 191  stlink_usb_error_check(): STLINK_BAD_AP_ERROR
    Debug: 928 191 arm_adi_v5.c:1226 dap_put_ap(): refcount AP#0xff put 0
    Debug: 929 191 arm_adi_v5.c:1154 dap_find_get_ap(): No MEM-AP AHB3 found
    Debug: 930 191 arm_adi_v5.c:1201 dap_get_ap(): refcount AP#0x0 get 1
    Debug: 931 191 arm_adi_v5.c:1144 dap_find_get_ap(): Found MEM-AP AHB5
     at AP index: 0 (IDR=0x14770015)
    
    Introduce dap_find_by_types_get_ap() to search for the array of AP IDs.
    
    With the patch cortex_m_find_mem_ap() succeeds immediately:
    
    Debug: 168 118  target_examine_one(): [stm32u3x.cpu] Examination started
    Debug: 169 118  target_call_event_callbacks(): event 19 (examine-start)
    Debug: 170 118 arm_adi_v5.c:1222 dap_get_ap(): refcount AP#0x0 get 1
    Debug: 171 118 arm_adi_v5.c:1150 dap_find_by_types_get_ap(): Found MEM-AP
     AHB5 at AP index: 0 (IDR=0x14770015)
    
    Change-Id: Iabcfa1fd64a48febb0f759a213f15d69621ea5cf
    Signed-off-by: Tomas Vanek <[email protected]>

diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c
index 67a3fcc577..2e02034472 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,35 @@ 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_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 ebd2752bd8..b7472510b6 100644
--- a/src/target/arm_adi_v5.h
+++ b/src/target/arm_adi_v5.h
@@ -738,10 +738,21 @@ 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 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 */
-int dap_find_get_ap(struct adiv5_dap *dap,
+static inline int dap_find_get_ap(struct adiv5_dap *dap,
                        enum ap_type type_to_find,
-                       struct adiv5_ap **ap_out);
+                       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 fc12a1770b..c4eee8c071 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)

-- 

Reply via email to