mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
feat(esp_gdbstub): support watchpoint trigger reason
This commit is contained in:
@@ -169,6 +169,15 @@ void esp_gdbstub_clear_step(void);
|
||||
void esp_gdbstub_do_step(esp_gdbstub_frame_t *regs_frame);
|
||||
void esp_gdbstub_trigger_cpu(void);
|
||||
|
||||
#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
|
||||
/**
|
||||
* Check if a watchpoint triggered the current debug exception.
|
||||
* @param[out] addr Address of the triggered watchpoint (only valid if return is true)
|
||||
* @return true if a watchpoint triggered, false otherwise (breakpoint/step/other)
|
||||
*/
|
||||
bool esp_gdbstub_get_watchpoint_trigger_addr(uint32_t *addr);
|
||||
#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
|
||||
|
||||
/**
|
||||
* Write a value to register in frame
|
||||
* @param frame gdbstub frame
|
||||
|
||||
@@ -28,6 +28,10 @@
|
||||
#define GDBSTUB_QXFER_SUPPORTED_STR ""
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
|
||||
static void send_watchpoint_reason(void);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP_GDBSTUB_SUPPORT_TASKS
|
||||
static inline int gdb_tid_to_task_index(int tid);
|
||||
static inline int task_index_to_gdb_tid(int tid);
|
||||
@@ -107,6 +111,9 @@ static void send_reason(void)
|
||||
esp_gdbstub_send_start();
|
||||
esp_gdbstub_send_char('T');
|
||||
esp_gdbstub_send_hex(s_scratch.signal, 8);
|
||||
#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
|
||||
send_watchpoint_reason();
|
||||
#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
|
||||
esp_gdbstub_send_end();
|
||||
}
|
||||
|
||||
@@ -212,6 +219,35 @@ static bool not_send_reason = false;
|
||||
static bool process_gdb_kill = false;
|
||||
static bool gdb_debug_int = false;
|
||||
|
||||
/**
|
||||
* Detect if a watchpoint triggered and append the corresponding
|
||||
* GDB RSP stop-reply field (watch/rwatch/awatch) to the current packet.
|
||||
*/
|
||||
static void send_watchpoint_reason(void)
|
||||
{
|
||||
uint32_t wp_addr = 0;
|
||||
if (!esp_gdbstub_get_watchpoint_trigger_addr(&wp_addr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char *type_str = "watch";
|
||||
for (size_t i = 0; i < SOC_CPU_WATCHPOINTS_NUM; i++) {
|
||||
if (wp_list[i] == wp_addr) {
|
||||
if (wp_access[i] == ESP_CPU_WATCHPOINT_LOAD) {
|
||||
type_str = "rwatch";
|
||||
} else if (wp_access[i] == ESP_CPU_WATCHPOINT_ACCESS) {
|
||||
type_str = "awatch";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
esp_gdbstub_send_str(type_str);
|
||||
esp_gdbstub_send_char(':');
|
||||
esp_gdbstub_send_hex(wp_addr, 32);
|
||||
esp_gdbstub_send_char(';');
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle UART interrupt
|
||||
*
|
||||
|
||||
@@ -250,6 +250,22 @@ void esp_gdbstub_init_dports(void)
|
||||
{
|
||||
}
|
||||
|
||||
bool esp_gdbstub_get_watchpoint_trigger_addr(uint32_t *addr)
|
||||
{
|
||||
for (int i = 0; i < SOC_CPU_BREAKPOINTS_NUM; i++) {
|
||||
RV_WRITE_CSR(tselect, i);
|
||||
uint32_t tdata1 = RV_READ_CSR(tdata1);
|
||||
bool is_load = tdata1 & TDATA1_LOAD;
|
||||
bool is_store = tdata1 & TDATA1_STORE;
|
||||
bool is_exec = tdata1 & TDATA1_EXECUTE;
|
||||
if (!is_exec && (is_load || is_store)) {
|
||||
*addr = RV_READ_CSR(tdata2);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
|
||||
|
||||
#if (!CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE) && CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
|
||||
|
||||
@@ -307,6 +307,23 @@ void esp_gdbstub_init_dports(void)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
|
||||
bool esp_gdbstub_get_watchpoint_trigger_addr(uint32_t *addr)
|
||||
{
|
||||
uint32_t debugcause;
|
||||
RSR(XT_REG_DEBUGCAUSE, debugcause);
|
||||
if (debugcause & XCHAL_DEBUGCAUSE_DBREAK_MASK) {
|
||||
if (debugcause & (1 << 8)) {
|
||||
RSR(XT_REG_DBREAKA_1, *addr);
|
||||
} else {
|
||||
RSR(XT_REG_DBREAKA_0, *addr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
|
||||
|
||||
#if CONFIG_IDF_TARGET_ARCH_XTENSA && (!CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE) && CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
|
||||
static bool stall_started = false;
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user