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);
 
-- 
2.34.1


Reply via email to