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 <[email protected]> --- 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
