From df2565050202f448733407a1c000117ec7ffdb67 Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Mon, 12 Aug 2019 08:56:37 +1000 Subject: libdebugger/arm: Support ROM tables. - 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(-) (limited to 'cpukit/libdebugger') 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); } /* -- cgit v1.2.3