|
@@ -32,6 +32,7 @@
|
|
|
#include "hw/core/qdev-prop-internal.h"
|
|
|
#include "migration/vmstate.h"
|
|
|
#include "fpu/softfloat-helpers.h"
|
|
|
+#include "sysemu/device_tree.h"
|
|
|
#include "sysemu/kvm.h"
|
|
|
#include "sysemu/tcg.h"
|
|
|
#include "kvm/kvm_riscv.h"
|
|
@@ -2381,6 +2382,59 @@ char *riscv_isa_string(RISCVCPU *cpu)
|
|
|
return isa_str;
|
|
|
}
|
|
|
|
|
|
+#ifndef CONFIG_USER_ONLY
|
|
|
+static char **riscv_isa_extensions_list(RISCVCPU *cpu, int *count)
|
|
|
+{
|
|
|
+ int maxlen = ARRAY_SIZE(riscv_single_letter_exts) + ARRAY_SIZE(isa_edata_arr);
|
|
|
+ char **extensions = g_new(char *, maxlen);
|
|
|
+
|
|
|
+ for (int i = 0; i < sizeof(riscv_single_letter_exts) - 1; i++) {
|
|
|
+ if (cpu->env.misa_ext & RV(riscv_single_letter_exts[i])) {
|
|
|
+ extensions[*count] = g_new(char, 2);
|
|
|
+ snprintf(extensions[*count], 2, "%c",
|
|
|
+ qemu_tolower(riscv_single_letter_exts[i]));
|
|
|
+ (*count)++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (const RISCVIsaExtData *edata = isa_edata_arr; edata->name; edata++) {
|
|
|
+ if (isa_ext_is_enabled(cpu, edata->ext_enable_offset)) {
|
|
|
+ extensions[*count] = g_strdup(edata->name);
|
|
|
+ (*count)++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return extensions;
|
|
|
+}
|
|
|
+
|
|
|
+void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char *nodename)
|
|
|
+{
|
|
|
+ RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
|
|
|
+ const size_t maxlen = sizeof("rv128i");
|
|
|
+ g_autofree char *isa_base = g_new(char, maxlen);
|
|
|
+ g_autofree char *riscv_isa;
|
|
|
+ char **isa_extensions;
|
|
|
+ int count = 0;
|
|
|
+ int xlen = riscv_cpu_max_xlen(mcc);
|
|
|
+
|
|
|
+ riscv_isa = riscv_isa_string(cpu);
|
|
|
+ qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", riscv_isa);
|
|
|
+
|
|
|
+ snprintf(isa_base, maxlen, "rv%di", xlen);
|
|
|
+ qemu_fdt_setprop_string(fdt, nodename, "riscv,isa-base", isa_base);
|
|
|
+
|
|
|
+ isa_extensions = riscv_isa_extensions_list(cpu, &count);
|
|
|
+ qemu_fdt_setprop_string_array(fdt, nodename, "riscv,isa-extensions",
|
|
|
+ isa_extensions, count);
|
|
|
+
|
|
|
+ for (int i = 0; i < count; i++) {
|
|
|
+ g_free(isa_extensions[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ g_free(isa_extensions);
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
#define DEFINE_CPU(type_name, misa_mxl_max, initfn) \
|
|
|
{ \
|
|
|
.name = (type_name), \
|