targets: Print nested ROM tables with the 'dap info' command.

Move the ROM table printing into a separate function to allow
recursive calls with nested tables. ROM tables can nest. The
printing is limited to 16 levels.

Update the types of tables printed. When an entry can't be read, print
a warning and continue.

Change-Id: Ib134edd9e987af2f5f606071521885b17af4d70f
Signed-off-by: Chris Johns <chrisj@rtems.org>
Reviewed-on: http://openocd.zylin.com/1427
Tested-by: jenkins
Reviewed-by: Andreas Fritiofson <andreas.fritiofson@gmail.com>
__archive__
Chris Johns 2013-05-29 09:47:34 +10:00 committed by Andreas Fritiofson
parent e3bb6d390c
commit 623eb336cf
1 changed files with 382 additions and 344 deletions

View File

@ -1025,59 +1025,29 @@ int dap_lookup_cs_component(struct adiv5_dap *dap, int ap,
return retval;
}
static int dap_info_command(struct command_context *cmd_ctx,
struct adiv5_dap *dap, int ap)
static int dap_rom_display(struct command_context *cmd_ctx,
struct adiv5_dap *dap, int ap, uint32_t dbgbase, int depth)
{
int retval;
uint32_t dbgbase = 0, apid = 0; /* Silence gcc by initializing */
int romtable_present = 0;
uint8_t mem_ap;
uint32_t ap_old;
retval = dap_get_debugbase(dap, ap, &dbgbase, &apid);
if (retval != ERROR_OK)
return retval;
ap_old = dap->ap_current;
dap_ap_select(dap, ap);
/* Now we read ROM table ID registers, ref. ARM IHI 0029B sec */
mem_ap = ((apid&0x10000) && ((apid&0x0F) != 0));
command_print(cmd_ctx, "AP ID register 0x%8.8" PRIx32, apid);
if (apid) {
switch (apid&0x0F) {
case 0:
command_print(cmd_ctx, "\tType is JTAG-AP");
break;
case 1:
command_print(cmd_ctx, "\tType is MEM-AP AHB");
break;
case 2:
command_print(cmd_ctx, "\tType is MEM-AP APB");
break;
default:
command_print(cmd_ctx, "\tUnknown AP type");
break;
}
/* NOTE: a MEM-AP may have a single CoreSight component that's
* not a ROM table ... or have no such components at all.
*/
if (mem_ap)
command_print(cmd_ctx, "AP BASE 0x%8.8" PRIx32, dbgbase);
} else
command_print(cmd_ctx, "No AP found at this ap 0x%x", ap);
romtable_present = ((mem_ap) && (dbgbase != 0xFFFFFFFF));
if (romtable_present) {
uint32_t cid0, cid1, cid2, cid3, memtype, romentry;
uint16_t entry_offset;
int i;
char tabs[16 + 1];
if (depth > 16) {
command_print(cmd_ctx, "\tTables too deep");
return ERROR_FAIL;
}
for (i = 0; i < depth; ++i)
tabs[i] = '\t';
tabs[i] = '\0';
/* bit 16 of apid indicates a memory access port */
if (dbgbase & 0x02)
command_print(cmd_ctx, "\tValid ROM table present");
command_print(cmd_ctx, "\t%sValid ROM table present", tabs);
else
command_print(cmd_ctx, "\tROM table in legacy format");
command_print(cmd_ctx, "\t%sROM table in legacy format", tabs);
/* Now we read ROM table ID registers, ref. ARM IHI 0029B sec */
retval = mem_ap_read_u32(dap, (dbgbase&0xFFFFF000) | 0xFF0, &cid0);
@ -1100,25 +1070,25 @@ static int dap_info_command(struct command_context *cmd_ctx,
return retval;
if (!is_dap_cid_ok(cid3, cid2, cid1, cid0))
command_print(cmd_ctx, "\tCID3 0x%2.2x"
", CID2 0x%2.2x"
", CID1 0x%2.2x"
", CID0 0x%2.2x",
command_print(cmd_ctx, "\t%sCID3 0x%02x"
", CID2 0x%02x"
", CID1 0x%02x"
", CID0 0x%02x",
tabs,
(unsigned)cid3, (unsigned)cid2,
(unsigned)cid1, (unsigned)cid0);
if (memtype & 0x01)
command_print(cmd_ctx, "\tMEMTYPE system memory present on bus");
command_print(cmd_ctx, "\t%sMEMTYPE system memory present on bus", tabs);
else
command_print(cmd_ctx, "\tMEMTYPE System memory not present. "
"Dedicated debug bus.");
command_print(cmd_ctx, "\t%sMEMTYPE system memory not present: dedicated debug bus", tabs);
/* Now we read ROM table entries from dbgbase&0xFFFFF000) | 0x000 until we get 0x00000000 */
entry_offset = 0;
do {
for (entry_offset = 0; ; entry_offset += 4) {
retval = mem_ap_read_atomic_u32(dap, (dbgbase&0xFFFFF000) | entry_offset, &romentry);
if (retval != ERROR_OK)
return retval;
command_print(cmd_ctx, "\tROMTABLE[0x%x] = 0x%" PRIx32 "", entry_offset, romentry);
command_print(cmd_ctx, "\t%sROMTABLE[0x%x] = 0x%" PRIx32 "",
tabs, entry_offset, romentry);
if (romentry & 0x01) {
uint32_t c_cid0, c_cid1, c_cid2, c_cid3;
uint32_t c_pid0, c_pid1, c_pid2, c_pid3, c_pid4;
@ -1130,8 +1100,11 @@ static int dap_info_command(struct command_context *cmd_ctx,
/* IDs are in last 4K section */
retval = mem_ap_read_atomic_u32(dap, component_base + 0xFE0, &c_pid0);
if (retval != ERROR_OK)
return retval;
if (retval != ERROR_OK) {
command_print(cmd_ctx, "\t%s\tCan't read component with base address 0x%" PRIx32
", the corresponding core might be turned off", tabs, component_base);
continue;
}
c_pid0 &= 0xff;
retval = mem_ap_read_atomic_u32(dap, component_base + 0xFE4, &c_pid1);
if (retval != ERROR_OK)
@ -1167,12 +1140,12 @@ static int dap_info_command(struct command_context *cmd_ctx,
return retval;
c_cid3 &= 0xff;
command_print(cmd_ctx, "\t\tComponent base address 0x%" PRIx32 ","
"start address 0x%" PRIx32, component_base,
command_print(cmd_ctx, "\t%s\tComponent base address 0x%" PRIx32 ", "
"start address 0x%" PRIx32, tabs, component_base,
/* component may take multiple 4K pages */
component_base - 0x1000*(c_pid4 >> 4));
command_print(cmd_ctx, "\t\tComponent class is 0x%x, %s",
(int) (c_cid1 >> 4) & 0xf,
(uint32_t)(component_base - 0x1000*(c_pid4 >> 4)));
command_print(cmd_ctx, "\t%s\tComponent class is 0x%x, %s",
tabs, (c_cid1 >> 4) & 0xf,
/* See ARM IHI 0029B Table 3-3 */
class_description[(c_cid1 >> 4) & 0xf]);
@ -1283,25 +1256,26 @@ static int dap_info_command(struct command_context *cmd_ctx,
}
break;
}
command_print(cmd_ctx, "\t\tType is 0x%2.2x, %s, %s",
(unsigned) (devtype & 0xff),
command_print(cmd_ctx, "\t%s\tType is 0x%02x, %s, %s",
tabs, devtype & 0xff,
major, subtype);
/* REVISIT also show 0xfc8 DevId */
}
if (!is_dap_cid_ok(cid3, cid2, cid1, cid0))
command_print(cmd_ctx,
"\t\tCID3 0%2.2x"
", CID2 0%2.2x"
", CID1 0%2.2x"
", CID0 0%2.2x",
"\t%s\tCID3 0%02x"
", CID2 0%02x"
", CID1 0%02x"
", CID0 0%02x",
tabs,
(int)c_cid3,
(int)c_cid2,
(int)c_cid1,
(int)c_cid0);
command_print(cmd_ctx,
"\t\tPeripheral ID[4..0] = hex "
"%2.2x %2.2x %2.2x %2.2x %2.2x",
"\t%s\tPeripheral ID[4..0] = hex "
"%02x %02x %02x %02x %02x", tabs,
(int)c_pid4, (int)c_pid3, (int)c_pid2,
(int)c_pid1, (int)c_pid0);
@ -1367,6 +1341,10 @@ static int dap_info_command(struct command_context *cmd_ctx,
type = "Coresight TPIU";
full = "(Trace Port Interface Unit)";
break;
case 0x913:
type = "Coresight ITM";
full = "(Instrumentation Trace Macrocell)";
break;
case 0x921:
type = "Cortex-A8 ETM";
full = "(Embedded Trace)";
@ -1399,21 +1377,81 @@ static int dap_info_command(struct command_context *cmd_ctx,
type = "Cortex-A8 Debug";
full = "(Debug Unit)";
break;
case 0xc09:
type = "Cortex-A9 Debug";
full = "(Debug Unit)";
break;
default:
type = "-*- unrecognized -*-";
full = "";
break;
}
command_print(cmd_ctx, "\t\tPart is %s %s",
type, full);
command_print(cmd_ctx, "\t%s\tPart is %s %s",
tabs, type, full);
/* ROM Table? */
if (((c_cid1 >> 4) & 0x0f) == 1) {
retval = dap_rom_display(cmd_ctx, dap, ap, component_base, depth + 1);
if (retval != ERROR_OK)
return retval;
}
} else {
if (romentry)
command_print(cmd_ctx, "\t\tComponent not present");
command_print(cmd_ctx, "\t%s\tComponent not present", tabs);
else
command_print(cmd_ctx, "\t\tEnd of ROM table");
break;
}
entry_offset += 4;
} while (romentry > 0);
}
command_print(cmd_ctx, "\t%s\tEnd of ROM table", tabs);
return ERROR_OK;
}
static int dap_info_command(struct command_context *cmd_ctx,
struct adiv5_dap *dap, int ap)
{
int retval;
uint32_t dbgbase = 0, apid = 0; /* Silence gcc by initializing */
int romtable_present = 0;
uint8_t mem_ap;
uint32_t ap_old;
retval = dap_get_debugbase(dap, ap, &dbgbase, &apid);
if (retval != ERROR_OK)
return retval;
ap_old = dap->ap_current;
dap_ap_select(dap, ap);
/* Now we read ROM table ID registers, ref. ARM IHI 0029B sec */
mem_ap = ((apid&0x10000) && ((apid&0x0F) != 0));
command_print(cmd_ctx, "AP ID register 0x%8.8" PRIx32, apid);
if (apid) {
switch (apid&0x0F) {
case 0:
command_print(cmd_ctx, "\tType is JTAG-AP");
break;
case 1:
command_print(cmd_ctx, "\tType is MEM-AP AHB");
break;
case 2:
command_print(cmd_ctx, "\tType is MEM-AP APB");
break;
default:
command_print(cmd_ctx, "\tUnknown AP type");
break;
}
/* NOTE: a MEM-AP may have a single CoreSight component that's
* not a ROM table ... or have no such components at all.
*/
if (mem_ap)
command_print(cmd_ctx, "AP BASE 0x%8.8" PRIx32, dbgbase);
} else
command_print(cmd_ctx, "No AP found at this ap 0x%x", ap);
romtable_present = ((mem_ap) && (dbgbase != 0xFFFFFFFF));
if (romtable_present) {
dap_rom_display(cmd_ctx, dap, ap, dbgbase, 0);
} else
command_print(cmd_ctx, "\tNo ROM table present");
dap_ap_select(dap, ap_old);