From 964a8b203413c37590000f654702723de5be1e75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pero=20Or=C5=A1oli=C4=87?= Date: Sun, 19 Jan 2025 18:37:21 +0100 Subject: [PATCH 1/3] jtag_scan: add workaround for ESP32-P4 which has two ir_value --- src/target/jtag_scan.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/target/jtag_scan.c b/src/target/jtag_scan.c index 141e75305e1..09d9ebd15a6 100644 --- a/src/target/jtag_scan.c +++ b/src/target/jtag_scan.c @@ -208,11 +208,16 @@ static void jtag_display_idcodes(void) #endif } -static jtag_ir_quirks_s jtag_device_get_quirks(const uint32_t idcode) +static jtag_ir_quirks_s jtag_device_get_quirks(const uint32_t idcode, size_t *previous_idx) { for (size_t idx = 0; dev_descr[idx].idcode; ++idx) { - if ((idcode & dev_descr[idx].idmask) == dev_descr[idx].idcode) + if ((idcode & dev_descr[idx].idmask) == dev_descr[idx].idcode) { + /* workaround for ESP32-P4 which has 2 different ir_value */ + if (idcode == 0x12c25U && *previous_idx == idx) + idx++; + *previous_idx = idx; return dev_descr[idx].ir_quirks; + } } return (jtag_ir_quirks_s){0}; } @@ -228,8 +233,9 @@ static bool jtag_read_irs(void) size_t prescan = 0U; size_t device = 0U; uint8_t ir_len = 0U; + size_t previous_idx = 0U; /* Grab the first device's quirks, if any */ - jtag_ir_quirks_s ir_quirks = jtag_device_get_quirks(jtag_devs[0].jd_idcode); + jtag_ir_quirks_s ir_quirks = jtag_device_get_quirks(jtag_devs[0].jd_idcode, &previous_idx); /* Try scanning out the IR for the device */ while (ir_len <= JTAG_MAX_IR_LEN) { @@ -272,7 +278,7 @@ static bool jtag_read_irs(void) ++device; ir_len = overrun; /* Grab the device quirks for this new device, if any */ - ir_quirks = jtag_device_get_quirks(jtag_devs[device].jd_idcode); + ir_quirks = jtag_device_get_quirks(jtag_devs[device].jd_idcode, &previous_idx); } } From ee943509354c55fce5452f8ef161122cffce90f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pero=20Or=C5=A1oli=C4=87?= Date: Sun, 19 Jan 2025 19:10:04 +0100 Subject: [PATCH 2/3] ESP32-P4: Add JTAG IDs Tested on BMA, after jtag_scan: ID code 0x00012c25: ESP32-P4 ID code 0x00012c25: ESP32-P4 RISC-V debug v0.13/v1.0 DMI RISC-V debug v0.13 DM Skipping hart 0 -> Unavailable RISC-V debug v0.13/v1.0 DMI --- src/target/jtag_devs.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/target/jtag_devs.c b/src/target/jtag_devs.c index ecd6eca761a..011ab7cf53a 100644 --- a/src/target/jtag_devs.c +++ b/src/target/jtag_devs.c @@ -413,6 +413,32 @@ const jtag_dev_descr_s dev_descr[] = { #endif .handler = riscv_jtag_dtm_handler, }, + { + .idcode = 0x00012c25U, + .idmask = 0x0fffffffU, +#if ENABLE_DEBUG == 1 + .descr = "ESP32-P4", +#endif + .handler = riscv_jtag_dtm_handler, + .ir_quirks = + { + .ir_length = 5U, + .ir_value = 5U, + }, + }, + { + .idcode = 0x00012c25U, + .idmask = 0x0fffffffU, +#if ENABLE_DEBUG == 1 + .descr = "ESP32-P4", +#endif + .handler = riscv_jtag_dtm_handler, + .ir_quirks = + { + .ir_length = 5U, + .ir_value = 1U, + }, + }, #endif #if defined(CONFIG_CORTEXAR) // && defined(ENABLE_SITARA) { From 7dad25b0b6fb7beb2676fa6a98d310cf2685a7d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pero=20Or=C5=A1oli=C4=87?= Date: Tue, 21 Jan 2025 23:01:47 +0100 Subject: [PATCH 3/3] riscv_debug: Turn on DM before trying to read version According to the RISC-V debug specification, DM must be turned on before accessing DM registers (like reading version of DM). This fixes attaching to the target. --- src/target/riscv_debug.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/target/riscv_debug.c b/src/target/riscv_debug.c index 97a55590428..07280e18de2 100644 --- a/src/target/riscv_debug.c +++ b/src/target/riscv_debug.c @@ -302,8 +302,31 @@ void riscv_dmi_init(riscv_dmi_s *const dmi) /* The first DM is always at base address 0 */ uint32_t base_addr = 0U; do { + /* Turn on DM before trying to read version */ + if (!riscv_dmi_write(dmi, base_addr + RV_DM_CONTROL, RV_DM_CTRL_ACTIVE)) { + DEBUG_ERROR("error turning on DM!\n"); + return; + } + + /* After changing the value of dm_active, the debugger must poll dmcontrol + * until dm_active has taken the requested value */ + bool dm_active = false; + uint32_t dm_control = 0U; + uint8_t counter = 0U; + while (!dm_active) { + if (!riscv_dmi_read(dmi, base_addr + RV_DM_CONTROL, &dm_control)) { + DEBUG_ERROR("error turning on DM!\n"); + return; + } + dm_active = dm_control & 1U; + if (++counter >= 100U) { + DEBUG_ERROR("Timeout while trying to turn on DM\n"); + return; + } + } + /* Read out the DM's status register */ - uint32_t dm_status = 0; + uint32_t dm_status = 0U; if (!riscv_dmi_read(dmi, base_addr + RV_DM_STATUS, &dm_status)) { /* If we fail to read the status register, abort */ break;