Not all Sdtrig implementations have heterogeneous triggers. Add
support to the CPU class Sdtrig config to specify the trigger
types that each trigger supports.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
target/riscv/cpu.c | 8 ++++++++
target/riscv/debug.c | 17 +++++++++++++----
target/riscv/debug.h | 5 +++++
3 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6f7a327fc7..5708da5054 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -2961,6 +2961,14 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char *nodename)
/* Sdtrig implementation has 2 triggers that support match, match6, icount */
static const RISCVSdtrigConfig default_sdtrig_config = {
.nr_triggers = 2,
+ .triggers = {
+ [0 ... 1] = {
+ .type_mask = (1 << TRIGGER_TYPE_AD_MATCH) |
+ (1 << TRIGGER_TYPE_AD_MATCH6) |
+ (1 << TRIGGER_TYPE_INST_CNT) |
+ (1 << TRIGGER_TYPE_UNAVAIL),
+ },
+ },
};
bool riscv_sdtrig_default_implementation(const RISCVSdtrigConfig *config)
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index 93615b43fb..e8d343bf42 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -845,11 +845,19 @@ void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val)
}
if (tdata_index == TDATA1) {
+ CPUState *cs = env_cpu(env);
+ RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cs);
+
if (val == 0) {
/* special case, writing 0 results in disabled trigger */
val = build_tdata1(env, TRIGGER_TYPE_UNAVAIL, 0, 0);
}
trigger_type = extract_trigger_type(env, val);
+ if (!(mcc->def->debug_cfg->triggers[index].type_mask &
+ (1 << trigger_type))) {
+ val = build_tdata1(env, TRIGGER_TYPE_UNAVAIL, 0, 0);
+ trigger_type = extract_trigger_type(env, val);
+ }
}
switch (trigger_type) {
@@ -887,11 +895,12 @@ void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val)
target_ulong tinfo_csr_read(CPURISCVState *env)
{
- /* assume all triggers support the same types of triggers */
+ CPUState *cs = env_cpu(env);
+ RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cs);
+ target_ulong index = env->sdtrig_state.trigger_cur;
+
/* XXX: should we set 1 (version 1.0) in the version field? */
- return BIT(TRIGGER_TYPE_AD_MATCH) |
- BIT(TRIGGER_TYPE_INST_CNT) |
- BIT(TRIGGER_TYPE_AD_MATCH6);
+ return mcc->def->debug_cfg->triggers[index].type_mask;
}
void riscv_cpu_debug_excp_handler(CPUState *cs)
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
index 3ba12f95cd..f9e840d615 100644
--- a/target/riscv/debug.h
+++ b/target/riscv/debug.h
@@ -135,8 +135,13 @@ enum {
#define MHSELECT_IGNORE 0
#define MHSELECT_MCONTEXT 4
+struct trigger_properties {
+ uint16_t type_mask; /* Trigger types supported (0 = no trigger here) */
+};
+
typedef struct RISCVSdtrigConfig {
unsigned int nr_triggers;
+ struct trigger_properties triggers[RV_MAX_SDTRIG_TRIGGERS];
} RISCVSdtrigConfig;
bool tdata_available(CPURISCVState *env, int tdata_index);
--
2.51.0