target/riscv/cpu.h | 13 +++++++
target/riscv/machine.c | 5 +--
target/riscv/tcg/tcg-cpu.c | 3 ++
4 files changed, 88 insertions(+), 2 deletions(-)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index
73d4280..dbcdfcd 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1123,6 +1123,7 @@ static void riscv_cpu_init(Object *obj)
cpu->cfg.pmp_regions = 16;
cpu->cfg.pmp_granularity = MIN_RISCV_PMP_GRANULARITY;
cpu->env.vext_ver = VEXT_VERSION_1_00_0;
+ cpu->env.debug_ver = DEBUG_VERSION_0_13_0;
cpu->cfg.max_satp_mode = -1;
if (mcc->def->profile) {
@@ -1138,6 +1139,9 @@ static void riscv_cpu_init(Object *obj)
if (mcc->def->vext_spec != RISCV_PROFILE_ATTR_UNUSED) {
cpu->env.vext_ver = mcc->def->vext_spec;
}
+ if (mcc->def->debug_spec != RISCV_PROFILE_ATTR_UNUSED) {
+ cpu->env.debug_ver = mcc->def->debug_spec;
+ }
#ifndef CONFIG_USER_ONLY
if (mcc->def->custom_csrs) {
riscv_register_custom_csrs(cpu, mcc->def->custom_csrs); @@
-1720,6 +1724,66 @@ static const PropertyInfo prop_priv_spec = {
.set = prop_priv_spec_set,
};
+static int debug_spec_from_str(const char *debug_spec_str) {
+ int debug_version = -1;
+
+ if (!g_strcmp0(debug_spec_str, DEBUG_VER_0_13_0_STR)) {
+ debug_version = DEBUG_VERSION_0_13_0;
+ } else if (!g_strcmp0(debug_spec_str, DEBUG_VER_1_00_0_STR)) {
+ debug_version = DEBUG_VERSION_1_00_0;
+ }
+
+ return debug_version;
+}
+
+static const char *debug_spec_to_str(int debug_version) {
+ switch (debug_version) {
+ case DEBUG_VERSION_0_13_0:
+ return DEBUG_VER_0_13_0_STR;
+ case DEBUG_VERSION_1_00_0:
+ return DEBUG_VER_1_00_0_STR;
+ default:
+ return NULL;
+ }
+}
+
+static void prop_debug_spec_set(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp) {
+ RISCVCPU *cpu = RISCV_CPU(obj);
+ g_autofree char *value = NULL;
+ int debug_version = -1;
+
+ visit_type_str(v, name, &value, errp);
+
+ debug_version = debug_spec_from_str(value);
+ if (debug_version < 0) {
+ error_setg(errp, "Unsupported debug spec version '%s'", value);
+ return;
+ }
+
+ cpu_option_add_user_setting(name, debug_version);
+ cpu->env.debug_ver = debug_version; }
+
+static void prop_debug_spec_get(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp) {
+ RISCVCPU *cpu = RISCV_CPU(obj);
+ const char *value = debug_spec_to_str(cpu->env.debug_ver);
+
+ visit_type_str(v, name, (char **)&value, errp); }
+
+static const PropertyInfo prop_debug_spec = {
+ .type = "str",
+ .description = "debug_spec",
+ .get = prop_debug_spec_get,
+ .set = prop_debug_spec_set,
+};
+
static void prop_vext_spec_set(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
@@ -2648,6 +2712,7 @@ static const Property riscv_cpu_properties[] = {
{.name = "priv_spec", .info = &prop_priv_spec},
{.name = "vext_spec", .info = &prop_vext_spec},
+ {.name = "debug_spec", .info = &prop_debug_spec},
{.name = "vlen", .info = &prop_vlen},
{.name = "elen", .info = &prop_elen}, @@ -2818,6 +2883,10 @@
static void riscv_cpu_class_base_init(ObjectClass *c, const void *data)
assert(def->vext_spec != 0);
mcc->def->vext_spec = def->vext_spec;
}
+ if (def->debug_spec != RISCV_PROFILE_ATTR_UNUSED) {
+ assert(def->debug_spec <= DEBUG_VERSION_LATEST);
+ mcc->def->debug_spec = def->debug_spec;
+ }
mcc->def->misa_ext |= def->misa_ext;
riscv_cpu_cfg_merge(&mcc->def->cfg, &def->cfg); diff --git
a/target/riscv/cpu.h b/target/riscv/cpu.h index 36e7f10..fc1ae7c
100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -100,6 +100,7 @@ typedef struct riscv_cpu_profile {
bool present;
bool user_set;
int priv_spec;
+ int debug_spec;
int satp_mode;
const int32_t ext_offsets[];
} RISCVCPUProfile;
@@ -123,6 +124,16 @@ enum {
PRIV_VERSION_LATEST = PRIV_VERSION_1_13_0,
};
+/* Debug specification version */
+#define DEBUG_VER_0_13_0_STR "v0.13"
+#define DEBUG_VER_1_00_0_STR "v1.0"
+enum {
+ DEBUG_VERSION_0_13_0 = 0,
+ DEBUG_VERSION_1_00_0,
+
+ DEBUG_VERSION_LATEST = DEBUG_VERSION_1_00_0, };
+
#define VEXT_VERSION_1_00_0 0x00010000
#define VEXT_VER_1_00_0_STR "v1.0"
@@ -245,6 +256,7 @@ struct CPUArchState {
target_ulong priv_ver;
target_ulong vext_ver;
+ target_ulong debug_ver;
/* RISCVMXL, but uint32_t for vmstate migration */
uint32_t misa_mxl; /* current mxl */
@@ -563,6 +575,7 @@ typedef struct RISCVCPUDef {
uint32_t misa_ext;
int priv_spec;
int32_t vext_spec;
+ int debug_spec;
RISCVCPUConfig cfg;
bool bare;
const RISCVCSR *custom_csrs;
diff --git a/target/riscv/machine.c b/target/riscv/machine.c index
18d790a..8658f55 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -427,8 +427,8 @@ static const VMStateDescription vmstate_sstc = {
const VMStateDescription vmstate_riscv_cpu = {
.name = "cpu",
- .version_id = 10,
- .minimum_version_id = 10,
+ .version_id = 11,
+ .minimum_version_id = 11,
.post_load = riscv_cpu_post_load,
.fields = (const VMStateField[]) {
VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32), @@ -443,6
+443,7 @@ const VMStateDescription vmstate_riscv_cpu = {
VMSTATE_UINTTL(env.guest_phys_fault_addr, RISCVCPU),
VMSTATE_UINTTL(env.priv_ver, RISCVCPU),
VMSTATE_UINTTL(env.vext_ver, RISCVCPU),
+ VMSTATE_UINTTL(env.debug_ver, RISCVCPU),
VMSTATE_UINT32(env.misa_mxl, RISCVCPU),
VMSTATE_UINT32(env.misa_ext, RISCVCPU),
VMSTATE_UNUSED(4),
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index d396825..160fcf1 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -1598,6 +1598,9 @@ static void riscv_init_max_cpu_extensions(Object