From 57d3a0f8fa959eb812d64540dbe0fc84493bc1bd Mon Sep 17 00:00:00 2001 From: wangyanwen Date: Thu, 12 Dec 2024 12:29:34 +0800 Subject: [PATCH] src/target/riscv: fix etrace and hardware breakpoint conflicts Change-Id: Ieb74fd2631a7dc9b0c9fd901153136164653c29e Signed-off-by: wangyanwen --- src/target/riscv/nuclei_riscv.c | 11 +++++++++-- src/target/riscv/riscv.c | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/target/riscv/nuclei_riscv.c b/src/target/riscv/nuclei_riscv.c index 1d0944ebc..ac78c1eab 100644 --- a/src/target/riscv/nuclei_riscv.c +++ b/src/target/riscv/nuclei_riscv.c @@ -386,6 +386,7 @@ COMMAND_HANDLER(handle_nuclei_cpuinfo) static target_addr_t atb2axi_config_addr = 0xa5a5a5a5; static target_addr_t buffer_addr = 0xa5a5a5a5; static uint32_t buffer_size; +static riscv_reg_t tselect = 0xa5a5a5a5; static int etrace_read_reg(struct target *target, uint32_t offset, uint32_t *value) { @@ -447,6 +448,8 @@ COMMAND_HANDLER(handle_etrace_config_command) COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], buffer_size); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], wrap); + etrace_write_reg(target, ETRACE_ENDOFFSET, 0); + etrace_write_reg(target, ETRACE_FLG, 0); etrace_write_reg(target, ETRACE_BASE_HI, (uint32_t)(buffer_addr >> 32)); etrace_write_reg(target, ETRACE_BASE_LO, (uint32_t)buffer_addr); etrace_write_reg(target, ETRACE_WLEN, buffer_size); @@ -474,13 +477,18 @@ COMMAND_HANDLER(handle_etrace_enable_command) target_real = target; riscv_reg_t dpc_rb; - riscv_reg_t tselect = 0; riscv_reg_t tdata1 = field_value(CSR_MCONTROL_TYPE(riscv_xlen(target_real)), CSR_TDATA1_TYPE_MCONTROL) | field_value(CSR_MCONTROL_ACTION, CSR_MCONTROL_ACTION_TRACE_ON) | field_value(CSR_MCONTROL_M, 1) | field_value(CSR_MCONTROL_S, 1) | field_value(CSR_MCONTROL_U, 1) | field_value(CSR_MCONTROL_EXECUTE, 1); + RISCV_INFO(r); + if (atb2axi_config_addr == 0xa5a5a5a5) { + if (find_next_free_trigger(target_real, CSR_TDATA1_TYPE_MCONTROL, false, &tselect) != ERROR_OK) + return ERROR_FAIL; + r->reserved_triggers[tselect] = true; + } if (riscv_reg_set(target_real, GDB_REGNO_TSELECT, tselect) != ERROR_OK) return ERROR_FAIL; if (riscv_reg_set(target_real, GDB_REGNO_TDATA1, tdata1) != ERROR_OK) @@ -506,7 +514,6 @@ COMMAND_HANDLER(handle_etrace_disable_command) target_real = target; riscv_reg_t dpc_rb; - riscv_reg_t tselect = 1; riscv_reg_t tdata1 = field_value(CSR_MCONTROL_TYPE(riscv_xlen(target_real)), CSR_TDATA1_TYPE_MCONTROL) | field_value(CSR_MCONTROL_ACTION, CSR_MCONTROL_ACTION_TRACE_OFF) | field_value(CSR_MCONTROL_M, 1) | diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index fab2128e3..925b9bfbf 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -604,7 +604,7 @@ static bool can_use_napot_match(struct trigger *trigger) } /* Find the next free trigger of the given type, without talking to the target. */ -static int find_next_free_trigger(struct target *target, int type, bool chained, +int find_next_free_trigger(struct target *target, int type, bool chained, unsigned int *idx) { assert(idx);