* [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support
@ 2023-11-02 22:44 Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 01/19] target/riscv: create TYPE_RISCV_VENDOR_CPU Daniel Henrique Barboza
` (18 more replies)
0 siblings, 19 replies; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-02 22:44 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
Hi,
In this version two new patches were added, both while discussing v6
with Alistair:
- new 'rva22u64' CPU. This is a CPU suggested by Alistair and others to
allow users to use a profile without having to deal with profile
enablement. This is done in patch 18;
- 'max' CPU profile restriction. There's no user benefit to have profile
support in a CPU that has all extensions enabled. This is done in
patch 19.
Other changes were done based on Drew's feedback on v8:
- patch 3: handle RVH priv_ver bump if it's user enabled, and put some
comments explaining how it interacts with the 'priv_spec' user option.
- patch 4: rv64i cpu_init() now sets max setp_mode to SV64, and
we're returning 'MBARE' as default satp_mode for all 'bare' CPUs
if the user doesn't set a satp_mode in the command line. This will do
what we want without having to change cpu_riscv_set_satp() and
satp_finalize(), so patches 3 and 4 from v8 were dropped. Drew saw the
diff of this patch and decided to keep his ack from v8;
Patches based on riscv-to-apply.next.
Patches missing acks: 3, 18, 19
Changes from v8:
- patches 3 and 4 from v8: dropped
- patch 3 (patch 5 from v8):
- bump priv_ver when RVH is enabled
- add a disclaimer when bumping priv_ver about the priv_spec option
having precedence
- patch 4 (patch 6 from v8):
- set set_satp_mode_max_supported() to SV64 in rv64i_bare_cpu_init()
- set PRIV_VERSION_1_10_0 in rv64i_bare_cpu_init()
- change set_satp_mode_default_map() to set MBARE for 'bare' CPUs
- patch 18 (new):
- add rva22u64 CPU
- patch 19 (new):
- forbid profile support for 'max' CPU
- v8 link: https://lore.kernel.org/qemu-riscv/20231101204204.345470-1-dbarboza@ventanamicro.com/
Daniel Henrique Barboza (19):
target/riscv: create TYPE_RISCV_VENDOR_CPU
target/riscv/tcg: do not use "!generic" CPU checks
target/riscv/tcg: update priv_ver on user_set extensions
target/riscv: add rv64i CPU
target/riscv: add zicbop extension flag
target/riscv/tcg: add 'zic64b' support
riscv-qmp-cmds.c: expose named features in cpu_model_expansion
target/riscv: add rva22u64 profile definition
target/riscv/kvm: add 'rva22u64' flag as unavailable
target/riscv/tcg: add user flag for profile support
target/riscv/tcg: add MISA user options hash
target/riscv/tcg: add riscv_cpu_write_misa_bit()
target/riscv/tcg: handle profile MISA bits
target/riscv/tcg: add hash table insert helpers
target/riscv/tcg: honor user choice for G MISA bits
target/riscv/tcg: validate profiles during finalize
riscv-qmp-cmds.c: add profile flags in cpu-model-expansion
target/riscv: add 'rva22u64' CPU
target/riscv/tcg: do not support profiles for 'max' CPU
hw/riscv/virt.c | 5 +
target/riscv/cpu-qom.h | 4 +
target/riscv/cpu.c | 130 +++++++++++-
target/riscv/cpu.h | 13 ++
target/riscv/cpu_cfg.h | 3 +
target/riscv/kvm/kvm-cpu.c | 7 +-
target/riscv/riscv-qmp-cmds.c | 44 +++-
target/riscv/tcg/tcg-cpu.c | 370 ++++++++++++++++++++++++++++++----
8 files changed, 518 insertions(+), 58 deletions(-)
--
2.41.0
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v9 01/19] target/riscv: create TYPE_RISCV_VENDOR_CPU
2023-11-02 22:44 [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support Daniel Henrique Barboza
@ 2023-11-02 22:44 ` Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 02/19] target/riscv/tcg: do not use "!generic" CPU checks Daniel Henrique Barboza
` (17 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-02 22:44 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
We want to add a new CPU type for bare CPUs that will inherit specific
traits of the 2 existing types:
- it will allow for extensions to be enabled/disabled, like generic
CPUs;
- it will NOT inherit defaults, like vendor CPUs.
We can make this conditions met by adding an explicit type for the
existing vendor CPUs and change the existing logic to not imply that
"not generic" means vendor CPUs.
Let's add the "vendor" CPU type first.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu-qom.h | 1 +
target/riscv/cpu.c | 30 +++++++++++++++++++++---------
2 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
index f3fbe37a2c..7831e86d37 100644
--- a/target/riscv/cpu-qom.h
+++ b/target/riscv/cpu-qom.h
@@ -24,6 +24,7 @@
#define TYPE_RISCV_CPU "riscv-cpu"
#define TYPE_RISCV_DYNAMIC_CPU "riscv-dynamic-cpu"
+#define TYPE_RISCV_VENDOR_CPU "riscv-vendor-cpu"
#define RISCV_CPU_TYPE_SUFFIX "-" TYPE_RISCV_CPU
#define RISCV_CPU_TYPE_NAME(name) (name RISCV_CPU_TYPE_SUFFIX)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d73e1da2a2..4bb677275c 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1741,6 +1741,13 @@ void riscv_cpu_list(void)
.instance_init = initfn \
}
+#define DEFINE_VENDOR_CPU(type_name, initfn) \
+ { \
+ .name = type_name, \
+ .parent = TYPE_RISCV_VENDOR_CPU, \
+ .instance_init = initfn \
+ }
+
static const TypeInfo riscv_cpu_type_infos[] = {
{
.name = TYPE_RISCV_CPU,
@@ -1758,21 +1765,26 @@ static const TypeInfo riscv_cpu_type_infos[] = {
.parent = TYPE_RISCV_CPU,
.abstract = true,
},
+ {
+ .name = TYPE_RISCV_VENDOR_CPU,
+ .parent = TYPE_RISCV_CPU,
+ .abstract = true,
+ },
DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
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),
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32_sifive_e_cpu_init),
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32_sifive_u_cpu_init),
+ DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init),
+ DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32_sifive_e_cpu_init),
+ DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
+ DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32_sifive_u_cpu_init),
#elif defined(TARGET_RISCV64)
DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE64, rv64_base_cpu_init),
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64_sifive_e_cpu_init),
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64_sifive_u_cpu_init),
- DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C, rv64_sifive_u_cpu_init),
- DEFINE_CPU(TYPE_RISCV_CPU_THEAD_C906, rv64_thead_c906_cpu_init),
- DEFINE_CPU(TYPE_RISCV_CPU_VEYRON_V1, rv64_veyron_v1_cpu_init),
+ DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64_sifive_e_cpu_init),
+ DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64_sifive_u_cpu_init),
+ DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SHAKTI_C, rv64_sifive_u_cpu_init),
+ DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_THEAD_C906, rv64_thead_c906_cpu_init),
+ DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1, rv64_veyron_v1_cpu_init),
DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128, rv128_base_cpu_init),
#endif
};
--
2.41.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v9 02/19] target/riscv/tcg: do not use "!generic" CPU checks
2023-11-02 22:44 [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 01/19] target/riscv: create TYPE_RISCV_VENDOR_CPU Daniel Henrique Barboza
@ 2023-11-02 22:44 ` Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 03/19] target/riscv/tcg: update priv_ver on user_set extensions Daniel Henrique Barboza
` (16 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-02 22:44 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
Our current logic in get/setters of MISA and multi-letter extensions
works because we have only 2 CPU types, generic and vendor, and by using
"!generic" we're implying that we're talking about vendor CPUs. When adding
a third CPU type this logic will break so let's handle it beforehand.
In set_misa_ext_cfg() and set_multi_ext_cfg(), check for "vendor" cpu instead
of "not generic". The "generic CPU" checks remaining are from
riscv_cpu_add_misa_properties() and cpu_add_multi_ext_prop() before
applying default values for the extensions.
This leaves us with:
- vendor CPUs will not allow extension enablement, all other CPUs will;
- generic CPUs will inherit default values for extensions, all others
won't.
And now we can add a new, third CPU type, that will allow extensions to
be enabled and will not inherit defaults, without changing the existing
logic.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/tcg/tcg-cpu.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 1a3351b142..08f8dded56 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -654,6 +654,11 @@ static bool riscv_cpu_is_generic(Object *cpu_obj)
return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL;
}
+static bool riscv_cpu_is_vendor(Object *cpu_obj)
+{
+ return object_dynamic_cast(cpu_obj, TYPE_RISCV_VENDOR_CPU) != NULL;
+}
+
/*
* We'll get here via the following path:
*
@@ -716,7 +721,7 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, const char *name,
target_ulong misa_bit = misa_ext_cfg->misa_bit;
RISCVCPU *cpu = RISCV_CPU(obj);
CPURISCVState *env = &cpu->env;
- bool generic_cpu = riscv_cpu_is_generic(obj);
+ bool vendor_cpu = riscv_cpu_is_vendor(obj);
bool prev_val, value;
if (!visit_type_bool(v, name, &value, errp)) {
@@ -730,7 +735,7 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, const char *name,
}
if (value) {
- if (!generic_cpu) {
+ if (vendor_cpu) {
g_autofree char *cpuname = riscv_cpu_get_name(cpu);
error_setg(errp, "'%s' CPU does not allow enabling extensions",
cpuname);
@@ -835,7 +840,7 @@ static void cpu_set_multi_ext_cfg(Object *obj, Visitor *v, const char *name,
{
const RISCVCPUMultiExtConfig *multi_ext_cfg = opaque;
RISCVCPU *cpu = RISCV_CPU(obj);
- bool generic_cpu = riscv_cpu_is_generic(obj);
+ bool vendor_cpu = riscv_cpu_is_vendor(obj);
bool prev_val, value;
if (!visit_type_bool(v, name, &value, errp)) {
@@ -859,7 +864,7 @@ static void cpu_set_multi_ext_cfg(Object *obj, Visitor *v, const char *name,
return;
}
- if (value && !generic_cpu) {
+ if (value && vendor_cpu) {
g_autofree char *cpuname = riscv_cpu_get_name(cpu);
error_setg(errp, "'%s' CPU does not allow enabling extensions",
cpuname);
--
2.41.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v9 03/19] target/riscv/tcg: update priv_ver on user_set extensions
2023-11-02 22:44 [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 01/19] target/riscv: create TYPE_RISCV_VENDOR_CPU Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 02/19] target/riscv/tcg: do not use "!generic" CPU checks Daniel Henrique Barboza
@ 2023-11-02 22:44 ` Daniel Henrique Barboza
2023-11-03 8:33 ` Andrew Jones
2023-11-02 22:44 ` [PATCH v9 04/19] target/riscv: add rv64i CPU Daniel Henrique Barboza
` (15 subsequent siblings)
18 siblings, 1 reply; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-02 22:44 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
We'll add a new bare CPU type that won't have any default priv_ver. This
means that the CPU will default to priv_ver = 0, i.e. 1.10.0.
At the same we'll allow these CPUs to enable extensions at will, but
then, if the extension has a priv_ver newer than 1.10, we'll end up
disabling it. Users will then need to manually set priv_ver to something
other than 1.10 to enable the extensions they want, which is not ideal.
Change the setter() of extensions to allow user enabled extensions to
bump the priv_ver of the CPU. This will make it convenient for users to
enable extensions for CPUs that doesn't set a default priv_ver.
This change does not affect any existing CPU: vendor CPUs does not allow
extensions to be enabled, and generic CPUs are already set to priv_ver
LATEST.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
target/riscv/tcg/tcg-cpu.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 08f8dded56..0e684ab86f 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -114,6 +114,22 @@ static int cpu_cfg_ext_get_min_version(uint32_t ext_offset)
g_assert_not_reached();
}
+static void cpu_validate_multi_ext_priv_ver(CPURISCVState *env,
+ uint32_t ext_offset)
+{
+ int ext_priv_ver;
+
+ if (env->priv_ver == PRIV_VERSION_LATEST) {
+ return;
+ }
+
+ ext_priv_ver = cpu_cfg_ext_get_min_version(ext_offset);
+
+ if (env->priv_ver < ext_priv_ver) {
+ env->priv_ver = ext_priv_ver;
+ }
+}
+
static void cpu_cfg_ext_auto_update(RISCVCPU *cpu, uint32_t ext_offset,
bool value)
{
@@ -742,6 +758,14 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, const char *name,
return;
}
+ if (misa_bit == RVH && env->priv_ver < PRIV_VERSION_1_12_0) {
+ /*
+ * Note: the 'priv_spec' command line option, if present,
+ * will take precedence over this priv_ver bump.
+ */
+ env->priv_ver = PRIV_VERSION_1_12_0;
+ }
+
env->misa_ext |= misa_bit;
env->misa_ext_mask |= misa_bit;
} else {
@@ -871,6 +895,14 @@ static void cpu_set_multi_ext_cfg(Object *obj, Visitor *v, const char *name,
return;
}
+ if (value) {
+ /*
+ * Note: the 'priv_spec' command line option, if present,
+ * will take precedence over this priv_ver bump.
+ */
+ cpu_validate_multi_ext_priv_ver(&cpu->env, multi_ext_cfg->offset);
+ }
+
isa_ext_update_enabled(cpu, multi_ext_cfg->offset, value);
}
--
2.41.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v9 04/19] target/riscv: add rv64i CPU
2023-11-02 22:44 [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support Daniel Henrique Barboza
` (2 preceding siblings ...)
2023-11-02 22:44 ` [PATCH v9 03/19] target/riscv/tcg: update priv_ver on user_set extensions Daniel Henrique Barboza
@ 2023-11-02 22:44 ` Daniel Henrique Barboza
2023-11-03 8:37 ` Andrew Jones
2023-11-02 22:44 ` [PATCH v9 05/19] target/riscv: add zicbop extension flag Daniel Henrique Barboza
` (14 subsequent siblings)
18 siblings, 1 reply; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-02 22:44 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
We don't have any form of a 'bare bones' CPU. rv64, our default CPUs,
comes with a lot of defaults. This is fine for most regular uses but
it's not suitable when more control of what is actually loaded in the
CPU is required.
A bare-bones CPU would be annoying to deal with if not by profile
support, a way to load a multitude of extensions with a single flag.
Profile support is going to be implemented shortly, so let's add a CPU
for it.
The new 'rv64i' CPU will have only RVI loaded. It is inspired in the
profile specification that dictates, for RVA22U64 [1]:
"RVA22U64 Mandatory Base
RV64I is the mandatory base ISA for RVA22U64"
And so it seems that RV64I is the mandatory base ISA for all profiles
listed in [1], making it an ideal CPU to use with profile support.
rv64i is a CPU of type TYPE_RISCV_BARE_CPU. It has a mix of features
from pre-existent CPUs:
- it allows extensions to be enabled, like generic CPUs;
- it will not inherit extension defaults, like vendor CPUs.
This is the minimum extension set to boot OpenSBI and buildroot using
rv64i:
./build/qemu-system-riscv64 -nographic -M virt \
-cpu rv64i,sv39=true,g=true,c=true,s=true,u=true
Our minimal riscv,isa in this case will be:
# cat /proc/device-tree/cpus/cpu@0/riscv,isa
rv64imafdc_zicntr_zicsr_zifencei_zihpm_zca_zcd#
[1] https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
target/riscv/cpu-qom.h | 2 ++
target/riscv/cpu.c | 49 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 51 insertions(+)
diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
index 7831e86d37..ea9a752280 100644
--- a/target/riscv/cpu-qom.h
+++ b/target/riscv/cpu-qom.h
@@ -25,6 +25,7 @@
#define TYPE_RISCV_CPU "riscv-cpu"
#define TYPE_RISCV_DYNAMIC_CPU "riscv-dynamic-cpu"
#define TYPE_RISCV_VENDOR_CPU "riscv-vendor-cpu"
+#define TYPE_RISCV_BARE_CPU "riscv-bare-cpu"
#define RISCV_CPU_TYPE_SUFFIX "-" TYPE_RISCV_CPU
#define RISCV_CPU_TYPE_NAME(name) (name RISCV_CPU_TYPE_SUFFIX)
@@ -35,6 +36,7 @@
#define TYPE_RISCV_CPU_BASE32 RISCV_CPU_TYPE_NAME("rv32")
#define TYPE_RISCV_CPU_BASE64 RISCV_CPU_TYPE_NAME("rv64")
#define TYPE_RISCV_CPU_BASE128 RISCV_CPU_TYPE_NAME("x-rv128")
+#define TYPE_RISCV_CPU_RV64I RISCV_CPU_TYPE_NAME("rv64i")
#define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex")
#define TYPE_RISCV_CPU_SHAKTI_C RISCV_CPU_TYPE_NAME("shakti-c")
#define TYPE_RISCV_CPU_SIFIVE_E31 RISCV_CPU_TYPE_NAME("sifive-e31")
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 4bb677275c..e9be0c7dae 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -370,6 +370,17 @@ static void set_satp_mode_max_supported(RISCVCPU *cpu,
/* Set the satp mode to the max supported */
static void set_satp_mode_default_map(RISCVCPU *cpu)
{
+ /*
+ * Bare CPUs does not default to the max available.
+ * Users must set a valid satp_mode in the command
+ * line.
+ */
+ if (object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_BARE_CPU) != NULL) {
+ warn_report("No satp mode set. Defaulting to 'bare'");
+ cpu->cfg.satp_mode.map = (1 << VM_1_10_MBARE);
+ return;
+ }
+
cpu->cfg.satp_mode.map = cpu->cfg.satp_mode.supported;
}
#endif
@@ -552,6 +563,31 @@ static void rv128_base_cpu_init(Object *obj)
set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
#endif
}
+
+static void rv64i_bare_cpu_init(Object *obj)
+{
+ CPURISCVState *env = &RISCV_CPU(obj)->env;
+ riscv_cpu_set_misa(env, MXL_RV64, RVI);
+
+ /* Remove the defaults from the parent class */
+ RISCV_CPU(obj)->cfg.ext_zicntr = false;
+ RISCV_CPU(obj)->cfg.ext_zihpm = false;
+
+ /*
+ * Set 1.10 instead of leaving it blank, which
+ * defaults to 1.10 anyway.
+ */
+ env->priv_ver = PRIV_VERSION_1_10_0;
+
+ /*
+ * Support all available satp_mode settings. The default
+ * value will be set to MBARE if the user doesn't set
+ * satp_mode manually (see set_satp_mode_default()).
+ */
+#ifndef CONFIG_USER_ONLY
+ set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV64);
+#endif
+}
#else
static void rv32_base_cpu_init(Object *obj)
{
@@ -1748,6 +1784,13 @@ void riscv_cpu_list(void)
.instance_init = initfn \
}
+#define DEFINE_BARE_CPU(type_name, initfn) \
+ { \
+ .name = type_name, \
+ .parent = TYPE_RISCV_BARE_CPU, \
+ .instance_init = initfn \
+ }
+
static const TypeInfo riscv_cpu_type_infos[] = {
{
.name = TYPE_RISCV_CPU,
@@ -1770,6 +1813,11 @@ static const TypeInfo riscv_cpu_type_infos[] = {
.parent = TYPE_RISCV_CPU,
.abstract = true,
},
+ {
+ .name = TYPE_RISCV_BARE_CPU,
+ .parent = TYPE_RISCV_CPU,
+ .abstract = true,
+ },
DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_MAX, riscv_max_cpu_init),
#if defined(TARGET_RISCV32)
@@ -1786,6 +1834,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_THEAD_C906, rv64_thead_c906_cpu_init),
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1, rv64_veyron_v1_cpu_init),
DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128, rv128_base_cpu_init),
+ DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV64I, rv64i_bare_cpu_init),
#endif
};
--
2.41.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v9 05/19] target/riscv: add zicbop extension flag
2023-11-02 22:44 [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support Daniel Henrique Barboza
` (3 preceding siblings ...)
2023-11-02 22:44 ` [PATCH v9 04/19] target/riscv: add rv64i CPU Daniel Henrique Barboza
@ 2023-11-02 22:44 ` Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 06/19] target/riscv/tcg: add 'zic64b' support Daniel Henrique Barboza
` (13 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-02 22:44 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
QEMU already implements zicbom (Cache Block Management Operations) and
zicboz (Cache Block Zero Operations). Commit 59cb29d6a5 ("target/riscv:
add Zicbop cbo.prefetch{i, r, m} placeholder") added placeholders for
what would be the instructions for zicbop (Cache Block Prefetch
Operations), which are now no-ops.
The RVA22U64 profile mandates zicbop, which means that applications that
run with this profile might expect zicbop to be present in the riscv,isa
DT and might behave badly if it's absent.
Adding zicbop as an extension will make our future RVA22U64
implementation more in line with what userspace expects and, if/when
cache block prefetch operations became relevant to QEMU, we already have
the extension flag to turn then on/off as needed.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
hw/riscv/virt.c | 5 +++++
target/riscv/cpu.c | 3 +++
target/riscv/cpu_cfg.h | 2 ++
3 files changed, 10 insertions(+)
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index e64886a4d8..ae18aec09a 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -250,6 +250,11 @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket,
cpu_ptr->cfg.cboz_blocksize);
}
+ if (cpu_ptr->cfg.ext_zicbop) {
+ qemu_fdt_setprop_cell(ms->fdt, cpu_name, "riscv,cbop-block-size",
+ cpu_ptr->cfg.cbop_blocksize);
+ }
+
qemu_fdt_setprop_string(ms->fdt, cpu_name, "compatible", "riscv");
qemu_fdt_setprop_string(ms->fdt, cpu_name, "status", "okay");
qemu_fdt_setprop_cell(ms->fdt, cpu_name, "reg",
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index e9be0c7dae..057dd3d186 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -78,6 +78,7 @@ const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, RVV,
*/
const RISCVIsaExtData isa_edata_arr[] = {
ISA_EXT_DATA_ENTRY(zicbom, PRIV_VERSION_1_12_0, ext_zicbom),
+ ISA_EXT_DATA_ENTRY(zicbop, PRIV_VERSION_1_12_0, ext_zicbop),
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),
@@ -1380,6 +1381,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
MULTI_EXT_CFG_BOOL("zhinxmin", ext_zhinxmin, false),
MULTI_EXT_CFG_BOOL("zicbom", ext_zicbom, true),
+ MULTI_EXT_CFG_BOOL("zicbop", ext_zicbop, true),
MULTI_EXT_CFG_BOOL("zicboz", ext_zicboz, true),
MULTI_EXT_CFG_BOOL("zmmul", ext_zmmul, false),
@@ -1476,6 +1478,7 @@ Property riscv_cpu_options[] = {
DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
DEFINE_PROP_UINT16("cbom_blocksize", RISCVCPU, cfg.cbom_blocksize, 64),
+ DEFINE_PROP_UINT16("cbop_blocksize", RISCVCPU, cfg.cbop_blocksize, 64),
DEFINE_PROP_UINT16("cboz_blocksize", RISCVCPU, cfg.cboz_blocksize, 64),
DEFINE_PROP_END_OF_LIST(),
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index 634ff673b3..c21e4bcc47 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -65,6 +65,7 @@ struct RISCVCPUConfig {
bool ext_zicntr;
bool ext_zicsr;
bool ext_zicbom;
+ bool ext_zicbop;
bool ext_zicboz;
bool ext_zicond;
bool ext_zihintntl;
@@ -142,6 +143,7 @@ struct RISCVCPUConfig {
uint16_t vlen;
uint16_t elen;
uint16_t cbom_blocksize;
+ uint16_t cbop_blocksize;
uint16_t cboz_blocksize;
bool mmu;
bool pmp;
--
2.41.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v9 06/19] target/riscv/tcg: add 'zic64b' support
2023-11-02 22:44 [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support Daniel Henrique Barboza
` (4 preceding siblings ...)
2023-11-02 22:44 ` [PATCH v9 05/19] target/riscv: add zicbop extension flag Daniel Henrique Barboza
@ 2023-11-02 22:44 ` Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 07/19] riscv-qmp-cmds.c: expose named features in cpu_model_expansion Daniel Henrique Barboza
` (12 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-02 22:44 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
zic64b is defined in the RVA22U64 profile [1] as a named feature for
"Cache blocks must be 64 bytes in size, naturally aligned in the address
space". It's a fantasy name for 64 bytes cache blocks. The RVA22U64
profile mandates this feature, meaning that applications using this
profile expects 64 bytes cache blocks.
To make the upcoming RVA22U64 implementation complete, we'll zic64b as
a 'named feature', not a regular extension. This means that:
- it won't be exposed to users;
- it won't be written in riscv,isa.
This will be extended to other named extensions in the future, so we're
creating some common boilerplate for them as well.
zic64b is default to 'true' since we're already using 64 bytes blocks.
If any cache block size (cbo{m,p,z}_blocksize) is changed to something
different than 64, zic64b is set to 'false'.
Our profile implementation will then be able to check the current state
of zic64b and take the appropriate action (e.g. throw a warning).
[1] https://github.com/riscv/riscv-profiles/releases/download/v1.0/profiles.pdf
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
target/riscv/cpu.c | 6 ++++++
target/riscv/cpu.h | 1 +
target/riscv/cpu_cfg.h | 1 +
target/riscv/tcg/tcg-cpu.c | 31 +++++++++++++++++++++++++++++++
4 files changed, 39 insertions(+)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 057dd3d186..4b92f320e0 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1448,6 +1448,12 @@ const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
DEFINE_PROP_END_OF_LIST(),
};
+const RISCVCPUMultiExtConfig riscv_cpu_named_features[] = {
+ MULTI_EXT_CFG_BOOL("zic64b", zic64b, true),
+
+ DEFINE_PROP_END_OF_LIST(),
+};
+
/* Deprecated entries marked for future removal */
const RISCVCPUMultiExtConfig riscv_cpu_deprecated_exts[] = {
MULTI_EXT_CFG_BOOL("Zifencei", ext_zifencei, true),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 8efc4d83ec..bf12f34082 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -745,6 +745,7 @@ typedef struct RISCVCPUMultiExtConfig {
extern const RISCVCPUMultiExtConfig riscv_cpu_extensions[];
extern const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[];
extern const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[];
+extern const RISCVCPUMultiExtConfig riscv_cpu_named_features[];
extern const RISCVCPUMultiExtConfig riscv_cpu_deprecated_exts[];
extern Property riscv_cpu_options[];
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index c21e4bcc47..414c4eba77 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -116,6 +116,7 @@ struct RISCVCPUConfig {
bool ext_smepmp;
bool rvv_ta_all_1s;
bool rvv_ma_all_1s;
+ bool zic64b;
uint32_t mvendorid;
uint64_t marchid;
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 0e684ab86f..b0f69c6437 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -114,6 +114,19 @@ static int cpu_cfg_ext_get_min_version(uint32_t ext_offset)
g_assert_not_reached();
}
+static bool cpu_cfg_offset_is_named_feat(uint32_t ext_offset)
+{
+ const RISCVCPUMultiExtConfig *feat;
+
+ for (feat = riscv_cpu_named_features; feat->name != NULL; feat++) {
+ if (feat->offset == ext_offset) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
static void cpu_validate_multi_ext_priv_ver(CPURISCVState *env,
uint32_t ext_offset)
{
@@ -123,6 +136,10 @@ static void cpu_validate_multi_ext_priv_ver(CPURISCVState *env,
return;
}
+ if (cpu_cfg_offset_is_named_feat(ext_offset)) {
+ return;
+ }
+
ext_priv_ver = cpu_cfg_ext_get_min_version(ext_offset);
if (env->priv_ver < ext_priv_ver) {
@@ -280,6 +297,18 @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
}
}
+static void riscv_cpu_validate_zic64b(RISCVCPU *cpu)
+{
+ cpu->cfg.zic64b = cpu->cfg.cbom_blocksize == 64 &&
+ cpu->cfg.cbop_blocksize == 64 &&
+ cpu->cfg.cboz_blocksize == 64;
+}
+
+static void riscv_cpu_validate_named_features(RISCVCPU *cpu)
+{
+ riscv_cpu_validate_zic64b(cpu);
+}
+
/*
* Check consistency between chosen extensions while setting
* cpu->cfg accordingly.
@@ -644,6 +673,8 @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
return;
}
+ riscv_cpu_validate_named_features(cpu);
+
if (cpu->cfg.ext_smepmp && !cpu->cfg.pmp) {
/*
* Enhanced PMP should only be available
--
2.41.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v9 07/19] riscv-qmp-cmds.c: expose named features in cpu_model_expansion
2023-11-02 22:44 [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support Daniel Henrique Barboza
` (5 preceding siblings ...)
2023-11-02 22:44 ` [PATCH v9 06/19] target/riscv/tcg: add 'zic64b' support Daniel Henrique Barboza
@ 2023-11-02 22:44 ` Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 08/19] target/riscv: add rva22u64 profile definition Daniel Henrique Barboza
` (11 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-02 22:44 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
Named features (zic64b the sole example at this moment) aren't expose to
users, thus we need another way to expose them.
Go through each named feature, get its boolean value, do the needed
conversions (bool to qbool, qbool to QObject) and add it to output dict.
Another adjustment is needed: named features are evaluated during
finalize(), so riscv_cpu_finalize_features() needs to be mandatory
regardless of whether we have an input dict or not. Otherwise zic64b
will always return 'false', which is incorrect: the default values of
cache blocksizes ([cbom/cbop/cboz]_blocksize) are set to 64, satisfying
the conditions for zic64b.
Here's an API usage example after this patch:
$ ./build/qemu-system-riscv64 -S -M virt -display none
-qmp tcp:localhost:1234,server,wait=off
$ ./scripts/qmp/qmp-shell localhost:1234
Welcome to the QMP low-level shell!
Connected to QEMU 8.1.50
(QEMU) query-cpu-model-expansion type=full model={"name":"rv64"}
{"return": {"model":
{"name": "rv64", "props": {... "zic64b": true, ...}}}}
zic64b is set to 'true', as expected, since all cache sizes are 64
bytes by default.
If we change one of the cache blocksizes, zic64b is returned as 'false':
(QEMU) query-cpu-model-expansion type=full model={"name":"rv64","props":{"cbom_blocksize":128}}
{"return": {"model":
{"name": "rv64", "props": {... "zic64b": false, ...}}}}
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
target/riscv/riscv-qmp-cmds.c | 30 +++++++++++++++++++++++++-----
1 file changed, 25 insertions(+), 5 deletions(-)
diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c
index 2f2dbae7c8..5ada279776 100644
--- a/target/riscv/riscv-qmp-cmds.c
+++ b/target/riscv/riscv-qmp-cmds.c
@@ -26,6 +26,7 @@
#include "qapi/error.h"
#include "qapi/qapi-commands-machine-target.h"
+#include "qapi/qmp/qbool.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qobject-input-visitor.h"
@@ -99,6 +100,22 @@ static void riscv_obj_add_multiext_props(Object *obj, QDict *qdict_out,
}
}
+static void riscv_obj_add_named_feats_qdict(Object *obj, QDict *qdict_out)
+{
+ const RISCVCPUMultiExtConfig *named_cfg;
+ RISCVCPU *cpu = RISCV_CPU(obj);
+ QObject *value;
+ bool flag_val;
+
+ for (int i = 0; riscv_cpu_named_features[i].name != NULL; i++) {
+ named_cfg = &riscv_cpu_named_features[i];
+ flag_val = isa_ext_is_enabled(cpu, named_cfg->offset);
+ value = QOBJECT(qbool_from_bool(flag_val));
+
+ qdict_put_obj(qdict_out, named_cfg->name, value);
+ }
+}
+
static void riscv_cpuobj_validate_qdict_in(Object *obj, QObject *props,
const QDict *qdict_in,
Error **errp)
@@ -129,11 +146,6 @@ static void riscv_cpuobj_validate_qdict_in(Object *obj, QObject *props,
goto err;
}
- riscv_cpu_finalize_features(RISCV_CPU(obj), &local_err);
- if (local_err) {
- goto err;
- }
-
visit_end_struct(visitor, NULL);
err:
@@ -191,6 +203,13 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
}
}
+ riscv_cpu_finalize_features(RISCV_CPU(obj), &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ object_unref(obj);
+ return NULL;
+ }
+
expansion_info = g_new0(CpuModelExpansionInfo, 1);
expansion_info->model = g_malloc0(sizeof(*expansion_info->model));
expansion_info->model->name = g_strdup(model->name);
@@ -200,6 +219,7 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
riscv_obj_add_multiext_props(obj, qdict_out, riscv_cpu_extensions);
riscv_obj_add_multiext_props(obj, qdict_out, riscv_cpu_experimental_exts);
riscv_obj_add_multiext_props(obj, qdict_out, riscv_cpu_vendor_exts);
+ riscv_obj_add_named_feats_qdict(obj, qdict_out);
/* Add our CPU boolean options too */
riscv_obj_add_qdict_prop(obj, qdict_out, "mmu");
--
2.41.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v9 08/19] target/riscv: add rva22u64 profile definition
2023-11-02 22:44 [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support Daniel Henrique Barboza
` (6 preceding siblings ...)
2023-11-02 22:44 ` [PATCH v9 07/19] riscv-qmp-cmds.c: expose named features in cpu_model_expansion Daniel Henrique Barboza
@ 2023-11-02 22:44 ` Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 09/19] target/riscv/kvm: add 'rva22u64' flag as unavailable Daniel Henrique Barboza
` (10 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-02 22:44 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
The rva22U64 profile, described in:
https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc#rva22-profiles
Contains a set of CPU extensions aimed for 64-bit userspace
applications. Enabling this set to be enabled via a single user flag
makes it convenient to enable a predictable set of features for the CPU,
giving users more predicability when running/testing their workloads.
QEMU implements all possible extensions of this profile. All the so
called 'synthetic extensions' described in the profile that are cache
related are ignored/assumed enabled (Za64rs, Zic64b, Ziccif, Ziccrse,
Ziccamoa, Zicclsm) since we do not implement a cache model.
An abstraction called RISCVCPUProfile is created to store the profile.
'ext_offsets' contains mandatory extensions that QEMU supports. Same
thing with the 'misa_ext' mask. Optional extensions must be enabled
manually in the command line if desired.
The design here is to use the common target/riscv/cpu.c file to store
the profile declaration and export it to the accelerator files. Each
accelerator is then responsible to expose it (or not) to users and how
to enable the extensions.
Next patches will implement the profile for TCG and KVM.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
target/riscv/cpu.c | 32 ++++++++++++++++++++++++++++++++
target/riscv/cpu.h | 12 ++++++++++++
2 files changed, 44 insertions(+)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 4b92f320e0..d24ffbf3f8 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1490,6 +1490,38 @@ Property riscv_cpu_options[] = {
DEFINE_PROP_END_OF_LIST(),
};
+/*
+ * RVA22U64 defines some 'named features' or 'synthetic extensions'
+ * that are cache related: Za64rs, Zic64b, Ziccif, Ziccrse, Ziccamoa
+ * and Zicclsm. We do not implement caching in QEMU so we'll consider
+ * all these named features as always enabled.
+ *
+ * There's no riscv,isa update for them (nor for zic64b, despite it
+ * having a cfg offset) at this moment.
+ */
+static RISCVCPUProfile RVA22U64 = {
+ .name = "rva22u64",
+ .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVU,
+ .ext_offsets = {
+ CPU_CFG_OFFSET(ext_zicsr), CPU_CFG_OFFSET(ext_zihintpause),
+ CPU_CFG_OFFSET(ext_zba), CPU_CFG_OFFSET(ext_zbb),
+ CPU_CFG_OFFSET(ext_zbs), CPU_CFG_OFFSET(ext_zfhmin),
+ CPU_CFG_OFFSET(ext_zkt), CPU_CFG_OFFSET(ext_zicntr),
+ CPU_CFG_OFFSET(ext_zihpm), CPU_CFG_OFFSET(ext_zicbom),
+ CPU_CFG_OFFSET(ext_zicbop), CPU_CFG_OFFSET(ext_zicboz),
+
+ /* mandatory named features for this profile */
+ CPU_CFG_OFFSET(zic64b),
+
+ RISCV_PROFILE_EXT_LIST_END
+ }
+};
+
+RISCVCPUProfile *riscv_profiles[] = {
+ &RVA22U64,
+ NULL,
+};
+
static Property riscv_cpu_properties[] = {
DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index bf12f34082..e4d5d69207 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -66,6 +66,18 @@ const char *riscv_get_misa_ext_description(uint32_t bit);
#define CPU_CFG_OFFSET(_prop) offsetof(struct RISCVCPUConfig, _prop)
+typedef struct riscv_cpu_profile {
+ const char *name;
+ uint32_t misa_ext;
+ bool enabled;
+ bool user_set;
+ const int32_t ext_offsets[];
+} RISCVCPUProfile;
+
+#define RISCV_PROFILE_EXT_LIST_END -1
+
+extern RISCVCPUProfile *riscv_profiles[];
+
/* Privileged specification version */
enum {
PRIV_VERSION_1_10_0 = 0,
--
2.41.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v9 09/19] target/riscv/kvm: add 'rva22u64' flag as unavailable
2023-11-02 22:44 [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support Daniel Henrique Barboza
` (7 preceding siblings ...)
2023-11-02 22:44 ` [PATCH v9 08/19] target/riscv: add rva22u64 profile definition Daniel Henrique Barboza
@ 2023-11-02 22:44 ` Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 10/19] target/riscv/tcg: add user flag for profile support Daniel Henrique Barboza
` (9 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-02 22:44 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
KVM does not have the means to support enabling the rva22u64 profile.
The main reasons are:
- we're missing support for some mandatory rva22u64 extensions in the
KVM module;
- we can't make promises about enabling a profile since it all depends
on host support in the end.
We'll revisit this decision in the future if needed. For now mark the
'rva22u64' profile as unavailable when running a KVM CPU:
$ qemu-system-riscv64 -machine virt,accel=kvm -cpu rv64,rva22u64=true
qemu-system-riscv64: can't apply global rv64-riscv-cpu.rva22u64=true:
'rva22u64' is not available with KVM
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
target/riscv/kvm/kvm-cpu.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 78fa1fa162..9c6ff774b5 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -398,7 +398,7 @@ static void cpu_set_cfg_unavailable(Object *obj, Visitor *v,
}
if (value) {
- error_setg(errp, "extension %s is not available with KVM",
+ error_setg(errp, "'%s' is not available with KVM",
propname);
}
}
@@ -479,6 +479,11 @@ static void kvm_riscv_add_cpu_user_properties(Object *cpu_obj)
riscv_cpu_add_kvm_unavail_prop_array(cpu_obj, riscv_cpu_extensions);
riscv_cpu_add_kvm_unavail_prop_array(cpu_obj, riscv_cpu_vendor_exts);
riscv_cpu_add_kvm_unavail_prop_array(cpu_obj, riscv_cpu_experimental_exts);
+
+ /* We don't have the needed KVM support for profiles */
+ for (i = 0; riscv_profiles[i] != NULL; i++) {
+ riscv_cpu_add_kvm_unavail_prop(cpu_obj, riscv_profiles[i]->name);
+ }
}
static int kvm_riscv_get_regs_core(CPUState *cs)
--
2.41.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v9 10/19] target/riscv/tcg: add user flag for profile support
2023-11-02 22:44 [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support Daniel Henrique Barboza
` (8 preceding siblings ...)
2023-11-02 22:44 ` [PATCH v9 09/19] target/riscv/kvm: add 'rva22u64' flag as unavailable Daniel Henrique Barboza
@ 2023-11-02 22:44 ` Daniel Henrique Barboza
2023-11-03 8:41 ` Andrew Jones
2023-11-02 22:44 ` [PATCH v9 11/19] target/riscv/tcg: add MISA user options hash Daniel Henrique Barboza
` (8 subsequent siblings)
18 siblings, 1 reply; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-02 22:44 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
The TCG emulation implements all the extensions described in the
RVA22U64 profile, both mandatory and optional. The mandatory extensions
will be enabled via the profile flag. We'll leave the optional
extensions to be enabled by hand.
Given that this is the first profile we're implementing in TCG we'll
need some ground work first:
- all profiles declared in riscv_profiles[] will be exposed to users.
TCG is the main accelerator we're considering when adding profile
support in QEMU, so for now it's safe to assume that all profiles in
riscv_profiles[] will be relevant to TCG;
- we'll not support user profile settings for vendor CPUs. The flags
will still be exposed but users won't be able to change them;
- profile support, albeit available for all non-vendor CPUs, will be
based on top of the new 'rv64i' CPU. Setting a profile to 'true' means
enable all mandatory extensions of this profile, setting it to 'false'
will disable all mandatory profile extensions of the CPU, which will
obliterate preset defaults. This is not a problem for a bare CPU like
rv64i but it can allow for silly scenarios when using other CPUs. E.g.
an user can do "-cpu rv64,rva22u64=false" and have a bunch of default
rv64 extensions disabled. The recommended way of using profiles is the
rv64i CPU, but users are free to experiment.
For now we'll handle multi-letter extensions only. MISA extensions need
additional steps that we'll take care later. At this point we can boot a
Linux buildroot using rva22u64 using the following options:
-cpu rv64i,rva22u64=true,sv39=true,g=true,c=true,s=true
Note that being an usermode/application profile we still need to
explicitly set 's=true' to enable Supervisor mode to boot Linux.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
target/riscv/tcg/tcg-cpu.c | 67 ++++++++++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+)
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index b0f69c6437..b52910850f 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -871,6 +871,71 @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)
}
}
+static void cpu_set_profile(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ RISCVCPUProfile *profile = opaque;
+ RISCVCPU *cpu = RISCV_CPU(obj);
+ bool value;
+ int i, ext_offset;
+
+ if (riscv_cpu_is_vendor(obj)) {
+ error_setg(errp, "Profile %s is not available for vendor CPUs",
+ profile->name);
+ return;
+ }
+
+ if (cpu->env.misa_mxl != MXL_RV64) {
+ error_setg(errp, "Profile %s only available for 64 bit CPUs",
+ profile->name);
+ return;
+ }
+
+ if (!visit_type_bool(v, name, &value, errp)) {
+ return;
+ }
+
+ profile->user_set = true;
+ profile->enabled = value;
+
+ for (i = 0; profile->ext_offsets[i] != RISCV_PROFILE_EXT_LIST_END; i++) {
+ ext_offset = profile->ext_offsets[i];
+
+ if (profile->enabled) {
+ /*
+ * Note: the 'priv_spec' command line option, if present,
+ * will take precedence over this priv_ver bump.
+ */
+ cpu_validate_multi_ext_priv_ver(&cpu->env, ext_offset);
+ }
+
+ g_hash_table_insert(multi_ext_user_opts,
+ GUINT_TO_POINTER(ext_offset),
+ (gpointer)profile->enabled);
+ isa_ext_update_enabled(cpu, ext_offset, profile->enabled);
+ }
+}
+
+static void cpu_get_profile(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ RISCVCPUProfile *profile = opaque;
+ bool value = profile->enabled;
+
+ visit_type_bool(v, name, &value, errp);
+}
+
+static void riscv_cpu_add_profiles(Object *cpu_obj)
+{
+ for (int i = 0; riscv_profiles[i] != NULL; i++) {
+ const RISCVCPUProfile *profile = riscv_profiles[i];
+
+ object_property_add(cpu_obj, profile->name, "bool",
+ cpu_get_profile, cpu_set_profile,
+ NULL, (void *)profile);
+ }
+}
+
static bool cpu_ext_is_deprecated(const char *ext_name)
{
return isupper(ext_name[0]);
@@ -1002,6 +1067,8 @@ static void riscv_cpu_add_user_properties(Object *obj)
riscv_cpu_add_multiext_prop_array(obj, riscv_cpu_deprecated_exts);
+ riscv_cpu_add_profiles(obj);
+
for (Property *prop = riscv_cpu_options; prop && prop->name; prop++) {
qdev_property_add_static(DEVICE(obj), prop);
}
--
2.41.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v9 11/19] target/riscv/tcg: add MISA user options hash
2023-11-02 22:44 [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support Daniel Henrique Barboza
` (9 preceding siblings ...)
2023-11-02 22:44 ` [PATCH v9 10/19] target/riscv/tcg: add user flag for profile support Daniel Henrique Barboza
@ 2023-11-02 22:44 ` Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 12/19] target/riscv/tcg: add riscv_cpu_write_misa_bit() Daniel Henrique Barboza
` (7 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-02 22:44 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
We already track user choice for multi-letter extensions because we
needed to honor user choice when enabling/disabling extensions during
realize(). We refrained from adding the same mechanism for MISA
extensions since we didn't need it.
Profile support requires tne need to check for user choice for MISA
extensions, so let's add the corresponding hash now. It works like the
existing multi-letter hash (multi_ext_user_opts) but tracking MISA bits
options in the cpu_set_misa_ext_cfg() callback.
Note that we can't re-use the same hash from multi-letter extensions
because that hash uses cpu->cfg offsets as keys, while for MISA
extensions we're using MISA bits as keys.
After adding the user hash in cpu_set_misa_ext_cfg(), setting default
values with object_property_set_bool() in add_misa_properties() will end
up marking the user choice hash with them. Set the default value
manually to avoid it.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
target/riscv/tcg/tcg-cpu.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index b52910850f..c1f203bf34 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -34,6 +34,7 @@
/* Hash that stores user set extensions */
static GHashTable *multi_ext_user_opts;
+static GHashTable *misa_ext_user_opts;
static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset)
{
@@ -775,6 +776,10 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, const char *name,
return;
}
+ g_hash_table_insert(misa_ext_user_opts,
+ GUINT_TO_POINTER(misa_bit),
+ (gpointer)value);
+
prev_val = env->misa_ext & misa_bit;
if (value == prev_val) {
@@ -846,6 +851,7 @@ static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
*/
static void riscv_cpu_add_misa_properties(Object *cpu_obj)
{
+ CPURISCVState *env = &RISCV_CPU(cpu_obj)->env;
bool use_def_vals = riscv_cpu_is_generic(cpu_obj);
int i;
@@ -866,7 +872,13 @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)
NULL, (void *)misa_cfg);
object_property_set_description(cpu_obj, name, desc);
if (use_def_vals) {
- object_property_set_bool(cpu_obj, name, misa_cfg->enabled, NULL);
+ if (misa_cfg->enabled) {
+ env->misa_ext |= bit;
+ env->misa_ext_mask |= bit;
+ } else {
+ env->misa_ext &= ~bit;
+ env->misa_ext_mask &= ~bit;
+ }
}
}
}
@@ -1119,6 +1131,7 @@ static void tcg_cpu_instance_init(CPUState *cs)
RISCVCPU *cpu = RISCV_CPU(cs);
Object *obj = OBJECT(cpu);
+ misa_ext_user_opts = g_hash_table_new(NULL, g_direct_equal);
multi_ext_user_opts = g_hash_table_new(NULL, g_direct_equal);
riscv_cpu_add_user_properties(obj);
--
2.41.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v9 12/19] target/riscv/tcg: add riscv_cpu_write_misa_bit()
2023-11-02 22:44 [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support Daniel Henrique Barboza
` (10 preceding siblings ...)
2023-11-02 22:44 ` [PATCH v9 11/19] target/riscv/tcg: add MISA user options hash Daniel Henrique Barboza
@ 2023-11-02 22:44 ` Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 13/19] target/riscv/tcg: handle profile MISA bits Daniel Henrique Barboza
` (6 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-02 22:44 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
We have two instances of the setting/clearing a MISA bit from
env->misa_ext and env->misa_ext_mask pattern. And the next patch will
end up adding one more.
Create a helper to avoid code repetition.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
target/riscv/tcg/tcg-cpu.c | 32 ++++++++++++++++++--------------
1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index c1f203bf34..d80f72a9da 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -42,6 +42,20 @@ static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset)
GUINT_TO_POINTER(ext_offset));
}
+static void riscv_cpu_write_misa_bit(RISCVCPU *cpu, uint32_t bit,
+ bool enabled)
+{
+ CPURISCVState *env = &cpu->env;
+
+ if (enabled) {
+ env->misa_ext |= bit;
+ env->misa_ext_mask |= bit;
+ } else {
+ env->misa_ext &= ~bit;
+ env->misa_ext_mask &= ~bit;
+ }
+}
+
static void riscv_cpu_synchronize_from_tb(CPUState *cs,
const TranslationBlock *tb)
{
@@ -801,13 +815,9 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, const char *name,
*/
env->priv_ver = PRIV_VERSION_1_12_0;
}
-
- env->misa_ext |= misa_bit;
- env->misa_ext_mask |= misa_bit;
- } else {
- env->misa_ext &= ~misa_bit;
- env->misa_ext_mask &= ~misa_bit;
}
+
+ riscv_cpu_write_misa_bit(cpu, misa_bit, value);
}
static void cpu_get_misa_ext_cfg(Object *obj, Visitor *v, const char *name,
@@ -851,7 +861,6 @@ static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
*/
static void riscv_cpu_add_misa_properties(Object *cpu_obj)
{
- CPURISCVState *env = &RISCV_CPU(cpu_obj)->env;
bool use_def_vals = riscv_cpu_is_generic(cpu_obj);
int i;
@@ -872,13 +881,8 @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)
NULL, (void *)misa_cfg);
object_property_set_description(cpu_obj, name, desc);
if (use_def_vals) {
- if (misa_cfg->enabled) {
- env->misa_ext |= bit;
- env->misa_ext_mask |= bit;
- } else {
- env->misa_ext &= ~bit;
- env->misa_ext_mask &= ~bit;
- }
+ riscv_cpu_write_misa_bit(RISCV_CPU(cpu_obj), bit,
+ misa_cfg->enabled);
}
}
}
--
2.41.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v9 13/19] target/riscv/tcg: handle profile MISA bits
2023-11-02 22:44 [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support Daniel Henrique Barboza
` (11 preceding siblings ...)
2023-11-02 22:44 ` [PATCH v9 12/19] target/riscv/tcg: add riscv_cpu_write_misa_bit() Daniel Henrique Barboza
@ 2023-11-02 22:44 ` Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 14/19] target/riscv/tcg: add hash table insert helpers Daniel Henrique Barboza
` (5 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-02 22:44 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
The profile support is handling multi-letter extensions only. Let's add
support for MISA bits as well.
We'll go through every known MISA bit. If the profile doesn't declare
the bit as mandatory, ignore it. Otherwise, set the bit in env->misa_ext
and env->misa_ext_mask.
Now that we're setting profile MISA bits, one can use the rv64i CPU to boot
Linux using the following options:
-cpu rv64i,rva22u64=true,rv39=true,s=true,zifencei=true
In the near future, when rva22s64 (where, 's', 'zifencei' and sv39 are
mandatory), is implemented, rv64i will be able to boot Linux loading
rva22s64 and no additional flags.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/tcg/tcg-cpu.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index d80f72a9da..f5a71b38f6 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -914,6 +914,27 @@ static void cpu_set_profile(Object *obj, Visitor *v, const char *name,
profile->user_set = true;
profile->enabled = value;
+ for (i = 0; misa_bits[i] != 0; i++) {
+ uint32_t bit = misa_bits[i];
+
+ if (!(profile->misa_ext & bit)) {
+ continue;
+ }
+
+ if (bit == RVI && !profile->enabled) {
+ /*
+ * Disabling profiles will not disable the base
+ * ISA RV64I.
+ */
+ continue;
+ }
+
+ g_hash_table_insert(misa_ext_user_opts,
+ GUINT_TO_POINTER(bit),
+ (gpointer)value);
+ riscv_cpu_write_misa_bit(cpu, bit, profile->enabled);
+ }
+
for (i = 0; profile->ext_offsets[i] != RISCV_PROFILE_EXT_LIST_END; i++) {
ext_offset = profile->ext_offsets[i];
--
2.41.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v9 14/19] target/riscv/tcg: add hash table insert helpers
2023-11-02 22:44 [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support Daniel Henrique Barboza
` (12 preceding siblings ...)
2023-11-02 22:44 ` [PATCH v9 13/19] target/riscv/tcg: handle profile MISA bits Daniel Henrique Barboza
@ 2023-11-02 22:44 ` Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 15/19] target/riscv/tcg: honor user choice for G MISA bits Daniel Henrique Barboza
` (4 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-02 22:44 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
Previous patches added several g_hash_table_insert() patterns. Add two
helpers, one for each user hash, to make the code cleaner.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
target/riscv/tcg/tcg-cpu.c | 28 ++++++++++++++++------------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index f5a71b38f6..fd9d4e9845 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -42,6 +42,18 @@ static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset)
GUINT_TO_POINTER(ext_offset));
}
+static void cpu_cfg_ext_add_user_opt(uint32_t ext_offset, bool value)
+{
+ g_hash_table_insert(multi_ext_user_opts, GUINT_TO_POINTER(ext_offset),
+ (gpointer)value);
+}
+
+static void cpu_misa_ext_add_user_opt(uint32_t bit, bool value)
+{
+ g_hash_table_insert(misa_ext_user_opts, GUINT_TO_POINTER(bit),
+ (gpointer)value);
+}
+
static void riscv_cpu_write_misa_bit(RISCVCPU *cpu, uint32_t bit,
bool enabled)
{
@@ -790,9 +802,7 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, const char *name,
return;
}
- g_hash_table_insert(misa_ext_user_opts,
- GUINT_TO_POINTER(misa_bit),
- (gpointer)value);
+ cpu_misa_ext_add_user_opt(misa_bit, value);
prev_val = env->misa_ext & misa_bit;
@@ -929,9 +939,7 @@ static void cpu_set_profile(Object *obj, Visitor *v, const char *name,
continue;
}
- g_hash_table_insert(misa_ext_user_opts,
- GUINT_TO_POINTER(bit),
- (gpointer)value);
+ cpu_misa_ext_add_user_opt(bit, profile->enabled);
riscv_cpu_write_misa_bit(cpu, bit, profile->enabled);
}
@@ -946,9 +954,7 @@ static void cpu_set_profile(Object *obj, Visitor *v, const char *name,
cpu_validate_multi_ext_priv_ver(&cpu->env, ext_offset);
}
- g_hash_table_insert(multi_ext_user_opts,
- GUINT_TO_POINTER(ext_offset),
- (gpointer)profile->enabled);
+ cpu_cfg_ext_add_user_opt(ext_offset, profile->enabled);
isa_ext_update_enabled(cpu, ext_offset, profile->enabled);
}
}
@@ -1011,9 +1017,7 @@ static void cpu_set_multi_ext_cfg(Object *obj, Visitor *v, const char *name,
multi_ext_cfg->name, lower);
}
- g_hash_table_insert(multi_ext_user_opts,
- GUINT_TO_POINTER(multi_ext_cfg->offset),
- (gpointer)value);
+ cpu_cfg_ext_add_user_opt(multi_ext_cfg->offset, value);
prev_val = isa_ext_is_enabled(cpu, multi_ext_cfg->offset);
--
2.41.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v9 15/19] target/riscv/tcg: honor user choice for G MISA bits
2023-11-02 22:44 [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support Daniel Henrique Barboza
` (13 preceding siblings ...)
2023-11-02 22:44 ` [PATCH v9 14/19] target/riscv/tcg: add hash table insert helpers Daniel Henrique Barboza
@ 2023-11-02 22:44 ` Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 16/19] target/riscv/tcg: validate profiles during finalize Daniel Henrique Barboza
` (3 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-02 22:44 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
RVG behaves like a profile: a single flag enables a set of bits. Right
now we're considering user choice when handling RVG and zicsr/zifencei
and ignoring user choice on MISA bits.
We'll add user warnings for profiles when the user disables its
mandatory extensions in the next patch. We'll do the same thing with RVG
now to keep consistency between RVG and profile handling.
First and foremost, create a new RVG only helper to avoid clogging
riscv_cpu_validate_set_extensions(). We do not want to annoy users with
RVG warnings like we did in the past (see 9b9741c38f), thus we'll only
warn if RVG was user set and the user disabled a RVG extension in the
command line.
For every RVG MISA bit (IMAFD), zicsr and zifencei, the logic then
becomes:
- if enabled, do nothing;
- if disabled and not user set, enable it;
- if disabled and user set, throw a warning that it's a RVG mandatory
extension.
This same logic will be used for profiles in the next patch.
Note that this is a behavior change, where we would error out if the
user disabled either zicsr or zifencei. As long as users are explicitly
disabling things in the command line we'll let them have a go at it, at
least in this step. We'll error out later in the validation if needed.
Other notable changes from the previous RVG code:
- use riscv_cpu_write_misa_bit() instead of manually updating both
env->misa_ext and env->misa_ext_mask;
- set zicsr and zifencei directly. We're already checking if they
were user set and priv version will never fail for these
extensions, making cpu_cfg_ext_auto_update() redundant.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/tcg/tcg-cpu.c | 73 +++++++++++++++++++++++++-------------
1 file changed, 48 insertions(+), 25 deletions(-)
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index fd9d4e9845..0ac94fa142 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -42,6 +42,12 @@ static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset)
GUINT_TO_POINTER(ext_offset));
}
+static bool cpu_misa_ext_is_user_set(uint32_t misa_bit)
+{
+ return g_hash_table_contains(misa_ext_user_opts,
+ GUINT_TO_POINTER(misa_bit));
+}
+
static void cpu_cfg_ext_add_user_opt(uint32_t ext_offset, bool value)
{
g_hash_table_insert(multi_ext_user_opts, GUINT_TO_POINTER(ext_offset),
@@ -336,6 +342,46 @@ static void riscv_cpu_validate_named_features(RISCVCPU *cpu)
riscv_cpu_validate_zic64b(cpu);
}
+static void riscv_cpu_validate_g(RISCVCPU *cpu)
+{
+ const char *warn_msg = "RVG mandates disabled extension %s";
+ uint32_t g_misa_bits[] = {RVI, RVM, RVA, RVF, RVD};
+ bool send_warn = cpu_misa_ext_is_user_set(RVG);
+
+ for (int i = 0; i < ARRAY_SIZE(g_misa_bits); i++) {
+ uint32_t bit = g_misa_bits[i];
+
+ if (riscv_has_ext(&cpu->env, bit)) {
+ continue;
+ }
+
+ if (!cpu_misa_ext_is_user_set(bit)) {
+ riscv_cpu_write_misa_bit(cpu, bit, true);
+ continue;
+ }
+
+ if (send_warn) {
+ warn_report(warn_msg, riscv_get_misa_ext_name(bit));
+ }
+ }
+
+ if (!cpu->cfg.ext_zicsr) {
+ if (!cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zicsr))) {
+ cpu->cfg.ext_zicsr = true;
+ } else if (send_warn) {
+ warn_report(warn_msg, "zicsr");
+ }
+ }
+
+ if (!cpu->cfg.ext_zifencei) {
+ if (!cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zifencei))) {
+ cpu->cfg.ext_zifencei = true;
+ } else if (send_warn) {
+ warn_report(warn_msg, "zifencei");
+ }
+ }
+}
+
/*
* Check consistency between chosen extensions while setting
* cpu->cfg accordingly.
@@ -345,31 +391,8 @@ 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_zicsr && cpu->cfg.ext_zifencei)) {
-
- if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zicsr)) &&
- !cpu->cfg.ext_zicsr) {
- error_setg(errp, "RVG requires Zicsr but user set Zicsr to false");
- return;
- }
-
- if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zifencei)) &&
- !cpu->cfg.ext_zifencei) {
- error_setg(errp, "RVG requires Zifencei but user set "
- "Zifencei to false");
- return;
- }
-
- cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zicsr), true);
- cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zifencei), true);
-
- env->misa_ext |= RVI | RVM | RVA | RVF | RVD;
- env->misa_ext_mask |= RVI | RVM | RVA | RVF | RVD;
+ if (riscv_has_ext(env, RVG)) {
+ riscv_cpu_validate_g(cpu);
}
if (riscv_has_ext(env, RVI) && riscv_has_ext(env, RVE)) {
--
2.41.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v9 16/19] target/riscv/tcg: validate profiles during finalize
2023-11-02 22:44 [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support Daniel Henrique Barboza
` (14 preceding siblings ...)
2023-11-02 22:44 ` [PATCH v9 15/19] target/riscv/tcg: honor user choice for G MISA bits Daniel Henrique Barboza
@ 2023-11-02 22:44 ` Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 17/19] riscv-qmp-cmds.c: add profile flags in cpu-model-expansion Daniel Henrique Barboza
` (2 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-02 22:44 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
Enabling a profile and then disabling some of its mandatory extensions
is a valid use. It can be useful for debugging and testing. But the
common expected use of enabling a profile is to enable all its mandatory
extensions.
Add an user warning when mandatory extensions from an enabled profile
are disabled in the command line. We're also going to disable the
profile flag in this case since the profile must include all the
mandatory extensions. This flag can be exposed by QMP to indicate the
actual profile state after the CPU is realized.
After this patch, this will throw warnings:
-cpu rv64,rva22u64=true,zihintpause=false,zicbom=false,zicboz=false
qemu-system-riscv64: warning: Profile rva22u64 mandates disabled extension zihintpause
qemu-system-riscv64: warning: Profile rva22u64 mandates disabled extension zicbom
qemu-system-riscv64: warning: Profile rva22u64 mandates disabled extension zicboz
Note that the following will NOT throw warnings because the profile is
being enabled last, hence all its mandatory extensions will be enabled:
-cpu rv64,zihintpause=false,zicbom=false,zicboz=false,rva22u64=true
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
target/riscv/tcg/tcg-cpu.c | 69 ++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 0ac94fa142..ef43264cb3 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -147,6 +147,26 @@ static int cpu_cfg_ext_get_min_version(uint32_t ext_offset)
g_assert_not_reached();
}
+static const char *cpu_cfg_ext_get_name(uint32_t ext_offset)
+{
+ const RISCVCPUMultiExtConfig *feat;
+ const RISCVIsaExtData *edata;
+
+ for (edata = isa_edata_arr; edata->name != NULL; edata++) {
+ if (edata->ext_enable_offset == ext_offset) {
+ return edata->name;
+ }
+ }
+
+ for (feat = riscv_cpu_named_features; feat->name != NULL; feat++) {
+ if (feat->offset == ext_offset) {
+ return feat->name;
+ }
+ }
+
+ g_assert_not_reached();
+}
+
static bool cpu_cfg_offset_is_named_feat(uint32_t ext_offset)
{
const RISCVCPUMultiExtConfig *feat;
@@ -706,6 +726,54 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
riscv_cpu_disable_priv_spec_isa_exts(cpu);
}
+static void riscv_cpu_validate_profile(RISCVCPU *cpu,
+ RISCVCPUProfile *profile)
+{
+ const char *warn_msg = "Profile %s mandates disabled extension %s";
+ bool send_warn = profile->user_set && profile->enabled;
+ bool profile_impl = true;
+ int i;
+
+ for (i = 0; misa_bits[i] != 0; i++) {
+ uint32_t bit = misa_bits[i];
+
+ if (!(profile->misa_ext & bit)) {
+ continue;
+ }
+
+ if (!riscv_has_ext(&cpu->env, bit)) {
+ profile_impl = false;
+
+ if (send_warn) {
+ warn_report(warn_msg, profile->name,
+ riscv_get_misa_ext_name(bit));
+ }
+ }
+ }
+
+ for (i = 0; profile->ext_offsets[i] != RISCV_PROFILE_EXT_LIST_END; i++) {
+ int ext_offset = profile->ext_offsets[i];
+
+ if (!isa_ext_is_enabled(cpu, ext_offset)) {
+ profile_impl = false;
+
+ if (send_warn) {
+ warn_report(warn_msg, profile->name,
+ cpu_cfg_ext_get_name(ext_offset));
+ }
+ }
+ }
+
+ profile->enabled = profile_impl;
+}
+
+static void riscv_cpu_validate_profiles(RISCVCPU *cpu)
+{
+ for (int i = 0; riscv_profiles[i] != NULL; i++) {
+ riscv_cpu_validate_profile(cpu, riscv_profiles[i]);
+ }
+}
+
void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
{
CPURISCVState *env = &cpu->env;
@@ -724,6 +792,7 @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
}
riscv_cpu_validate_named_features(cpu);
+ riscv_cpu_validate_profiles(cpu);
if (cpu->cfg.ext_smepmp && !cpu->cfg.pmp) {
/*
--
2.41.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v9 17/19] riscv-qmp-cmds.c: add profile flags in cpu-model-expansion
2023-11-02 22:44 [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support Daniel Henrique Barboza
` (15 preceding siblings ...)
2023-11-02 22:44 ` [PATCH v9 16/19] target/riscv/tcg: validate profiles during finalize Daniel Henrique Barboza
@ 2023-11-02 22:44 ` Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 18/19] target/riscv: add 'rva22u64' CPU Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 19/19] target/riscv/tcg: do not support profiles for 'max' CPU Daniel Henrique Barboza
18 siblings, 0 replies; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-02 22:44 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
Expose all profile flags for all CPUs when executing
query-cpu-model-expansion. This will allow callers to quickly determine
if a certain profile is implemented by a given CPU. This includes vendor
CPUs - the fact that they don't have profile user flags doesn't mean
that they don't implement the profile.
After this change it's possible to quickly determine if our stock CPUs
implement the existing rva22u64 profile. Here's a few examples:
$ ./build/qemu-system-riscv64 -S -M virt -display none
-qmp tcp:localhost:1234,server,wait=off
$ ./scripts/qmp/qmp-shell localhost:1234
Welcome to the QMP low-level shell!
Connected to QEMU 8.1.50
- As expected, the 'max' CPU implements the rva22u64 profile.
(QEMU) query-cpu-model-expansion type=full model={"name":"max"}
{"return": {"model":
{"name": "rv64", "props": {... "rva22u64": true, ...}}}}
- rv64 is missing "zba", "zbb", "zbs", "zkt" and "zfhmin":
query-cpu-model-expansion type=full model={"name":"rv64"}
{"return": {"model":
{"name": "rv64", "props": {... "rva22u64": false, ...}}}}
query-cpu-model-expansion type=full model={"name":"rv64",
"props":{"zba":true,"zbb":true,"zbs":true,"zkt":true,"zfhmin":true}}
{"return": {"model":
{"name": "rv64", "props": {... "rva22u64": true, ...}}}}
We have no vendor CPUs that supports rva22u64 (veyron-v1 is the closest
- it is missing just 'zkt').
In short, aside from the 'max' CPU, we have no CPUs that supports
rva22u64 by default.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
target/riscv/riscv-qmp-cmds.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c
index 5ada279776..205aaabeb9 100644
--- a/target/riscv/riscv-qmp-cmds.c
+++ b/target/riscv/riscv-qmp-cmds.c
@@ -116,6 +116,19 @@ static void riscv_obj_add_named_feats_qdict(Object *obj, QDict *qdict_out)
}
}
+static void riscv_obj_add_profiles_qdict(Object *obj, QDict *qdict_out)
+{
+ RISCVCPUProfile *profile;
+ QObject *value;
+
+ for (int i = 0; riscv_profiles[i] != NULL; i++) {
+ profile = riscv_profiles[i];
+ value = QOBJECT(qbool_from_bool(profile->enabled));
+
+ qdict_put_obj(qdict_out, profile->name, value);
+ }
+}
+
static void riscv_cpuobj_validate_qdict_in(Object *obj, QObject *props,
const QDict *qdict_in,
Error **errp)
@@ -220,6 +233,7 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
riscv_obj_add_multiext_props(obj, qdict_out, riscv_cpu_experimental_exts);
riscv_obj_add_multiext_props(obj, qdict_out, riscv_cpu_vendor_exts);
riscv_obj_add_named_feats_qdict(obj, qdict_out);
+ riscv_obj_add_profiles_qdict(obj, qdict_out);
/* Add our CPU boolean options too */
riscv_obj_add_qdict_prop(obj, qdict_out, "mmu");
--
2.41.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v9 18/19] target/riscv: add 'rva22u64' CPU
2023-11-02 22:44 [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support Daniel Henrique Barboza
` (16 preceding siblings ...)
2023-11-02 22:44 ` [PATCH v9 17/19] riscv-qmp-cmds.c: add profile flags in cpu-model-expansion Daniel Henrique Barboza
@ 2023-11-02 22:44 ` Daniel Henrique Barboza
2023-11-03 8:50 ` Andrew Jones
2023-11-02 22:44 ` [PATCH v9 19/19] target/riscv/tcg: do not support profiles for 'max' CPU Daniel Henrique Barboza
18 siblings, 1 reply; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-02 22:44 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
This CPU was suggested by Alistair [1] and others during the profile
design discussions. It consists of the bare 'rv64i' CPU with rva22u64
enabled by default, like an alias of '-cpu rv64i,rva22u64=true'.
Users now have an even easier way of consuming this user-mode profile by
doing '-cpu rva22u64'. Extensions can be enabled/disabled at will on top
of it.
We can boot Linux with this "user-mode" CPU by doing:
-cpu rva22u64,sv39=true,s=true,zifencei=true
[1] https://lore.kernel.org/qemu-riscv/CAKmqyKP7xzZ9Sx=-Lbx2Ob0qCfB7Z+JO944FQ2TQ+49mqo0q_Q@mail.gmail.com/
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
target/riscv/cpu-qom.h | 1 +
target/riscv/cpu.c | 10 ++++++++++
target/riscv/tcg/tcg-cpu.c | 9 +++++++++
3 files changed, 20 insertions(+)
diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
index ea9a752280..ac38ffc6cf 100644
--- a/target/riscv/cpu-qom.h
+++ b/target/riscv/cpu-qom.h
@@ -37,6 +37,7 @@
#define TYPE_RISCV_CPU_BASE64 RISCV_CPU_TYPE_NAME("rv64")
#define TYPE_RISCV_CPU_BASE128 RISCV_CPU_TYPE_NAME("x-rv128")
#define TYPE_RISCV_CPU_RV64I RISCV_CPU_TYPE_NAME("rv64i")
+#define TYPE_RISCV_CPU_RVA22U64 RISCV_CPU_TYPE_NAME("rva22u64")
#define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex")
#define TYPE_RISCV_CPU_SHAKTI_C RISCV_CPU_TYPE_NAME("shakti-c")
#define TYPE_RISCV_CPU_SIFIVE_E31 RISCV_CPU_TYPE_NAME("sifive-e31")
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d24ffbf3f8..1f2932031a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1542,6 +1542,15 @@ static Property riscv_cpu_properties[] = {
DEFINE_PROP_END_OF_LIST(),
};
+#if defined(TARGET_RISCV64)
+static void rva22u64_bare_cpu_init(Object *obj)
+{
+ rv64i_bare_cpu_init(obj);
+
+ RVA22U64.enabled = true;
+}
+#endif
+
static const gchar *riscv_gdb_arch_name(CPUState *cs)
{
RISCVCPU *cpu = RISCV_CPU(cs);
@@ -1876,6 +1885,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1, rv64_veyron_v1_cpu_init),
DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128, rv128_base_cpu_init),
DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV64I, rv64i_bare_cpu_init),
+ DEFINE_BARE_CPU(TYPE_RISCV_CPU_RVA22U64, rva22u64_bare_cpu_init),
#endif
};
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index ef43264cb3..553fb337e7 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -1068,6 +1068,15 @@ static void riscv_cpu_add_profiles(Object *cpu_obj)
object_property_add(cpu_obj, profile->name, "bool",
cpu_get_profile, cpu_set_profile,
NULL, (void *)profile);
+
+ /*
+ * CPUs might enable a profile right from the start.
+ * Enable its mandatory extensions right away in this
+ * case.
+ */
+ if (profile->enabled) {
+ object_property_set_bool(cpu_obj, profile->name, true, NULL);
+ }
}
}
--
2.41.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v9 19/19] target/riscv/tcg: do not support profiles for 'max' CPU
2023-11-02 22:44 [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support Daniel Henrique Barboza
` (17 preceding siblings ...)
2023-11-02 22:44 ` [PATCH v9 18/19] target/riscv: add 'rva22u64' CPU Daniel Henrique Barboza
@ 2023-11-02 22:44 ` Daniel Henrique Barboza
2023-11-03 9:01 ` Andrew Jones
18 siblings, 1 reply; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-02 22:44 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer,
ajones, Daniel Henrique Barboza
There's no gain in allowing the 'max' CPU to support profiles, since it
already contains everything that QEMU can support. And we'll open the
door for 'unorthodox' stuff like users disabling profiles of the 'max'
CPU.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
target/riscv/tcg/tcg-cpu.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 553fb337e7..9a964a426e 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -825,6 +825,11 @@ static bool riscv_cpu_is_vendor(Object *cpu_obj)
return object_dynamic_cast(cpu_obj, TYPE_RISCV_VENDOR_CPU) != NULL;
}
+static bool riscv_cpu_has_max_extensions(Object *cpu_obj)
+{
+ return object_dynamic_cast(cpu_obj, TYPE_RISCV_CPU_MAX) != NULL;
+}
+
/*
* We'll get here via the following path:
*
@@ -1003,6 +1008,12 @@ static void cpu_set_profile(Object *obj, Visitor *v, const char *name,
return;
}
+ if (riscv_cpu_has_max_extensions(obj)) {
+ error_setg(errp, "Profile %s is not available for the 'max' CPU",
+ profile->name);
+ return;
+ }
+
if (cpu->env.misa_mxl != MXL_RV64) {
error_setg(errp, "Profile %s only available for 64 bit CPUs",
profile->name);
@@ -1251,11 +1262,6 @@ static void riscv_init_max_cpu_extensions(Object *obj)
}
}
-static bool riscv_cpu_has_max_extensions(Object *cpu_obj)
-{
- return object_dynamic_cast(cpu_obj, TYPE_RISCV_CPU_MAX) != NULL;
-}
-
static void tcg_cpu_instance_init(CPUState *cs)
{
RISCVCPU *cpu = RISCV_CPU(cs);
--
2.41.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH v9 03/19] target/riscv/tcg: update priv_ver on user_set extensions
2023-11-02 22:44 ` [PATCH v9 03/19] target/riscv/tcg: update priv_ver on user_set extensions Daniel Henrique Barboza
@ 2023-11-03 8:33 ` Andrew Jones
2023-11-03 11:34 ` Daniel Henrique Barboza
0 siblings, 1 reply; 27+ messages in thread
From: Andrew Jones @ 2023-11-03 8:33 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, bmeng, liweiwei,
zhiwei_liu, palmer
On Thu, Nov 02, 2023 at 07:44:29PM -0300, Daniel Henrique Barboza wrote:
> We'll add a new bare CPU type that won't have any default priv_ver. This
> means that the CPU will default to priv_ver = 0, i.e. 1.10.0.
>
> At the same we'll allow these CPUs to enable extensions at will, but
> then, if the extension has a priv_ver newer than 1.10, we'll end up
> disabling it. Users will then need to manually set priv_ver to something
> other than 1.10 to enable the extensions they want, which is not ideal.
>
> Change the setter() of extensions to allow user enabled extensions to
> bump the priv_ver of the CPU. This will make it convenient for users to
> enable extensions for CPUs that doesn't set a default priv_ver.
>
> This change does not affect any existing CPU: vendor CPUs does not allow
> extensions to be enabled, and generic CPUs are already set to priv_ver
> LATEST.
The only problem I see is that priv_ver will be silently bumped for any
CPU type which accepts extensions. While generic CPUs currently always
select LATEST, meaning it doesn't matter, and the new bare CPU type needs
this feature, we'll also eventually have CPU types that set a priv_ver
in their definition which should not be changed. For example, when the
rva22s64 profile is introduced it will set its priv_ver to 1.12, as
mandated by the profile, if a user then adds an extension which requires
a later profile, its priv_ver will get silently bumped. Maybe that won't
matter, though, because later in realize we'll check that Ss1p12 is true
and when it's false we'll complain that the profile is not compliant?
Or maybe I'm reading the profile spec too strictly and/or am too
pessimistic about later specs being backwards compatible. If we believe
later specs are always compatible with older, then we could advertise
compliance with a profile which mandates 1.12 as long as its spec is 1.12
or later.
Anyway, just food for thought. I think we can address this later when
we get the first CPU type which sets a priv_ver and accepts extensions.
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
> target/riscv/tcg/tcg-cpu.c | 32 ++++++++++++++++++++++++++++++++
> 1 file changed, 32 insertions(+)
>
> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
> index 08f8dded56..0e684ab86f 100644
> --- a/target/riscv/tcg/tcg-cpu.c
> +++ b/target/riscv/tcg/tcg-cpu.c
> @@ -114,6 +114,22 @@ static int cpu_cfg_ext_get_min_version(uint32_t ext_offset)
> g_assert_not_reached();
> }
>
> +static void cpu_validate_multi_ext_priv_ver(CPURISCVState *env,
> + uint32_t ext_offset)
> +{
> + int ext_priv_ver;
> +
> + if (env->priv_ver == PRIV_VERSION_LATEST) {
> + return;
> + }
> +
> + ext_priv_ver = cpu_cfg_ext_get_min_version(ext_offset);
> +
> + if (env->priv_ver < ext_priv_ver) {
> + env->priv_ver = ext_priv_ver;
> + }
> +}
> +
> static void cpu_cfg_ext_auto_update(RISCVCPU *cpu, uint32_t ext_offset,
> bool value)
> {
> @@ -742,6 +758,14 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, const char *name,
> return;
> }
>
> + if (misa_bit == RVH && env->priv_ver < PRIV_VERSION_1_12_0) {
> + /*
> + * Note: the 'priv_spec' command line option, if present,
> + * will take precedence over this priv_ver bump.
> + */
> + env->priv_ver = PRIV_VERSION_1_12_0;
> + }
> +
> env->misa_ext |= misa_bit;
> env->misa_ext_mask |= misa_bit;
> } else {
> @@ -871,6 +895,14 @@ static void cpu_set_multi_ext_cfg(Object *obj, Visitor *v, const char *name,
> return;
> }
>
> + if (value) {
> + /*
> + * Note: the 'priv_spec' command line option, if present,
> + * will take precedence over this priv_ver bump.
> + */
The above comment would be better in cpu_validate_multi_ext_priv_ver() at
the line where the bumping is done.
> + cpu_validate_multi_ext_priv_ver(&cpu->env, multi_ext_cfg->offset);
> + }
> +
> isa_ext_update_enabled(cpu, multi_ext_cfg->offset, value);
> }
>
> --
> 2.41.0
>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Thanks,
drew
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v9 04/19] target/riscv: add rv64i CPU
2023-11-02 22:44 ` [PATCH v9 04/19] target/riscv: add rv64i CPU Daniel Henrique Barboza
@ 2023-11-03 8:37 ` Andrew Jones
0 siblings, 0 replies; 27+ messages in thread
From: Andrew Jones @ 2023-11-03 8:37 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, bmeng, liweiwei,
zhiwei_liu, palmer
On Thu, Nov 02, 2023 at 07:44:30PM -0300, Daniel Henrique Barboza wrote:
> We don't have any form of a 'bare bones' CPU. rv64, our default CPUs,
> comes with a lot of defaults. This is fine for most regular uses but
> it's not suitable when more control of what is actually loaded in the
> CPU is required.
>
> A bare-bones CPU would be annoying to deal with if not by profile
> support, a way to load a multitude of extensions with a single flag.
> Profile support is going to be implemented shortly, so let's add a CPU
> for it.
>
> The new 'rv64i' CPU will have only RVI loaded. It is inspired in the
> profile specification that dictates, for RVA22U64 [1]:
>
> "RVA22U64 Mandatory Base
> RV64I is the mandatory base ISA for RVA22U64"
>
> And so it seems that RV64I is the mandatory base ISA for all profiles
> listed in [1], making it an ideal CPU to use with profile support.
>
> rv64i is a CPU of type TYPE_RISCV_BARE_CPU. It has a mix of features
> from pre-existent CPUs:
>
> - it allows extensions to be enabled, like generic CPUs;
> - it will not inherit extension defaults, like vendor CPUs.
>
> This is the minimum extension set to boot OpenSBI and buildroot using
> rv64i:
>
> ./build/qemu-system-riscv64 -nographic -M virt \
> -cpu rv64i,sv39=true,g=true,c=true,s=true,u=true
>
> Our minimal riscv,isa in this case will be:
>
> # cat /proc/device-tree/cpus/cpu@0/riscv,isa
> rv64imafdc_zicntr_zicsr_zifencei_zihpm_zca_zcd#
>
> [1] https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
> ---
> target/riscv/cpu-qom.h | 2 ++
> target/riscv/cpu.c | 49 ++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 51 insertions(+)
>
> diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
> index 7831e86d37..ea9a752280 100644
> --- a/target/riscv/cpu-qom.h
> +++ b/target/riscv/cpu-qom.h
> @@ -25,6 +25,7 @@
> #define TYPE_RISCV_CPU "riscv-cpu"
> #define TYPE_RISCV_DYNAMIC_CPU "riscv-dynamic-cpu"
> #define TYPE_RISCV_VENDOR_CPU "riscv-vendor-cpu"
> +#define TYPE_RISCV_BARE_CPU "riscv-bare-cpu"
>
> #define RISCV_CPU_TYPE_SUFFIX "-" TYPE_RISCV_CPU
> #define RISCV_CPU_TYPE_NAME(name) (name RISCV_CPU_TYPE_SUFFIX)
> @@ -35,6 +36,7 @@
> #define TYPE_RISCV_CPU_BASE32 RISCV_CPU_TYPE_NAME("rv32")
> #define TYPE_RISCV_CPU_BASE64 RISCV_CPU_TYPE_NAME("rv64")
> #define TYPE_RISCV_CPU_BASE128 RISCV_CPU_TYPE_NAME("x-rv128")
> +#define TYPE_RISCV_CPU_RV64I RISCV_CPU_TYPE_NAME("rv64i")
> #define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex")
> #define TYPE_RISCV_CPU_SHAKTI_C RISCV_CPU_TYPE_NAME("shakti-c")
> #define TYPE_RISCV_CPU_SIFIVE_E31 RISCV_CPU_TYPE_NAME("sifive-e31")
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 4bb677275c..e9be0c7dae 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -370,6 +370,17 @@ static void set_satp_mode_max_supported(RISCVCPU *cpu,
> /* Set the satp mode to the max supported */
> static void set_satp_mode_default_map(RISCVCPU *cpu)
> {
> + /*
> + * Bare CPUs does not default to the max available.
Bare CPUs do not
> + * Users must set a valid satp_mode in the command
> + * line.
> + */
> + if (object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_BARE_CPU) != NULL) {
> + warn_report("No satp mode set. Defaulting to 'bare'");
> + cpu->cfg.satp_mode.map = (1 << VM_1_10_MBARE);
> + return;
> + }
> +
> cpu->cfg.satp_mode.map = cpu->cfg.satp_mode.supported;
> }
> #endif
> @@ -552,6 +563,31 @@ static void rv128_base_cpu_init(Object *obj)
> set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
> #endif
> }
> +
> +static void rv64i_bare_cpu_init(Object *obj)
> +{
> + CPURISCVState *env = &RISCV_CPU(obj)->env;
> + riscv_cpu_set_misa(env, MXL_RV64, RVI);
> +
> + /* Remove the defaults from the parent class */
> + RISCV_CPU(obj)->cfg.ext_zicntr = false;
> + RISCV_CPU(obj)->cfg.ext_zihpm = false;
> +
> + /*
> + * Set 1.10 instead of leaving it blank, which
> + * defaults to 1.10 anyway.
> + */
I'd either write "Set to QEMU's first supported priv version" or just drop
the comment.
> + env->priv_ver = PRIV_VERSION_1_10_0;
> +
> + /*
> + * Support all available satp_mode settings. The default
> + * value will be set to MBARE if the user doesn't set
> + * satp_mode manually (see set_satp_mode_default()).
> + */
> +#ifndef CONFIG_USER_ONLY
> + set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV64);
> +#endif
> +}
> #else
> static void rv32_base_cpu_init(Object *obj)
> {
> @@ -1748,6 +1784,13 @@ void riscv_cpu_list(void)
> .instance_init = initfn \
> }
>
> +#define DEFINE_BARE_CPU(type_name, initfn) \
> + { \
> + .name = type_name, \
> + .parent = TYPE_RISCV_BARE_CPU, \
> + .instance_init = initfn \
> + }
> +
> static const TypeInfo riscv_cpu_type_infos[] = {
> {
> .name = TYPE_RISCV_CPU,
> @@ -1770,6 +1813,11 @@ static const TypeInfo riscv_cpu_type_infos[] = {
> .parent = TYPE_RISCV_CPU,
> .abstract = true,
> },
> + {
> + .name = TYPE_RISCV_BARE_CPU,
> + .parent = TYPE_RISCV_CPU,
> + .abstract = true,
> + },
> DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
> DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_MAX, riscv_max_cpu_init),
> #if defined(TARGET_RISCV32)
> @@ -1786,6 +1834,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
> DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_THEAD_C906, rv64_thead_c906_cpu_init),
> DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1, rv64_veyron_v1_cpu_init),
> DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128, rv128_base_cpu_init),
> + DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV64I, rv64i_bare_cpu_init),
> #endif
> };
>
> --
> 2.41.0
>
Thanks,
drew
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v9 10/19] target/riscv/tcg: add user flag for profile support
2023-11-02 22:44 ` [PATCH v9 10/19] target/riscv/tcg: add user flag for profile support Daniel Henrique Barboza
@ 2023-11-03 8:41 ` Andrew Jones
0 siblings, 0 replies; 27+ messages in thread
From: Andrew Jones @ 2023-11-03 8:41 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, bmeng, liweiwei,
zhiwei_liu, palmer
On Thu, Nov 02, 2023 at 07:44:36PM -0300, Daniel Henrique Barboza wrote:
...
> + if (profile->enabled) {
> + /*
> + * Note: the 'priv_spec' command line option, if present,
> + * will take precedence over this priv_ver bump.
> + */
> + cpu_validate_multi_ext_priv_ver(&cpu->env, ext_offset);
> + }
If we moved the comment into cpu_validate_multi_ext_priv_ver() we wouldn't
need it's third occurrence to be added here.
Thanks,
drew
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v9 18/19] target/riscv: add 'rva22u64' CPU
2023-11-02 22:44 ` [PATCH v9 18/19] target/riscv: add 'rva22u64' CPU Daniel Henrique Barboza
@ 2023-11-03 8:50 ` Andrew Jones
0 siblings, 0 replies; 27+ messages in thread
From: Andrew Jones @ 2023-11-03 8:50 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, bmeng, liweiwei,
zhiwei_liu, palmer
On Thu, Nov 02, 2023 at 07:44:44PM -0300, Daniel Henrique Barboza wrote:
> This CPU was suggested by Alistair [1] and others during the profile
> design discussions. It consists of the bare 'rv64i' CPU with rva22u64
> enabled by default, like an alias of '-cpu rv64i,rva22u64=true'.
>
> Users now have an even easier way of consuming this user-mode profile by
> doing '-cpu rva22u64'. Extensions can be enabled/disabled at will on top
> of it.
>
> We can boot Linux with this "user-mode" CPU by doing:
>
> -cpu rva22u64,sv39=true,s=true,zifencei=true
>
> [1] https://lore.kernel.org/qemu-riscv/CAKmqyKP7xzZ9Sx=-Lbx2Ob0qCfB7Z+JO944FQ2TQ+49mqo0q_Q@mail.gmail.com/
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
> target/riscv/cpu-qom.h | 1 +
> target/riscv/cpu.c | 10 ++++++++++
> target/riscv/tcg/tcg-cpu.c | 9 +++++++++
> 3 files changed, 20 insertions(+)
>
> diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
> index ea9a752280..ac38ffc6cf 100644
> --- a/target/riscv/cpu-qom.h
> +++ b/target/riscv/cpu-qom.h
> @@ -37,6 +37,7 @@
> #define TYPE_RISCV_CPU_BASE64 RISCV_CPU_TYPE_NAME("rv64")
> #define TYPE_RISCV_CPU_BASE128 RISCV_CPU_TYPE_NAME("x-rv128")
> #define TYPE_RISCV_CPU_RV64I RISCV_CPU_TYPE_NAME("rv64i")
> +#define TYPE_RISCV_CPU_RVA22U64 RISCV_CPU_TYPE_NAME("rva22u64")
> #define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex")
> #define TYPE_RISCV_CPU_SHAKTI_C RISCV_CPU_TYPE_NAME("shakti-c")
> #define TYPE_RISCV_CPU_SIFIVE_E31 RISCV_CPU_TYPE_NAME("sifive-e31")
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index d24ffbf3f8..1f2932031a 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1542,6 +1542,15 @@ static Property riscv_cpu_properties[] = {
> DEFINE_PROP_END_OF_LIST(),
> };
>
> +#if defined(TARGET_RISCV64)
> +static void rva22u64_bare_cpu_init(Object *obj)
The "rva22u64_bare" name is a bit weird, indicating it's both an rva22u64
type and a bare type, which isn't possible. Why not just
rva22u64_cpu_init()?
> +{
> + rv64i_bare_cpu_init(obj);
> +
> + RVA22U64.enabled = true;
> +}
> +#endif
> +
> static const gchar *riscv_gdb_arch_name(CPUState *cs)
> {
> RISCVCPU *cpu = RISCV_CPU(cs);
> @@ -1876,6 +1885,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
> DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1, rv64_veyron_v1_cpu_init),
> DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128, rv128_base_cpu_init),
> DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV64I, rv64i_bare_cpu_init),
> + DEFINE_BARE_CPU(TYPE_RISCV_CPU_RVA22U64, rva22u64_bare_cpu_init),
Oh, I see. Because we want to use DEFINE_BARE_CPU() here we wanted bare in
the init function name. Maybe, for self-documentation / less confusion
purposes, we should have a DEFINE_PROFILE_CPU() macro even if it's just an
alias for DEFINE_BARE_CPU().
> #endif
> };
>
> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
> index ef43264cb3..553fb337e7 100644
> --- a/target/riscv/tcg/tcg-cpu.c
> +++ b/target/riscv/tcg/tcg-cpu.c
> @@ -1068,6 +1068,15 @@ static void riscv_cpu_add_profiles(Object *cpu_obj)
> object_property_add(cpu_obj, profile->name, "bool",
> cpu_get_profile, cpu_set_profile,
> NULL, (void *)profile);
> +
> + /*
> + * CPUs might enable a profile right from the start.
> + * Enable its mandatory extensions right away in this
> + * case.
> + */
> + if (profile->enabled) {
> + object_property_set_bool(cpu_obj, profile->name, true, NULL);
> + }
> }
> }
>
> --
> 2.41.0
>
Other than the naming nits.
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Thanks,
drew
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v9 19/19] target/riscv/tcg: do not support profiles for 'max' CPU
2023-11-02 22:44 ` [PATCH v9 19/19] target/riscv/tcg: do not support profiles for 'max' CPU Daniel Henrique Barboza
@ 2023-11-03 9:01 ` Andrew Jones
2023-11-03 11:13 ` Daniel Henrique Barboza
0 siblings, 1 reply; 27+ messages in thread
From: Andrew Jones @ 2023-11-03 9:01 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, bmeng, liweiwei,
zhiwei_liu, palmer
On Thu, Nov 02, 2023 at 07:44:45PM -0300, Daniel Henrique Barboza wrote:
> There's no gain in allowing the 'max' CPU to support profiles, since it
> already contains everything that QEMU can support. And we'll open the
> door for 'unorthodox' stuff like users disabling profiles of the 'max'
> CPU.
I don't see a lot of value in this patch, but maybe I'm just too cruel to
users that don't know what they're doing. I even see a negative value to
this patch because I can conceive of writing a script where I generally
want to use rv64i with my explicit list of profiles/extensions, but then
I may want to temporarily "boost" my CPU to 'max' for some reason. If
I write my script like
CPU=rv64i
EXTENSIONS=profile=on,extension=on
qemu -cpu $CPU,$EXTENSIONS ...
then I can't just do
CPU=max ./my-script
to boost my CPU, since max will error out when it sees profiles being
enabled (even though that should be no-op for it). Instead, I need to
do
CPU=max EXTENSIONS= ./my-script
which isn't horrible, but a bit annoying.
So, personally, I would drop this patch.
Thanks,
drew
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
> target/riscv/tcg/tcg-cpu.c | 16 +++++++++++-----
> 1 file changed, 11 insertions(+), 5 deletions(-)
>
> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
> index 553fb337e7..9a964a426e 100644
> --- a/target/riscv/tcg/tcg-cpu.c
> +++ b/target/riscv/tcg/tcg-cpu.c
> @@ -825,6 +825,11 @@ static bool riscv_cpu_is_vendor(Object *cpu_obj)
> return object_dynamic_cast(cpu_obj, TYPE_RISCV_VENDOR_CPU) != NULL;
> }
>
> +static bool riscv_cpu_has_max_extensions(Object *cpu_obj)
> +{
> + return object_dynamic_cast(cpu_obj, TYPE_RISCV_CPU_MAX) != NULL;
> +}
> +
> /*
> * We'll get here via the following path:
> *
> @@ -1003,6 +1008,12 @@ static void cpu_set_profile(Object *obj, Visitor *v, const char *name,
> return;
> }
>
> + if (riscv_cpu_has_max_extensions(obj)) {
> + error_setg(errp, "Profile %s is not available for the 'max' CPU",
> + profile->name);
> + return;
> + }
> +
> if (cpu->env.misa_mxl != MXL_RV64) {
> error_setg(errp, "Profile %s only available for 64 bit CPUs",
> profile->name);
> @@ -1251,11 +1262,6 @@ static void riscv_init_max_cpu_extensions(Object *obj)
> }
> }
>
> -static bool riscv_cpu_has_max_extensions(Object *cpu_obj)
> -{
> - return object_dynamic_cast(cpu_obj, TYPE_RISCV_CPU_MAX) != NULL;
> -}
> -
> static void tcg_cpu_instance_init(CPUState *cs)
> {
> RISCVCPU *cpu = RISCV_CPU(cs);
> --
> 2.41.0
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v9 19/19] target/riscv/tcg: do not support profiles for 'max' CPU
2023-11-03 9:01 ` Andrew Jones
@ 2023-11-03 11:13 ` Daniel Henrique Barboza
0 siblings, 0 replies; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-03 11:13 UTC (permalink / raw)
To: Andrew Jones
Cc: qemu-devel, qemu-riscv, alistair.francis, bmeng, liweiwei,
zhiwei_liu, palmer
On 11/3/23 06:01, Andrew Jones wrote:
> On Thu, Nov 02, 2023 at 07:44:45PM -0300, Daniel Henrique Barboza wrote:
>> There's no gain in allowing the 'max' CPU to support profiles, since it
>> already contains everything that QEMU can support. And we'll open the
>> door for 'unorthodox' stuff like users disabling profiles of the 'max'
>> CPU.
>
> I don't see a lot of value in this patch, but maybe I'm just too cruel to
> users that don't know what they're doing. I even see a negative value to
> this patch because I can conceive of writing a script where I generally
> want to use rv64i with my explicit list of profiles/extensions, but then
> I may want to temporarily "boost" my CPU to 'max' for some reason. If
> I write my script like
>
> CPU=rv64i
> EXTENSIONS=profile=on,extension=on
> qemu -cpu $CPU,$EXTENSIONS ...
>
> then I can't just do
>
> CPU=max ./my-script
>
> to boost my CPU, since max will error out when it sees profiles being
> enabled (even though that should be no-op for it). Instead, I need to
> do
>
> CPU=max EXTENSIONS= ./my-script
>
> which isn't horrible, but a bit annoying.
>
> So, personally, I would drop this patch.
Fair enough. I wasn't creative enough with scripting to see the value of 'max' and
profiles. Let's drop it.
Thanks,
Daniel
>
> Thanks,
> drew
>
>>
>> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
>> ---
>> target/riscv/tcg/tcg-cpu.c | 16 +++++++++++-----
>> 1 file changed, 11 insertions(+), 5 deletions(-)
>>
>> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
>> index 553fb337e7..9a964a426e 100644
>> --- a/target/riscv/tcg/tcg-cpu.c
>> +++ b/target/riscv/tcg/tcg-cpu.c
>> @@ -825,6 +825,11 @@ static bool riscv_cpu_is_vendor(Object *cpu_obj)
>> return object_dynamic_cast(cpu_obj, TYPE_RISCV_VENDOR_CPU) != NULL;
>> }
>>
>> +static bool riscv_cpu_has_max_extensions(Object *cpu_obj)
>> +{
>> + return object_dynamic_cast(cpu_obj, TYPE_RISCV_CPU_MAX) != NULL;
>> +}
>> +
>> /*
>> * We'll get here via the following path:
>> *
>> @@ -1003,6 +1008,12 @@ static void cpu_set_profile(Object *obj, Visitor *v, const char *name,
>> return;
>> }
>>
>> + if (riscv_cpu_has_max_extensions(obj)) {
>> + error_setg(errp, "Profile %s is not available for the 'max' CPU",
>> + profile->name);
>> + return;
>> + }
>> +
>> if (cpu->env.misa_mxl != MXL_RV64) {
>> error_setg(errp, "Profile %s only available for 64 bit CPUs",
>> profile->name);
>> @@ -1251,11 +1262,6 @@ static void riscv_init_max_cpu_extensions(Object *obj)
>> }
>> }
>>
>> -static bool riscv_cpu_has_max_extensions(Object *cpu_obj)
>> -{
>> - return object_dynamic_cast(cpu_obj, TYPE_RISCV_CPU_MAX) != NULL;
>> -}
>> -
>> static void tcg_cpu_instance_init(CPUState *cs)
>> {
>> RISCVCPU *cpu = RISCV_CPU(cs);
>> --
>> 2.41.0
>>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v9 03/19] target/riscv/tcg: update priv_ver on user_set extensions
2023-11-03 8:33 ` Andrew Jones
@ 2023-11-03 11:34 ` Daniel Henrique Barboza
0 siblings, 0 replies; 27+ messages in thread
From: Daniel Henrique Barboza @ 2023-11-03 11:34 UTC (permalink / raw)
To: Andrew Jones
Cc: qemu-devel, qemu-riscv, alistair.francis, bmeng, liweiwei,
zhiwei_liu, palmer
On 11/3/23 05:33, Andrew Jones wrote:
> On Thu, Nov 02, 2023 at 07:44:29PM -0300, Daniel Henrique Barboza wrote:
>> We'll add a new bare CPU type that won't have any default priv_ver. This
>> means that the CPU will default to priv_ver = 0, i.e. 1.10.0.
>>
>> At the same we'll allow these CPUs to enable extensions at will, but
>> then, if the extension has a priv_ver newer than 1.10, we'll end up
>> disabling it. Users will then need to manually set priv_ver to something
>> other than 1.10 to enable the extensions they want, which is not ideal.
>>
>> Change the setter() of extensions to allow user enabled extensions to
>> bump the priv_ver of the CPU. This will make it convenient for users to
>> enable extensions for CPUs that doesn't set a default priv_ver.
>>
>> This change does not affect any existing CPU: vendor CPUs does not allow
>> extensions to be enabled, and generic CPUs are already set to priv_ver
>> LATEST.
>
> The only problem I see is that priv_ver will be silently bumped for any
> CPU type which accepts extensions. While generic CPUs currently always
> select LATEST, meaning it doesn't matter, and the new bare CPU type needs
> this feature, we'll also eventually have CPU types that set a priv_ver
> in their definition which should not be changed. For example, when the
> rva22s64 profile is introduced it will set its priv_ver to 1.12, as
> mandated by the profile, if a user then adds an extension which requires
> a later profile, its priv_ver will get silently bumped. Maybe that won't
> matter, though, because later in realize we'll check that Ss1p12 is true
> and when it's false we'll complain that the profile is not compliant?
> Or maybe I'm reading the profile spec too strictly and/or am too
> pessimistic about later specs being backwards compatible. If we believe
> later specs are always compatible with older, then we could advertise
> compliance with a profile which mandates 1.12 as long as its spec is 1.12
> or later
TBH I have no idea if a profile that demands priv spec 1.12 (like rva22s64, the
profile we're adding next) would be compliant with a CPU that runs a newer priv
spec. We'll have to cross that bridge when we come to it I guess ...
Thanks,
Daniel
.
>
> Anyway, just food for thought. I think we can address this later when
> we get the first CPU type which sets a priv_ver and accepts extensions.
>
>>
>> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
>> ---
>> target/riscv/tcg/tcg-cpu.c | 32 ++++++++++++++++++++++++++++++++
>> 1 file changed, 32 insertions(+)
>>
>> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
>> index 08f8dded56..0e684ab86f 100644
>> --- a/target/riscv/tcg/tcg-cpu.c
>> +++ b/target/riscv/tcg/tcg-cpu.c
>> @@ -114,6 +114,22 @@ static int cpu_cfg_ext_get_min_version(uint32_t ext_offset)
>> g_assert_not_reached();
>> }
>>
>> +static void cpu_validate_multi_ext_priv_ver(CPURISCVState *env,
>> + uint32_t ext_offset)
>> +{
>> + int ext_priv_ver;
>> +
>> + if (env->priv_ver == PRIV_VERSION_LATEST) {
>> + return;
>> + }
>> +
>> + ext_priv_ver = cpu_cfg_ext_get_min_version(ext_offset);
>> +
>> + if (env->priv_ver < ext_priv_ver) {
>> + env->priv_ver = ext_priv_ver;
>> + }
>> +}
>> +
>> static void cpu_cfg_ext_auto_update(RISCVCPU *cpu, uint32_t ext_offset,
>> bool value)
>> {
>> @@ -742,6 +758,14 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, const char *name,
>> return;
>> }
>>
>> + if (misa_bit == RVH && env->priv_ver < PRIV_VERSION_1_12_0) {
>> + /*
>> + * Note: the 'priv_spec' command line option, if present,
>> + * will take precedence over this priv_ver bump.
>> + */
>> + env->priv_ver = PRIV_VERSION_1_12_0;
>> + }
>> +
>> env->misa_ext |= misa_bit;
>> env->misa_ext_mask |= misa_bit;
>> } else {
>> @@ -871,6 +895,14 @@ static void cpu_set_multi_ext_cfg(Object *obj, Visitor *v, const char *name,
>> return;
>> }
>>
>> + if (value) {
>> + /*
>> + * Note: the 'priv_spec' command line option, if present,
>> + * will take precedence over this priv_ver bump.
>> + */
>
> The above comment would be better in cpu_validate_multi_ext_priv_ver() at
> the line where the bumping is done.
>
>> + cpu_validate_multi_ext_priv_ver(&cpu->env, multi_ext_cfg->offset);
>> + }
>> +
>> isa_ext_update_enabled(cpu, multi_ext_cfg->offset, value);
>> }
>>
>> --
>> 2.41.0
>>
>
> Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
>
> Thanks,
> drew
^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2023-11-03 11:35 UTC | newest]
Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-02 22:44 [PATCH v9 00/19] rv64i and rva22u64 CPUs, RVA22U64 profile support Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 01/19] target/riscv: create TYPE_RISCV_VENDOR_CPU Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 02/19] target/riscv/tcg: do not use "!generic" CPU checks Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 03/19] target/riscv/tcg: update priv_ver on user_set extensions Daniel Henrique Barboza
2023-11-03 8:33 ` Andrew Jones
2023-11-03 11:34 ` Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 04/19] target/riscv: add rv64i CPU Daniel Henrique Barboza
2023-11-03 8:37 ` Andrew Jones
2023-11-02 22:44 ` [PATCH v9 05/19] target/riscv: add zicbop extension flag Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 06/19] target/riscv/tcg: add 'zic64b' support Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 07/19] riscv-qmp-cmds.c: expose named features in cpu_model_expansion Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 08/19] target/riscv: add rva22u64 profile definition Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 09/19] target/riscv/kvm: add 'rva22u64' flag as unavailable Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 10/19] target/riscv/tcg: add user flag for profile support Daniel Henrique Barboza
2023-11-03 8:41 ` Andrew Jones
2023-11-02 22:44 ` [PATCH v9 11/19] target/riscv/tcg: add MISA user options hash Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 12/19] target/riscv/tcg: add riscv_cpu_write_misa_bit() Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 13/19] target/riscv/tcg: handle profile MISA bits Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 14/19] target/riscv/tcg: add hash table insert helpers Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 15/19] target/riscv/tcg: honor user choice for G MISA bits Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 16/19] target/riscv/tcg: validate profiles during finalize Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 17/19] riscv-qmp-cmds.c: add profile flags in cpu-model-expansion Daniel Henrique Barboza
2023-11-02 22:44 ` [PATCH v9 18/19] target/riscv: add 'rva22u64' CPU Daniel Henrique Barboza
2023-11-03 8:50 ` Andrew Jones
2023-11-02 22:44 ` [PATCH v9 19/19] target/riscv/tcg: do not support profiles for 'max' CPU Daniel Henrique Barboza
2023-11-03 9:01 ` Andrew Jones
2023-11-03 11:13 ` Daniel Henrique Barboza
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).