]> git.gag.com Git - fw/openocd/commitdiff
arm_adi_v5: add support for 64bit Class 0x9 ROM tables
authorAntonio Borneo <borneo.antonio@gmail.com>
Sat, 15 Jan 2022 20:31:41 +0000 (21:31 +0100)
committerAntonio Borneo <borneo.antonio@gmail.com>
Sat, 14 May 2022 08:56:37 +0000 (08:56 +0000)
Arm documentation does not explicitly report the order of the two
32bit words that compose the 64bit value. But both ADIv5 and ADIv6
specify that only little-endian is supported (ADIv5.2 obsoletes
the big-endian support). This change reads the 64bit value in
little-endian.

Detect the 64bit content and use it.

Change-Id: I723ec099c7e8c70c1f9a568e32ea867fcbf1f1db
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/6465
Tested-by: jenkins
src/target/arm_adi_v5.c

index 789fe5a44c36474f3692fe98b28a6ac207b5ae37..24de3053020f752e8ddb6e4b29f083851468bcad 100644 (file)
@@ -1461,7 +1461,7 @@ struct rtp_ops {
         * @param priv      Pointer to private data.
         * @return          ERROR_OK on success, else a fault code.
         */
-       int (*rom_table_entry)(int retval, int depth, unsigned int offset, uint32_t romentry,
+       int (*rom_table_entry)(int retval, int depth, unsigned int offset, uint64_t romentry,
                        void *priv);
        /**
         * Private data
@@ -1506,7 +1506,7 @@ static int rtp_ops_cs_component(const struct rtp_ops *ops,
  * Input parameter @a retval is propagated.
  */
 static int rtp_ops_rom_table_entry(const struct rtp_ops *ops,
-               int retval, int depth, unsigned int offset, uint32_t romentry)
+               int retval, int depth, unsigned int offset, uint64_t romentry)
 {
        if (!ops->rom_table_entry)
                return retval;
@@ -1533,20 +1533,39 @@ static int rtp_cs_component(const struct rtp_ops *ops,
 
 static int rtp_rom_loop(const struct rtp_ops *ops,
                struct adiv5_ap *ap, target_addr_t base_address, int depth,
-               unsigned int max_entries)
+               unsigned int width, unsigned int max_entries)
 {
        assert(IS_ALIGNED(base_address, ARM_CS_ALIGN));
 
        unsigned int offset = 0;
        while (max_entries--) {
-               uint32_t romentry;
+               uint64_t romentry;
+               uint32_t romentry_low, romentry_high;
+               target_addr_t component_base;
                unsigned int saved_offset = offset;
 
-               int retval = mem_ap_read_atomic_u32(ap, base_address + offset, &romentry);
+               int retval = mem_ap_read_u32(ap, base_address + offset, &romentry_low);
                offset += 4;
+               if (retval == ERROR_OK && width == 64) {
+                       retval = mem_ap_read_u32(ap, base_address + offset, &romentry_high);
+                       offset += 4;
+               }
+               if (retval == ERROR_OK)
+                       retval = dap_run(ap->dap);
                if (retval != ERROR_OK)
                        LOG_DEBUG("Failed read ROM table entry");
 
+               if (width == 64) {
+                       romentry = (((uint64_t)romentry_high) << 32) | romentry_low;
+                       component_base = base_address +
+                               ((((uint64_t)romentry_high) << 32) | (romentry_low & ARM_CS_ROMENTRY_OFFSET_MASK));
+               } else {
+                       romentry = romentry_low;
+                       /* "romentry" is signed */
+                       component_base = base_address + (int32_t)(romentry_low & ARM_CS_ROMENTRY_OFFSET_MASK);
+                       if (!is_64bit_ap(ap))
+                               component_base = (uint32_t)component_base;
+               }
                retval = rtp_ops_rom_table_entry(ops, retval, depth, saved_offset, romentry);
                if (retval != ERROR_OK)
                        return retval;
@@ -1559,8 +1578,7 @@ static int rtp_rom_loop(const struct rtp_ops *ops,
                if (!(romentry & ARM_CS_ROMENTRY_PRESENT))
                        continue;
 
-               /* Recurse. "romentry" is signed */
-               target_addr_t component_base = base_address + (int32_t)(romentry & ARM_CS_ROMENTRY_OFFSET_MASK);
+               /* Recurse */
                retval = rtp_cs_component(ops, ap, component_base, depth + 1);
                if (retval == CORESIGHT_COMPONENT_FOUND)
                        return CORESIGHT_COMPONENT_FOUND;
@@ -1599,7 +1617,7 @@ static int rtp_cs_component(const struct rtp_ops *ops,
        const unsigned int class = ARM_CS_CIDR_CLASS(v.cid);
 
        if (class == ARM_CS_CLASS_0X1_ROM_TABLE)
-               return rtp_rom_loop(ops, ap, base_address, depth, 960);
+               return rtp_rom_loop(ops, ap, base_address, depth, 32, 960);
 
        if (class == ARM_CS_CLASS_0X9_CS_COMPONENT) {
                if ((v.devarch & ARM_CS_C9_DEVARCH_PRESENT) == 0)
@@ -1609,7 +1627,10 @@ static int rtp_cs_component(const struct rtp_ops *ops,
                if ((v.devarch & DEVARCH_ID_MASK) != DEVARCH_ROM_C_0X9)
                        return ERROR_OK;
 
-               return rtp_rom_loop(ops, ap, base_address, depth, 512);
+               if ((v.devid & ARM_CS_C9_DEVID_FORMAT_MASK) == ARM_CS_C9_DEVID_FORMAT_64BIT)
+                       return rtp_rom_loop(ops, ap, base_address, depth, 64, 256);
+               else
+                       return rtp_rom_loop(ops, ap, base_address, depth, 32, 512);
        }
 
        /* Class other than 0x1 and 0x9 */
@@ -1786,7 +1807,7 @@ static int dap_info_cs_component(int retval, struct cs_component_vals *v, int de
 }
 
 static int dap_info_rom_table_entry(int retval, int depth,
-               unsigned int offset, uint32_t romentry, void *priv)
+               unsigned int offset, uint64_t romentry, void *priv)
 {
        struct command_invocation *cmd = priv;
        char tabs[16] = "";
@@ -1801,7 +1822,7 @@ static int dap_info_rom_table_entry(int retval, int depth,
                return retval;
        }
 
-       command_print(cmd, "\t%sROMTABLE[0x%x] = 0x%08" PRIx32,
+       command_print(cmd, "\t%sROMTABLE[0x%x] = 0x%08" PRIx64,
                        tabs, offset, romentry);
 
        if (romentry == 0) {