All CPUs have the same amount of triggers: 2 triggers per hart, set via RV_MAX_TRIGGERS. This is not enough anymore: we'll have at least one future CPU that will demand more triggers per hart when implementing the RISC-V Server Ref Platform, requiring at least 11 triggers per hart.
Parametrize the trigger amount using a new 'num_triggers' property. The default amount is kept at 2 for backwards compatibility. The new maximum is bumped to a generous 1024 triggers per hart, which hopefully will be enough for the foreseeable future. The property can be set in two ways: - a '.num_triggers' CPU definition flag, allowing CPUs to set a custom amount inside the CPU def in DEFINE_RISCV_CPU(); - a new 'num-triggers' user property. The user property has a higher priority than an existing '.num_triggers' CPU def setting. Assuming a hypothetical case where a CPU 'X' is defined with '.num_triggers = 8': - -cpu X,num-triggers=30 => num_triggers set to 30 - -cpu X (...) => num_triggers set to 8 For a CPU that doesn't set '.num_triggers': - -cpu rv64,num-triggers=30 => num_triggers set to 30 - -cpu rv64 (...) => num_triggers set to 2 Signed-off-by: Daniel Henrique Barboza <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> --- target/riscv/cpu.c | 11 +++++++++++ target/riscv/cpu.h | 19 ++++++++++++++++++- target/riscv/debug.c | 16 ++++++++-------- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index b20271a220..6d8f9ad3a6 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -1167,6 +1167,11 @@ static void riscv_cpu_init(Object *obj) IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX); qdev_init_gpio_in_named(DEVICE(cpu), riscv_cpu_set_nmi, "riscv.cpu.rnmi", RNMI_MAX); + + if (mcc->def->num_triggers) { + env->num_triggers = mcc->def->num_triggers; + } + #endif /* CONFIG_USER_ONLY */ general_user_opts = g_hash_table_new(g_str_hash, g_str_equal); @@ -2619,6 +2624,8 @@ static const Property riscv_cpu_properties[] = { DEFAULT_RNMI_IRQVEC), DEFINE_PROP_UINT64("rnmi-exception-vector", RISCVCPU, env.rnmi_excpvec, DEFAULT_RNMI_EXCPVEC), + DEFINE_PROP_UINT32("num-triggers", RISCVCPU, env.num_triggers, + RV_DEFAULT_NUM_TRIGGERS), #endif DEFINE_PROP_BOOL("short-isa-string", RISCVCPU, cfg.short_isa_string, false), @@ -2764,6 +2771,10 @@ static void riscv_cpu_class_base_init(ObjectClass *c, const void *data) !valid_vm_1_10_32[mcc->def->cfg.max_satp_mode]) { mcc->def->cfg.max_satp_mode = VM_1_10_SV32; } + + if (def->num_triggers) { + mcc->def->num_triggers = def->num_triggers; + } #endif } if (def->priv_spec != RISCV_PROFILE_ATTR_UNUSED) { diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index ea92e2c68c..38f02a9dc7 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -189,7 +189,22 @@ extern RISCVCPUImpliedExtsRule *riscv_multi_ext_implied_rules[]; #define RV_VLEN_MAX 1024 #define RV_MAX_MHPMEVENTS 32 #define RV_MAX_MHPMCOUNTERS 32 -#define RV_MAX_TRIGGERS 2 + +/* + * The Debug 1.0 spec allows a humongous amount of triggers. Section + * "Enumeration" says: "The above algorithm reads back tselect so that + * implementations which have 2^n triggers only need to implement n + * bits of tselect.". tselect can have up to XLEN bits, so the max + * theoretical RV_MAX_TRIGGERS value is 2^XLEN. + * + * Allowing 2^XLEN triggers per hart is silly so we'll set a max to a + * modest 1024 triggers, which is way more than what we see current + * hardware use (most chips uses 2-4 triggers per hart, RISC-V Server + * Ref requires at least 11). With a 1024 max per hart we'll be set + * for a long time ... hopefully. + */ +#define RV_MAX_TRIGGERS 1024 +#define RV_DEFAULT_NUM_TRIGGERS 2 FIELD(VTYPE, VLMUL, 0, 3) FIELD(VTYPE, VSEW, 3, 3) @@ -576,6 +591,8 @@ typedef struct RISCVCPUDef { RISCVCPUConfig cfg; bool bare; const RISCVCSR *custom_csrs; + /* This is just a setter for env->num_triggers. */ + uint32_t num_triggers; } RISCVCPUDef; /** diff --git a/target/riscv/debug.c b/target/riscv/debug.c index 9a4910c431..ba5bc6ae13 100644 --- a/target/riscv/debug.c +++ b/target/riscv/debug.c @@ -26,6 +26,7 @@ #include "qemu/osdep.h" #include "qemu/log.h" #include "qapi/error.h" +#include "qemu/error-report.h" #include "cpu.h" #include "target/riscv/debug.h" #include "trace.h" @@ -1049,14 +1050,13 @@ void riscv_trigger_realize(CPURISCVState *env) { int i; - /* - * Alloc env->tdata1/2/3, cpu_breakpoint, cpu_watchpoint and - * itrigger_timer dynamically. This is overkill now - * given that they could be static arrays with RV_MAX_TRIGGERS - * but we'll parametrize the trigger number later, i.e. the - * array length won't be static. - */ - env->num_triggers = RV_MAX_TRIGGERS; + if (env->num_triggers > RV_MAX_TRIGGERS) { + error_report( + "Invalid configuration: 'num-triggers' must be less than %u", + RV_MAX_TRIGGERS); + exit(1); + } + env->tdata1 = g_new0(uint64_t, env->num_triggers); env->tdata2 = g_new0(uint64_t, env->num_triggers); env->tdata3 = g_new0(uint64_t, env->num_triggers); -- 2.43.0
