From: Nikita Shubin <nikita.shubin@maquefel.me>
To: Palmer Dabbelt <palmer@dabbelt.com>,
Alistair Francis <alistair.francis@wdc.com>,
Bin Meng <bin.meng@windriver.com>,
Weiwei Li <liweiwei@iscas.ac.cn>,
Daniel Henrique Barboza <dbarboza@ventanamicro.com>,
Liu Zhiwei <zhiwei_liu@linux.alibaba.com>,
Sunil V L <sunilvl@ventanamicro.com>
Cc: Nikita Shubin <n.shubin@yadro.com>,
qemu-riscv@nongnu.org, qemu-devel@nongnu.org
Subject: [RFC PATCH] hw/riscv: hart: allow other cpu instance
Date: Thu, 27 Jul 2023 11:05:45 +0300 [thread overview]
Message-ID: <20230727080545.7908-1-nikita.shubin@maquefel.me> (raw)
From: Nikita Shubin <n.shubin@yadro.com>
Allow using instances derivative from RISCVCPU
Signed-off-by: Nikita Shubin <n.shubin@yadro.com>
---
Currently it is not possible to overload instance of RISCVCPU,
i.e. something like this:
static const TypeInfo riscv_cpu_type_infos[] = {
{
.name = TYPE_ANOTHER_RISCV_CPU,
.parent = TYPE_RISCV_CPU,
.instance_size = sizeof(MyCPUState),
.instance_init = riscv_my_cpu_init,
}
};
Because we have RISCVHartArrayState.harts with exactly
the size of RISCVCPU.
Using own instances can be used to store some internal hart state.
---
hw/riscv/boot.c | 5 +++--
hw/riscv/riscv_hart.c | 20 ++++++++++++--------
hw/riscv/sifive_u.c | 7 +++++--
hw/riscv/spike.c | 4 +++-
hw/riscv/virt-acpi-build.c | 2 +-
hw/riscv/virt.c | 6 +++---
include/hw/riscv/riscv_hart.h | 18 +++++++++++++++++-
7 files changed, 44 insertions(+), 18 deletions(-)
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 52bf8e67de..c0456dcc2e 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -36,7 +36,8 @@
bool riscv_is_32bit(RISCVHartArrayState *harts)
{
- return harts->harts[0].env.misa_mxl_max == MXL_RV32;
+ RISCVCPU *hart = riscv_array_get_hart(harts, 0);
+ return hart->env.misa_mxl_max == MXL_RV32;
}
/*
@@ -414,7 +415,7 @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts
reset_vec[4] = 0x0182b283; /* ld t0, 24(t0) */
}
- if (!harts->harts[0].cfg.ext_icsr) {
+ if (!riscv_array_get_hart(harts, 0)->cfg.ext_icsr) {
/*
* The Zicsr extension has been disabled, so let's ensure we don't
* run the CSR instruction. Let's fill the address with a non
diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
index 613ea2aaa0..74fc10ef48 100644
--- a/hw/riscv/riscv_hart.c
+++ b/hw/riscv/riscv_hart.c
@@ -43,24 +43,28 @@ static void riscv_harts_cpu_reset(void *opaque)
}
static bool riscv_hart_realize(RISCVHartArrayState *s, int idx,
- char *cpu_type, Error **errp)
+ char *cpu_type, size_t size, Error **errp)
{
- object_initialize_child(OBJECT(s), "harts[*]", &s->harts[idx], cpu_type);
- qdev_prop_set_uint64(DEVICE(&s->harts[idx]), "resetvec", s->resetvec);
- s->harts[idx].env.mhartid = s->hartid_base + idx;
- qemu_register_reset(riscv_harts_cpu_reset, &s->harts[idx]);
- return qdev_realize(DEVICE(&s->harts[idx]), NULL, errp);
+ RISCVCPU *hart = riscv_array_get_hart(s, idx);
+ object_initialize_child_internal(OBJECT(s), "harts[*]",
+ hart, size, cpu_type);
+ qdev_prop_set_uint64(DEVICE(hart), "resetvec", s->resetvec);
+ hart->env.mhartid = s->hartid_base + idx;
+ qemu_register_reset(riscv_harts_cpu_reset, hart);
+ return qdev_realize(DEVICE(hart), NULL, errp);
}
static void riscv_harts_realize(DeviceState *dev, Error **errp)
{
RISCVHartArrayState *s = RISCV_HART_ARRAY(dev);
+ size_t size = object_type_get_instance_size(s->cpu_type);
int n;
- s->harts = g_new0(RISCVCPU, s->num_harts);
+ s->harts = g_new0(RISCVCPU *, s->num_harts);
for (n = 0; n < s->num_harts; n++) {
- if (!riscv_hart_realize(s, n, s->cpu_type, errp)) {
+ s->harts[n] = RISCV_CPU(object_new(s->cpu_type));
+ if (!riscv_hart_realize(s, n, s->cpu_type, size, errp)) {
return;
}
}
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 35a335b8d0..b8a54db81b 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -104,6 +104,7 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
char *nodename;
uint32_t plic_phandle, prci_phandle, gpio_phandle, phandle = 1;
uint32_t hfclk_phandle, rtcclk_phandle, phy_phandle;
+ RISCVCPU *hart;
static const char * const ethclk_names[2] = { "pclk", "hclk" };
static const char * const clint_compat[2] = {
"sifive,clint0", "riscv,clint0"
@@ -180,9 +181,11 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
} else {
qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
}
- isa = riscv_isa_string(&s->soc.u_cpus.harts[cpu - 1]);
+ hart = riscv_array_get_hart(&s->soc.u_cpus, cpu - 1);
+ isa = riscv_isa_string(hart);
} else {
- isa = riscv_isa_string(&s->soc.e_cpus.harts[0]);
+ hart = riscv_array_get_hart(&s->soc.e_cpus, 0);
+ isa = riscv_isa_string(hart);
}
qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", isa);
qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv");
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index 81f7e53aed..85b7568dad 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -61,6 +61,7 @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
uint32_t cpu_phandle, intc_phandle, phandle = 1;
char *name, *mem_name, *clint_name, *clust_name;
char *core_name, *cpu_name, *intc_name;
+ RISCVCPU *hart;
static const char * const clint_compat[2] = {
"sifive,clint0", "riscv,clint0"
};
@@ -103,6 +104,7 @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
clint_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4);
for (cpu = s->soc[socket].num_harts - 1; cpu >= 0; cpu--) {
+ hart = riscv_array_get_hart(&s->soc[socket], cpu);
cpu_phandle = phandle++;
cpu_name = g_strdup_printf("/cpus/cpu@%d",
@@ -113,7 +115,7 @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
} else {
qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv48");
}
- name = riscv_isa_string(&s->soc[socket].harts[cpu]);
+ name = riscv_isa_string(hart);
qemu_fdt_setprop_string(fdt, cpu_name, "riscv,isa", name);
g_free(name);
qemu_fdt_setprop_string(fdt, cpu_name, "compatible", "riscv");
diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index 7331248f59..7cff4e4baf 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -158,7 +158,7 @@ static void build_rhct(GArray *table_data,
isa_offset = table_data->len - table.table_offset;
build_append_int_noprefix(table_data, 0, 2); /* Type 0 */
- cpu = &s->soc[0].harts[0];
+ cpu = riscv_array_get_hart(&s->soc[0], 0);
isa = riscv_isa_string(cpu);
len = 8 + strlen(isa) + 1;
aligned_len = (len % 2) ? (len + 1) : len;
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index d90286dc46..59b42cc5e4 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -236,7 +236,7 @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket,
uint8_t satp_mode_max;
for (cpu = s->soc[socket].num_harts - 1; cpu >= 0; cpu--) {
- RISCVCPU *cpu_ptr = &s->soc[socket].harts[cpu];
+ RISCVCPU *cpu_ptr = riscv_array_get_hart(&s->soc[socket], cpu);
cpu_phandle = (*phandle)++;
@@ -730,12 +730,12 @@ static void create_fdt_pmu(RISCVVirtState *s)
{
char *pmu_name;
MachineState *ms = MACHINE(s);
- RISCVCPU hart = s->soc[0].harts[0];
+ RISCVCPU *hart = riscv_array_get_hart(&s->soc[0], 0);
pmu_name = g_strdup_printf("/soc/pmu");
qemu_fdt_add_subnode(ms->fdt, pmu_name);
qemu_fdt_setprop_string(ms->fdt, pmu_name, "compatible", "riscv,pmu");
- riscv_pmu_generate_fdt_node(ms->fdt, hart.cfg.pmu_num, pmu_name);
+ riscv_pmu_generate_fdt_node(ms->fdt, hart->cfg.pmu_num, pmu_name);
g_free(pmu_name);
}
diff --git a/include/hw/riscv/riscv_hart.h b/include/hw/riscv/riscv_hart.h
index bbc21cdc9a..a5393c361b 100644
--- a/include/hw/riscv/riscv_hart.h
+++ b/include/hw/riscv/riscv_hart.h
@@ -38,7 +38,23 @@ struct RISCVHartArrayState {
uint32_t hartid_base;
char *cpu_type;
uint64_t resetvec;
- RISCVCPU *harts;
+ RISCVCPU **harts;
};
+/**
+ * riscv_array_get_hart:
+ */
+static inline RISCVCPU *riscv_array_get_hart(RISCVHartArrayState *harts, int i)
+{
+ return harts->harts[i];
+}
+
+/**
+ * riscv_array_get_num_harts:
+ */
+static inline unsigned riscv_array_get_num_harts(RISCVHartArrayState *harts)
+{
+ return harts->num_harts;
+}
+
#endif
--
2.39.2
next reply other threads:[~2023-07-27 8:58 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-27 8:05 Nikita Shubin [this message]
2023-07-31 14:12 ` [RFC PATCH] hw/riscv: hart: allow other cpu instance Daniel Henrique Barboza
2023-08-08 7:56 ` Nikita Shubin
2023-08-08 11:27 ` Daniel Henrique Barboza
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=20230727080545.7908-1-nikita.shubin@maquefel.me \
--to=nikita.shubin@maquefel.me \
--cc=alistair.francis@wdc.com \
--cc=bin.meng@windriver.com \
--cc=dbarboza@ventanamicro.com \
--cc=liweiwei@iscas.ac.cn \
--cc=n.shubin@yadro.com \
--cc=palmer@dabbelt.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-riscv@nongnu.org \
--cc=sunilvl@ventanamicro.com \
--cc=zhiwei_liu@linux.alibaba.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).