Skip to content

Commit

Permalink
esp32c3: Split out the target preparation (switching off the WDTs) fr…
Browse files Browse the repository at this point in the history
…om discovery so we can halt them early enough for discovery to be more reliable
  • Loading branch information
dragonmux committed Nov 16, 2023
1 parent 59d96d5 commit 89da05a
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 3 deletions.
24 changes: 21 additions & 3 deletions src/target/esp32c3.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions src/target/riscv_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
5 changes: 5 additions & 0 deletions src/target/target_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
1 change: 1 addition & 0 deletions src/target/target_probe.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

0 comments on commit 89da05a

Please sign in to comment.