mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-29 05:38:42 +00:00
riscv: Use semihosting to set breakpoint and watchpoint when running under debugger
This commit is contained in:

committed by
Ivan Grokhotkov

parent
72822dfc8f
commit
dea45a9d72
@@ -14,6 +14,7 @@
|
||||
#include "soc/assist_debug_reg.h"
|
||||
#include "esp_attr.h"
|
||||
#include "riscv/csr.h"
|
||||
#include "riscv/semihosting.h"
|
||||
|
||||
/*performance counter*/
|
||||
#define CSR_PCER_MACHINE 0x7e0
|
||||
@@ -71,8 +72,29 @@ static inline void cpu_ll_init_hwloop(void)
|
||||
// Nothing needed here for ESP32-C3
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR bool cpu_ll_is_debugger_attached(void)
|
||||
{
|
||||
return REG_GET_BIT(ASSIST_DEBUG_CORE_0_DEBUG_MODE_REG, ASSIST_DEBUG_CORE_0_DEBUG_MODULE_ACTIVE);
|
||||
}
|
||||
|
||||
static inline void cpu_ll_set_breakpoint(int id, uint32_t pc)
|
||||
{
|
||||
if (cpu_ll_is_debugger_attached()) {
|
||||
/* If we want to set breakpoint which when hit transfers control to debugger
|
||||
* we need to set `action` in `mcontrol` to 1 (Enter Debug Mode).
|
||||
* That `action` value is supported only when `dmode` of `tdata1` is set.
|
||||
* But `dmode` can be modified by debugger only (from Debug Mode).
|
||||
*
|
||||
* So when debugger is connected we use special syscall to ask it to set breakpoint for us.
|
||||
*/
|
||||
long args[] = {true, id, (long)pc};
|
||||
int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_BREAKPOINT_SET, args);
|
||||
if (ret == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* The code bellow sets breakpoint which will trigger `Breakpoint` exception
|
||||
* instead transfering control to debugger. */
|
||||
RV_WRITE_CSR(tselect,id);
|
||||
RV_SET_CSR(CSR_TCONTROL,TCONTROL_MTE);
|
||||
RV_SET_CSR(CSR_TDATA1, TDATA1_USER|TDATA1_MACHINE|TDATA1_EXECUTE);
|
||||
@@ -82,6 +104,14 @@ static inline void cpu_ll_set_breakpoint(int id, uint32_t pc)
|
||||
|
||||
static inline void cpu_ll_clear_breakpoint(int id)
|
||||
{
|
||||
if (cpu_ll_is_debugger_attached()) {
|
||||
/* see description in cpu_ll_set_breakpoint() */
|
||||
long args[] = {false, id};
|
||||
int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_BREAKPOINT_SET, args);
|
||||
if (ret == 0){
|
||||
return;
|
||||
}
|
||||
}
|
||||
RV_WRITE_CSR(tselect,id);
|
||||
RV_CLEAR_CSR(CSR_TCONTROL,TCONTROL_MTE);
|
||||
RV_CLEAR_CSR(CSR_TDATA1, TDATA1_USER|TDATA1_MACHINE|TDATA1_EXECUTE);
|
||||
@@ -105,6 +135,17 @@ static inline void cpu_ll_set_watchpoint(int id,
|
||||
bool on_write)
|
||||
{
|
||||
uint32_t addr_napot;
|
||||
|
||||
if (cpu_ll_is_debugger_attached()) {
|
||||
/* see description in cpu_ll_set_breakpoint() */
|
||||
long args[] = {true, id, (long)addr, (long)size,
|
||||
(long)((on_read ? ESP_SEMIHOSTING_WP_FLG_RD : 0) | (on_write ? ESP_SEMIHOSTING_WP_FLG_WR : 0))};
|
||||
int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_WATCHPOINT_SET, args);
|
||||
if (ret == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
RV_WRITE_CSR(tselect,id);
|
||||
RV_SET_CSR(CSR_TCONTROL, TCONTROL_MPTE | TCONTROL_MTE);
|
||||
RV_SET_CSR(CSR_TDATA1, TDATA1_USER|TDATA1_MACHINE);
|
||||
@@ -123,6 +164,14 @@ static inline void cpu_ll_set_watchpoint(int id,
|
||||
|
||||
static inline void cpu_ll_clear_watchpoint(int id)
|
||||
{
|
||||
if (cpu_ll_is_debugger_attached()) {
|
||||
/* see description in cpu_ll_set_breakpoint() */
|
||||
long args[] = {false, id};
|
||||
int ret = semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_WATCHPOINT_SET, args);
|
||||
if (ret == 0){
|
||||
return;
|
||||
}
|
||||
}
|
||||
RV_WRITE_CSR(tselect,id);
|
||||
RV_CLEAR_CSR(CSR_TCONTROL,TCONTROL_MTE);
|
||||
RV_CLEAR_CSR(CSR_TDATA1, TDATA1_USER|TDATA1_MACHINE);
|
||||
@@ -132,11 +181,6 @@ static inline void cpu_ll_clear_watchpoint(int id)
|
||||
return;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR bool cpu_ll_is_debugger_attached(void)
|
||||
{
|
||||
return REG_GET_BIT(ASSIST_DEBUG_CORE_0_DEBUG_MODE_REG, ASSIST_DEBUG_CORE_0_DEBUG_MODULE_ACTIVE);
|
||||
}
|
||||
|
||||
static inline void cpu_ll_break(void)
|
||||
{
|
||||
asm volatile("ebreak\n");
|
||||
|
Reference in New Issue
Block a user