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
