This is an automated email from Gerrit.

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

-- gerrit

commit 82eb9a8b9d58531689a85dfca87f2b2e2729d77b
Author: Daniel Goehring <[email protected]>
Date:   Fri Jul 18 21:36:57 2025 -0600

    target/arm: add nested AP lookup support
    
    Add equivalent AP lookup commands which support gateways for
    nested APs. Since a nested AP's address can be identical
    to a non-nested AP's address, these added routines use the
    gateway AP's address for the AP lookup.
    
    Change-Id: I5a8d25f258233f709cb5dc831f029fb6f9fb2a01
    Signed-off-by: Daniel Goehring <[email protected]>

diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c
index 2a599904c4..def4faa75a 100644
--- a/src/target/arm_adi_v5.c
+++ b/src/target/arm_adi_v5.c
@@ -1167,20 +1167,24 @@ static inline bool is_ap_in_use(struct adiv5_ap *ap)
 
 static struct adiv5_ap *_dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num)
 {
+       struct adiv5_ap *ap;
+       struct adiv5_ap *ap_gateway;
+
        if (!is_ap_num_valid(dap, ap_num)) {
                LOG_ERROR("Invalid AP#0x%" PRIx64, ap_num);
                return NULL;
        }
        if (is_adiv6(dap)) {
                for (unsigned int i = 0; i <= DP_APSEL_MAX; i++) {
-                       struct adiv5_ap *ap = &dap->ap[i];
-                       if (is_ap_in_use(ap) && ap->ap_num == ap_num) {
+                       ap = &dap->ap[i];
+                       ap_gateway = ap->ap_gateway;
+                       if (is_ap_in_use(ap) && !ap_gateway && ap->ap_num == 
ap_num) {
                                ++ap->refcount;
                                return ap;
                        }
                }
                for (unsigned int i = 0; i <= DP_APSEL_MAX; i++) {
-                       struct adiv5_ap *ap = &dap->ap[i];
+                       ap = &dap->ap[i];
                        if (!is_ap_in_use(ap)) {
                                ap->ap_gateway = NULL;
                                ap->ap_num = ap_num;
@@ -1193,13 +1197,68 @@ static struct adiv5_ap *_dap_get_ap(struct adiv5_dap 
*dap, uint64_t ap_num)
        }
 
        /* ADIv5 */
-       struct adiv5_ap *ap = &dap->ap[ap_num];
+       ap = &dap->ap[ap_num];
        ap->ap_gateway = NULL;
        ap->ap_num = ap_num;
        ++ap->refcount;
        return ap;
 }
 
+static struct adiv5_ap *_dap_get_ap_gateway(struct adiv5_dap *dap, uint64_t 
ap_num, uint64_t ap_num_gateway)
+{
+       struct adiv5_ap *ap;
+       struct adiv5_ap *ap_gateway;
+
+       if (!is_ap_num_valid(dap, ap_num)) {
+               LOG_ERROR("Invalid AP#0x%" PRIx64, ap_num);
+               return NULL;
+       }
+       if (!is_ap_num_valid(dap, ap_num_gateway)) {
+               LOG_ERROR("Invalid AP_GATEWAY#0x%" PRIx64, ap_num_gateway);
+               return NULL;
+       }
+
+       if (is_adiv6(dap)) {
+               for (unsigned int i = 0; i <= DP_APSEL_MAX; i++) {
+                       ap = &dap->ap[i];
+                       ap_gateway = ap->ap_gateway;
+                       if (is_ap_in_use(ap) && ap_gateway && 
is_ap_in_use(ap_gateway) &&
+                               ap->ap_num == ap_num && ap_gateway->ap_num == 
ap_num_gateway) {
+                               ++ap->refcount;
+                               ++ap_gateway->refcount;
+                               return ap;
+                       }
+               }
+               ap_gateway = dap_get_ap(dap, ap_num_gateway);
+               if (!ap_gateway) {
+                       LOG_ERROR("No more AP available!");
+                       return NULL;
+               }
+               for (unsigned int i = 0; i <= DP_APSEL_MAX; i++) {
+                       ap = &dap->ap[i];
+                       if (!is_ap_in_use(ap)) {
+                               ap->ap_gateway = ap_gateway;
+                               ap->ap_num = ap_num;
+                               ++ap->refcount;
+                               return ap;
+                       }
+               }
+               dap_put_ap(ap_gateway);
+               LOG_ERROR("No more AP available!");
+               return NULL;
+       }
+
+       /* ADIv5 */
+       ap = &dap->ap[ap_num];
+       ap_gateway = &dap->ap[ap_num_gateway];
+       ap->ap_gateway = ap_gateway;
+       ap->ap_num = ap_num;
+       ap_gateway->ap_num = ap_num_gateway;
+       ++ap->refcount;
+       ++ap_gateway->refcount;
+       return ap;
+}
+
 /* Return AP with specified ap_num. Increment AP refcount */
 struct adiv5_ap *dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num)
 {
@@ -1209,6 +1268,18 @@ struct adiv5_ap *dap_get_ap(struct adiv5_dap *dap, 
uint64_t ap_num)
        return ap;
 }
 
+struct adiv5_ap *dap_get_ap_gateway(struct adiv5_dap *dap, uint64_t ap_num, 
uint64_t ap_num_gateway)
+{
+       struct adiv5_ap *ap = _dap_get_ap_gateway(dap, ap_num, ap_num_gateway);
+       if (ap) {
+               LOG_DEBUG("refcount AP#0x%" PRIx64 " get %u", ap_num, 
ap->refcount);
+               if (ap->ap_gateway)
+                       LOG_DEBUG("refcount AP_GATEWAY#0x%" PRIx64 " get %u",
+                               ap_num_gateway, ap->ap_gateway->refcount);
+       }
+       return ap;
+}
+
 /* Return AP with specified ap_num. Increment AP refcount and keep it non-zero 
*/
 struct adiv5_ap *dap_get_config_ap(struct adiv5_dap *dap, uint64_t ap_num)
 {
@@ -1220,9 +1291,27 @@ struct adiv5_ap *dap_get_config_ap(struct adiv5_dap 
*dap, uint64_t ap_num)
        return ap;
 }
 
+/* Return AP with specified ap_num. Increment AP refcount and keep it non-zero 
*/
+struct adiv5_ap *dap_get_config_ap_gateway(struct adiv5_dap *dap, uint64_t 
ap_num, uint64_t ap_num_gateway)
+{
+       struct adiv5_ap *ap = _dap_get_ap_gateway(dap, ap_num, ap_num_gateway);
+       if (ap) {
+               ap->config_ap_never_release = true;
+               LOG_DEBUG("refcount AP#0x%" PRIx64 " get_config %u", ap_num, 
ap->refcount);
+               if (ap->ap_gateway) {
+                       ap->ap_gateway->config_ap_never_release = true;
+                       LOG_DEBUG("refcount AP_GATEWAY#0x%" PRIx64 " get_config 
%u",
+                               ap_num_gateway, ap->ap_gateway->refcount);
+               }
+       }
+       return ap;
+}
+
 /* Decrement AP refcount and release the AP when refcount reaches zero */
 int dap_put_ap(struct adiv5_ap *ap)
 {
+       struct adiv5_ap *ap_gateway = ap->ap_gateway;
+
        if (ap->refcount == 0) {
                LOG_ERROR("BUG: refcount AP#0x%" PRIx64 " put underflow", 
ap->ap_num);
                return ERROR_FAIL;
@@ -1234,11 +1323,33 @@ int dap_put_ap(struct adiv5_ap *ap)
        if (!is_ap_in_use(ap)) {
                /* defaults from dap_instance_init() */
                ap->ap_num = DP_APSEL_INVALID;
+               ap->ap_gateway = NULL;
                ap->memaccess_tck = 255;
                ap->tar_autoincr_block = (1 << 10);
                ap->csw_default = CSW_AHB_DEFAULT;
                ap->cfg_reg = MEM_AP_REG_CFG_INVALID;
        }
+
+       if (ap_gateway) {
+               if (ap_gateway->refcount == 0) {
+                       LOG_ERROR("BUG: refcount AP_GATEWAY#0x%" PRIx64 " put 
underflow", ap_gateway->ap_num);
+                       return ERROR_FAIL;
+               }
+
+               --ap_gateway->refcount;
+
+               LOG_DEBUG("refcount AP_GATEWAY#0x%" PRIx64 " put %u", 
ap_gateway->ap_num, ap_gateway->refcount);
+               if (!is_ap_in_use(ap_gateway)) {
+                       /* defaults from dap_instance_init() */
+                       ap_gateway->ap_num = DP_APSEL_INVALID;
+                       ap_gateway->ap_gateway = NULL;
+                       ap_gateway->memaccess_tck = 255;
+                       ap_gateway->tar_autoincr_block = (1 << 10);
+                       ap_gateway->csw_default = CSW_AHB_DEFAULT;
+                       ap_gateway->cfg_reg = MEM_AP_REG_CFG_INVALID;
+               }
+       }
+
        return ERROR_OK;
 }
 
diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h
index 49bc3ff0b0..72a29faff2 100644
--- a/src/target/arm_adi_v5.h
+++ b/src/target/arm_adi_v5.h
@@ -750,9 +750,11 @@ int dap_find_get_ap(struct adiv5_dap *dap,
 
 /* Return AP with specified ap_num. Increment AP refcount */
 struct adiv5_ap *dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num);
+struct adiv5_ap *dap_get_ap_gateway(struct adiv5_dap *dap, uint64_t ap_num, 
uint64_t ap_num_gateway);
 
 /* Return AP with specified ap_num. Increment AP refcount and keep it non-zero 
*/
 struct adiv5_ap *dap_get_config_ap(struct adiv5_dap *dap, uint64_t ap_num);
+struct adiv5_ap *dap_get_config_ap_gateway(struct adiv5_dap *dap, uint64_t 
ap_num, uint64_t ap_num_gateway);
 
 /* Decrement AP refcount and release the AP when refcount reaches zero */
 int dap_put_ap(struct adiv5_ap *ap);

-- 

Reply via email to