arm_adi_v5: add support for 64bit Class 0x9 ROM tables

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
This commit is contained in:
Antonio Borneo 2022-01-15 21:31:41 +01:00
parent d74f11dcd4
commit a47d1f1b79
1 changed files with 32 additions and 11 deletions

View 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) {