The priv_spec property accepts a fixed set of values (v1.10.0, v1.11.0,
v1.12.0, v1.13.0) but was implemented as a string type with manual
string-to-enum conversion in custom getter/setter functions.
Convert it to use QEnumLookup with visit_type_enum() for:
- Automatic input validation by the visitor framework
- QMP introspection support (valid values are discoverable)
- Reduced boilerplate (priv_spec_from_str/to_str removed)
This resolves the "FIXME enum?" comment in cpu.c.
Signed-off-by: khaled saleh <[email protected]>
---
target/riscv/cpu.c | 59 +++++++++++---------------------------
target/riscv/cpu.h | 1 +
target/riscv/tcg/tcg-cpu.c | 3 +-
3 files changed, 20 insertions(+), 43 deletions(-)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 506a018d52..8365471572 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -26,6 +26,7 @@
#include "internals.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
+#include "qapi/util.h"
#include "qemu/error-report.h"
#include "hw/core/qdev-properties.h"
#include "hw/core/qdev-prop-internal.h"
@@ -1655,51 +1656,25 @@ static const PropertyInfo prop_pmp_granularity = {
.set = prop_pmp_granularity_set,
};
-static int priv_spec_from_str(const char *priv_spec_str)
-{
- int priv_version = -1;
-
- if (!g_strcmp0(priv_spec_str, PRIV_VER_1_13_0_STR)) {
- priv_version = PRIV_VERSION_1_13_0;
- } else if (!g_strcmp0(priv_spec_str, PRIV_VER_1_12_0_STR)) {
- priv_version = PRIV_VERSION_1_12_0;
- } else if (!g_strcmp0(priv_spec_str, PRIV_VER_1_11_0_STR)) {
- priv_version = PRIV_VERSION_1_11_0;
- } else if (!g_strcmp0(priv_spec_str, PRIV_VER_1_10_0_STR)) {
- priv_version = PRIV_VERSION_1_10_0;
- }
-
- return priv_version;
-}
+static const char *const priv_spec_str[] = {
+ [PRIV_VERSION_1_10_0] = PRIV_VER_1_10_0_STR,
+ [PRIV_VERSION_1_11_0] = PRIV_VER_1_11_0_STR,
+ [PRIV_VERSION_1_12_0] = PRIV_VER_1_12_0_STR,
+ [PRIV_VERSION_1_13_0] = PRIV_VER_1_13_0_STR,
+};
-const char *priv_spec_to_str(int priv_version)
-{
- switch (priv_version) {
- case PRIV_VERSION_1_10_0:
- return PRIV_VER_1_10_0_STR;
- case PRIV_VERSION_1_11_0:
- return PRIV_VER_1_11_0_STR;
- case PRIV_VERSION_1_12_0:
- return PRIV_VER_1_12_0_STR;
- case PRIV_VERSION_1_13_0:
- return PRIV_VER_1_13_0_STR;
- default:
- return NULL;
- }
-}
+const QEnumLookup priv_spec_lookup = {
+ .array = priv_spec_str,
+ .size = ARRAY_SIZE(priv_spec_str),
+};
static void prop_priv_spec_set(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
RISCVCPU *cpu = RISCV_CPU(obj);
- g_autofree char *value = NULL;
- int priv_version = -1;
-
- visit_type_str(v, name, &value, errp);
+ int priv_version;
- priv_version = priv_spec_from_str(value);
- if (priv_version < 0) {
- error_setg(errp, "Unsupported privilege spec version '%s'", value);
+ if (!visit_type_enum(v, name, &priv_version, &priv_spec_lookup, errp)) {
return;
}
@@ -1718,15 +1693,15 @@ static void prop_priv_spec_get(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
RISCVCPU *cpu = RISCV_CPU(obj);
- const char *value = priv_spec_to_str(cpu->env.priv_ver);
+ int value = cpu->env.priv_ver;
- visit_type_str(v, name, (char **)&value, errp);
+ visit_type_enum(v, name, &value, &priv_spec_lookup, errp);
}
static const PropertyInfo prop_priv_spec = {
- .type = "str",
+ .type = "RISCVPrivSpec",
.description = "priv_spec",
- /* FIXME enum? */
+ .enum_table = &priv_spec_lookup,
.get = prop_priv_spec_get,
.set = prop_priv_spec_set,
};
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index fae839cade..522b63016f 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -70,6 +70,7 @@ typedef struct CPUArchState CPURISCVState;
#define RVG RV('G')
#define RVB RV('B')
+extern const QEnumLookup priv_spec_lookup;
extern const uint32_t misa_bits[];
const char *riscv_get_misa_ext_name(uint32_t bit);
const char *riscv_get_misa_ext_description(uint32_t bit);
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 02c98cc2db..2ec4b8e98e 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -27,6 +27,7 @@
#include "time_helper.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
+#include "qapi/util.h"
#include "qemu/accel.h"
#include "qemu/error-report.h"
#include "qemu/log.h"
@@ -86,7 +87,7 @@ static void riscv_cpu_write_misa_bit(RISCVCPU *cpu, uint32_t
bit,
static const char *cpu_priv_ver_to_str(int priv_ver)
{
- const char *priv_spec_str = priv_spec_to_str(priv_ver);
+ const char *priv_spec_str = qapi_enum_lookup(&priv_spec_lookup, priv_ver);
g_assert(priv_spec_str);