From be4224bb263259125d10ac11d8bd5806343de441 Mon Sep 17 00:00:00 2001 From: dragonmux Date: Fri, 10 Nov 2023 14:27:07 +0000 Subject: [PATCH] esp32c3: Split out the target preparation (switching off the WDTs) from discovery so we can halt them early enough for discovery to be more reliable --- src/target/esp32c3.c | 24 +++++++++++++++++++++--- src/target/riscv_debug.c | 6 ++++++ src/target/target_probe.c | 5 +++++ src/target/target_probe.h | 1 + 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/target/esp32c3.c b/src/target/esp32c3.c index 98300b5cfd5..43bbff65374 100644 --- a/src/target/esp32c3.c +++ b/src/target/esp32c3.c @@ -37,6 +37,7 @@ #include "riscv_debug.h" #include "spi.h" #include "sfdp.h" +#include "jep106.h" #define ESP32_C3_ARCH_ID 0x80000001U #define ESP32_C3_IMPL_ID 0x00000001U @@ -149,21 +150,38 @@ static bool esp32c3_exit_flash_mode(target_s *target); static bool esp32c3_spi_flash_erase(target_flash_s *flash, target_addr_t addr, size_t length); static bool esp32c3_spi_flash_write(target_flash_s *flash, target_addr_t dest, const void *src, size_t length); -bool esp32c3_probe(target_s *const target) +/* Make an ESP32-C3 ready for probe operations having identified one */ +bool esp32c3_target_prepare(target_s *const target) { const riscv_hart_s *const hart = riscv_hart_struct(target); /* Seems that the best we can do is check the marchid and mimplid register values */ - if (hart->archid != ESP32_C3_ARCH_ID || hart->implid != ESP32_C3_IMPL_ID) + if (target->designer_code != JEP106_MANUFACTURER_ESPRESSIF || hart->archid != ESP32_C3_ARCH_ID || + hart->implid != ESP32_C3_IMPL_ID) return false; + /* Allocate the private structure here so we can store the WDT states */ esp32c3_priv_s *const priv = calloc(1, sizeof(esp32c3_priv_s)); if (!priv) { /* calloc failed: heap exhaustion */ DEBUG_ERROR("calloc: failed in %s\n", __func__); return false; } target->target_storage = priv; - target->driver = "ESP32-C3"; + /* Prepare the target for memory IO */ + target->mem_read = riscv32_mem_read; + target->mem_write = riscv32_mem_write; + /* Now disable the WDTs so the stop causing problems ready for discovering trigger slots, etc */ esp32c3_disable_wdts(target); + return true; +} + +bool esp32c3_probe(target_s *const target) +{ + const riscv_hart_s *const hart = riscv_hart_struct(target); + /* Seems that the best we can do is check the marchid and mimplid register values */ + if (hart->archid != ESP32_C3_ARCH_ID || hart->implid != ESP32_C3_IMPL_ID) + return false; + + target->driver = "ESP32-C3"; /* We have to provide our own halt/resume functions to take care of the WDTs as they cause Problems */ target->halt_request = esp32c3_halt_request; diff --git a/src/target/riscv_debug.c b/src/target/riscv_debug.c index 944340195b8..8bca58f9739 100644 --- a/src/target/riscv_debug.c +++ b/src/target/riscv_debug.c @@ -385,6 +385,12 @@ static bool riscv_hart_init(riscv_hart_s *const hart) target->designer_code = hart->vendorid ? hart->vendorid : hart->dbg_module->dmi_bus->designer_code; target->cpuid = hart->archid; + /* + * Now we've identified the target, and before we can do things like trigger discovery + * we need to first run any target-specific setup (eg, halting the WDTs on the ESP32-C3) + * so the next steps won't get screwed up by them. + */ + esp32c3_target_prepare(target); /* Now we're in a safe environment, leasurely read out the triggers, etc. */ riscv_hart_discover_triggers(hart); diff --git a/src/target/target_probe.c b/src/target/target_probe.c index a5511c18c6a..343a170f17d 100644 --- a/src/target/target_probe.c +++ b/src/target/target_probe.c @@ -129,3 +129,8 @@ TARGET_PROBE_WEAK_NOP(zynq7_probe) TARGET_PROBE_WEAK_NOP(esp32c3_probe) LPC55_DP_PREPARE_WEAK_NOP(lpc55_dp_prepare) +/* + * This isn't actually a probe routine, but it shares its signature with them, + * so uses the same no-op stub because we can get away with that. + */ +TARGET_PROBE_WEAK_NOP(esp32c3_target_prepare) diff --git a/src/target/target_probe.h b/src/target/target_probe.h index ba768498bd5..57d95e8d4f8 100644 --- a/src/target/target_probe.h +++ b/src/target/target_probe.h @@ -97,5 +97,6 @@ bool zynq7_probe(target_s *target); bool esp32c3_probe(target_s *target); void lpc55_dp_prepare(adiv5_debug_port_s *dp); +bool esp32c3_target_prepare(target_s *target); #endif /* TARGET_TARGET_PROBE_H */