[PATCH] libdebugger/arm: Support ROM tables.
chrisj at rtems.org
chrisj at rtems.org
Sun Aug 11 22:58:20 UTC 2019
From: Chris Johns <chrisj at rtems.org>
- Parse the ROM taables if present to find the component base for
the debug hardware. This lets the RPi2 run dl09.exe.
---
cpukit/libdebugger/rtems-debugger-arm.c | 303 +++++++++++++++++++++++-
1 file changed, 294 insertions(+), 9 deletions(-)
diff --git a/cpukit/libdebugger/rtems-debugger-arm.c b/cpukit/libdebugger/rtems-debugger-arm.c
index 72e67aed96..3d5dea0ab7 100644
--- a/cpukit/libdebugger/rtems-debugger-arm.c
+++ b/cpukit/libdebugger/rtems-debugger-arm.c
@@ -26,6 +26,8 @@
#define TARGET_DEBUG 0
+#define ARM_DUMP_ROM_TABLES 0
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -548,10 +550,278 @@ arm_debug_cp14_enable(rtems_debugger_target* target)
static jmp_buf unlock_abort_jmpbuf;
static size_t arm_debug_retries;
+static void
+arm_debug_dump_rom_table(uint32_t* rom, size_t depth)
+{
+ uint32_t pidr[7];
+ uint32_t cidr[4];
+ uint32_t memtype;
+ uint32_t pidr4_4KB_count;
+ size_t r;
+
+ static const char *table_class[16] = {
+ "reserved",
+ "ROM table",
+ "reserved", "reserved",
+ "reserved",
+ "reserved",
+ "reserved",
+ "reserved",
+ "reserved",
+ "CoreSight component",
+ "reserved",
+ "Peripheral Test Block",
+ "reserved",
+ "OptimoDE DESS",
+ "Generic IP component",
+ "PrimeCell or System component"
+ };
+
+ #define ROM_READ(b_, o_, r_) b_[((o_) / sizeof(uint32_t)) + (r_)]
+
+ if (depth > 16) {
+ rtems_debugger_printf("]] rom: too deep\n");
+ return;
+ }
+
+ for (r = 0; r < 4; ++r)
+ pidr[r] = ROM_READ(rom, 0xfe0, r) & 0xff;
+ for (r = 0; r < 3; ++r)
+ pidr[r + 4] = ROM_READ(rom, 0xfd0, r) & 0xff;
+ for (r = 0; r < 4; ++r)
+ cidr[r] = ROM_READ(rom, 0xff0, r) & 0xff;
+ memtype = ROM_READ(rom, 0xfcc, 0);
+
+ pidr4_4KB_count = pidr[4] & (((1 << (7 - 4)) - 1) >> 4);
+
+ rtems_debugger_printf("]] rom = %p\n", rom);
+ rtems_debugger_printf(" PIDR: %08x %08x %08x %08x %08x %08x %08x\n",
+ pidr[0], pidr[1], pidr[2], pidr[3],
+ pidr[4], pidr[5], pidr[6]);
+ rtems_debugger_printf(" CIDR: %08x %08x %08x %08x\n",
+ cidr[0], cidr[1], cidr[2], cidr[3]);
+ rtems_debugger_printf(" 4KB count: %u\n", pidr4_4KB_count);
+
+ if ((memtype & 0x01) != 0)
+ rtems_debugger_printf(" MEMTYPE sys memory present on bus\n");
+ else
+ rtems_debugger_printf(" MEMTYPE sys memory not present: dedicated debug bus\n");
+
+ /*
+ * Read ROM table entries until we get 0
+ */
+ for (r = 0; rom[r] != 0; ++r) {
+ uint32_t romentry = rom[r];
+ uint32_t c_pidr[7];
+ uint32_t c_cidr[4];
+ uint32_t* c_base;
+ uint32_t table_type;
+ size_t i;
+
+ c_base = (uint32_t*) ((intptr_t) rom + (romentry & 0xFFFFF000));
+
+ /*
+ * Read the IDs.
+ */
+ for (i = 0; i < 4; ++i)
+ c_pidr[i] = ROM_READ(c_base, 0xfe0, i) & 0xff;
+ for (i = 0; i < 3; ++i)
+ c_pidr[i + 4] = ROM_READ(c_base, 0xfd0, i) & 0xff;
+ for (i = 0; i < 4; ++i)
+ c_cidr[i] = ROM_READ(c_base, 0xff0, i) & 0xff;
+
+ table_type = ROM_READ(c_base, 0xfcc, 0);
+
+ rtems_debugger_printf(" > Base: %p, start: 0x%" PRIx32 "\n",
+ c_base,
+ /* component may take multiple 4K pages */
+ (uint32_t)((intptr_t) c_base - 0x1000 * (c_pidr[4] >> 4)));
+ rtems_debugger_printf(" Class is 0x%x, %s\n",
+ (c_cidr[1] >> 4) & 0xf, table_class[(c_cidr[1] >> 4) & 0xf]);
+
+ if (((c_cidr[1] >> 4) & 0x0f) == 1) {
+ arm_debug_dump_rom_table(c_base, depth + 1);
+ }
+ else if (((c_cidr[1] >> 4) & 0x0f) == 9) {
+ const char* major = "reserved";
+ const char* subtype = "reserved";
+ unsigned minor = (table_type >> 4) & 0x0f;
+
+ switch (table_type & 0x0f) {
+ case 0:
+ major = "Miscellaneous";
+ switch (minor) {
+ case 0:
+ subtype = "other";
+ break;
+ case 4:
+ subtype = "Validation component";
+ break;
+ }
+ break;
+ case 1:
+ major = "Trace Sink";
+ switch (minor) {
+ case 0:
+ subtype = "other";
+ break;
+ case 1:
+ subtype = "Port";
+ break;
+ case 2:
+ subtype = "Buffer";
+ break;
+ case 3:
+ subtype = "Router";
+ break;
+ }
+ break;
+ case 2:
+ major = "Trace Link";
+ switch (minor) {
+ case 0:
+ subtype = "other";
+ break;
+ case 1:
+ subtype = "Funnel, router";
+ break;
+ case 2:
+ subtype = "Filter";
+ break;
+ case 3:
+ subtype = "FIFO, buffer";
+ break;
+ }
+ break;
+ case 3:
+ major = "Trace Source";
+ switch (minor) {
+ case 0:
+ subtype = "other";
+ break;
+ case 1:
+ subtype = "Processor";
+ break;
+ case 2:
+ subtype = "DSP";
+ break;
+ case 3:
+ subtype = "Engine/Coprocessor";
+ break;
+ case 4:
+ subtype = "Bus";
+ break;
+ case 6:
+ subtype = "Software";
+ break;
+ }
+ break;
+ case 4:
+ major = "Debug Control";
+ switch (minor) {
+ case 0:
+ subtype = "other";
+ break;
+ case 1:
+ subtype = "Trigger Matrix";
+ break;
+ case 2:
+ subtype = "Debug Auth";
+ break;
+ case 3:
+ subtype = "Power Requestor";
+ break;
+ }
+ break;
+ case 5:
+ major = "Debug Logic";
+ switch (minor) {
+ case 0:
+ subtype = "other";
+ break;
+ case 1:
+ subtype = "Processor";
+ break;
+ case 2:
+ subtype = "DSP";
+ break;
+ case 3:
+ subtype = "Engine/Coprocessor";
+ break;
+ case 4:
+ subtype = "Bus";
+ break;
+ case 5:
+ subtype = "Memory";
+ }
+ break;
+ case 6:
+ major = "Perfomance Monitor";
+ switch (minor) {
+ case 0:
+ subtype = "other";
+ break;
+ case 1:
+ subtype = "Processor";
+ break;
+ case 2:
+ subtype = "DSP";
+ break;
+ case 3:
+ subtype = "Engine/Coprocessor";
+ break;
+ case 4:
+ subtype = "Bus";
+ break;
+ case 5:
+ subtype = "Memory";
+ break;
+ }
+ break;
+ }
+
+ rtems_debugger_printf(" Type: 0x%02" PRIx32 ", %s, %s\n",
+ table_type & 0xff, major, subtype);
+ rtems_debugger_printf(" PID[4..0]: %02x %02x %02x %02x %02x\n",
+ c_pidr[4], c_pidr[3], c_pidr[2], c_pidr[1], c_pidr[0]);
+
+ if (((c_cidr[1] >> 4) & 0x0f) == 1) {
+ arm_debug_dump_rom_table(c_base, depth + 1);
+ }
+ }
+ }
+}
+
+static int
+arm_debug_rom_discover(uint32_t* rom, uint32_t comp, uint32_t** addr, int* index)
+{
+ size_t r = 0;
+ *addr = 0;
+ while ((rom[r] & 1) != 0) {
+ uint32_t* c_base = (uint32_t*) ((intptr_t) rom + (rom[r] & 0xfffff000));
+ uint32_t c_cid1 = c_base[0xff4 / sizeof(uint32_t)];
+ uint32_t type;
+ if (((c_cid1 >> 4) & 0x0f) == 1) {
+ if (arm_debug_rom_discover(c_base, comp, addr, index))
+ return true;
+ }
+ type = c_base[0xfcc / sizeof(uint32_t)] & 0xff;
+ if (comp == type) {
+ if (*index > 0)
+ --(*index);
+ else {
+ *addr = c_base;
+ return true;
+ }
+ }
+ ++r;
+ }
+ return false;
+}
+
static int
arm_debug_mmap_enable(rtems_debugger_target* target, uint32_t dbgdidr)
{
- uint32_t rom;
uint32_t val;
void* abort_handler;
int rc = -1;
@@ -562,15 +832,29 @@ arm_debug_mmap_enable(rtems_debugger_target* target, uint32_t dbgdidr)
arm_debug_retries = 5;
/*
- * The DBGDSAR is a signed offset from DBGDRAR. Both need to be
- * valid for the debug register address to be valid. Currently there
- * is no support to decode a ROM table.
+ * The DBGDSAR (DSAR) is a signed offset from DBGDRAR. Both need to
+ * be valid for the debug register address to be valid. Read the
+ * DBGRAR first.
*/
- ARM_CP14_READ(rom, 1, 0, 0);
- if ((rom & 3) == 3) {
- ARM_CP14_READ(val, 2, 0, 0);
- if ((val & 3) == 3 ) {
- debug_registers = (void*) ((rom & ~3) + ((int32_t) (val & ~3)));
+ ARM_CP14_READ(val, 1, 0, 0);
+ if ((val & 3) == 3) {
+ uint32_t* rom = (uint32_t*) (val & 0xfffff000);
+ uint32_t* comp_base = NULL;
+ int core = (int) _SMP_Get_current_processor();
+
+ if (ARM_DUMP_ROM_TABLES)
+ arm_debug_dump_rom_table(rom, 0);
+
+ debug_registers = NULL;
+
+ if (arm_debug_rom_discover(rom, 0x15, &comp_base, &core)) {
+ debug_registers = comp_base;
+ rtems_debugger_printf("rtems-db: ram debug: ROM Base: %p\n", comp_base);
+ } else {
+ ARM_CP14_READ(val, 2, 0, 0);
+ if ((val & 3) == 3 ) {
+ debug_registers = (void*) ((intptr_t) rom + (val & ~3));
+ }
}
}
@@ -580,6 +864,7 @@ arm_debug_mmap_enable(rtems_debugger_target* target, uint32_t dbgdidr)
rtems_debugger_printf("rtems-db: arm debug: no valid register map\n");
return -1;
}
+ rtems_debugger_printf("rtems-db: arm debug: BSP Base: %p\n", debug_registers);
}
/*
--
2.19.1
More information about the devel
mailing list