This is an automated email from Gerrit.

Antonio Borneo ([email protected]) just uploaded a new patch set to 
Gerrit, which you can find at http://openocd.zylin.com/6412

-- gerrit

commit b5b26f0670efa2f5de373ae9bfcc38974e34ebbc
Author: Antonio Borneo <[email protected]>
Date:   Thu Aug 5 17:08:11 2021 +0200

    arm_adi_v5: fix access to 64-bit MEM-AP
    
    Commit ac22cdc57322 ("target/adiv5: Large Physical Address
    Extension") reads the register MEM_AP_REG_CFG and keeps it in a
    new field of struct adiv5_ap. The test on LE bit (Large Extension)
    is used to identify if mem_ap addresses are 32 or 64 bits.
    But the register MEM_AP_REG_CFG is only read during mem_ap_init(),
    that is called only when the AP is used as a target debug AP or if
    a target mem_ap is attached to that AP.
    
    The openocd commands '<dapname> baseaddr', '<dapname> info' and
    'dap info' can be executed on AP that has not been associated yet
    to a target, thus executed without any knowledge of MEM_AP_REG_CFG
    value. The initialization to ADI_BAD_CFG causes openocd to always
    use 32 bit mode on un-associated APs.
    
    Verify if MEM_AP_REG_CFG has not been read and eventually read it.
    In case of 32 bits mode AP, MEM_AP_REG_BASE64 is defined as 'RES0'
    (reserved, but readable); the code can queue both the read of
    MEM_AP_REG_CFG and MEM_AP_REG_BASE64, before knowing if the former
    is required. This speeds-up the operation.
    Rename ADI_BAD_CFG as MEM_AP_REG_CFG_INVALID.
    
    Change-Id: If3bbd792b56a483022c37ccc2ce82b5ba5c36caa
    Signed-off-by: Antonio Borneo <[email protected]>
    Fixes: ac22cdc57322 ("target/adiv5: Large Physical Address Extension")

diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c
index c421fe6..40f672b 100644
--- a/src/target/arm_adi_v5.c
+++ b/src/target/arm_adi_v5.c
@@ -946,25 +946,30 @@ int dap_get_debugbase(struct adiv5_ap *ap,
        int retval;
        uint32_t baseptr_upper, baseptr_lower;
 
-       baseptr_upper = 0;
-
-       if (is_64bit_ap(ap)) {
-               /* Read higher order 32-bits of base address */
-               retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE64, 
&baseptr_upper);
+       if (ap->cfg_reg == MEM_AP_REG_CFG_INVALID) {
+               retval = dap_queue_ap_read(ap, MEM_AP_REG_CFG, &ap->cfg_reg);
                if (retval != ERROR_OK)
                        return retval;
        }
-
        retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE, &baseptr_lower);
        if (retval != ERROR_OK)
                return retval;
        retval = dap_queue_ap_read(ap, AP_REG_IDR, apid);
        if (retval != ERROR_OK)
                return retval;
+       /* MEM_AP_REG_BASE64 is defined as 'RES0'; can be read and then ignored 
on 32 bits AP */
+       if (ap->cfg_reg == MEM_AP_REG_CFG_INVALID || is_64bit_ap(ap)) {
+               retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE64, 
&baseptr_upper);
+               if (retval != ERROR_OK)
+                       return retval;
+       }
+
        retval = dap_run(dap);
        if (retval != ERROR_OK)
                return retval;
 
+       if (!is_64bit_ap(ap))
+               baseptr_upper = 0;
        *dbgbase = (((target_addr_t)baseptr_upper) << 32) | baseptr_lower;
 
        return ERROR_OK;
@@ -1768,20 +1773,26 @@ COMMAND_HANDLER(dap_baseaddr_command)
        ap = dap_ap(dap, apsel);
        retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE, &baseaddr_lower);
 
-       if (is_64bit_ap(ap) && retval == ERROR_OK)
+       if (retval == ERROR_OK && ap->cfg_reg == MEM_AP_REG_CFG_INVALID)
+               retval = dap_queue_ap_read(ap, MEM_AP_REG_CFG, &ap->cfg_reg);
+
+       if (retval == ERROR_OK && (ap->cfg_reg == MEM_AP_REG_CFG_INVALID || 
is_64bit_ap(ap))) {
+               /* MEM_AP_REG_BASE64 is defined as 'RES0'; can be read and then 
ignored on 32 bits AP */
                retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE64, 
&baseaddr_upper);
+       }
+
+       if (retval == ERROR_OK)
+               retval = dap_run(dap);
        if (retval != ERROR_OK)
                return retval;
-       retval = dap_run(dap);
-       if (retval != ERROR_OK)
-               return retval;
+
        if (is_64bit_ap(ap)) {
                baseaddr = (((target_addr_t)baseaddr_upper) << 32) | 
baseaddr_lower;
                command_print(CMD, "0x%016" PRIx64, baseaddr);
        } else
                command_print(CMD, "0x%08" PRIx32, baseaddr_lower);
 
-       return retval;
+       return ERROR_OK;
 }
 
 COMMAND_HANDLER(dap_memaccess_command)
diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h
index 5d1e793..73ceea0 100644
--- a/src/target/arm_adi_v5.h
+++ b/src/target/arm_adi_v5.h
@@ -151,9 +151,10 @@
 #define CSW_APB_DEFAULT         (CSW_DBGSWENABLE)
 
 /* Fields of the MEM-AP's CFG register */
-#define MEM_AP_REG_CFG_BE   BIT(0)
-#define MEM_AP_REG_CFG_LA   BIT(1)
-#define MEM_AP_REG_CFG_LD   BIT(2)
+#define MEM_AP_REG_CFG_BE       BIT(0)
+#define MEM_AP_REG_CFG_LA       BIT(1)
+#define MEM_AP_REG_CFG_LD       BIT(2)
+#define MEM_AP_REG_CFG_INVALID  0xFFFFFFF8
 
 /* Fields of the MEM-AP's IDR register */
 #define IDR_REV     (0xFUL << 28)
diff --git a/src/target/arm_dap.c b/src/target/arm_dap.c
index a399c51..2f21aa1 100644
--- a/src/target/arm_dap.c
+++ b/src/target/arm_dap.c
@@ -36,8 +36,6 @@ extern const struct dap_ops swd_dap_ops;
 extern const struct dap_ops jtag_dp_ops;
 extern struct adapter_driver *adapter_driver;
 
-#define ADI_BAD_CFG 0xBAD00000
-
 /* DAP command support */
 struct arm_dap_object {
        struct list_head lh;
@@ -59,7 +57,7 @@ static void dap_instance_init(struct adiv5_dap *dap)
                dap->ap[i].tar_autoincr_block = (1<<10);
                /* default CSW value */
                dap->ap[i].csw_default = CSW_AHB_DEFAULT;
-               dap->ap[i].cfg_reg = ADI_BAD_CFG; /* mem_ap configuration reg 
(large physical addr, etc.) */
+               dap->ap[i].cfg_reg = MEM_AP_REG_CFG_INVALID; /* mem_ap 
configuration reg (large physical addr, etc.) */
        }
        INIT_LIST_HEAD(&dap->cmd_journal);
        INIT_LIST_HEAD(&dap->cmd_pool);

-- 

Reply via email to