arm_adi_v5: add support for 64bit Class 0x9 ROM tables 65/6465/6
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) {

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)