aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorDaniel Henrique Barboza <dbarboza@ventanamicro.com>2023-07-06 07:17:29 -0300
committerAlistair Francis <alistair.francis@wdc.com>2023-07-10 22:29:20 +1000
commited7e6182063ead28274751bd59f11f74a4cf3063 (patch)
treee5d0c686e70b69024c604a1e7207061d326fbd89 /target
parente28b9c497428f9efccc7b7f5fc69e7c6524b41a0 (diff)
downloadqemu-ed7e6182063ead28274751bd59f11f74a4cf3063.zip
qemu-ed7e6182063ead28274751bd59f11f74a4cf3063.tar.gz
qemu-ed7e6182063ead28274751bd59f11f74a4cf3063.tar.bz2
target/riscv/cpu: add misa_ext_info_arr[]
Next patch will add KVM specific user properties for both MISA and multi-letter extensions. For MISA extensions we want to make use of what is already available in misa_ext_cfgs[] to avoid code repetition. misa_ext_info_arr[] array will hold name and description for each MISA extension that misa_ext_cfgs[] is declaring. We'll then use this new array in KVM code to avoid duplicating strings. Two getters were added to allow KVM to retrieve the 'name' and 'description' for each MISA property. There's nothing holding us back from doing the same with multi-letter extensions. For now doing just with MISA extensions is enough. It is worth documenting that even using the __bultin_ctz() directive to populate the misa_ext_info_arr[] we are forced to assign 'name' and 'description' during runtime in riscv_cpu_add_misa_properties(). The reason is that some Gitlab runners ('clang-user' and 'tsan-build') will throw errors like this if we fetch 'name' and 'description' from the array in the MISA_CFG() macro: ../target/riscv/cpu.c:1624:5: error: initializer element is not a compile-time constant MISA_CFG(RVA, true), ^~~~~~~~~~~~~~~~~~~ ../target/riscv/cpu.c:1619:53: note: expanded from macro 'MISA_CFG' {.name = misa_ext_info_arr[MISA_INFO_IDX(_bit)].name, \ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~ gcc and others compilers/builders were fine with that change. We can't ignore failures in the Gitlab pipeline though, so code was changed to make every runner happy. As a side effect, misa_ext_cfg[] is no longer a 'const' array because it must be set during runtime. Suggested-by: Andrew Jones <ajones@ventanamicro.com> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-Id: <20230706101738.460804-12-dbarboza@ventanamicro.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'target')
-rw-r--r--target/riscv/cpu.c110
-rw-r--r--target/riscv/cpu.h7
2 files changed, 88 insertions, 29 deletions
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0e1265b..35ba220 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1636,33 +1636,83 @@ static void cpu_get_misa_ext_cfg(Object *obj, Visitor *v, const char *name,
visit_type_bool(v, name, &value, errp);
}
-static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
- {.name = "a", .description = "Atomic instructions",
- .misa_bit = RVA, .enabled = true},
- {.name = "c", .description = "Compressed instructions",
- .misa_bit = RVC, .enabled = true},
- {.name = "d", .description = "Double-precision float point",
- .misa_bit = RVD, .enabled = true},
- {.name = "f", .description = "Single-precision float point",
- .misa_bit = RVF, .enabled = true},
- {.name = "i", .description = "Base integer instruction set",
- .misa_bit = RVI, .enabled = true},
- {.name = "e", .description = "Base integer instruction set (embedded)",
- .misa_bit = RVE, .enabled = false},
- {.name = "m", .description = "Integer multiplication and division",
- .misa_bit = RVM, .enabled = true},
- {.name = "s", .description = "Supervisor-level instructions",
- .misa_bit = RVS, .enabled = true},
- {.name = "u", .description = "User-level instructions",
- .misa_bit = RVU, .enabled = true},
- {.name = "h", .description = "Hypervisor",
- .misa_bit = RVH, .enabled = true},
- {.name = "x-j", .description = "Dynamic translated languages",
- .misa_bit = RVJ, .enabled = false},
- {.name = "v", .description = "Vector operations",
- .misa_bit = RVV, .enabled = false},
- {.name = "g", .description = "General purpose (IMAFD_Zicsr_Zifencei)",
- .misa_bit = RVG, .enabled = false},
+typedef struct misa_ext_info {
+ const char *name;
+ const char *description;
+} MISAExtInfo;
+
+#define MISA_INFO_IDX(_bit) \
+ __builtin_ctz(_bit)
+
+#define MISA_EXT_INFO(_bit, _propname, _descr) \
+ [MISA_INFO_IDX(_bit)] = {.name = _propname, .description = _descr}
+
+static const MISAExtInfo misa_ext_info_arr[] = {
+ MISA_EXT_INFO(RVA, "a", "Atomic instructions"),
+ MISA_EXT_INFO(RVC, "c", "Compressed instructions"),
+ MISA_EXT_INFO(RVD, "d", "Double-precision float point"),
+ MISA_EXT_INFO(RVF, "f", "Single-precision float point"),
+ MISA_EXT_INFO(RVI, "i", "Base integer instruction set"),
+ MISA_EXT_INFO(RVE, "e", "Base integer instruction set (embedded)"),
+ MISA_EXT_INFO(RVM, "m", "Integer multiplication and division"),
+ MISA_EXT_INFO(RVS, "s", "Supervisor-level instructions"),
+ MISA_EXT_INFO(RVU, "u", "User-level instructions"),
+ MISA_EXT_INFO(RVH, "h", "Hypervisor"),
+ MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"),
+ MISA_EXT_INFO(RVV, "v", "Vector operations"),
+ MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
+};
+
+static int riscv_validate_misa_info_idx(uint32_t bit)
+{
+ int idx;
+
+ /*
+ * Our lowest valid input (RVA) is 1 and
+ * __builtin_ctz() is UB with zero.
+ */
+ g_assert(bit != 0);
+ idx = MISA_INFO_IDX(bit);
+
+ g_assert(idx < ARRAY_SIZE(misa_ext_info_arr));
+ return idx;
+}
+
+const char *riscv_get_misa_ext_name(uint32_t bit)
+{
+ int idx = riscv_validate_misa_info_idx(bit);
+ const char *val = misa_ext_info_arr[idx].name;
+
+ g_assert(val != NULL);
+ return val;
+}
+
+const char *riscv_get_misa_ext_description(uint32_t bit)
+{
+ int idx = riscv_validate_misa_info_idx(bit);
+ const char *val = misa_ext_info_arr[idx].description;
+
+ g_assert(val != NULL);
+ return val;
+}
+
+#define MISA_CFG(_bit, _enabled) \
+ {.misa_bit = _bit, .enabled = _enabled}
+
+static RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
+ MISA_CFG(RVA, true),
+ MISA_CFG(RVC, true),
+ MISA_CFG(RVD, true),
+ MISA_CFG(RVF, true),
+ MISA_CFG(RVI, true),
+ MISA_CFG(RVE, false),
+ MISA_CFG(RVM, true),
+ MISA_CFG(RVS, true),
+ MISA_CFG(RVU, true),
+ MISA_CFG(RVH, true),
+ MISA_CFG(RVJ, false),
+ MISA_CFG(RVV, false),
+ MISA_CFG(RVG, false),
};
static void riscv_cpu_add_misa_properties(Object *cpu_obj)
@@ -1670,7 +1720,11 @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)
int i;
for (i = 0; i < ARRAY_SIZE(misa_ext_cfgs); i++) {
- const RISCVCPUMisaExtConfig *misa_cfg = &misa_ext_cfgs[i];
+ RISCVCPUMisaExtConfig *misa_cfg = &misa_ext_cfgs[i];
+ int bit = misa_cfg->misa_bit;
+
+ misa_cfg->name = riscv_get_misa_ext_name(bit);
+ misa_cfg->description = riscv_get_misa_ext_description(bit);
object_property_add(cpu_obj, misa_cfg->name, "bool",
cpu_get_misa_ext_cfg,
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3081603..6ea22e0 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -41,7 +41,10 @@
#define RV(x) ((target_ulong)1 << (x - 'A'))
-/* Consider updating misa_ext_cfgs[] when adding new MISA bits here */
+/*
+ * Consider updating misa_ext_info_arr[] and misa_ext_cfgs[]
+ * when adding new MISA bits here.
+ */
#define RVI RV('I')
#define RVE RV('E') /* E and I are mutually exclusive */
#define RVM RV('M')
@@ -56,6 +59,8 @@
#define RVJ RV('J')
#define RVG RV('G')
+const char *riscv_get_misa_ext_name(uint32_t bit);
+const char *riscv_get_misa_ext_description(uint32_t bit);
/* Privileged specification version */
enum {