esp_gdbstup: implement runtime gdbstub for riscv

This commit is contained in:
Alexey Lapshin
2023-04-08 00:09:22 +08:00
parent 36588c4b35
commit 9322c2b82d
12 changed files with 355 additions and 55 deletions

View File

@@ -187,6 +187,25 @@ static inline void enable_all_wdts(void)
}
}
int getActiveTaskNum(void);
int __swrite(struct _reent *, void *, const char *, int);
int gdbstub__swrite(struct _reent *data1, void *data2, const char *buff, int len);
volatile esp_gdbstub_frame_t *temp_regs_frame;
#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
static int bp_count = 0;
static int wp_count = 0;
static uint32_t bp_list[SOC_CPU_BREAKPOINTS_NUM] = {0};
static uint32_t wp_list[SOC_CPU_WATCHPOINTS_NUM] = {0};
static uint32_t wp_size[SOC_CPU_WATCHPOINTS_NUM] = {0};
static esp_cpu_watchpoint_trigger_t wp_access[SOC_CPU_WATCHPOINTS_NUM] = {0};
static volatile bool step_in_progress = false;
static bool not_send_reason = false;
static bool process_gdb_kill = false;
static bool gdb_debug_int = false;
/**
* @breef Handle UART interrupt
*
@@ -196,24 +215,7 @@ static inline void enable_all_wdts(void)
*
* @param curr_regs - actual registers frame
*
*/
static int bp_count = 0;
static int wp_count = 0;
static uint32_t bp_list[GDB_BP_SIZE] = {0};
static uint32_t wp_list[GDB_WP_SIZE] = {0};
static uint32_t wp_size[GDB_WP_SIZE] = {0};
static esp_cpu_watchpoint_trigger_t wp_access[GDB_WP_SIZE] = {0};
static volatile bool step_in_progress = false;
static bool not_send_reason = false;
static bool process_gdb_kill = false;
static bool gdb_debug_int = false;
int getActiveTaskNum(void);
int __swrite(struct _reent *, void *, const char *, int);
int gdbstub__swrite(struct _reent *data1, void *data2, const char *buff, int len);
volatile esp_gdbstub_frame_t *temp_regs_frame;
*/
void gdbstub_handle_uart_int(esp_gdbstub_frame_t *regs_frame)
{
temp_regs_frame = regs_frame;
@@ -264,11 +266,9 @@ void gdbstub_handle_uart_int(esp_gdbstub_frame_t *regs_frame)
if (res == -2) {
esp_gdbstub_send_str_packet(NULL);
}
#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
if (res == GDBSTUB_ST_CONT) {
break;
}
#endif /* CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME */
}
{
/* Resume other core */
@@ -356,16 +356,12 @@ void gdbstub_handle_debug_int(esp_gdbstub_frame_t *regs_frame)
gdb_debug_int = false;
}
intr_handle_t intr_handle_;
extern void _xt_gdbstub_int(void * );
#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
/** @brief Init gdbstub
* Init uart interrupt for gdbstub
* */
void esp_gdbstub_init(void)
{
esp_intr_alloc(ETS_UART0_INTR_SOURCE, 0, _xt_gdbstub_int, NULL, &intr_handle_);
esp_intr_alloc(ETS_UART0_INTR_SOURCE, 0, esp_gdbstub_int, NULL, NULL);
esp_gdbstub_init_dports();
}
#endif /* CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME */
@@ -474,8 +470,10 @@ static void handle_M_command(const unsigned char *cmd, int len)
esp_gdbstub_send_end();
}
#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
void update_breakpoints(void)
{
#if CONFIG_IDF_TARGET_ARCH_XTENSA
for (size_t i = 0; i < GDB_BP_SIZE; i++) {
if (bp_list[i] != 0) {
esp_cpu_set_breakpoint(i, (const void *)bp_list[i]);
@@ -490,9 +488,33 @@ void update_breakpoints(void)
esp_cpu_clear_watchpoint(i);
}
}
#else // CONFIG_IDF_TARGET_ARCH_XTENSA
#if (GDB_BP_SIZE != GDB_WP_SIZE)
#error "riscv have a common number of BP and WP"
#endif
/*
* On riscv we have no separated registers for setting BP and WP as we have for xtensa.
* Instead we have common registers which could be configured as BP or WP.
*/
size_t i = 0;
for (size_t b = 0; b < GDB_BP_SIZE; b++) {
if (bp_list[b] != 0) {
esp_cpu_set_breakpoint(i, (const void *)bp_list[b]);
i++;
}
}
for (size_t w = 0; w < GDB_WP_SIZE && i < GDB_WP_SIZE; w++) {
if (wp_list[w] != 0) {
esp_cpu_set_watchpoint(i, (void *)wp_list[w], wp_size[w], wp_access[w]);
i++;
}
}
for (; i < GDB_BP_SIZE; i++) {
esp_cpu_clear_breakpoint(i);
}
#endif // CONFIG_IDF_TARGET_ARCH_XTENSA
}
#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
/** Write breakpoint */
static void handle_Z0_command(const unsigned char *cmd, int len)
{
@@ -626,7 +648,7 @@ static void handle_S_command(const unsigned char *cmd, int len)
static void handle_s_command(const unsigned char *cmd, int len)
{
step_in_progress = true;
esp_gdbstub_do_step();
esp_gdbstub_do_step((esp_gdbstub_frame_t *)temp_regs_frame);
}
/** Step ... */
@@ -888,9 +910,11 @@ static eTaskState get_task_state(size_t index)
eTaskState result = eReady;
TaskHandle_t handle = NULL;
get_task_handle(index, &handle);
#if CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
if (gdb_debug_int == false) {
result = eTaskGetState(handle);
}
#endif
return result;
}