aboutsummaryrefslogtreecommitdiff
path: root/target/riscv/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/riscv/cpu.c')
-rw-r--r--target/riscv/cpu.c1030
1 files changed, 200 insertions, 830 deletions
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index f557270..ac4a6c7 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -23,9 +23,7 @@
#include "qemu/log.h"
#include "cpu.h"
#include "cpu_vendorid.h"
-#include "pmu.h"
#include "internals.h"
-#include "time_helper.h"
#include "exec/exec-all.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
@@ -35,20 +33,13 @@
#include "fpu/softfloat-helpers.h"
#include "sysemu/kvm.h"
#include "sysemu/tcg.h"
-#include "kvm_riscv.h"
+#include "kvm/kvm_riscv.h"
#include "tcg/tcg.h"
/* RISC-V CPU definitions */
static const char riscv_single_letter_exts[] = "IEMAFDQCPVH";
-
-struct isa_ext_data {
- const char *name;
- int min_version;
- int ext_enable_offset;
-};
-
-#define ISA_EXT_DATA_ENTRY(_name, _min_ver, _prop) \
- {#_name, _min_ver, offsetof(struct RISCVCPUConfig, _prop)}
+const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, RVV,
+ RVC, RVS, RVU, RVH, RVJ, RVG, 0};
/*
* From vector_helper.c
@@ -61,6 +52,9 @@ struct isa_ext_data {
#define BYTE(x) (x)
#endif
+#define ISA_EXT_DATA_ENTRY(_name, _min_ver, _prop) \
+ {#_name, _min_ver, CPU_CFG_OFFSET(_prop)}
+
/*
* Here are the ordering rules of extension naming defined by RISC-V
* specification :
@@ -81,7 +75,7 @@ struct isa_ext_data {
* Single letter extensions are checked in riscv_cpu_validate_misa_priv()
* instead.
*/
-static const struct isa_ext_data isa_edata_arr[] = {
+const RISCVIsaExtData isa_edata_arr[] = {
ISA_EXT_DATA_ENTRY(zicbom, PRIV_VERSION_1_12_0, ext_icbom),
ISA_EXT_DATA_ENTRY(zicboz, PRIV_VERSION_1_12_0, ext_icboz),
ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond),
@@ -160,20 +154,20 @@ static const struct isa_ext_data isa_edata_arr[] = {
ISA_EXT_DATA_ENTRY(xtheadmempair, PRIV_VERSION_1_11_0, ext_xtheadmempair),
ISA_EXT_DATA_ENTRY(xtheadsync, PRIV_VERSION_1_11_0, ext_xtheadsync),
ISA_EXT_DATA_ENTRY(xventanacondops, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
+
+ DEFINE_PROP_END_OF_LIST(),
};
-static bool isa_ext_is_enabled(RISCVCPU *cpu,
- const struct isa_ext_data *edata)
+bool isa_ext_is_enabled(RISCVCPU *cpu, uint32_t ext_offset)
{
- bool *ext_enabled = (void *)&cpu->cfg + edata->ext_enable_offset;
+ bool *ext_enabled = (void *)&cpu->cfg + ext_offset;
return *ext_enabled;
}
-static void isa_ext_update_enabled(RISCVCPU *cpu,
- const struct isa_ext_data *edata, bool en)
+void isa_ext_update_enabled(RISCVCPU *cpu, uint32_t ext_offset, bool en)
{
- bool *ext_enabled = (void *)&cpu->cfg + edata->ext_enable_offset;
+ bool *ext_enabled = (void *)&cpu->cfg + ext_offset;
*ext_enabled = en;
}
@@ -258,8 +252,6 @@ static const char * const riscv_intr_names[] = {
"reserved"
};
-static void riscv_cpu_add_user_properties(Object *obj);
-
const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
{
if (async) {
@@ -271,7 +263,7 @@ const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
}
}
-static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
+void riscv_cpu_set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
{
env->misa_mxl_max = env->misa_mxl = mxl;
env->misa_ext_mask = env->misa_ext = ext;
@@ -376,9 +368,9 @@ static void riscv_any_cpu_init(Object *obj)
RISCVCPU *cpu = RISCV_CPU(obj);
CPURISCVState *env = &cpu->env;
#if defined(TARGET_RISCV32)
- set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
+ riscv_cpu_set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
#elif defined(TARGET_RISCV64)
- set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
+ riscv_cpu_set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
#endif
#ifndef CONFIG_USER_ONLY
@@ -396,13 +388,29 @@ static void riscv_any_cpu_init(Object *obj)
cpu->cfg.pmp = true;
}
+static void riscv_max_cpu_init(Object *obj)
+{
+ RISCVCPU *cpu = RISCV_CPU(obj);
+ CPURISCVState *env = &cpu->env;
+ RISCVMXL mlx = MXL_RV64;
+
+#ifdef TARGET_RISCV32
+ mlx = MXL_RV32;
+#endif
+ riscv_cpu_set_misa(env, mlx, 0);
+ env->priv_ver = PRIV_VERSION_LATEST;
+#ifndef CONFIG_USER_ONLY
+ set_satp_mode_max_supported(RISCV_CPU(obj), mlx == MXL_RV32 ?
+ VM_1_10_SV32 : VM_1_10_SV57);
+#endif
+}
+
#if defined(TARGET_RISCV64)
static void rv64_base_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
/* We set this in the realise function */
- set_misa(env, MXL_RV64, 0);
- riscv_cpu_add_user_properties(obj);
+ riscv_cpu_set_misa(env, MXL_RV64, 0);
/* Set latest version of privileged specification */
env->priv_ver = PRIV_VERSION_LATEST;
#ifndef CONFIG_USER_ONLY
@@ -414,7 +422,8 @@ static void rv64_sifive_u_cpu_init(Object *obj)
{
RISCVCPU *cpu = RISCV_CPU(obj);
CPURISCVState *env = &cpu->env;
- set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+ riscv_cpu_set_misa(env, MXL_RV64,
+ RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
env->priv_ver = PRIV_VERSION_1_10_0;
#ifndef CONFIG_USER_ONLY
set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
@@ -432,7 +441,7 @@ static void rv64_sifive_e_cpu_init(Object *obj)
CPURISCVState *env = &RISCV_CPU(obj)->env;
RISCVCPU *cpu = RISCV_CPU(obj);
- set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
+ riscv_cpu_set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
env->priv_ver = PRIV_VERSION_1_10_0;
#ifndef CONFIG_USER_ONLY
set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -449,7 +458,7 @@ static void rv64_thead_c906_cpu_init(Object *obj)
CPURISCVState *env = &RISCV_CPU(obj)->env;
RISCVCPU *cpu = RISCV_CPU(obj);
- set_misa(env, MXL_RV64, RVG | RVC | RVS | RVU);
+ riscv_cpu_set_misa(env, MXL_RV64, RVG | RVC | RVS | RVU);
env->priv_ver = PRIV_VERSION_1_11_0;
cpu->cfg.ext_zfa = true;
@@ -480,7 +489,7 @@ static void rv64_veyron_v1_cpu_init(Object *obj)
CPURISCVState *env = &RISCV_CPU(obj)->env;
RISCVCPU *cpu = RISCV_CPU(obj);
- set_misa(env, MXL_RV64, RVG | RVC | RVS | RVU | RVH);
+ riscv_cpu_set_misa(env, MXL_RV64, RVG | RVC | RVS | RVU | RVH);
env->priv_ver = PRIV_VERSION_1_12_0;
/* Enable ISA extensions */
@@ -525,8 +534,7 @@ static void rv128_base_cpu_init(Object *obj)
}
CPURISCVState *env = &RISCV_CPU(obj)->env;
/* We set this in the realise function */
- set_misa(env, MXL_RV128, 0);
- riscv_cpu_add_user_properties(obj);
+ riscv_cpu_set_misa(env, MXL_RV128, 0);
/* Set latest version of privileged specification */
env->priv_ver = PRIV_VERSION_LATEST;
#ifndef CONFIG_USER_ONLY
@@ -538,8 +546,7 @@ static void rv32_base_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
/* We set this in the realise function */
- set_misa(env, MXL_RV32, 0);
- riscv_cpu_add_user_properties(obj);
+ riscv_cpu_set_misa(env, MXL_RV32, 0);
/* Set latest version of privileged specification */
env->priv_ver = PRIV_VERSION_LATEST;
#ifndef CONFIG_USER_ONLY
@@ -551,7 +558,8 @@ static void rv32_sifive_u_cpu_init(Object *obj)
{
RISCVCPU *cpu = RISCV_CPU(obj);
CPURISCVState *env = &cpu->env;
- set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+ riscv_cpu_set_misa(env, MXL_RV32,
+ RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
env->priv_ver = PRIV_VERSION_1_10_0;
#ifndef CONFIG_USER_ONLY
set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
@@ -569,7 +577,7 @@ static void rv32_sifive_e_cpu_init(Object *obj)
CPURISCVState *env = &RISCV_CPU(obj)->env;
RISCVCPU *cpu = RISCV_CPU(obj);
- set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
+ riscv_cpu_set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
env->priv_ver = PRIV_VERSION_1_10_0;
#ifndef CONFIG_USER_ONLY
set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -586,7 +594,7 @@ static void rv32_ibex_cpu_init(Object *obj)
CPURISCVState *env = &RISCV_CPU(obj)->env;
RISCVCPU *cpu = RISCV_CPU(obj);
- set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
+ riscv_cpu_set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
env->priv_ver = PRIV_VERSION_1_11_0;
#ifndef CONFIG_USER_ONLY
set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -604,7 +612,7 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
CPURISCVState *env = &RISCV_CPU(obj)->env;
RISCVCPU *cpu = RISCV_CPU(obj);
- set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
+ riscv_cpu_set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
env->priv_ver = PRIV_VERSION_1_10_0;
#ifndef CONFIG_USER_ONLY
set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -617,19 +625,6 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
}
#endif
-#if defined(CONFIG_KVM)
-static void riscv_host_cpu_init(Object *obj)
-{
- CPURISCVState *env = &RISCV_CPU(obj)->env;
-#if defined(TARGET_RISCV32)
- set_misa(env, MXL_RV32, 0);
-#elif defined(TARGET_RISCV64)
- set_misa(env, MXL_RV64, 0);
-#endif
- riscv_cpu_add_user_properties(obj);
-}
-#endif /* CONFIG_KVM */
-
static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
{
ObjectClass *oc;
@@ -648,6 +643,17 @@ static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
return oc;
}
+char *riscv_cpu_get_name(RISCVCPU *cpu)
+{
+ RISCVCPUClass *rcc = RISCV_CPU_GET_CLASS(cpu);
+ const char *typename = object_class_get_name(OBJECT_CLASS(rcc));
+
+ g_assert(g_str_has_suffix(typename, RISCV_CPU_TYPE_SUFFIX));
+
+ return g_strndup(typename,
+ strlen(typename) - strlen(RISCV_CPU_TYPE_SUFFIX));
+}
+
static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
{
RISCVCPU *cpu = RISCV_CPU(cs);
@@ -798,24 +804,6 @@ static vaddr riscv_cpu_get_pc(CPUState *cs)
return env->pc;
}
-static void riscv_cpu_synchronize_from_tb(CPUState *cs,
- const TranslationBlock *tb)
-{
- if (!(tb_cflags(tb) & CF_PCREL)) {
- RISCVCPU *cpu = RISCV_CPU(cs);
- CPURISCVState *env = &cpu->env;
- RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
-
- tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
-
- if (xl == MXL_RV32) {
- env->pc = (int32_t) tb->pc;
- } else {
- env->pc = tb->pc;
- }
- }
-}
-
static bool riscv_cpu_has_work(CPUState *cs)
{
#ifndef CONFIG_USER_ONLY
@@ -831,29 +819,6 @@ static bool riscv_cpu_has_work(CPUState *cs)
#endif
}
-static void riscv_restore_state_to_opc(CPUState *cs,
- const TranslationBlock *tb,
- const uint64_t *data)
-{
- RISCVCPU *cpu = RISCV_CPU(cs);
- CPURISCVState *env = &cpu->env;
- RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
- target_ulong pc;
-
- if (tb_cflags(tb) & CF_PCREL) {
- pc = (env->pc & TARGET_PAGE_MASK) | data[0];
- } else {
- pc = data[0];
- }
-
- if (xl == MXL_RV32) {
- env->pc = (int32_t)pc;
- } else {
- env->pc = pc;
- }
- env->bins = data[1];
-}
-
static void riscv_cpu_reset_hold(Object *obj)
{
#ifndef CONFIG_USER_ONLY
@@ -956,390 +921,6 @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
}
}
-static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg,
- Error **errp)
-{
- int vext_version = VEXT_VERSION_1_00_0;
-
- if (!is_power_of_2(cfg->vlen)) {
- error_setg(errp, "Vector extension VLEN must be power of 2");
- return;
- }
- if (cfg->vlen > RV_VLEN_MAX || cfg->vlen < 128) {
- error_setg(errp,
- "Vector extension implementation only supports VLEN "
- "in the range [128, %d]", RV_VLEN_MAX);
- return;
- }
- if (!is_power_of_2(cfg->elen)) {
- error_setg(errp, "Vector extension ELEN must be power of 2");
- return;
- }
- if (cfg->elen > 64 || cfg->elen < 8) {
- error_setg(errp,
- "Vector extension implementation only supports ELEN "
- "in the range [8, 64]");
- return;
- }
- if (cfg->vext_spec) {
- if (!g_strcmp0(cfg->vext_spec, "v1.0")) {
- vext_version = VEXT_VERSION_1_00_0;
- } else {
- error_setg(errp, "Unsupported vector spec version '%s'",
- cfg->vext_spec);
- return;
- }
- } else {
- qemu_log("vector version is not specified, "
- "use the default value v1.0\n");
- }
- env->vext_ver = vext_version;
-}
-
-static void riscv_cpu_validate_priv_spec(RISCVCPU *cpu, Error **errp)
-{
- CPURISCVState *env = &cpu->env;
- int priv_version = -1;
-
- if (cpu->cfg.priv_spec) {
- if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) {
- priv_version = PRIV_VERSION_1_12_0;
- } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) {
- priv_version = PRIV_VERSION_1_11_0;
- } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) {
- priv_version = PRIV_VERSION_1_10_0;
- } else {
- error_setg(errp,
- "Unsupported privilege spec version '%s'",
- cpu->cfg.priv_spec);
- return;
- }
-
- env->priv_ver = priv_version;
- }
-}
-
-static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
-{
- CPURISCVState *env = &cpu->env;
- int i;
-
- /* Force disable extensions if priv spec version does not match */
- for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
- if (isa_ext_is_enabled(cpu, &isa_edata_arr[i]) &&
- (env->priv_ver < isa_edata_arr[i].min_version)) {
- isa_ext_update_enabled(cpu, &isa_edata_arr[i], false);
-#ifndef CONFIG_USER_ONLY
- warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx
- " because privilege spec version does not match",
- isa_edata_arr[i].name, env->mhartid);
-#else
- warn_report("disabling %s extension because "
- "privilege spec version does not match",
- isa_edata_arr[i].name);
-#endif
- }
- }
-}
-
-static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)
-{
- RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
- CPUClass *cc = CPU_CLASS(mcc);
- CPURISCVState *env = &cpu->env;
-
- /* Validate that MISA_MXL is set properly. */
- switch (env->misa_mxl_max) {
-#ifdef TARGET_RISCV64
- case MXL_RV64:
- case MXL_RV128:
- cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
- break;
-#endif
- case MXL_RV32:
- cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
- break;
- default:
- g_assert_not_reached();
- }
-
- if (env->misa_mxl_max != env->misa_mxl) {
- error_setg(errp, "misa_mxl_max must be equal to misa_mxl");
- return;
- }
-}
-
-/*
- * Check consistency between chosen extensions while setting
- * cpu->cfg accordingly.
- */
-void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
-{
- CPURISCVState *env = &cpu->env;
- Error *local_err = NULL;
-
- /* Do some ISA extension error checking */
- if (riscv_has_ext(env, RVG) &&
- !(riscv_has_ext(env, RVI) && riscv_has_ext(env, RVM) &&
- riscv_has_ext(env, RVA) && riscv_has_ext(env, RVF) &&
- riscv_has_ext(env, RVD) &&
- cpu->cfg.ext_icsr && cpu->cfg.ext_ifencei)) {
- warn_report("Setting G will also set IMAFD_Zicsr_Zifencei");
- cpu->cfg.ext_icsr = true;
- cpu->cfg.ext_ifencei = true;
-
- env->misa_ext |= RVI | RVM | RVA | RVF | RVD;
- env->misa_ext_mask |= RVI | RVM | RVA | RVF | RVD;
- }
-
- if (riscv_has_ext(env, RVI) && riscv_has_ext(env, RVE)) {
- error_setg(errp,
- "I and E extensions are incompatible");
- return;
- }
-
- if (!riscv_has_ext(env, RVI) && !riscv_has_ext(env, RVE)) {
- error_setg(errp,
- "Either I or E extension must be set");
- return;
- }
-
- if (riscv_has_ext(env, RVS) && !riscv_has_ext(env, RVU)) {
- error_setg(errp,
- "Setting S extension without U extension is illegal");
- return;
- }
-
- if (riscv_has_ext(env, RVH) && !riscv_has_ext(env, RVI)) {
- error_setg(errp,
- "H depends on an I base integer ISA with 32 x registers");
- return;
- }
-
- if (riscv_has_ext(env, RVH) && !riscv_has_ext(env, RVS)) {
- error_setg(errp, "H extension implicitly requires S-mode");
- return;
- }
-
- if (riscv_has_ext(env, RVF) && !cpu->cfg.ext_icsr) {
- error_setg(errp, "F extension requires Zicsr");
- return;
- }
-
- if ((cpu->cfg.ext_zawrs) && !riscv_has_ext(env, RVA)) {
- error_setg(errp, "Zawrs extension requires A extension");
- return;
- }
-
- if (cpu->cfg.ext_zfa && !riscv_has_ext(env, RVF)) {
- error_setg(errp, "Zfa extension requires F extension");
- return;
- }
-
- if (cpu->cfg.ext_zfh) {
- cpu->cfg.ext_zfhmin = true;
- }
-
- if (cpu->cfg.ext_zfhmin && !riscv_has_ext(env, RVF)) {
- error_setg(errp, "Zfh/Zfhmin extensions require F extension");
- return;
- }
-
- if (cpu->cfg.ext_zfbfmin && !riscv_has_ext(env, RVF)) {
- error_setg(errp, "Zfbfmin extension depends on F extension");
- return;
- }
-
- if (riscv_has_ext(env, RVD) && !riscv_has_ext(env, RVF)) {
- error_setg(errp, "D extension requires F extension");
- return;
- }
-
- if (riscv_has_ext(env, RVV)) {
- riscv_cpu_validate_v(env, &cpu->cfg, &local_err);
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
-
- /* The V vector extension depends on the Zve64d extension */
- cpu->cfg.ext_zve64d = true;
- }
-
- /* The Zve64d extension depends on the Zve64f extension */
- if (cpu->cfg.ext_zve64d) {
- cpu->cfg.ext_zve64f = true;
- }
-
- /* The Zve64f extension depends on the Zve32f extension */
- if (cpu->cfg.ext_zve64f) {
- cpu->cfg.ext_zve32f = true;
- }
-
- if (cpu->cfg.ext_zve64d && !riscv_has_ext(env, RVD)) {
- error_setg(errp, "Zve64d/V extensions require D extension");
- return;
- }
-
- if (cpu->cfg.ext_zve32f && !riscv_has_ext(env, RVF)) {
- error_setg(errp, "Zve32f/Zve64f extensions require F extension");
- return;
- }
-
- if (cpu->cfg.ext_zvfh) {
- cpu->cfg.ext_zvfhmin = true;
- }
-
- if (cpu->cfg.ext_zvfhmin && !cpu->cfg.ext_zve32f) {
- error_setg(errp, "Zvfh/Zvfhmin extensions require Zve32f extension");
- return;
- }
-
- if (cpu->cfg.ext_zvfh && !cpu->cfg.ext_zfhmin) {
- error_setg(errp, "Zvfh extensions requires Zfhmin extension");
- return;
- }
-
- if (cpu->cfg.ext_zvfbfmin && !cpu->cfg.ext_zfbfmin) {
- error_setg(errp, "Zvfbfmin extension depends on Zfbfmin extension");
- return;
- }
-
- if (cpu->cfg.ext_zvfbfmin && !cpu->cfg.ext_zve32f) {
- error_setg(errp, "Zvfbfmin extension depends on Zve32f extension");
- return;
- }
-
- if (cpu->cfg.ext_zvfbfwma && !cpu->cfg.ext_zvfbfmin) {
- error_setg(errp, "Zvfbfwma extension depends on Zvfbfmin extension");
- return;
- }
-
- /* Set the ISA extensions, checks should have happened above */
- if (cpu->cfg.ext_zhinx) {
- cpu->cfg.ext_zhinxmin = true;
- }
-
- if ((cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinxmin) && !cpu->cfg.ext_zfinx) {
- error_setg(errp, "Zdinx/Zhinx/Zhinxmin extensions require Zfinx");
- return;
- }
-
- if (cpu->cfg.ext_zfinx) {
- if (!cpu->cfg.ext_icsr) {
- error_setg(errp, "Zfinx extension requires Zicsr");
- return;
- }
- if (riscv_has_ext(env, RVF)) {
- error_setg(errp,
- "Zfinx cannot be supported together with F extension");
- return;
- }
- }
-
- if (cpu->cfg.ext_zce) {
- cpu->cfg.ext_zca = true;
- cpu->cfg.ext_zcb = true;
- cpu->cfg.ext_zcmp = true;
- cpu->cfg.ext_zcmt = true;
- if (riscv_has_ext(env, RVF) && env->misa_mxl_max == MXL_RV32) {
- cpu->cfg.ext_zcf = true;
- }
- }
-
- /* zca, zcd and zcf has a PRIV 1.12.0 restriction */
- if (riscv_has_ext(env, RVC) && env->priv_ver >= PRIV_VERSION_1_12_0) {
- cpu->cfg.ext_zca = true;
- if (riscv_has_ext(env, RVF) && env->misa_mxl_max == MXL_RV32) {
- cpu->cfg.ext_zcf = true;
- }
- if (riscv_has_ext(env, RVD)) {
- cpu->cfg.ext_zcd = true;
- }
- }
-
- if (env->misa_mxl_max != MXL_RV32 && cpu->cfg.ext_zcf) {
- error_setg(errp, "Zcf extension is only relevant to RV32");
- return;
- }
-
- if (!riscv_has_ext(env, RVF) && cpu->cfg.ext_zcf) {
- error_setg(errp, "Zcf extension requires F extension");
- return;
- }
-
- if (!riscv_has_ext(env, RVD) && cpu->cfg.ext_zcd) {
- error_setg(errp, "Zcd extension requires D extension");
- return;
- }
-
- if ((cpu->cfg.ext_zcf || cpu->cfg.ext_zcd || cpu->cfg.ext_zcb ||
- cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt) && !cpu->cfg.ext_zca) {
- error_setg(errp, "Zcf/Zcd/Zcb/Zcmp/Zcmt extensions require Zca "
- "extension");
- return;
- }
-
- if (cpu->cfg.ext_zcd && (cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt)) {
- error_setg(errp, "Zcmp/Zcmt extensions are incompatible with "
- "Zcd extension");
- return;
- }
-
- if (cpu->cfg.ext_zcmt && !cpu->cfg.ext_icsr) {
- error_setg(errp, "Zcmt extension requires Zicsr extension");
- return;
- }
-
- /*
- * In principle Zve*x would also suffice here, were they supported
- * in qemu
- */
- if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned ||
- cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksed || cpu->cfg.ext_zvksh) &&
- !cpu->cfg.ext_zve32f) {
- error_setg(errp,
- "Vector crypto extensions require V or Zve* extensions");
- return;
- }
-
- if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64f) {
- error_setg(
- errp,
- "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
- return;
- }
-
- if (cpu->cfg.ext_zk) {
- cpu->cfg.ext_zkn = true;
- cpu->cfg.ext_zkr = true;
- cpu->cfg.ext_zkt = true;
- }
-
- if (cpu->cfg.ext_zkn) {
- cpu->cfg.ext_zbkb = true;
- cpu->cfg.ext_zbkc = true;
- cpu->cfg.ext_zbkx = true;
- cpu->cfg.ext_zkne = true;
- cpu->cfg.ext_zknd = true;
- cpu->cfg.ext_zknh = true;
- }
-
- if (cpu->cfg.ext_zks) {
- cpu->cfg.ext_zbkb = true;
- cpu->cfg.ext_zbkc = true;
- cpu->cfg.ext_zbkx = true;
- cpu->cfg.ext_zksed = true;
- cpu->cfg.ext_zksh = true;
- }
-
- /*
- * Disable isa extensions based on priv spec after we
- * validated and set everything we need.
- */
- riscv_cpu_disable_priv_spec_isa_exts(cpu);
-}
-
#ifndef CONFIG_USER_ONLY
static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
{
@@ -1428,74 +1009,6 @@ static void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
#endif
}
-static void riscv_cpu_validate_misa_priv(CPURISCVState *env, Error **errp)
-{
- if (riscv_has_ext(env, RVH) && env->priv_ver < PRIV_VERSION_1_12_0) {
- error_setg(errp, "H extension requires priv spec 1.12.0");
- return;
- }
-}
-
-static void riscv_cpu_realize_tcg(DeviceState *dev, Error **errp)
-{
- RISCVCPU *cpu = RISCV_CPU(dev);
- CPURISCVState *env = &cpu->env;
- Error *local_err = NULL;
-
- if (object_dynamic_cast(OBJECT(dev), TYPE_RISCV_CPU_HOST)) {
- error_setg(errp, "'host' CPU is not compatible with TCG acceleration");
- return;
- }
-
- riscv_cpu_validate_misa_mxl(cpu, &local_err);
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
-
- riscv_cpu_validate_priv_spec(cpu, &local_err);
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
-
- riscv_cpu_validate_misa_priv(env, &local_err);
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
-
- if (cpu->cfg.epmp && !cpu->cfg.pmp) {
- /*
- * Enhanced PMP should only be available
- * on harts with PMP support
- */
- error_setg(errp, "Invalid configuration: EPMP requires PMP support");
- return;
- }
-
- riscv_cpu_validate_set_extensions(cpu, &local_err);
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
-
-#ifndef CONFIG_USER_ONLY
- CPU(dev)->tcg_cflags |= CF_PCREL;
-
- if (cpu->cfg.ext_sstc) {
- riscv_timer_init(cpu);
- }
-
- if (cpu->cfg.pmu_num) {
- if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscofpmf) {
- cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
- riscv_pmu_timer_cb, cpu);
- }
- }
-#endif
-}
-
static void riscv_cpu_realize(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
@@ -1503,20 +1016,17 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
Error *local_err = NULL;
+ if (object_dynamic_cast(OBJECT(dev), TYPE_RISCV_CPU_ANY) != NULL) {
+ warn_report("The 'any' CPU is deprecated and will be "
+ "removed in the future.");
+ }
+
cpu_exec_realizefn(cs, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
return;
}
- if (tcg_enabled()) {
- riscv_cpu_realize_tcg(dev, &local_err);
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
- }
-
riscv_cpu_finalize_features(cpu, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
@@ -1565,7 +1075,7 @@ static void cpu_riscv_set_satp(Object *obj, Visitor *v, const char *name,
satp_map->init |= 1 << satp;
}
-static void riscv_add_satp_mode_properties(Object *obj)
+void riscv_add_satp_mode_properties(Object *obj)
{
RISCVCPU *cpu = RISCV_CPU(obj);
@@ -1647,55 +1157,22 @@ static void riscv_cpu_set_irq(void *opaque, int irq, int level)
}
#endif /* CONFIG_USER_ONLY */
-static void riscv_cpu_init(Object *obj)
+static bool riscv_cpu_is_dynamic(Object *cpu_obj)
{
-#ifndef CONFIG_USER_ONLY
- qdev_init_gpio_in(DEVICE(obj), riscv_cpu_set_irq,
- IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX);
-#endif /* CONFIG_USER_ONLY */
+ return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL;
}
-typedef struct RISCVCPUMisaExtConfig {
- const char *name;
- const char *description;
- target_ulong misa_bit;
- bool enabled;
-} RISCVCPUMisaExtConfig;
-
-static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, const char *name,
- void *opaque, Error **errp)
+static void riscv_cpu_post_init(Object *obj)
{
- const RISCVCPUMisaExtConfig *misa_ext_cfg = opaque;
- target_ulong misa_bit = misa_ext_cfg->misa_bit;
- RISCVCPU *cpu = RISCV_CPU(obj);
- CPURISCVState *env = &cpu->env;
- bool value;
-
- if (!visit_type_bool(v, name, &value, errp)) {
- return;
- }
-
- if (value) {
- env->misa_ext |= misa_bit;
- env->misa_ext_mask |= misa_bit;
- } else {
- env->misa_ext &= ~misa_bit;
- env->misa_ext_mask &= ~misa_bit;
- }
+ accel_cpu_instance_init(CPU(obj));
}
-static void cpu_get_misa_ext_cfg(Object *obj, Visitor *v, const char *name,
- void *opaque, Error **errp)
+static void riscv_cpu_init(Object *obj)
{
- const RISCVCPUMisaExtConfig *misa_ext_cfg = opaque;
- target_ulong misa_bit = misa_ext_cfg->misa_bit;
- RISCVCPU *cpu = RISCV_CPU(obj);
- CPURISCVState *env = &cpu->env;
- bool value;
-
- value = env->misa_ext & misa_bit;
-
- visit_type_bool(v, name, &value, errp);
+#ifndef CONFIG_USER_ONLY
+ qdev_init_gpio_in(DEVICE(obj), riscv_cpu_set_irq,
+ IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX);
+#endif /* CONFIG_USER_ONLY */
}
typedef struct misa_ext_info {
@@ -1758,231 +1235,150 @@ const char *riscv_get_misa_ext_description(uint32_t bit)
return val;
}
-#define MISA_CFG(_bit, _enabled) \
- {.misa_bit = _bit, .enabled = _enabled}
-
-static RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
- MISA_CFG(RVA, true),
- MISA_CFG(RVC, true),
- MISA_CFG(RVD, true),
- MISA_CFG(RVF, true),
- MISA_CFG(RVI, true),
- MISA_CFG(RVE, false),
- MISA_CFG(RVM, true),
- MISA_CFG(RVS, true),
- MISA_CFG(RVU, true),
- MISA_CFG(RVH, true),
- MISA_CFG(RVJ, false),
- MISA_CFG(RVV, false),
- MISA_CFG(RVG, false),
-};
-
-static void riscv_cpu_add_misa_properties(Object *cpu_obj)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(misa_ext_cfgs); i++) {
- RISCVCPUMisaExtConfig *misa_cfg = &misa_ext_cfgs[i];
- int bit = misa_cfg->misa_bit;
+#define MULTI_EXT_CFG_BOOL(_name, _prop, _defval) \
+ {.name = _name, .offset = CPU_CFG_OFFSET(_prop), \
+ .enabled = _defval}
- misa_cfg->name = riscv_get_misa_ext_name(bit);
- misa_cfg->description = riscv_get_misa_ext_description(bit);
-
- /* Check if KVM already created the property */
- if (object_property_find(cpu_obj, misa_cfg->name)) {
- continue;
- }
-
- object_property_add(cpu_obj, misa_cfg->name, "bool",
- cpu_get_misa_ext_cfg,
- cpu_set_misa_ext_cfg,
- NULL, (void *)misa_cfg);
- object_property_set_description(cpu_obj, misa_cfg->name,
- misa_cfg->description);
- object_property_set_bool(cpu_obj, misa_cfg->name,
- misa_cfg->enabled, NULL);
- }
-}
-
-static Property riscv_cpu_extensions[] = {
+const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
/* Defaults for standard extensions */
- DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
- DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
- DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
- DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
- DEFINE_PROP_BOOL("Zihintntl", RISCVCPU, cfg.ext_zihintntl, true),
- DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true),
- DEFINE_PROP_BOOL("Zawrs", RISCVCPU, cfg.ext_zawrs, true),
- DEFINE_PROP_BOOL("Zfa", RISCVCPU, cfg.ext_zfa, true),
- DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
- DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
- DEFINE_PROP_BOOL("Zve32f", RISCVCPU, cfg.ext_zve32f, false),
- DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false),
- DEFINE_PROP_BOOL("Zve64d", RISCVCPU, cfg.ext_zve64d, false),
- DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
- DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
- DEFINE_PROP_BOOL("sstc", RISCVCPU, cfg.ext_sstc, true),
+ MULTI_EXT_CFG_BOOL("sscofpmf", ext_sscofpmf, false),
+ MULTI_EXT_CFG_BOOL("zifencei", ext_ifencei, true),
+ MULTI_EXT_CFG_BOOL("zicsr", ext_icsr, true),
+ MULTI_EXT_CFG_BOOL("zihintntl", ext_zihintntl, true),
+ MULTI_EXT_CFG_BOOL("zihintpause", ext_zihintpause, true),
+ MULTI_EXT_CFG_BOOL("zawrs", ext_zawrs, true),
+ MULTI_EXT_CFG_BOOL("zfa", ext_zfa, true),
+ MULTI_EXT_CFG_BOOL("zfh", ext_zfh, false),
+ MULTI_EXT_CFG_BOOL("zfhmin", ext_zfhmin, false),
+ MULTI_EXT_CFG_BOOL("zve32f", ext_zve32f, false),
+ MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
+ MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
+ MULTI_EXT_CFG_BOOL("sstc", ext_sstc, true),
+
+ MULTI_EXT_CFG_BOOL("smstateen", ext_smstateen, false),
+ MULTI_EXT_CFG_BOOL("svadu", ext_svadu, true),
+ MULTI_EXT_CFG_BOOL("svinval", ext_svinval, false),
+ MULTI_EXT_CFG_BOOL("svnapot", ext_svnapot, false),
+ MULTI_EXT_CFG_BOOL("svpbmt", ext_svpbmt, false),
+
+ MULTI_EXT_CFG_BOOL("zba", ext_zba, true),
+ MULTI_EXT_CFG_BOOL("zbb", ext_zbb, true),
+ MULTI_EXT_CFG_BOOL("zbc", ext_zbc, true),
+ MULTI_EXT_CFG_BOOL("zbkb", ext_zbkb, false),
+ MULTI_EXT_CFG_BOOL("zbkc", ext_zbkc, false),
+ MULTI_EXT_CFG_BOOL("zbkx", ext_zbkx, false),
+ MULTI_EXT_CFG_BOOL("zbs", ext_zbs, true),
+ MULTI_EXT_CFG_BOOL("zk", ext_zk, false),
+ MULTI_EXT_CFG_BOOL("zkn", ext_zkn, false),
+ MULTI_EXT_CFG_BOOL("zknd", ext_zknd, false),
+ MULTI_EXT_CFG_BOOL("zkne", ext_zkne, false),
+ MULTI_EXT_CFG_BOOL("zknh", ext_zknh, false),
+ MULTI_EXT_CFG_BOOL("zkr", ext_zkr, false),
+ MULTI_EXT_CFG_BOOL("zks", ext_zks, false),
+ MULTI_EXT_CFG_BOOL("zksed", ext_zksed, false),
+ MULTI_EXT_CFG_BOOL("zksh", ext_zksh, false),
+ MULTI_EXT_CFG_BOOL("zkt", ext_zkt, false),
+
+ MULTI_EXT_CFG_BOOL("zdinx", ext_zdinx, false),
+ MULTI_EXT_CFG_BOOL("zfinx", ext_zfinx, false),
+ MULTI_EXT_CFG_BOOL("zhinx", ext_zhinx, false),
+ MULTI_EXT_CFG_BOOL("zhinxmin", ext_zhinxmin, false),
+
+ MULTI_EXT_CFG_BOOL("zicbom", ext_icbom, true),
+ MULTI_EXT_CFG_BOOL("zicboz", ext_icboz, true),
+
+ MULTI_EXT_CFG_BOOL("zmmul", ext_zmmul, false),
+
+ MULTI_EXT_CFG_BOOL("zca", ext_zca, false),
+ MULTI_EXT_CFG_BOOL("zcb", ext_zcb, false),
+ MULTI_EXT_CFG_BOOL("zcd", ext_zcd, false),
+ MULTI_EXT_CFG_BOOL("zce", ext_zce, false),
+ MULTI_EXT_CFG_BOOL("zcf", ext_zcf, false),
+ MULTI_EXT_CFG_BOOL("zcmp", ext_zcmp, false),
+ MULTI_EXT_CFG_BOOL("zcmt", ext_zcmt, false),
+ MULTI_EXT_CFG_BOOL("zicond", ext_zicond, false),
- DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
- DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
- DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
- DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
+ DEFINE_PROP_END_OF_LIST(),
+};
- DEFINE_PROP_BOOL("smstateen", RISCVCPU, cfg.ext_smstateen, false),
- DEFINE_PROP_BOOL("svadu", RISCVCPU, cfg.ext_svadu, true),
- DEFINE_PROP_BOOL("svinval", RISCVCPU, cfg.ext_svinval, false),
- DEFINE_PROP_BOOL("svnapot", RISCVCPU, cfg.ext_svnapot, false),
- DEFINE_PROP_BOOL("svpbmt", RISCVCPU, cfg.ext_svpbmt, false),
-
- DEFINE_PROP_BOOL("zba", RISCVCPU, cfg.ext_zba, true),
- DEFINE_PROP_BOOL("zbb", RISCVCPU, cfg.ext_zbb, true),
- DEFINE_PROP_BOOL("zbc", RISCVCPU, cfg.ext_zbc, true),
- DEFINE_PROP_BOOL("zbkb", RISCVCPU, cfg.ext_zbkb, false),
- DEFINE_PROP_BOOL("zbkc", RISCVCPU, cfg.ext_zbkc, false),
- DEFINE_PROP_BOOL("zbkx", RISCVCPU, cfg.ext_zbkx, false),
- DEFINE_PROP_BOOL("zbs", RISCVCPU, cfg.ext_zbs, true),
- DEFINE_PROP_BOOL("zk", RISCVCPU, cfg.ext_zk, false),
- DEFINE_PROP_BOOL("zkn", RISCVCPU, cfg.ext_zkn, false),
- DEFINE_PROP_BOOL("zknd", RISCVCPU, cfg.ext_zknd, false),
- DEFINE_PROP_BOOL("zkne", RISCVCPU, cfg.ext_zkne, false),
- DEFINE_PROP_BOOL("zknh", RISCVCPU, cfg.ext_zknh, false),
- DEFINE_PROP_BOOL("zkr", RISCVCPU, cfg.ext_zkr, false),
- DEFINE_PROP_BOOL("zks", RISCVCPU, cfg.ext_zks, false),
- DEFINE_PROP_BOOL("zksed", RISCVCPU, cfg.ext_zksed, false),
- DEFINE_PROP_BOOL("zksh", RISCVCPU, cfg.ext_zksh, false),
- DEFINE_PROP_BOOL("zkt", RISCVCPU, cfg.ext_zkt, false),
-
- DEFINE_PROP_BOOL("zdinx", RISCVCPU, cfg.ext_zdinx, false),
- DEFINE_PROP_BOOL("zfinx", RISCVCPU, cfg.ext_zfinx, false),
- DEFINE_PROP_BOOL("zhinx", RISCVCPU, cfg.ext_zhinx, false),
- DEFINE_PROP_BOOL("zhinxmin", RISCVCPU, cfg.ext_zhinxmin, false),
-
- DEFINE_PROP_BOOL("zicbom", RISCVCPU, cfg.ext_icbom, true),
- DEFINE_PROP_UINT16("cbom_blocksize", RISCVCPU, cfg.cbom_blocksize, 64),
- DEFINE_PROP_BOOL("zicboz", RISCVCPU, cfg.ext_icboz, true),
- DEFINE_PROP_UINT16("cboz_blocksize", RISCVCPU, cfg.cboz_blocksize, 64),
+const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
+ MULTI_EXT_CFG_BOOL("xtheadba", ext_xtheadba, false),
+ MULTI_EXT_CFG_BOOL("xtheadbb", ext_xtheadbb, false),
+ MULTI_EXT_CFG_BOOL("xtheadbs", ext_xtheadbs, false),
+ MULTI_EXT_CFG_BOOL("xtheadcmo", ext_xtheadcmo, false),
+ MULTI_EXT_CFG_BOOL("xtheadcondmov", ext_xtheadcondmov, false),
+ MULTI_EXT_CFG_BOOL("xtheadfmemidx", ext_xtheadfmemidx, false),
+ MULTI_EXT_CFG_BOOL("xtheadfmv", ext_xtheadfmv, false),
+ MULTI_EXT_CFG_BOOL("xtheadmac", ext_xtheadmac, false),
+ MULTI_EXT_CFG_BOOL("xtheadmemidx", ext_xtheadmemidx, false),
+ MULTI_EXT_CFG_BOOL("xtheadmempair", ext_xtheadmempair, false),
+ MULTI_EXT_CFG_BOOL("xtheadsync", ext_xtheadsync, false),
+ MULTI_EXT_CFG_BOOL("xventanacondops", ext_XVentanaCondOps, false),
- DEFINE_PROP_BOOL("zmmul", RISCVCPU, cfg.ext_zmmul, false),
-
- DEFINE_PROP_BOOL("zca", RISCVCPU, cfg.ext_zca, false),
- DEFINE_PROP_BOOL("zcb", RISCVCPU, cfg.ext_zcb, false),
- DEFINE_PROP_BOOL("zcd", RISCVCPU, cfg.ext_zcd, false),
- DEFINE_PROP_BOOL("zce", RISCVCPU, cfg.ext_zce, false),
- DEFINE_PROP_BOOL("zcf", RISCVCPU, cfg.ext_zcf, false),
- DEFINE_PROP_BOOL("zcmp", RISCVCPU, cfg.ext_zcmp, false),
- DEFINE_PROP_BOOL("zcmt", RISCVCPU, cfg.ext_zcmt, false),
- DEFINE_PROP_BOOL("zicond", RISCVCPU, cfg.ext_zicond, false),
-
- /* Vendor-specific custom extensions */
- DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
- DEFINE_PROP_BOOL("xtheadbb", RISCVCPU, cfg.ext_xtheadbb, false),
- DEFINE_PROP_BOOL("xtheadbs", RISCVCPU, cfg.ext_xtheadbs, false),
- DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
- DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false),
- DEFINE_PROP_BOOL("xtheadfmemidx", RISCVCPU, cfg.ext_xtheadfmemidx, false),
- DEFINE_PROP_BOOL("xtheadfmv", RISCVCPU, cfg.ext_xtheadfmv, false),
- DEFINE_PROP_BOOL("xtheadmac", RISCVCPU, cfg.ext_xtheadmac, false),
- DEFINE_PROP_BOOL("xtheadmemidx", RISCVCPU, cfg.ext_xtheadmemidx, false),
- DEFINE_PROP_BOOL("xtheadmempair", RISCVCPU, cfg.ext_xtheadmempair, false),
- DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
- DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
-
- /* These are experimental so mark with 'x-' */
+ DEFINE_PROP_END_OF_LIST(),
+};
+/* These are experimental so mark with 'x-' */
+const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
/* ePMP 0.9.3 */
- DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
- DEFINE_PROP_BOOL("x-smaia", RISCVCPU, cfg.ext_smaia, false),
- DEFINE_PROP_BOOL("x-ssaia", RISCVCPU, cfg.ext_ssaia, false),
+ MULTI_EXT_CFG_BOOL("x-epmp", epmp, false),
+ MULTI_EXT_CFG_BOOL("x-smaia", ext_smaia, false),
+ MULTI_EXT_CFG_BOOL("x-ssaia", ext_ssaia, false),
- DEFINE_PROP_BOOL("x-zvfh", RISCVCPU, cfg.ext_zvfh, false),
- DEFINE_PROP_BOOL("x-zvfhmin", RISCVCPU, cfg.ext_zvfhmin, false),
+ MULTI_EXT_CFG_BOOL("x-zvfh", ext_zvfh, false),
+ MULTI_EXT_CFG_BOOL("x-zvfhmin", ext_zvfhmin, false),
- DEFINE_PROP_BOOL("x-zfbfmin", RISCVCPU, cfg.ext_zfbfmin, false),
- DEFINE_PROP_BOOL("x-zvfbfmin", RISCVCPU, cfg.ext_zvfbfmin, false),
- DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false),
+ MULTI_EXT_CFG_BOOL("x-zfbfmin", ext_zfbfmin, false),
+ MULTI_EXT_CFG_BOOL("x-zvfbfmin", ext_zvfbfmin, false),
+ MULTI_EXT_CFG_BOOL("x-zvfbfwma", ext_zvfbfwma, false),
/* Vector cryptography extensions */
- DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
- DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
- DEFINE_PROP_BOOL("x-zvkg", RISCVCPU, cfg.ext_zvkg, false),
- DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
- DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
- DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
- DEFINE_PROP_BOOL("x-zvksed", RISCVCPU, cfg.ext_zvksed, false),
- DEFINE_PROP_BOOL("x-zvksh", RISCVCPU, cfg.ext_zvksh, false),
+ MULTI_EXT_CFG_BOOL("x-zvbb", ext_zvbb, false),
+ MULTI_EXT_CFG_BOOL("x-zvbc", ext_zvbc, false),
+ MULTI_EXT_CFG_BOOL("x-zvkg", ext_zvkg, false),
+ MULTI_EXT_CFG_BOOL("x-zvkned", ext_zvkned, false),
+ MULTI_EXT_CFG_BOOL("x-zvknha", ext_zvknha, false),
+ MULTI_EXT_CFG_BOOL("x-zvknhb", ext_zvknhb, false),
+ MULTI_EXT_CFG_BOOL("x-zvksed", ext_zvksed, false),
+ MULTI_EXT_CFG_BOOL("x-zvksh", ext_zvksh, false),
DEFINE_PROP_END_OF_LIST(),
};
+/* Deprecated entries marked for future removal */
+const RISCVCPUMultiExtConfig riscv_cpu_deprecated_exts[] = {
+ MULTI_EXT_CFG_BOOL("Zifencei", ext_ifencei, true),
+ MULTI_EXT_CFG_BOOL("Zicsr", ext_icsr, true),
+ MULTI_EXT_CFG_BOOL("Zihintntl", ext_zihintntl, true),
+ MULTI_EXT_CFG_BOOL("Zihintpause", ext_zihintpause, true),
+ MULTI_EXT_CFG_BOOL("Zawrs", ext_zawrs, true),
+ MULTI_EXT_CFG_BOOL("Zfa", ext_zfa, true),
+ MULTI_EXT_CFG_BOOL("Zfh", ext_zfh, false),
+ MULTI_EXT_CFG_BOOL("Zfhmin", ext_zfhmin, false),
+ MULTI_EXT_CFG_BOOL("Zve32f", ext_zve32f, false),
+ MULTI_EXT_CFG_BOOL("Zve64f", ext_zve64f, false),
+ MULTI_EXT_CFG_BOOL("Zve64d", ext_zve64d, false),
-#ifndef CONFIG_USER_ONLY
-static void cpu_set_cfg_unavailable(Object *obj, Visitor *v,
- const char *name,
- void *opaque, Error **errp)
-{
- const char *propname = opaque;
- bool value;
-
- if (!visit_type_bool(v, name, &value, errp)) {
- return;
- }
-
- if (value) {
- error_setg(errp, "extension %s is not available with KVM",
- propname);
- }
-}
-#endif
+ DEFINE_PROP_END_OF_LIST(),
+};
-/*
- * Add CPU properties with user-facing flags.
- *
- * This will overwrite existing env->misa_ext values with the
- * defaults set via riscv_cpu_add_misa_properties().
- */
-static void riscv_cpu_add_user_properties(Object *obj)
-{
- Property *prop;
- DeviceState *dev = DEVICE(obj);
+Property riscv_cpu_options[] = {
+ DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
-#ifndef CONFIG_USER_ONLY
- riscv_add_satp_mode_properties(obj);
+ DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
+ DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
- if (kvm_enabled()) {
- kvm_riscv_init_user_properties(obj);
- }
-#endif
+ DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
+ DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
- riscv_cpu_add_misa_properties(obj);
+ DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
+ DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
- for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
-#ifndef CONFIG_USER_ONLY
- if (kvm_enabled()) {
- /* Check if KVM created the property already */
- if (object_property_find(obj, prop->name)) {
- continue;
- }
+ DEFINE_PROP_UINT16("cbom_blocksize", RISCVCPU, cfg.cbom_blocksize, 64),
+ DEFINE_PROP_UINT16("cboz_blocksize", RISCVCPU, cfg.cboz_blocksize, 64),
- /*
- * Set the default to disabled for every extension
- * unknown to KVM and error out if the user attempts
- * to enable any of them.
- *
- * We're giving a pass for non-bool properties since they're
- * not related to the availability of extensions and can be
- * safely ignored as is.
- */
- if (prop->info == &qdev_prop_bool) {
- object_property_add(obj, prop->name, "bool",
- NULL, cpu_set_cfg_unavailable,
- NULL, (void *)prop->name);
- continue;
- }
- }
-#endif
- qdev_property_add_static(dev, prop);
- }
-}
+ DEFINE_PROP_END_OF_LIST(),
+};
static Property riscv_cpu_properties[] = {
DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
@@ -2051,30 +1447,6 @@ static const struct SysemuCPUOps riscv_sysemu_ops = {
};
#endif
-#include "hw/core/tcg-cpu-ops.h"
-
-static const struct TCGCPUOps riscv_tcg_ops = {
- .initialize = riscv_translate_init,
- .synchronize_from_tb = riscv_cpu_synchronize_from_tb,
- .restore_state_to_opc = riscv_restore_state_to_opc,
-
-#ifndef CONFIG_USER_ONLY
- .tlb_fill = riscv_cpu_tlb_fill,
- .cpu_exec_interrupt = riscv_cpu_exec_interrupt,
- .do_interrupt = riscv_cpu_do_interrupt,
- .do_transaction_failed = riscv_cpu_do_transaction_failed,
- .do_unaligned_access = riscv_cpu_do_unaligned_access,
- .debug_excp_handler = riscv_cpu_debug_excp_handler,
- .debug_check_breakpoint = riscv_cpu_debug_check_breakpoint,
- .debug_check_watchpoint = riscv_cpu_debug_check_watchpoint,
-#endif /* !CONFIG_USER_ONLY */
-};
-
-static bool riscv_cpu_is_dynamic(Object *cpu_obj)
-{
- return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL;
-}
-
static void cpu_set_mvendorid(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
@@ -2212,7 +1584,6 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
#endif
cc->gdb_arch_name = riscv_gdb_arch_name;
cc->gdb_get_dynamic_xml = riscv_gdb_get_dynamic_xml;
- cc->tcg_ops = &riscv_tcg_ops;
object_class_property_add(c, "mvendorid", "uint32", cpu_get_mvendorid,
cpu_set_mvendorid, NULL, NULL);
@@ -2229,13 +1600,13 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str,
int max_str_len)
{
+ const RISCVIsaExtData *edata;
char *old = *isa_str;
char *new = *isa_str;
- int i;
- for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
- if (isa_ext_is_enabled(cpu, &isa_edata_arr[i])) {
- new = g_strconcat(old, "_", isa_edata_arr[i].name, NULL);
+ for (edata = isa_edata_arr; edata && edata->name; edata++) {
+ if (isa_ext_is_enabled(cpu, edata->ext_enable_offset)) {
+ new = g_strconcat(old, "_", edata->name, NULL);
g_free(old);
old = new;
}
@@ -2312,6 +1683,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
.instance_size = sizeof(RISCVCPU),
.instance_align = __alignof(RISCVCPU),
.instance_init = riscv_cpu_init,
+ .instance_post_init = riscv_cpu_post_init,
.abstract = true,
.class_size = sizeof(RISCVCPUClass),
.class_init = riscv_cpu_class_init,
@@ -2322,9 +1694,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
.abstract = true,
},
DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
-#if defined(CONFIG_KVM)
- DEFINE_CPU(TYPE_RISCV_CPU_HOST, riscv_host_cpu_init),
-#endif
+ DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_MAX, riscv_max_cpu_init),
#if defined(TARGET_RISCV32)
DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE32, rv32_base_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init),