diff options
-rw-r--r-- | target/riscv/cpu.c | 12 | ||||
-rw-r--r-- | target/riscv/cpu_cfg.h | 1 | ||||
-rw-r--r-- | target/riscv/csr.c | 4 | ||||
-rw-r--r-- | target/riscv/tcg/tcg-cpu.c | 8 |
4 files changed, 25 insertions, 0 deletions
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index a2881bf..69d64ec 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -80,6 +80,7 @@ const RISCVIsaExtData isa_edata_arr[] = { ISA_EXT_DATA_ENTRY(zicbom, PRIV_VERSION_1_12_0, ext_zicbom), ISA_EXT_DATA_ENTRY(zicboz, PRIV_VERSION_1_12_0, ext_zicboz), ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond), + ISA_EXT_DATA_ENTRY(zicntr, PRIV_VERSION_1_12_0, ext_zicntr), ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_zicsr), ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_zifencei), ISA_EXT_DATA_ENTRY(zihintntl, PRIV_VERSION_1_10_0, ext_zihintntl), @@ -1208,6 +1209,15 @@ static void riscv_cpu_init(Object *obj) qdev_init_gpio_in(DEVICE(obj), riscv_cpu_set_irq, IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX); #endif /* CONFIG_USER_ONLY */ + + /* + * The timer and performance counters extensions were supported + * in QEMU before they were added as discrete extensions in the + * ISA. To keep compatibility we'll always default them to 'true' + * for all CPUs. Each accelerator will decide what to do when + * users disable them. + */ + RISCV_CPU(obj)->cfg.ext_zicntr = true; } typedef struct misa_ext_info { @@ -1297,6 +1307,8 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = { MULTI_EXT_CFG_BOOL("svnapot", ext_svnapot, false), MULTI_EXT_CFG_BOOL("svpbmt", ext_svpbmt, false), + MULTI_EXT_CFG_BOOL("zicntr", ext_zicntr, true), + MULTI_EXT_CFG_BOOL("zba", ext_zba, true), MULTI_EXT_CFG_BOOL("zbb", ext_zbb, true), MULTI_EXT_CFG_BOOL("zbc", ext_zbc, true), diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h index e7ce977..73fd4b3 100644 --- a/target/riscv/cpu_cfg.h +++ b/target/riscv/cpu_cfg.h @@ -62,6 +62,7 @@ struct RISCVCPUConfig { bool ext_zksh; bool ext_zkt; bool ext_zifencei; + bool ext_zicntr; bool ext_zicsr; bool ext_zicbom; bool ext_zicboz; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index f4e0a39..4ca96dd 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -122,6 +122,10 @@ static RISCVException ctr(CPURISCVState *env, int csrno) if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) || (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) { + if (!riscv_cpu_cfg(env)->ext_zicntr) { + return RISCV_EXCP_ILLEGAL_INST; + } + goto skip_ext_pmu_check; } diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c index c5ff03e..a1e4ed2 100644 --- a/target/riscv/tcg/tcg-cpu.c +++ b/target/riscv/tcg/tcg-cpu.c @@ -541,6 +541,14 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zksh), true); } + if (cpu->cfg.ext_zicntr && !cpu->cfg.ext_zicsr) { + if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zicntr))) { + error_setg(errp, "zicntr requires zicsr"); + return; + } + cpu->cfg.ext_zicntr = false; + } + /* * Disable isa extensions based on priv spec after we * validated and set everything we need. |