All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alistair Francis <Alistair.Francis@wdc.com>
To: "qemu-devel@nongnu.org" <qemu-devel@nongnu.org>,
	"qemu-riscv@nongnu.org" <qemu-riscv@nongnu.org>
Cc: "palmer@sifive.com" <palmer@sifive.com>,
	Alistair Francis <Alistair.Francis@wdc.com>,
	"alistair23@gmail.com" <alistair23@gmail.com>
Subject: [Qemu-riscv] [PATCH for 4.1 v1 1/6] target/riscv: Fall back to generating a RISC-V CPU
Date: Tue, 19 Mar 2019 18:20:57 +0000	[thread overview]
Message-ID: <da94d6ff2576fa9c70b0f8d02ed07dc19927ea1e.1553019560.git.alistair.francis@wdc.com> (raw)
In-Reply-To: <cover.1553019560.git.alistair.francis@wdc.com>

If a user specifies a CPU that we don't understand then we want to fall
back to a CPU generated from the ISA string.

At the moment the generated CPU is assumed to be a privledge spec
version 1.10 CPU with an MMU. This can be changed in the future.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/cpu.c | 95 +++++++++++++++++++++++++++++++++++++++++++++-
 target/riscv/cpu.h |  2 +
 2 files changed, 96 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d61bce6d55..31561c719f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -19,6 +19,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu/log.h"
+#include "qemu/error-report.h"
 #include "cpu.h"
 #include "exec/exec-all.h"
 #include "qapi/error.h"
@@ -103,6 +104,93 @@ static void set_resetvec(CPURISCVState *env, int resetvec)
 #endif
 }
 
+static void riscv_generate_cpu_init(Object *obj)
+{
+    RISCVCPU *cpu = RISCV_CPU(obj);
+    CPURISCVState *env = &cpu->env;
+    RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
+    const char *riscv_cpu = mcc->isa_str;
+    target_ulong target_misa = 0;
+    target_ulong rvxlen = 0;
+    int i;
+    bool valid = false;
+
+    for (i = 0; i < strlen(riscv_cpu); i++) {
+        if (i == 0 && riscv_cpu[i] == 'r' &&
+            riscv_cpu[i + 1] == 'v') {
+            /* Starts with "rv" */
+            i += 2;
+            if (riscv_cpu[i] == '3' && riscv_cpu[i + 1] == '2') {
+                i += 2;
+                valid = true;
+                rvxlen = RV32;
+            }
+            if (riscv_cpu[i] == '6' && riscv_cpu[i + 1] == '4') {
+                i += 2;
+                valid = true;
+                rvxlen = RV64;
+            }
+        }
+
+        switch (riscv_cpu[i]) {
+        case 'i':
+            if (target_misa & RVE) {
+                error_report("I and E extensions are incompatible");
+                exit(1);
+            }
+            target_misa |= RVI;
+            continue;
+        case 'e':
+            if (target_misa & RVI) {
+                error_report("I and E extensions are incompatible");
+                exit(1);
+            }
+            target_misa |= RVE;
+            continue;
+        case 'g':
+            target_misa |= RVI | RVM | RVA | RVF | RVD;
+            continue;
+        case 'm':
+            target_misa |= RVM;
+            continue;
+        case 'a':
+            target_misa |= RVA;
+            continue;
+        case 'f':
+            target_misa |= RVF;
+            continue;
+        case 'd':
+            target_misa |= RVD;
+            continue;
+        case 'c':
+            target_misa |= RVC;
+            continue;
+        case 's':
+            target_misa |= RVS;
+            continue;
+        case 'u':
+            target_misa |= RVU;
+            continue;
+        default:
+            warn_report("QEMU does not support the %c extension",
+                        riscv_cpu[i]);
+            continue;
+        }
+    }
+
+    if (!valid) {
+        error_report("'%s' does not appear to be a valid RISC-V CPU",
+                     riscv_cpu);
+        exit(1);
+    }
+
+    set_misa(env, rvxlen | target_misa);
+    set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
+    set_resetvec(env, DEFAULT_RSTVEC);
+    set_feature(env, RISCV_FEATURE_MMU);
+    set_feature(env, RISCV_FEATURE_PMP);
+}
+
 static void riscv_any_cpu_init(Object *obj)
 {
     CPURISCVState *env = &RISCV_CPU(obj)->env;
@@ -178,6 +266,7 @@ static void rv64imacu_nommu_cpu_init(Object *obj)
 static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
 {
     ObjectClass *oc;
+    RISCVCPUClass *mcc;
     char *typename;
     char **cpuname;
 
@@ -188,7 +277,10 @@ static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
     g_free(typename);
     if (!oc || !object_class_dynamic_cast(oc, TYPE_RISCV_CPU) ||
         object_class_is_abstract(oc)) {
-        return NULL;
+        /* No CPU found, try the generic CPU and pass in the ISA string */
+        oc = object_class_by_name(TYPE_RISCV_CPU_GEN);
+        mcc = RISCV_CPU_CLASS(oc);
+        mcc->isa_str = g_strdup(cpu_model);
     }
     return oc;
 }
@@ -440,6 +532,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
         .class_init = riscv_cpu_class_init,
     },
     DEFINE_CPU(TYPE_RISCV_CPU_ANY,              riscv_any_cpu_init),
+    DEFINE_CPU(TYPE_RISCV_CPU_GEN,              riscv_generate_cpu_init),
 #if defined(TARGET_RISCV32)
     DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_09_1, rv32gcsu_priv1_09_1_cpu_init),
     DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_10_0, rv32gcsu_priv1_10_0_cpu_init),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 20bce8742e..453108a855 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -48,6 +48,7 @@
 #define CPU_RESOLVING_TYPE TYPE_RISCV_CPU
 
 #define TYPE_RISCV_CPU_ANY              RISCV_CPU_TYPE_NAME("any")
+#define TYPE_RISCV_CPU_GEN              RISCV_CPU_TYPE_NAME("rv*")
 #define TYPE_RISCV_CPU_RV32GCSU_V1_09_1 RISCV_CPU_TYPE_NAME("rv32gcsu-v1.9.1")
 #define TYPE_RISCV_CPU_RV32GCSU_V1_10_0 RISCV_CPU_TYPE_NAME("rv32gcsu-v1.10.0")
 #define TYPE_RISCV_CPU_RV32IMACU_NOMMU  RISCV_CPU_TYPE_NAME("rv32imacu-nommu")
@@ -211,6 +212,7 @@ typedef struct RISCVCPUClass {
     /*< public >*/
     DeviceRealize parent_realize;
     void (*parent_reset)(CPUState *cpu);
+    const char *isa_str;
 } RISCVCPUClass;
 
 /**
-- 
2.21.0



  reply	other threads:[~2019-03-19 18:22 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-19 18:20 [Qemu-riscv] [PATCH for 4.1 v1 0/6] RISC-V: Allow specifying CPU ISA via command line Alistair Francis
2019-03-19 18:20 ` Alistair Francis [this message]
2019-03-19 18:21 ` [Qemu-riscv] [PATCH for 4.1 v1 2/6] target/riscv: Create settable CPU properties Alistair Francis
2019-03-19 18:21 ` [Qemu-riscv] [PATCH for 4.1 v1 3/6] riscv: virt: Allow specifying a CPU via commandline Alistair Francis
2019-03-19 18:21 ` [Qemu-riscv] [PATCH for 4.1 v1 4/6] target/riscvL Remove the unused any CPU Alistair Francis
2019-03-19 19:10   ` [Qemu-riscv] [Qemu-devel] " Peter Maydell
2019-03-20 21:35     ` Alistair Francis
2019-03-19 18:21 ` [Qemu-riscv] [PATCH for 4.1 v1 5/6] target/riscv: Remove the generic no MMU CPUs Alistair Francis
2019-03-19 18:21 ` [Qemu-riscv] [PATCH for 4.1 v1 6/6] riscv: Add a generic spike machine Alistair Francis

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=da94d6ff2576fa9c70b0f8d02ed07dc19927ea1e.1553019560.git.alistair.francis@wdc.com \
    --to=alistair.francis@wdc.com \
    --cc=alistair23@gmail.com \
    --cc=palmer@sifive.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-riscv@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.