[RFC PATCH 22/25] target/riscv/debug: Support heterogeneous trigger types

Nicholas Piggin posted 25 patches 3 weeks, 4 days ago
Maintainers: Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>, Weiwei Li <liwei1518@gmail.com>, Daniel Henrique Barboza <dbarboza@ventanamicro.com>, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
[RFC PATCH 22/25] target/riscv/debug: Support heterogeneous trigger types
Posted by Nicholas Piggin 3 weeks, 4 days ago
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