Implement a Sdtrig CPU configuration class that provides
details about the Sdtrig configuration.
It is stored as a pointer in RISCVCPUClass to avoid issues with
nested compound literals inside static initialisers with GCC 11.
For now, the number of supported triggers is configurable. This
requires some logic
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
target/riscv/cpu.c | 25 +++++++++++++++++++++++++
target/riscv/cpu.h | 4 ++++
target/riscv/debug.c | 5 ++++-
target/riscv/debug.h | 4 ++++
target/riscv/machine.c | 11 ++++++++---
5 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 057e221808..6f7a327fc7 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -23,6 +23,7 @@
#include "qemu/log.h"
#include "cpu.h"
#include "cpu_vendorid.h"
+#include "debug.h"
#include "internals.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
@@ -2816,6 +2817,11 @@ static void riscv_cpu_class_base_init(ObjectClass *c, const void *data)
mcc->def->vext_spec = def->vext_spec;
}
mcc->def->misa_ext |= def->misa_ext;
+#if !defined(CONFIG_USER_ONLY)
+ if (def->debug_cfg) {
+ mcc->def->debug_cfg = def->debug_cfg;
+ }
+#endif
riscv_cpu_cfg_merge(&mcc->def->cfg, &def->cfg);
@@ -2951,6 +2957,18 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char *nodename)
DEFINE_RISCV_CPU(type_name, parent_type_name, \
.profile = &(profile_))
+#if !defined(CONFIG_USER_ONLY)
+/* Sdtrig implementation has 2 triggers that support match, match6, icount */
+static const RISCVSdtrigConfig default_sdtrig_config = {
+ .nr_triggers = 2,
+};
+
+bool riscv_sdtrig_default_implementation(const RISCVSdtrigConfig *config)
+{
+ return config == &default_sdtrig_config;
+}
+#endif
+
static const TypeInfo riscv_cpu_type_infos[] = {
{
.name = TYPE_RISCV_CPU,
@@ -2968,6 +2986,9 @@ static const TypeInfo riscv_cpu_type_infos[] = {
.cfg.mmu = true,
.cfg.pmp = true,
.priv_spec = PRIV_VERSION_LATEST,
+#if !defined(CONFIG_USER_ONLY)
+ .debug_cfg = &default_sdtrig_config,
+#endif
),
DEFINE_ABSTRACT_RISCV_CPU(TYPE_RISCV_VENDOR_CPU, TYPE_RISCV_CPU),
@@ -2995,6 +3016,10 @@ static const TypeInfo riscv_cpu_type_infos[] = {
#else
.cfg.max_satp_mode = VM_1_10_SV57,
#endif
+
+#if !defined(CONFIG_USER_ONLY)
+ .debug_cfg = &default_sdtrig_config,
+#endif
),
DEFINE_RISCV_CPU(TYPE_RISCV_CPU_MAX, TYPE_RISCV_DYNAMIC_CPU,
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 44ed1665e2..c4f1cb0a9d 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -571,6 +571,9 @@ typedef struct RISCVCSR RISCVCSR;
typedef struct RISCVCPUDef {
RISCVMXL misa_mxl_max; /* max mxl for this cpu */
RISCVCPUProfile *profile;
+#if !defined(CONFIG_USER_ONLY)
+ const RISCVSdtrigConfig *debug_cfg;
+#endif
uint32_t misa_ext;
int priv_spec;
int32_t vext_spec;
@@ -666,6 +669,7 @@ void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv,
void *rmw_fn_arg);
RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit);
+bool riscv_sdtrig_default_implementation(const RISCVSdtrigConfig *config);
#endif /* !CONFIG_USER_ONLY */
void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv, bool virt_en);
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index 22f7958a79..93615b43fb 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -173,7 +173,10 @@ target_ulong tselect_csr_read(CPURISCVState *env)
void tselect_csr_write(CPURISCVState *env, target_ulong val)
{
- if (val < RV_DEFAULT_TRIGGERS) {
+ CPUState *cs = env_cpu(env);
+ RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cs);
+
+ if (val < mcc->def->debug_cfg->nr_triggers) {
env->sdtrig_state.trigger_cur = val;
}
}
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
index 8a047c8073..3ba12f95cd 100644
--- a/target/riscv/debug.h
+++ b/target/riscv/debug.h
@@ -135,6 +135,10 @@ enum {
#define MHSELECT_IGNORE 0
#define MHSELECT_MCONTEXT 4
+typedef struct RISCVSdtrigConfig {
+ unsigned int nr_triggers;
+} RISCVSdtrigConfig;
+
bool tdata_available(CPURISCVState *env, int tdata_index);
target_ulong tselect_csr_read(CPURISCVState *env);
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 23a5f60d2a..9f65bdca9b 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -221,10 +221,12 @@ static const VMStateDescription vmstate_kvmtimer = {
static bool debug_needed(void *opaque)
{
RISCVCPU *cpu = opaque;
+ RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
CPURISCVState *env = &cpu->env;
return cpu->cfg.debug &&
- env->sdtrig_state.mcontext == 0;
+ (riscv_sdtrig_default_implementation(mcc->def->debug_cfg) &&
+ env->sdtrig_state.mcontext == 0);
}
static int debug_pre_save(void *opaque)
@@ -277,15 +279,18 @@ static const VMStateDescription vmstate_debug = {
/*
* This is a newer version of the debug (sdtrig) state, required
- * to migrate hcontext/mcontext.
+ * to migrate hcontext/mcontext, or machines with non-default
+ * sdtrig implementation.
*/
static bool sdtrig_needed(void *opaque)
{
RISCVCPU *cpu = opaque;
+ RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
CPURISCVState *env = &cpu->env;
return cpu->cfg.debug &&
- env->sdtrig_state.mcontext != 0;
+ !(riscv_sdtrig_default_implementation(mcc->def->debug_cfg) &&
+ env->sdtrig_state.mcontext == 0);
}
static int sdtrig_post_load(void *opaque, int version_id)
--
2.51.0