* [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU
@ 2025-07-17 9:38 Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 01/14] hw/intc: Allow gaps in hartids for aclint and aplic Djordje Todorovic
` (16 more replies)
0 siblings, 17 replies; 44+ messages in thread
From: Djordje Todorovic @ 2025-07-17 9:38 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com,
philmd@linaro.org, Djordje Todorovic
I addressed several comments in this version, major ones:
- split CPC / CMGCR into separated changes
- split CPS into a separated change
- added functional tests for boston-aia board
Djordje Todorovic (14):
hw/intc: Allow gaps in hartids for aclint and aplic
target/riscv: Add cpu_set_exception_base
target/riscv: Add MIPS P8700 CPU
target/riscv: Add MIPS P8700 CSRs
target/riscv: Add mips.ccmov instruction
target/riscv: Add mips.pref instruction
target/riscv: Add Xmipslsp instructions
hw/misc: Add RISC-V CMGCR device implementation
hw/misc: Add RISC-V CPC device implementation
hw/riscv: Add support for RISCV CPS
hw/riscv: Add support for MIPS Boston-aia board mode
hw/pci: Allow explicit function numbers in pci
riscv/boston-aia: Add an e1000e NIC in slot 0 func 1
test/functional: Add test for boston-aia board
configs/devices/riscv64-softmmu/default.mak | 1 +
docs/system/riscv/mips.rst | 20 +
docs/system/target-riscv.rst | 1 +
hw/intc/riscv_aclint.c | 21 +-
hw/intc/riscv_aplic.c | 11 +-
hw/misc/Kconfig | 20 +
hw/misc/meson.build | 3 +
hw/misc/riscv_cmgcr.c | 234 ++++++++++
hw/misc/riscv_cpc.c | 239 ++++++++++
hw/pci/pci.c | 15 +-
hw/riscv/Kconfig | 6 +
hw/riscv/boston-aia.c | 489 ++++++++++++++++++++
hw/riscv/cps.c | 197 ++++++++
hw/riscv/meson.build | 3 +
include/hw/misc/riscv_cmgcr.h | 49 ++
include/hw/misc/riscv_cpc.h | 73 +++
include/hw/riscv/cps.h | 76 +++
target/riscv/cpu-qom.h | 1 +
target/riscv/cpu.c | 40 ++
target/riscv/cpu.h | 7 +
target/riscv/cpu_cfg.h | 6 +
target/riscv/cpu_cfg_fields.h.inc | 3 +
target/riscv/cpu_vendorid.h | 1 +
target/riscv/insn_trans/trans_xmips.c.inc | 142 ++++++
target/riscv/meson.build | 2 +
target/riscv/mips_csr.c | 228 +++++++++
target/riscv/translate.c | 3 +
target/riscv/xmips.decode | 35 ++
tests/functional/meson.build | 1 +
tests/functional/test_riscv64_boston.py | 78 ++++
30 files changed, 1994 insertions(+), 11 deletions(-)
create mode 100644 docs/system/riscv/mips.rst
create mode 100644 hw/misc/riscv_cmgcr.c
create mode 100644 hw/misc/riscv_cpc.c
create mode 100644 hw/riscv/boston-aia.c
create mode 100644 hw/riscv/cps.c
create mode 100644 include/hw/misc/riscv_cmgcr.h
create mode 100644 include/hw/misc/riscv_cpc.h
create mode 100644 include/hw/riscv/cps.h
create mode 100644 target/riscv/insn_trans/trans_xmips.c.inc
create mode 100644 target/riscv/mips_csr.c
create mode 100644 target/riscv/xmips.decode
create mode 100755 tests/functional/test_riscv64_boston.py
--
2.34.1
^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH v6 01/14] hw/intc: Allow gaps in hartids for aclint and aplic
2025-07-17 9:38 [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
@ 2025-07-17 9:38 ` Djordje Todorovic
2025-08-08 15:52 ` Philippe Mathieu-Daudé
2025-07-17 9:38 ` [PATCH v6 02/14] target/riscv: Add cpu_set_exception_base Djordje Todorovic
` (15 subsequent siblings)
16 siblings, 1 reply; 44+ messages in thread
From: Djordje Todorovic @ 2025-07-17 9:38 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com,
philmd@linaro.org, Djordje Todorovic
This is needed for riscv based CPUs by MIPS since those may have
sparse hart-ID layouts. ACLINT and APLIC still assume a dense
range, and if a hart is missing, this causes NULL derefs.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
---
hw/intc/riscv_aclint.c | 21 +++++++++++++++++++--
hw/intc/riscv_aplic.c | 11 ++++++++---
2 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
index b0139f03f5..22ac4133d5 100644
--- a/hw/intc/riscv_aclint.c
+++ b/hw/intc/riscv_aclint.c
@@ -292,7 +292,13 @@ static void riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp)
s->timecmp = g_new0(uint64_t, s->num_harts);
/* Claim timer interrupt bits */
for (i = 0; i < s->num_harts; i++) {
- RISCVCPU *cpu = RISCV_CPU(cpu_by_arch_id(s->hartid_base + i));
+ CPUState *cpu_by_hartid = cpu_by_arch_id(s->hartid_base + i);
+ if (cpu_by_hartid == NULL) {
+ qemu_log_mask(LOG_GUEST_ERROR, "aclint-mtimer: invalid hartid: %u",
+ s->hartid_base + i);
+ continue;
+ }
+ RISCVCPU *cpu = RISCV_CPU(cpu_by_hartid);
if (riscv_cpu_claim_interrupts(cpu, MIP_MTIP) < 0) {
error_report("MTIP already claimed");
exit(1);
@@ -481,7 +487,13 @@ static void riscv_aclint_swi_realize(DeviceState *dev, Error **errp)
/* Claim software interrupt bits */
for (i = 0; i < swi->num_harts; i++) {
- RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(swi->hartid_base + i));
+ CPUState *cpu_by_hartid = cpu_by_arch_id(swi->hartid_base + i);
+ if (cpu_by_hartid == NULL) {
+ qemu_log_mask(LOG_GUEST_ERROR, "aclint-swi: invalid hartid: %u",
+ swi->hartid_base + i);
+ continue;
+ }
+ RISCVCPU *cpu = RISCV_CPU(cpu_by_hartid);
/* We don't claim mip.SSIP because it is writable by software */
if (riscv_cpu_claim_interrupts(cpu, swi->sswi ? 0 : MIP_MSIP) < 0) {
error_report("MSIP already claimed");
@@ -545,6 +557,11 @@ DeviceState *riscv_aclint_swi_create(hwaddr addr, uint32_t hartid_base,
for (i = 0; i < num_harts; i++) {
CPUState *cpu = cpu_by_arch_id(hartid_base + i);
+ if (cpu == NULL) {
+ qemu_log_mask(LOG_GUEST_ERROR, "aclint-swi: invalid hartid: %u",
+ hartid_base + i);
+ continue;
+ }
RISCVCPU *rvcpu = RISCV_CPU(cpu);
qdev_connect_gpio_out(dev, i,
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
index 8bcd9f4697..c7846753fe 100644
--- a/hw/intc/riscv_aplic.c
+++ b/hw/intc/riscv_aplic.c
@@ -899,9 +899,11 @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
if (!aplic->msimode) {
/* Claim the CPU interrupt to be triggered by this APLIC */
for (i = 0; i < aplic->num_harts; i++) {
- RISCVCPU *cpu;
-
- cpu = RISCV_CPU(cpu_by_arch_id(aplic->hartid_base + i));
+ CPUState *temp = cpu_by_arch_id(aplic->hartid_base + i);
+ if (temp == NULL) {
+ continue;
+ }
+ RISCVCPU *cpu = RISCV_CPU(temp);
if (riscv_cpu_claim_interrupts(cpu,
(aplic->mmode) ? MIP_MEIP : MIP_SEIP) < 0) {
error_report("%s already claimed",
@@ -1076,6 +1078,9 @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
if (!msimode) {
for (i = 0; i < num_harts; i++) {
CPUState *cpu = cpu_by_arch_id(hartid_base + i);
+ if (cpu == NULL) {
+ continue;
+ }
qdev_connect_gpio_out_named(dev, NULL, i,
qdev_get_gpio_in(DEVICE(cpu),
--
2.34.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v6 04/14] target/riscv: Add MIPS P8700 CSRs
2025-07-17 9:38 [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
` (2 preceding siblings ...)
2025-07-17 9:38 ` [PATCH v6 03/14] target/riscv: Add MIPS P8700 CPU Djordje Todorovic
@ 2025-07-17 9:38 ` Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 05/14] target/riscv: Add mips.ccmov instruction Djordje Todorovic
` (12 subsequent siblings)
16 siblings, 0 replies; 44+ messages in thread
From: Djordje Todorovic @ 2025-07-17 9:38 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com,
philmd@linaro.org, Djordje Todorovic
Define MIPS CSRs used for P8700 CPU.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
---
target/riscv/cpu.c | 3 +
target/riscv/cpu.h | 3 +
target/riscv/meson.build | 1 +
target/riscv/mips_csr.c | 228 +++++++++++++++++++++++++++++++++++++++
4 files changed, 235 insertions(+)
create mode 100644 target/riscv/mips_csr.c
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 401c0f6c7d..7f453acbf8 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -3193,6 +3193,9 @@ static const TypeInfo riscv_cpu_type_infos[] = {
.cfg.ext_zbb = true,
.cfg.marchid = 0x8000000000000201,
.cfg.mvendorid = MIPS_VENDOR_ID,
+#ifndef CONFIG_USER_ONLY
+ .custom_csrs = mips_csr_list,
+#endif
),
#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index fba0b0506b..ed10709a65 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -972,5 +972,8 @@ const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
/* In th_csr.c */
extern const RISCVCSR th_csr_list[];
+/* Implemented in mips_csr.c */
+extern const RISCVCSR mips_csr_list[];
+
const char *priv_spec_to_str(int priv_version);
#endif /* RISCV_CPU_H */
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index a4bd61e52a..fbb6c8fb45 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -32,6 +32,7 @@ riscv_system_ss.add(files(
'debug.c',
'monitor.c',
'machine.c',
+ 'mips_csr.c',
'pmu.c',
'th_csr.c',
'time_helper.c',
diff --git a/target/riscv/mips_csr.c b/target/riscv/mips_csr.c
new file mode 100644
index 0000000000..2fc10b8618
--- /dev/null
+++ b/target/riscv/mips_csr.c
@@ -0,0 +1,228 @@
+/*
+ * MIPS-specific CSRs.
+ *
+ * Copyright (c) 2025 MIPS
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "cpu_vendorid.h"
+
+/* Static MIPS CSR state storage */
+static struct {
+ uint64_t tvec;
+ uint64_t config[12];
+ uint64_t pmacfg[16]; /* Fixed: was 15, should be 16 */
+} mips_csr_state;
+
+/* MIPS CSR */
+#define CSR_MIPSTVEC 0x7c0
+#define CSR_MIPSCONFIG0 0x7d0
+#define CSR_MIPSCONFIG1 0x7d1
+#define CSR_MIPSCONFIG2 0x7d2
+#define CSR_MIPSCONFIG3 0x7d3
+#define CSR_MIPSCONFIG4 0x7d4
+#define CSR_MIPSCONFIG5 0x7d5
+#define CSR_MIPSCONFIG6 0x7d6
+#define CSR_MIPSCONFIG7 0x7d7
+#define CSR_MIPSCONFIG8 0x7d8
+#define CSR_MIPSCONFIG9 0x7d9
+#define CSR_MIPSCONFIG10 0x7da
+#define CSR_MIPSCONFIG11 0x7db
+#define CSR_MIPSPMACFG0 0x7e0
+#define CSR_MIPSPMACFG1 0x7e1
+#define CSR_MIPSPMACFG2 0x7e2
+#define CSR_MIPSPMACFG3 0x7e3
+#define CSR_MIPSPMACFG4 0x7e4
+#define CSR_MIPSPMACFG5 0x7e5
+#define CSR_MIPSPMACFG6 0x7e6
+#define CSR_MIPSPMACFG7 0x7e7
+#define CSR_MIPSPMACFG8 0x7e8
+#define CSR_MIPSPMACFG9 0x7e9
+#define CSR_MIPSPMACFG10 0x7ea
+#define CSR_MIPSPMACFG11 0x7eb
+#define CSR_MIPSPMACFG12 0x7ec
+#define CSR_MIPSPMACFG13 0x7ed
+#define CSR_MIPSPMACFG14 0x7ee
+#define CSR_MIPSPMACFG15 0x7ef
+
+static RISCVException any(CPURISCVState *env, int csrno)
+{
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_mipstvec(CPURISCVState *env, int csrno,
+ target_ulong *val)
+{
+ *val = mips_csr_state.tvec;
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_mipstvec(CPURISCVState *env, int csrno,
+ target_ulong val, uintptr_t ra)
+{
+ mips_csr_state.tvec = val;
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_mipsconfig(CPURISCVState *env, int csrno,
+ target_ulong *val)
+{
+ *val = mips_csr_state.config[csrno - CSR_MIPSCONFIG0];
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_mipsconfig(CPURISCVState *env, int csrno,
+ target_ulong val, uintptr_t ra)
+{
+ mips_csr_state.config[csrno - CSR_MIPSCONFIG0] = val;
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_mipspmacfg(CPURISCVState *env, int csrno,
+ target_ulong *val)
+{
+ *val = mips_csr_state.pmacfg[csrno - CSR_MIPSPMACFG0];
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_mipspmacfg(CPURISCVState *env, int csrno,
+ target_ulong val, uintptr_t ra)
+{
+ mips_csr_state.pmacfg[csrno - CSR_MIPSPMACFG0] = val;
+ return RISCV_EXCP_NONE;
+}
+
+const RISCVCSR mips_csr_list[] = {
+ {
+ .csrno = CSR_MIPSTVEC,
+ .csr_ops = { "mipstvec", any, read_mipstvec, write_mipstvec }
+ },
+ {
+ .csrno = CSR_MIPSCONFIG0,
+ .csr_ops = { "mipsconfig0", any, read_mipsconfig, write_mipsconfig }
+ },
+ {
+ .csrno = CSR_MIPSCONFIG1,
+ .csr_ops = { "mipsconfig1", any, read_mipsconfig, write_mipsconfig }
+ },
+ {
+ .csrno = CSR_MIPSCONFIG2,
+ .csr_ops = { "mipsconfig2", any, read_mipsconfig, write_mipsconfig }
+ },
+ {
+ .csrno = CSR_MIPSCONFIG3,
+ .csr_ops = { "mipsconfig3", any, read_mipsconfig, write_mipsconfig }
+ },
+ {
+ .csrno = CSR_MIPSCONFIG4,
+ .csr_ops = { "mipsconfig4", any, read_mipsconfig, write_mipsconfig }
+ },
+ {
+ .csrno = CSR_MIPSCONFIG5,
+ .csr_ops = { "mipsconfig5", any, read_mipsconfig, write_mipsconfig }
+ },
+ {
+ .csrno = CSR_MIPSCONFIG6,
+ .csr_ops = { "mipsconfig6", any, read_mipsconfig, write_mipsconfig }
+ },
+ {
+ .csrno = CSR_MIPSCONFIG7,
+ .csr_ops = { "mipsconfig7", any, read_mipsconfig, write_mipsconfig }
+ },
+ {
+ .csrno = CSR_MIPSCONFIG8,
+ .csr_ops = { "mipsconfig8", any, read_mipsconfig, write_mipsconfig }
+ },
+ {
+ .csrno = CSR_MIPSCONFIG9,
+ .csr_ops = { "mipsconfig9", any, read_mipsconfig, write_mipsconfig }
+ },
+ {
+ .csrno = CSR_MIPSCONFIG10,
+ .csr_ops = { "mipsconfig10", any, read_mipsconfig, write_mipsconfig }
+ },
+ {
+ .csrno = CSR_MIPSCONFIG11,
+ .csr_ops = { "mipsconfig11", any, read_mipsconfig, write_mipsconfig }
+ },
+ {
+ .csrno = CSR_MIPSPMACFG0,
+ .csr_ops = { "mipspmacfg0", any, read_mipspmacfg, write_mipspmacfg }
+ },
+ {
+ .csrno = CSR_MIPSPMACFG1,
+ .csr_ops = { "mipspmacfg1", any, read_mipspmacfg, write_mipspmacfg }
+ },
+ {
+ .csrno = CSR_MIPSPMACFG2,
+ .csr_ops = { "mipspmacfg2", any, read_mipspmacfg, write_mipspmacfg }
+ },
+ {
+ .csrno = CSR_MIPSPMACFG3,
+ .csr_ops = { "mipspmacfg3", any, read_mipspmacfg, write_mipspmacfg }
+ },
+ {
+ .csrno = CSR_MIPSPMACFG4,
+ .csr_ops = { "mipspmacfg4", any, read_mipspmacfg, write_mipspmacfg }
+ },
+ {
+ .csrno = CSR_MIPSPMACFG5,
+ .csr_ops = { "mipspmacfg5", any, read_mipspmacfg, write_mipspmacfg }
+ },
+ {
+ .csrno = CSR_MIPSPMACFG6,
+ .csr_ops = { "mipspmacfg6", any, read_mipspmacfg, write_mipspmacfg }
+ },
+ {
+ .csrno = CSR_MIPSPMACFG7,
+ .csr_ops = { "mipspmacfg7", any, read_mipspmacfg, write_mipspmacfg }
+ },
+ {
+ .csrno = CSR_MIPSPMACFG8,
+ .csr_ops = { "mipspmacfg8", any, read_mipspmacfg, write_mipspmacfg }
+ },
+ {
+ .csrno = CSR_MIPSPMACFG9,
+ .csr_ops = { "mipspmacfg9", any, read_mipspmacfg, write_mipspmacfg }
+ },
+ {
+ .csrno = CSR_MIPSPMACFG10,
+ .csr_ops = { "mipspmacfg10", any, read_mipspmacfg, write_mipspmacfg }
+ },
+ {
+ .csrno = CSR_MIPSPMACFG11,
+ .csr_ops = { "mipspmacfg11", any, read_mipspmacfg, write_mipspmacfg }
+ },
+ {
+ .csrno = CSR_MIPSPMACFG12,
+ .csr_ops = { "mipspmacfg12", any, read_mipspmacfg, write_mipspmacfg }
+ },
+ {
+ .csrno = CSR_MIPSPMACFG13,
+ .csr_ops = { "mipspmacfg13", any, read_mipspmacfg, write_mipspmacfg }
+ },
+ {
+ .csrno = CSR_MIPSPMACFG14,
+ .csr_ops = { "mipspmacfg14", any, read_mipspmacfg, write_mipspmacfg }
+ },
+ {
+ .csrno = CSR_MIPSPMACFG15,
+ .csr_ops = { "mipspmacfg15", any, read_mipspmacfg, write_mipspmacfg }
+ },
+ { },
+};
--
2.34.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v6 03/14] target/riscv: Add MIPS P8700 CPU
2025-07-17 9:38 [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 01/14] hw/intc: Allow gaps in hartids for aclint and aplic Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 02/14] target/riscv: Add cpu_set_exception_base Djordje Todorovic
@ 2025-07-17 9:38 ` Djordje Todorovic
2025-08-08 17:02 ` Philippe Mathieu-Daudé
2025-07-17 9:38 ` [PATCH v6 04/14] target/riscv: Add MIPS P8700 CSRs Djordje Todorovic
` (13 subsequent siblings)
16 siblings, 1 reply; 44+ messages in thread
From: Djordje Todorovic @ 2025-07-17 9:38 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com,
philmd@linaro.org, Djordje Todorovic
Introduce P8700 CPU by MIPS.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
---
target/riscv/cpu-qom.h | 1 +
target/riscv/cpu.c | 15 +++++++++++++++
target/riscv/cpu_vendorid.h | 1 +
3 files changed, 17 insertions(+)
diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
index 1ee05eb393..1e62b96094 100644
--- a/target/riscv/cpu-qom.h
+++ b/target/riscv/cpu-qom.h
@@ -55,6 +55,7 @@
#define TYPE_RISCV_CPU_VEYRON_V1 RISCV_CPU_TYPE_NAME("veyron-v1")
#define TYPE_RISCV_CPU_TT_ASCALON RISCV_CPU_TYPE_NAME("tt-ascalon")
#define TYPE_RISCV_CPU_XIANGSHAN_NANHU RISCV_CPU_TYPE_NAME("xiangshan-nanhu")
+#define TYPE_RISCV_CPU_MIPS_P8700 RISCV_CPU_TYPE_NAME("mips-p8700")
#define TYPE_RISCV_CPU_HOST RISCV_CPU_TYPE_NAME("host")
OBJECT_DECLARE_CPU_TYPE(RISCVCPU, RISCVCPUClass, RISCV_CPU)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index e584bdc5ac..401c0f6c7d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -3180,6 +3180,21 @@ static const TypeInfo riscv_cpu_type_infos[] = {
.cfg.max_satp_mode = VM_1_10_SV39,
),
+ DEFINE_RISCV_CPU(TYPE_RISCV_CPU_MIPS_P8700, TYPE_RISCV_VENDOR_CPU,
+ .misa_mxl_max = MXL_RV64,
+ .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU,
+ .priv_spec = PRIV_VERSION_1_12_0,
+ .cfg.max_satp_mode = VM_1_10_SV48,
+ .cfg.ext_zifencei = true,
+ .cfg.ext_zicsr = true,
+ .cfg.mmu = true,
+ .cfg.pmp = true,
+ .cfg.ext_zba = true,
+ .cfg.ext_zbb = true,
+ .cfg.marchid = 0x8000000000000201,
+ .cfg.mvendorid = MIPS_VENDOR_ID,
+ ),
+
#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
DEFINE_RISCV_CPU(TYPE_RISCV_CPU_BASE128, TYPE_RISCV_DYNAMIC_CPU,
.cfg.max_satp_mode = VM_1_10_SV57,
diff --git a/target/riscv/cpu_vendorid.h b/target/riscv/cpu_vendorid.h
index 96b6b9c2cb..28f0ce9370 100644
--- a/target/riscv/cpu_vendorid.h
+++ b/target/riscv/cpu_vendorid.h
@@ -2,6 +2,7 @@
#define TARGET_RISCV_CPU_VENDORID_H
#define THEAD_VENDOR_ID 0x5b7
+#define MIPS_VENDOR_ID 0x722
#define VEYRON_V1_MARCHID 0x8000000000010000
#define VEYRON_V1_MIMPID 0x111
--
2.34.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v6 02/14] target/riscv: Add cpu_set_exception_base
2025-07-17 9:38 [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 01/14] hw/intc: Allow gaps in hartids for aclint and aplic Djordje Todorovic
@ 2025-07-17 9:38 ` Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 03/14] target/riscv: Add MIPS P8700 CPU Djordje Todorovic
` (14 subsequent siblings)
16 siblings, 0 replies; 44+ messages in thread
From: Djordje Todorovic @ 2025-07-17 9:38 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com,
philmd@linaro.org, Djordje Todorovic
Add a new function, so we can change reset vector from platforms
during runtime.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
---
target/riscv/cpu.c | 13 +++++++++++++
target/riscv/cpu.h | 4 ++++
2 files changed, 17 insertions(+)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 629ac37501..e584bdc5ac 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -73,6 +73,19 @@ bool riscv_cpu_option_set(const char *optname)
return g_hash_table_contains(general_user_opts, optname);
}
+#ifndef CONFIG_USER_ONLY
+void cpu_set_exception_base(int vp_index, target_ulong address)
+{
+ CPUState *cpu_state = qemu_get_cpu(vp_index);
+ if (cpu_state == NULL) {
+ qemu_log_mask(LOG_GUEST_ERROR, "cpu_set_exception_base: invalid vp_index: %u",
+ vp_index);
+ }
+ RISCVCPU *vp = RISCV_CPU(cpu_state);
+ vp->env.resetvec = address;
+}
+#endif
+
static void riscv_cpu_cfg_merge(RISCVCPUConfig *dest, const RISCVCPUConfig *src)
{
#define BOOL_FIELD(x) dest->x |= src->x;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 229ade9ed9..fba0b0506b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -656,6 +656,10 @@ G_NORETURN void riscv_raise_exception(CPURISCVState *env,
target_ulong riscv_cpu_get_fflags(CPURISCVState *env);
void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
+#ifndef CONFIG_USER_ONLY
+void cpu_set_exception_base(int vp_index, target_ulong address);
+#endif
+
FIELD(TB_FLAGS, MEM_IDX, 0, 3)
FIELD(TB_FLAGS, FS, 3, 2)
/* Vector flags */
--
2.34.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v6 06/14] target/riscv: Add mips.pref instruction
2025-07-17 9:38 [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
` (4 preceding siblings ...)
2025-07-17 9:38 ` [PATCH v6 05/14] target/riscv: Add mips.ccmov instruction Djordje Todorovic
@ 2025-07-17 9:38 ` Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 08/14] hw/misc: Add RISC-V CMGCR device implementation Djordje Todorovic
` (10 subsequent siblings)
16 siblings, 0 replies; 44+ messages in thread
From: Djordje Todorovic @ 2025-07-17 9:38 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com,
philmd@linaro.org, Djordje Todorovic
Add MIPS P8700 prefetch instruction defined by Xmipscbop.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
---
target/riscv/cpu.c | 3 +++
target/riscv/cpu_cfg.h | 3 ++-
target/riscv/cpu_cfg_fields.h.inc | 1 +
target/riscv/insn_trans/trans_xmips.c.inc | 14 ++++++++++++++
target/riscv/xmips.decode | 1 +
5 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 52828846c6..d280648b55 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -243,6 +243,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt),
ISA_EXT_DATA_ENTRY(svukte, PRIV_VERSION_1_13_0, ext_svukte),
ISA_EXT_DATA_ENTRY(svvptc, PRIV_VERSION_1_13_0, ext_svvptc),
+ ISA_EXT_DATA_ENTRY(xmipscbop, PRIV_VERSION_1_12_0, ext_xmipscbop),
ISA_EXT_DATA_ENTRY(xmipscmov, PRIV_VERSION_1_12_0, ext_xmipscmov),
ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba),
ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb),
@@ -1374,6 +1375,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
MULTI_EXT_CFG_BOOL("xtheadmempair", ext_xtheadmempair, false),
MULTI_EXT_CFG_BOOL("xtheadsync", ext_xtheadsync, false),
MULTI_EXT_CFG_BOOL("xventanacondops", ext_XVentanaCondOps, false),
+ MULTI_EXT_CFG_BOOL("xmipscbop", ext_xmipscbop, false),
MULTI_EXT_CFG_BOOL("xmipscmov", ext_xmipscmov, false),
{ },
@@ -3193,6 +3195,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
.cfg.pmp = true,
.cfg.ext_zba = true,
.cfg.ext_zbb = true,
+ .cfg.ext_xmipscbop = true,
.cfg.ext_xmipscmov = true,
.cfg.marchid = 0x8000000000000201,
.cfg.mvendorid = MIPS_VENDOR_ID,
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index 2db471ad17..9734963035 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -22,6 +22,7 @@
#define RISCV_CPU_CFG_H
struct RISCVCPUConfig {
+
#define BOOL_FIELD(x) bool x;
#define TYPED_FIELD(type, x, default) type x;
#include "cpu_cfg_fields.h.inc"
@@ -38,7 +39,7 @@ static inline bool always_true_p(const RISCVCPUConfig *cfg __attribute__((__unus
static inline bool has_xmips_p(const RISCVCPUConfig *cfg)
{
- return cfg->ext_xmipscmov;
+ return cfg->ext_xmipscbop || cfg->ext_xmipscmov;
}
static inline bool has_xthead_p(const RISCVCPUConfig *cfg)
diff --git a/target/riscv/cpu_cfg_fields.h.inc b/target/riscv/cpu_cfg_fields.h.inc
index baedf0c466..9ee0a099bb 100644
--- a/target/riscv/cpu_cfg_fields.h.inc
+++ b/target/riscv/cpu_cfg_fields.h.inc
@@ -145,6 +145,7 @@ BOOL_FIELD(ext_xtheadmemidx)
BOOL_FIELD(ext_xtheadmempair)
BOOL_FIELD(ext_xtheadsync)
BOOL_FIELD(ext_XVentanaCondOps)
+BOOL_FIELD(ext_xmipscbop)
BOOL_FIELD(ext_xmipscmov)
BOOL_FIELD(mmu)
diff --git a/target/riscv/insn_trans/trans_xmips.c.inc b/target/riscv/insn_trans/trans_xmips.c.inc
index f5aeacc6fd..620c59cc28 100644
--- a/target/riscv/insn_trans/trans_xmips.c.inc
+++ b/target/riscv/insn_trans/trans_xmips.c.inc
@@ -21,6 +21,12 @@
* (https://mips.com/products/hardware/p8700/)
*/
+#define REQUIRE_XMIPSCBOP(ctx) do { \
+ if (!ctx->cfg_ptr->ext_xmipscbop) { \
+ return false; \
+ } \
+} while (0)
+
#define REQUIRE_XMIPSCMOV(ctx) do { \
if (!ctx->cfg_ptr->ext_xmipscmov) { \
return false; \
@@ -42,3 +48,11 @@ static bool trans_ccmov(DisasContext *ctx, arg_ccmov *a)
return true;
}
+
+static bool trans_pref(DisasContext *ctx, arg_pref *a)
+{
+ REQUIRE_XMIPSCBOP(ctx);
+
+ /* Nop */
+ return true;
+}
diff --git a/target/riscv/xmips.decode b/target/riscv/xmips.decode
index cb334fa4bd..697bf26c26 100644
--- a/target/riscv/xmips.decode
+++ b/target/riscv/xmips.decode
@@ -9,3 +9,4 @@
# (https://mips.com/products/hardware/p8700/)
ccmov rs3:5 11 rs2:5 rs1:5 011 rd:5 0001011
+pref 000 imm_9:9 rs1:5 000 imm_hint:5 0001011
--
2.34.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v6 05/14] target/riscv: Add mips.ccmov instruction
2025-07-17 9:38 [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
` (3 preceding siblings ...)
2025-07-17 9:38 ` [PATCH v6 04/14] target/riscv: Add MIPS P8700 CSRs Djordje Todorovic
@ 2025-07-17 9:38 ` Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 06/14] target/riscv: Add mips.pref instruction Djordje Todorovic
` (11 subsequent siblings)
16 siblings, 0 replies; 44+ messages in thread
From: Djordje Todorovic @ 2025-07-17 9:38 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com,
philmd@linaro.org, Djordje Todorovic
Add mips.ccmov defined by Xmipscmov.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
---
target/riscv/cpu.c | 3 ++
target/riscv/cpu_cfg.h | 5 +++
target/riscv/cpu_cfg_fields.h.inc | 1 +
target/riscv/insn_trans/trans_xmips.c.inc | 44 +++++++++++++++++++++++
target/riscv/meson.build | 1 +
target/riscv/translate.c | 3 ++
target/riscv/xmips.decode | 11 ++++++
7 files changed, 68 insertions(+)
create mode 100644 target/riscv/insn_trans/trans_xmips.c.inc
create mode 100644 target/riscv/xmips.decode
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7f453acbf8..52828846c6 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -243,6 +243,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt),
ISA_EXT_DATA_ENTRY(svukte, PRIV_VERSION_1_13_0, ext_svukte),
ISA_EXT_DATA_ENTRY(svvptc, PRIV_VERSION_1_13_0, ext_svvptc),
+ ISA_EXT_DATA_ENTRY(xmipscmov, PRIV_VERSION_1_12_0, ext_xmipscmov),
ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba),
ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb),
ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs),
@@ -1373,6 +1374,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
MULTI_EXT_CFG_BOOL("xtheadmempair", ext_xtheadmempair, false),
MULTI_EXT_CFG_BOOL("xtheadsync", ext_xtheadsync, false),
MULTI_EXT_CFG_BOOL("xventanacondops", ext_XVentanaCondOps, false),
+ MULTI_EXT_CFG_BOOL("xmipscmov", ext_xmipscmov, false),
{ },
};
@@ -3191,6 +3193,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
.cfg.pmp = true,
.cfg.ext_zba = true,
.cfg.ext_zbb = true,
+ .cfg.ext_xmipscmov = true,
.cfg.marchid = 0x8000000000000201,
.cfg.mvendorid = MIPS_VENDOR_ID,
#ifndef CONFIG_USER_ONLY
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index aa28dc8d7e..2db471ad17 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -36,6 +36,11 @@ static inline bool always_true_p(const RISCVCPUConfig *cfg __attribute__((__unus
return true;
}
+static inline bool has_xmips_p(const RISCVCPUConfig *cfg)
+{
+ return cfg->ext_xmipscmov;
+}
+
static inline bool has_xthead_p(const RISCVCPUConfig *cfg)
{
return cfg->ext_xtheadba || cfg->ext_xtheadbb ||
diff --git a/target/riscv/cpu_cfg_fields.h.inc b/target/riscv/cpu_cfg_fields.h.inc
index 59f134a419..baedf0c466 100644
--- a/target/riscv/cpu_cfg_fields.h.inc
+++ b/target/riscv/cpu_cfg_fields.h.inc
@@ -145,6 +145,7 @@ BOOL_FIELD(ext_xtheadmemidx)
BOOL_FIELD(ext_xtheadmempair)
BOOL_FIELD(ext_xtheadsync)
BOOL_FIELD(ext_XVentanaCondOps)
+BOOL_FIELD(ext_xmipscmov)
BOOL_FIELD(mmu)
BOOL_FIELD(pmp)
diff --git a/target/riscv/insn_trans/trans_xmips.c.inc b/target/riscv/insn_trans/trans_xmips.c.inc
new file mode 100644
index 0000000000..f5aeacc6fd
--- /dev/null
+++ b/target/riscv/insn_trans/trans_xmips.c.inc
@@ -0,0 +1,44 @@
+/*
+ * RISC-V translation routines for the MIPS extensions (xmips*).
+ *
+ * Copyright (c) 2025 MIPS
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2.1 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Reference: MIPS P8700 instructions
+ * (https://mips.com/products/hardware/p8700/)
+ */
+
+#define REQUIRE_XMIPSCMOV(ctx) do { \
+ if (!ctx->cfg_ptr->ext_xmipscmov) { \
+ return false; \
+ } \
+} while (0)
+
+static bool trans_ccmov(DisasContext *ctx, arg_ccmov *a)
+{
+ REQUIRE_XMIPSCMOV(ctx);
+
+ TCGv zero, source1, source2, source3;
+ zero = tcg_constant_tl(0);
+ source1 = get_gpr(ctx, a->rs1, EXT_NONE);
+ source2 = get_gpr(ctx, a->rs2, EXT_NONE);
+ source3 = get_gpr(ctx, a->rs3, EXT_NONE);
+
+ tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[a->rd],
+ source2, zero, source1, source3);
+
+ return true;
+}
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index fbb6c8fb45..26cd11ec00 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -4,6 +4,7 @@ gen = [
decodetree.process('insn32.decode', extra_args: '--static-decode=decode_insn32'),
decodetree.process('xthead.decode', extra_args: '--static-decode=decode_xthead'),
decodetree.process('XVentanaCondOps.decode', extra_args: '--static-decode=decode_XVentanaCodeOps'),
+ decodetree.process('xmips.decode', extra_args: '--static-decode=decode_xmips'),
]
riscv_ss = ss.source_set()
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index d7a6de02df..a6713b78a1 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1194,8 +1194,10 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
#include "insn_trans/trans_svinval.c.inc"
#include "insn_trans/trans_rvbf16.c.inc"
#include "decode-xthead.c.inc"
+#include "decode-xmips.c.inc"
#include "insn_trans/trans_xthead.c.inc"
#include "insn_trans/trans_xventanacondops.c.inc"
+#include "insn_trans/trans_xmips.c.inc"
/* Include the auto-generated decoder for 16 bit insn */
#include "decode-insn16.c.inc"
@@ -1211,6 +1213,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
const RISCVDecoder decoder_table[] = {
{ always_true_p, decode_insn32 },
+ { has_xmips_p, decode_xmips},
{ has_xthead_p, decode_xthead},
{ has_XVentanaCondOps_p, decode_XVentanaCodeOps},
};
diff --git a/target/riscv/xmips.decode b/target/riscv/xmips.decode
new file mode 100644
index 0000000000..cb334fa4bd
--- /dev/null
+++ b/target/riscv/xmips.decode
@@ -0,0 +1,11 @@
+#
+# RISC-V translation routines for the MIPS extension
+#
+# Copyright (c) 2025 MIPS
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# Reference: MIPS P8700 instructions
+# (https://mips.com/products/hardware/p8700/)
+
+ccmov rs3:5 11 rs2:5 rs1:5 011 rd:5 0001011
--
2.34.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v6 08/14] hw/misc: Add RISC-V CMGCR device implementation
2025-07-17 9:38 [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
` (5 preceding siblings ...)
2025-07-17 9:38 ` [PATCH v6 06/14] target/riscv: Add mips.pref instruction Djordje Todorovic
@ 2025-07-17 9:38 ` Djordje Todorovic
2025-08-08 16:00 ` Philippe Mathieu-Daudé
2025-08-08 16:05 ` Philippe Mathieu-Daudé
2025-07-17 9:38 ` [PATCH v6 09/14] hw/misc: Add RISC-V CPC " Djordje Todorovic
` (9 subsequent siblings)
16 siblings, 2 replies; 44+ messages in thread
From: Djordje Todorovic @ 2025-07-17 9:38 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com,
philmd@linaro.org, Djordje Todorovic
Add RISC-V implementation of the Coherent Manager Global Control
Register (CMGCR) device. It is based on the existing MIPS CMGCR
implementation but adapted for RISC-V systems.
The CMGCR device provides global system control for multi-core
configurations in RISC-V systems.
This is needed for the MIPS BOSTON AIA board.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
---
hw/misc/Kconfig | 10 ++
hw/misc/meson.build | 2 +
hw/misc/riscv_cmgcr.c | 234 ++++++++++++++++++++++++++++++++++
include/hw/misc/riscv_cmgcr.h | 49 +++++++
4 files changed, 295 insertions(+)
create mode 100644 hw/misc/riscv_cmgcr.c
create mode 100644 include/hw/misc/riscv_cmgcr.h
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index ec0fa5aa9f..e3fce37c01 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -108,6 +108,16 @@ config STM32L4X5_RCC
config MIPS_ITU
bool
+config RISCV_CMGCR
+ bool
+ default n
+
+config MIPS_BOSTON_AIA
+ bool
+ default y
+ depends on RISCV64
+ select RISCV_CMGCR
+
config MPS2_FPGAIO
bool
select LED
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 6d47de482c..29c573f7ae 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -153,6 +153,8 @@ specific_ss.add(when: 'CONFIG_MAC_VIA', if_true: files('mac_via.c'))
specific_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_cmgcr.c', 'mips_cpc.c'))
specific_ss.add(when: 'CONFIG_MIPS_ITU', if_true: files('mips_itu.c'))
+specific_ss.add(when: 'CONFIG_RISCV_CMGCR', if_true: files('riscv_cmgcr.c'))
+
system_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa_ec.c'))
# HPPA devices
diff --git a/hw/misc/riscv_cmgcr.c b/hw/misc/riscv_cmgcr.c
new file mode 100644
index 0000000000..45d7a0f1ba
--- /dev/null
+++ b/hw/misc/riscv_cmgcr.c
@@ -0,0 +1,234 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
+ * Authors: Sanjay Lal <sanjayl@kymasys.com>
+ *
+ * Copyright (C) 2015 Imagination Technologies
+ *
+ * Copyright (C) 2025 MIPS
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "hw/sysbus.h"
+#include "migration/vmstate.h"
+#include "hw/misc/riscv_cmgcr.h"
+#include "hw/misc/riscv_cpc.h"
+#include "hw/qdev-properties.h"
+
+#include "cpu.h"
+
+#define CM_RESET_VEC 0x1FC00000
+#define GCR_ADDRSPACE_SZ 0x8000
+
+/* Offsets to register blocks */
+#define RISCV_GCB_OFS 0x0000 /* Global Control Block */
+#define RISCV_CLCB_OFS 0x2000 /* Core Control Block */
+#define RISCV_CORE_REG_STRIDE 0x100 /* Stride between core-specific registers */
+
+/* Global Control Block Register Map */
+#define GCR_CONFIG_OFS 0x0000
+#define GCR_BASE_OFS 0x0008
+#define GCR_REV_OFS 0x0030
+#define GCR_CPC_STATUS_OFS 0x00F0
+#define GCR_L2_CONFIG_OFS 0x0130
+
+/* GCR_L2_CONFIG register fields */
+#define GCR_L2_CONFIG_BYPASS_SHF 20
+#define GCR_L2_CONFIG_BYPASS_MSK ((0x1ULL) << GCR_L2_CONFIG_BYPASS_SHF)
+
+/* GCR_BASE register fields */
+#define GCR_BASE_GCRBASE_MSK 0xffffffff8000ULL
+
+/* GCR_CPC_BASE register fields */
+#define GCR_CPC_BASE_CPCEN_MSK 1
+#define GCR_CPC_BASE_CPCBASE_MSK 0xFFFFFFFF8000ULL
+#define GCR_CPC_BASE_MSK (GCR_CPC_BASE_CPCEN_MSK | GCR_CPC_BASE_CPCBASE_MSK)
+
+/* GCR_CL_RESETBASE_OFS register fields */
+#define GCR_CL_RESET_BASE_RESETBASE_MSK 0xFFFFFFFFFFFFF000U
+#define GCR_CL_RESET_BASE_MSK GCR_CL_RESET_BASE_RESETBASE_MSK
+
+static inline bool is_cpc_connected(RISCVGCRState *s)
+{
+ return s->cpc_mr != NULL;
+}
+
+static inline void update_cpc_base(RISCVGCRState *gcr, uint64_t val)
+{
+ if (is_cpc_connected(gcr)) {
+ gcr->cpc_base = val & GCR_CPC_BASE_MSK;
+ memory_region_transaction_begin();
+ memory_region_set_address(gcr->cpc_mr,
+ gcr->cpc_base & GCR_CPC_BASE_CPCBASE_MSK);
+ memory_region_set_enabled(gcr->cpc_mr,
+ gcr->cpc_base & GCR_CPC_BASE_CPCEN_MSK);
+ memory_region_transaction_commit();
+ }
+}
+
+static inline void update_gcr_base(RISCVGCRState *gcr, uint64_t val)
+{
+ gcr->gcr_base = val & GCR_BASE_GCRBASE_MSK;
+ memory_region_set_address(&gcr->iomem, gcr->gcr_base);
+
+ /* For boston-aia, cpc_base is set to gcr_base + 0x8001 to enable
+ cpc automatically. */
+ update_cpc_base(gcr, val + 0x8001);
+}
+
+/* Read GCR registers */
+static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size)
+{
+ RISCVGCRState *gcr = (RISCVGCRState *) opaque;
+
+ switch (addr) {
+ /* Global Control Block Register */
+ case GCR_CONFIG_OFS:
+ /* Set PCORES to 0 */
+ return 0;
+ case GCR_BASE_OFS:
+ return gcr->gcr_base;
+ case GCR_REV_OFS:
+ return gcr->gcr_rev;
+ case GCR_CPC_STATUS_OFS:
+ return is_cpc_connected(gcr);
+ case GCR_L2_CONFIG_OFS:
+ /* L2 BYPASS */
+ return GCR_L2_CONFIG_BYPASS_MSK;
+ default:
+ qemu_log_mask(LOG_UNIMP, "Read %d bytes at GCR offset 0x%" HWADDR_PRIx
+ "\n", size, addr);
+ }
+ return 0;
+}
+
+static inline target_ulong get_exception_base(RISCVGCRVPState *vps)
+{
+ return vps->reset_base & GCR_CL_RESET_BASE_RESETBASE_MSK;
+}
+
+/* Write GCR registers */
+static void gcr_write(void *opaque, hwaddr addr, uint64_t data, unsigned size)
+{
+ RISCVGCRState *gcr = (RISCVGCRState *)opaque;
+ RISCVGCRVPState *current_vps;
+ int cpu_index, c, h;
+
+ for (c = 0; c < gcr->num_core; c++) {
+ for (h = 0; h < gcr->num_hart; h++) {
+ if (addr == RISCV_CLCB_OFS + c * RISCV_CORE_REG_STRIDE + h * 8) {
+ cpu_index = c * gcr->num_hart + h;
+ current_vps = &gcr->vps[cpu_index];
+ current_vps->reset_base = data & GCR_CL_RESET_BASE_MSK;
+ cpu_set_exception_base(cpu_index + gcr->cluster_id *
+ gcr->num_core * gcr->num_hart,
+ get_exception_base(current_vps));
+ return;
+ }
+ }
+ }
+
+ switch (addr) {
+ case GCR_BASE_OFS:
+ update_gcr_base(gcr, data);
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "Write %d bytes at GCR offset 0x%" HWADDR_PRIx
+ " 0x%" PRIx64 "\n", size, addr, data);
+ break;
+ }
+}
+
+static const MemoryRegionOps gcr_ops = {
+ .read = gcr_read,
+ .write = gcr_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .impl = {
+ .max_access_size = 8,
+ },
+};
+
+static void riscv_gcr_init(Object *obj)
+{
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+ RISCVGCRState *s = RISCV_GCR(obj);
+
+ memory_region_init_io(&s->iomem, OBJECT(s), &gcr_ops, s,
+ "riscv-gcr", GCR_ADDRSPACE_SZ);
+ sysbus_init_mmio(sbd, &s->iomem);
+}
+
+static void riscv_gcr_reset(DeviceState *dev)
+{
+ RISCVGCRState *s = RISCV_GCR(dev);
+ int i;
+
+ /* Update cpc_base to gcr_base + 0x8001 to enable cpc automatically. */
+ update_cpc_base(s, s->gcr_base + 0x8001);
+
+ for (i = 0; i < s->num_vps; i++) {
+ s->vps[i].reset_base = CM_RESET_VEC & GCR_CL_RESET_BASE_MSK;
+ cpu_set_exception_base(i, get_exception_base(&s->vps[i]));
+ }
+}
+
+static const VMStateDescription vmstate_riscv_gcr = {
+ .name = "riscv-gcr",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT64(cpc_base, RISCVGCRState),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
+static const Property riscv_gcr_properties[] = {
+ DEFINE_PROP_UINT32("cluster-id", RISCVGCRState, cluster_id, 0),
+ DEFINE_PROP_UINT32("num-vp", RISCVGCRState, num_vps, 1),
+ DEFINE_PROP_UINT32("num-hart", RISCVGCRState, num_hart, 1),
+ DEFINE_PROP_UINT32("num-core", RISCVGCRState, num_core, 1),
+ DEFINE_PROP_INT32("gcr-rev", RISCVGCRState, gcr_rev, 0xa00),
+ DEFINE_PROP_UINT64("gcr-base", RISCVGCRState, gcr_base, GCR_BASE_ADDR),
+ DEFINE_PROP_LINK("cpc", RISCVGCRState, cpc_mr, TYPE_MEMORY_REGION,
+ MemoryRegion *),
+};
+
+static void riscv_gcr_realize(DeviceState *dev, Error **errp)
+{
+ RISCVGCRState *s = RISCV_GCR(dev);
+
+ /* Create local set of registers for each VP */
+ s->vps = g_new(RISCVGCRVPState, s->num_vps);
+}
+
+static void riscv_gcr_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ device_class_set_props(dc, riscv_gcr_properties);
+ dc->vmsd = &vmstate_riscv_gcr;
+ device_class_set_legacy_reset(dc, riscv_gcr_reset);
+ dc->realize = riscv_gcr_realize;
+}
+
+static const TypeInfo riscv_gcr_info = {
+ .name = TYPE_RISCV_GCR,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(RISCVGCRState),
+ .instance_init = riscv_gcr_init,
+ .class_init = riscv_gcr_class_init,
+};
+
+static void riscv_gcr_register_types(void)
+{
+ type_register_static(&riscv_gcr_info);
+}
+
+type_init(riscv_gcr_register_types)
diff --git a/include/hw/misc/riscv_cmgcr.h b/include/hw/misc/riscv_cmgcr.h
new file mode 100644
index 0000000000..f6c2073293
--- /dev/null
+++ b/include/hw/misc/riscv_cmgcr.h
@@ -0,0 +1,49 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2015 Imagination Technologies
+ *
+ * Copyright (C) 2025 MIPS
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ */
+
+#ifndef RISCV_CMGCR_H
+#define RISCV_CMGCR_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define TYPE_RISCV_GCR "riscv-gcr"
+OBJECT_DECLARE_SIMPLE_TYPE(RISCVGCRState, RISCV_GCR)
+
+#define GCR_BASE_ADDR 0x1fb80000ULL
+
+typedef struct RISCVGCRVPState RISCVGCRVPState;
+struct RISCVGCRVPState {
+ uint64_t reset_base;
+};
+
+typedef struct RISCVGCRState RISCVGCRState;
+struct RISCVGCRState {
+ SysBusDevice parent_obj;
+
+ int32_t gcr_rev;
+ uint32_t cluster_id;
+ uint32_t num_vps;
+ uint32_t num_hart;
+ uint32_t num_core;
+ hwaddr gcr_base;
+ MemoryRegion iomem;
+ MemoryRegion *cpc_mr;
+
+ uint64_t cpc_base;
+
+ /* VP Local/Other Registers */
+ RISCVGCRVPState *vps;
+};
+
+#endif /* RISCV_CMGCR_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v6 07/14] target/riscv: Add Xmipslsp instructions
2025-07-17 9:38 [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
` (7 preceding siblings ...)
2025-07-17 9:38 ` [PATCH v6 09/14] hw/misc: Add RISC-V CPC " Djordje Todorovic
@ 2025-07-17 9:38 ` Djordje Todorovic
2025-08-08 16:02 ` Philippe Mathieu-Daudé
2025-07-17 9:38 ` [PATCH v6 10/14] hw/riscv: Add support for RISCV CPS Djordje Todorovic
` (7 subsequent siblings)
16 siblings, 1 reply; 44+ messages in thread
From: Djordje Todorovic @ 2025-07-17 9:38 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com,
philmd@linaro.org, Djordje Todorovic
Add MIPS P8700 ldp, lwp, sdp, swp instructions.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
---
target/riscv/cpu.c | 3 +
target/riscv/cpu_cfg.h | 2 +-
target/riscv/cpu_cfg_fields.h.inc | 1 +
target/riscv/insn_trans/trans_xmips.c.inc | 84 +++++++++++++++++++++++
target/riscv/xmips.decode | 23 +++++++
5 files changed, 112 insertions(+), 1 deletion(-)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d280648b55..fcaee6628e 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -245,6 +245,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
ISA_EXT_DATA_ENTRY(svvptc, PRIV_VERSION_1_13_0, ext_svvptc),
ISA_EXT_DATA_ENTRY(xmipscbop, PRIV_VERSION_1_12_0, ext_xmipscbop),
ISA_EXT_DATA_ENTRY(xmipscmov, PRIV_VERSION_1_12_0, ext_xmipscmov),
+ ISA_EXT_DATA_ENTRY(xmipslsp, PRIV_VERSION_1_12_0, ext_xmipslsp),
ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba),
ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb),
ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs),
@@ -1377,6 +1378,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
MULTI_EXT_CFG_BOOL("xventanacondops", ext_XVentanaCondOps, false),
MULTI_EXT_CFG_BOOL("xmipscbop", ext_xmipscbop, false),
MULTI_EXT_CFG_BOOL("xmipscmov", ext_xmipscmov, false),
+ MULTI_EXT_CFG_BOOL("xmipslsp", ext_xmipslsp, false),
{ },
};
@@ -3195,6 +3197,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
.cfg.pmp = true,
.cfg.ext_zba = true,
.cfg.ext_zbb = true,
+ .cfg.ext_xmipslsp = true,
.cfg.ext_xmipscbop = true,
.cfg.ext_xmipscmov = true,
.cfg.marchid = 0x8000000000000201,
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index 9734963035..f35d477f27 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -39,7 +39,7 @@ static inline bool always_true_p(const RISCVCPUConfig *cfg __attribute__((__unus
static inline bool has_xmips_p(const RISCVCPUConfig *cfg)
{
- return cfg->ext_xmipscbop || cfg->ext_xmipscmov;
+ return cfg->ext_xmipscbop || cfg->ext_xmipscmov || cfg->ext_xmipslsp;
}
static inline bool has_xthead_p(const RISCVCPUConfig *cfg)
diff --git a/target/riscv/cpu_cfg_fields.h.inc b/target/riscv/cpu_cfg_fields.h.inc
index 9ee0a099bb..b5195959b2 100644
--- a/target/riscv/cpu_cfg_fields.h.inc
+++ b/target/riscv/cpu_cfg_fields.h.inc
@@ -147,6 +147,7 @@ BOOL_FIELD(ext_xtheadsync)
BOOL_FIELD(ext_XVentanaCondOps)
BOOL_FIELD(ext_xmipscbop)
BOOL_FIELD(ext_xmipscmov)
+BOOL_FIELD(ext_xmipslsp)
BOOL_FIELD(mmu)
BOOL_FIELD(pmp)
diff --git a/target/riscv/insn_trans/trans_xmips.c.inc b/target/riscv/insn_trans/trans_xmips.c.inc
index 620c59cc28..d0c1c9fd19 100644
--- a/target/riscv/insn_trans/trans_xmips.c.inc
+++ b/target/riscv/insn_trans/trans_xmips.c.inc
@@ -33,6 +33,12 @@
} \
} while (0)
+#define REQUIRE_XMIPSLSP(ctx) do { \
+ if (!ctx->cfg_ptr->ext_xmipslsp) { \
+ return false; \
+ } \
+} while (0)
+
static bool trans_ccmov(DisasContext *ctx, arg_ccmov *a)
{
REQUIRE_XMIPSCMOV(ctx);
@@ -49,6 +55,84 @@ static bool trans_ccmov(DisasContext *ctx, arg_ccmov *a)
return true;
}
+static bool trans_ldp(DisasContext *ctx, arg_ldp *a)
+{
+ REQUIRE_XMIPSLSP(ctx);
+ REQUIRE_64_OR_128BIT(ctx);
+
+ TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
+ TCGv dest0 = dest_gpr(ctx, a->rd);
+ TCGv dest1 = dest_gpr(ctx, a->rs3);
+ TCGv addr = tcg_temp_new();
+
+ tcg_gen_addi_tl(addr, src, a->imm_y);
+ tcg_gen_qemu_ld_tl(dest0, addr, ctx->mem_idx, MO_TESQ);
+ gen_set_gpr(ctx, a->rd, dest0);
+
+ tcg_gen_addi_tl(addr, addr, 8);
+ tcg_gen_qemu_ld_tl(dest1, addr, ctx->mem_idx, MO_TESQ);
+ gen_set_gpr(ctx, a->rs3, dest1);
+
+ return true;
+}
+
+static bool trans_lwp(DisasContext *ctx, arg_lwp *a)
+{
+ REQUIRE_XMIPSLSP(ctx);
+
+ TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
+ TCGv dest0 = dest_gpr(ctx, a->rd);
+ TCGv dest1 = dest_gpr(ctx, a->rs3);
+ TCGv addr = tcg_temp_new();
+
+ tcg_gen_addi_tl(addr, src, a->imm_x);
+ tcg_gen_qemu_ld_tl(dest0, addr, ctx->mem_idx, MO_TESL);
+ gen_set_gpr(ctx, a->rd, dest0);
+
+ tcg_gen_addi_tl(addr, addr, 4);
+ tcg_gen_qemu_ld_tl(dest1, addr, ctx->mem_idx, MO_TESL);
+ gen_set_gpr(ctx, a->rs3, dest1);
+
+ return true;
+}
+
+static bool trans_sdp(DisasContext *ctx, arg_sdp *a)
+{
+ REQUIRE_XMIPSLSP(ctx);
+ REQUIRE_64_OR_128BIT(ctx);
+
+ TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
+ TCGv data0 = get_gpr(ctx, a->rs2, EXT_NONE);
+ TCGv data1 = get_gpr(ctx, a->rs3, EXT_NONE);
+ TCGv addr = tcg_temp_new();
+
+ tcg_gen_addi_tl(addr, src, a->imm_w);
+ tcg_gen_qemu_st_tl(data0, addr, ctx->mem_idx, MO_TEUQ);
+
+ tcg_gen_addi_tl(addr, addr, 8);
+ tcg_gen_qemu_st_tl(data1, addr, ctx->mem_idx, MO_TEUQ);
+
+ return true;
+}
+
+static bool trans_swp(DisasContext *ctx, arg_swp *a)
+{
+ REQUIRE_XMIPSLSP(ctx);
+
+ TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
+ TCGv data0 = get_gpr(ctx, a->rs2, EXT_NONE);
+ TCGv data1 = get_gpr(ctx, a->rs3, EXT_NONE);
+ TCGv addr = tcg_temp_new();
+
+ tcg_gen_addi_tl(addr, src, a->imm_v);
+ tcg_gen_qemu_st_tl(data0, addr, ctx->mem_idx, MO_TESL);
+
+ tcg_gen_addi_tl(addr, addr, 4);
+ tcg_gen_qemu_st_tl(data1, addr, ctx->mem_idx, MO_TESL);
+
+ return true;
+}
+
static bool trans_pref(DisasContext *ctx, arg_pref *a)
{
REQUIRE_XMIPSCBOP(ctx);
diff --git a/target/riscv/xmips.decode b/target/riscv/xmips.decode
index 697bf26c26..99c98d4084 100644
--- a/target/riscv/xmips.decode
+++ b/target/riscv/xmips.decode
@@ -8,5 +8,28 @@
# Reference: MIPS P8700 instructions
# (https://mips.com/products/hardware/p8700/)
+# Fields
+%rs3 27:5
+%rs2 20:5
+%rs1 15:5
+%rd 7:5
+%imm_9 20:9
+%imm_hint 7:5
+%imm_v 25:2 9:3 !function=ex_shift_2
+%imm_w 25:2 10:2 !function=ex_shift_3
+%imm_x 22:5 !function=ex_shift_2
+%imm_y 23:4 !function=ex_shift_3
+
+# Formats
+@r4_immv ..... .. ..... ..... ... ... .. ....... %rs2 %rs3 %imm_v %rs1
+@r4_immw ..... .. ..... ..... ... .. ... ....... %rs2 %rs3 %imm_w %rs1
+@r4_immx ..... ..... .. ..... ... ..... ....... %rs3 %imm_x %rs1 %rd
+@r4_immy ..... .... ... ..... ... ..... ....... %rs3 %imm_y %rs1 %rd
+
+# *** RV64 MIPS Extension ***
ccmov rs3:5 11 rs2:5 rs1:5 011 rd:5 0001011
pref 000 imm_9:9 rs1:5 000 imm_hint:5 0001011
+ldp ..... .... 000 ..... 100 ..... 0001011 @r4_immy
+lwp ..... ..... 01 ..... 100 ..... 0001011 @r4_immx
+sdp ..... .. ..... ..... 101 .. 0000001011 @r4_immw
+swp ..... .. ..... ..... 101 ... 010001011 @r4_immv
--
2.34.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v6 09/14] hw/misc: Add RISC-V CPC device implementation
2025-07-17 9:38 [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
` (6 preceding siblings ...)
2025-07-17 9:38 ` [PATCH v6 08/14] hw/misc: Add RISC-V CMGCR device implementation Djordje Todorovic
@ 2025-07-17 9:38 ` Djordje Todorovic
2025-08-08 16:21 ` Philippe Mathieu-Daudé
2025-07-17 9:38 ` [PATCH v6 07/14] target/riscv: Add Xmipslsp instructions Djordje Todorovic
` (8 subsequent siblings)
16 siblings, 1 reply; 44+ messages in thread
From: Djordje Todorovic @ 2025-07-17 9:38 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com,
philmd@linaro.org, Djordje Todorovic
Add RISC-V implementation of the Cluster Power Controller (CPC) device.
It is based on the existing MIPS CPC implementations but adapted for
RISC-V systems.
The CPC device manages power control for CPU clusters in RISC-V
systems.
This is needed for the MIPS BOSTON AIA board.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
---
hw/misc/Kconfig | 5 +
hw/misc/meson.build | 1 +
hw/misc/riscv_cpc.c | 239 ++++++++++++++++++++++++++++++++++++
include/hw/misc/riscv_cpc.h | 73 +++++++++++
4 files changed, 318 insertions(+)
create mode 100644 hw/misc/riscv_cpc.c
create mode 100644 include/hw/misc/riscv_cpc.h
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index e3fce37c01..fe166e08bc 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -112,11 +112,16 @@ config RISCV_CMGCR
bool
default n
+config RISCV_CPC
+ bool
+ default n
+
config MIPS_BOSTON_AIA
bool
default y
depends on RISCV64
select RISCV_CMGCR
+ select RISCV_CPC
config MPS2_FPGAIO
bool
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 29c573f7ae..8a4d0c3ee1 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -154,6 +154,7 @@ specific_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_cmgcr.c', 'mips_cp
specific_ss.add(when: 'CONFIG_MIPS_ITU', if_true: files('mips_itu.c'))
specific_ss.add(when: 'CONFIG_RISCV_CMGCR', if_true: files('riscv_cmgcr.c'))
+specific_ss.add(when: 'CONFIG_RISCV_CPC', if_true: files('riscv_cpc.c'))
system_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa_ec.c'))
diff --git a/hw/misc/riscv_cpc.c b/hw/misc/riscv_cpc.c
new file mode 100644
index 0000000000..424562d7be
--- /dev/null
+++ b/hw/misc/riscv_cpc.c
@@ -0,0 +1,239 @@
+/*
+ * Cluster Power Controller emulation
+ *
+ * Copyright (c) 2016 Imagination Technologies
+ *
+ * Copyright (c) 2025 MIPS
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/timer.h"
+#include "hw/sysbus.h"
+#include "migration/vmstate.h"
+
+#include "hw/misc/riscv_cpc.h"
+#include "hw/qdev-properties.h"
+#include "hw/intc/riscv_aclint.h"
+#include "hw/resettable.h"
+
+static inline uint64_t cpc_vp_run_mask(RISCVCPCState *cpc)
+{
+ if (cpc->num_vp == 64) {
+ return 0xffffffffffffffff;
+ }
+ return (1ULL << cpc->num_vp) - 1;
+}
+
+static void riscv_cpu_reset_async_work(CPUState *cs, run_on_cpu_data data)
+{
+ RISCVCPCState *cpc = (RISCVCPCState *) data.host_ptr;
+ int i;
+
+ cpu_reset(cs);
+ cs->halted = 0;
+
+ /* Find this CPU's index in the CPC's CPU array */
+ for (i = 0; i < cpc->num_vp; i++) {
+ if (cpc->cpus[i] == cs) {
+ cpc->vp_running |= 1ULL << i;
+ break;
+ }
+ }
+}
+
+static void cpc_run_vp(RISCVCPCState *cpc, uint64_t vp_run)
+{
+ int i;
+
+ for (i = 0; i < cpc->num_vp; i++) {
+ CPUState *cs = cpc->cpus[i];
+ uint64_t mask = 1ULL << i;
+ if (mask & vp_run & ~cpc->vp_running) {
+ /*
+ * To avoid racing with a CPU we are just kicking off.
+ * We do the final bit of preparation for the work in
+ * the target CPUs context.
+ */
+ async_safe_run_on_cpu(cs, riscv_cpu_reset_async_work,
+ RUN_ON_CPU_HOST_PTR(cpc));
+ }
+ }
+}
+
+static void cpc_stop_vp(RISCVCPCState *cpc, uint64_t vp_stop)
+{
+ int i;
+
+ for (i = 0; i < cpc->num_vp; i++) {
+ CPUState *cs = cpc->cpus[i];
+ uint64_t mask = 1ULL << i;
+ if (mask & vp_stop & cpc->vp_running) {
+ cpu_interrupt(cs, CPU_INTERRUPT_HALT);
+ cpc->vp_running &= ~mask;
+ }
+ }
+}
+
+static void cpc_write(void *opaque, hwaddr offset, uint64_t data,
+ unsigned size)
+{
+ RISCVCPCState *s = opaque;
+ int cpu_index, c;
+
+ for (c = 0; c < s->num_core; c++) {
+ cpu_index = c * s->num_hart +
+ s->cluster_id * s->num_core * s->num_hart;
+ if (offset == CPC_CL_BASE_OFS + CPC_VP_RUN_OFS + c * CPC_CORE_REG_STRIDE) {
+ cpc_run_vp(s, (data << cpu_index) & cpc_vp_run_mask(s));
+ return;
+ }
+ if (offset == CPC_CL_BASE_OFS + CPC_VP_STOP_OFS + c * CPC_CORE_REG_STRIDE) {
+ cpc_stop_vp(s, (data << cpu_index) & cpc_vp_run_mask(s));
+ return;
+ }
+ }
+
+ switch (offset) {
+ default:
+ qemu_log_mask(LOG_UNIMP,
+ "%s: Bad offset 0x%x\n", __func__, (int)offset);
+ break;
+ }
+
+ return;
+}
+
+static uint64_t cpc_read(void *opaque, hwaddr offset, unsigned size)
+{
+ RISCVCPCState *s = opaque;
+ int c;
+
+ for (c = 0; c < s->num_core; c++) {
+ if (offset == CPC_CL_BASE_OFS + CPC_STAT_CONF_OFS + c * CPC_CORE_REG_STRIDE) {
+ /* Return the state as U6. */
+ return CPC_Cx_STAT_CONF_SEQ_STATE_U6;
+ }
+ }
+
+ switch (offset) {
+ case CPC_CM_STAT_CONF_OFS:
+ return CPC_Cx_STAT_CONF_SEQ_STATE_U5;
+ case CPC_MTIME_REG_OFS:
+ return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
+ RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ,
+ NANOSECONDS_PER_SECOND);
+ return 0;
+ default:
+ qemu_log_mask(LOG_UNIMP,
+ "%s: Bad offset 0x%x\n", __func__, (int)offset);
+ return 0;
+ }
+}
+
+static const MemoryRegionOps cpc_ops = {
+ .read = cpc_read,
+ .write = cpc_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .impl = {
+ .min_access_size = 4,
+ .max_access_size = 8,
+ },
+};
+
+static void riscv_cpc_init(Object *obj)
+{
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+ RISCVCPCState *s = RISCV_CPC(obj);
+
+ memory_region_init_io(&s->mr, OBJECT(s), &cpc_ops, s, "xmips-cpc",
+ CPC_ADDRSPACE_SZ);
+ sysbus_init_mmio(sbd, &s->mr);
+}
+
+static void riscv_cpc_realize(DeviceState *dev, Error **errp)
+{
+ RISCVCPCState *s = RISCV_CPC(dev);
+
+ if (s->vp_start_running > cpc_vp_run_mask(s)) {
+ error_setg(errp,
+ "incorrect vp_start_running 0x%" PRIx64 " for num_vp = %d",
+ s->vp_running, s->num_vp);
+ return;
+ }
+}
+
+static void riscv_cpc_reset_hold(Object *obj, ResetType type)
+{
+ RISCVCPCState *s = RISCV_CPC(obj);
+
+ /* Reflect the fact that all VPs are halted on reset */
+ s->vp_running = 0;
+
+ /* Put selected VPs into run state */
+ cpc_run_vp(s, s->vp_start_running);
+}
+
+static const VMStateDescription vmstate_riscv_cpc = {
+ .name = "xmips-cpc",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT64(vp_running, RISCVCPCState),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
+static const Property riscv_cpc_properties[] = {
+ DEFINE_PROP_UINT32("cluster-id", RISCVCPCState, cluster_id, 0x0),
+ DEFINE_PROP_UINT32("num-vp", RISCVCPCState, num_vp, 0x1),
+ DEFINE_PROP_UINT32("num-hart", RISCVCPCState, num_hart, 0x1),
+ DEFINE_PROP_UINT32("num-core", RISCVCPCState, num_core, 0x1),
+ DEFINE_PROP_UINT64("vp-start-running", RISCVCPCState, vp_start_running, 0x1),
+};
+
+static void riscv_cpc_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
+
+ dc->realize = riscv_cpc_realize;
+ rc->phases.hold = riscv_cpc_reset_hold;
+ dc->vmsd = &vmstate_riscv_cpc;
+ device_class_set_props(dc, riscv_cpc_properties);
+ dc->user_creatable = false;
+}
+
+static const TypeInfo riscv_cpc_info = {
+ .name = TYPE_RISCV_CPC,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(RISCVCPCState),
+ .instance_init = riscv_cpc_init,
+ .class_init = riscv_cpc_class_init,
+};
+
+static void riscv_cpc_register_types(void)
+{
+ type_register_static(&riscv_cpc_info);
+}
+
+type_init(riscv_cpc_register_types)
diff --git a/include/hw/misc/riscv_cpc.h b/include/hw/misc/riscv_cpc.h
new file mode 100644
index 0000000000..013d95fcc2
--- /dev/null
+++ b/include/hw/misc/riscv_cpc.h
@@ -0,0 +1,73 @@
+/*
+ * Cluster Power Controller emulation
+ *
+ * Copyright (c) 2016 Imagination Technologies
+ *
+ * Copyright (c) 2025 MIPS
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ */
+
+#ifndef RISCV_CPC_H
+#define RISCV_CPC_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define CPC_ADDRSPACE_SZ 0x6000
+
+/* CPC global register offsets relative to base address */
+#define CPC_MTIME_REG_OFS 0x50
+
+#define CPC_CM_STAT_CONF_OFS 0x1008
+
+/* CPC blocks offsets relative to base address */
+#define CPC_CL_BASE_OFS 0x2000
+#define CPC_CORE_REG_STRIDE 0x100 /* Stride between core-specific registers */
+
+/* CPC register offsets relative to block offsets */
+#define CPC_STAT_CONF_OFS 0x08
+#define CPC_VP_STOP_OFS 0x20
+#define CPC_VP_RUN_OFS 0x28
+#define CPC_VP_RUNNING_OFS 0x30
+
+#define SEQ_STATE_BIT 19
+#define SEQ_STATE_U5 0x6
+#define SEQ_STATE_U6 0x7
+#define CPC_Cx_STAT_CONF_SEQ_STATE_U5 (SEQ_STATE_U5 << SEQ_STATE_BIT)
+#define CPC_Cx_STAT_CONF_SEQ_STATE_U6 (SEQ_STATE_U6 << SEQ_STATE_BIT)
+
+#define TYPE_RISCV_CPC "xmips-cpc"
+OBJECT_DECLARE_SIMPLE_TYPE(RISCVCPCState, RISCV_CPC)
+
+typedef struct RISCVCPCState {
+ SysBusDevice parent_obj;
+
+ uint32_t cluster_id;
+ uint32_t num_vp;
+ uint32_t num_hart;
+ uint32_t num_core;
+ uint64_t vp_start_running; /* VPs running from restart */
+
+ MemoryRegion mr;
+ uint64_t vp_running; /* Indicates which VPs are in the run state */
+
+ /* Array of CPUs managed by this CPC */
+ CPUState **cpus;
+} RISCVCPCState;
+
+#endif /* RISCV_CPC_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v6 10/14] hw/riscv: Add support for RISCV CPS
2025-07-17 9:38 [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
` (8 preceding siblings ...)
2025-07-17 9:38 ` [PATCH v6 07/14] target/riscv: Add Xmipslsp instructions Djordje Todorovic
@ 2025-07-17 9:38 ` Djordje Todorovic
2025-08-08 16:26 ` Philippe Mathieu-Daudé
2025-07-17 9:38 ` [PATCH v6 11/14] hw/riscv: Add support for MIPS Boston-aia board mode Djordje Todorovic
` (6 subsequent siblings)
16 siblings, 1 reply; 44+ messages in thread
From: Djordje Todorovic @ 2025-07-17 9:38 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com,
philmd@linaro.org, Djordje Todorovic
Add support for the Coherent Processing System for RISC-V.
This enables SMP support for RISC-V boards that require
cache-coherent multiprocessor systems.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
---
hw/misc/Kconfig | 5 ++
hw/riscv/cps.c | 197 +++++++++++++++++++++++++++++++++++++++++
hw/riscv/meson.build | 2 +
include/hw/riscv/cps.h | 76 ++++++++++++++++
4 files changed, 280 insertions(+)
create mode 100644 hw/riscv/cps.c
create mode 100644 include/hw/riscv/cps.h
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index fe166e08bc..dac830d2f5 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -116,12 +116,17 @@ config RISCV_CPC
bool
default n
+config RISCV_CPS
+ bool
+ default n
+
config MIPS_BOSTON_AIA
bool
default y
depends on RISCV64
select RISCV_CMGCR
select RISCV_CPC
+ select RISCV_CPS
config MPS2_FPGAIO
bool
diff --git a/hw/riscv/cps.c b/hw/riscv/cps.c
new file mode 100644
index 0000000000..b6439a85d6
--- /dev/null
+++ b/hw/riscv/cps.c
@@ -0,0 +1,197 @@
+/*
+ * Coherent Processing System emulation.
+ *
+ * Copyright (c) 2016 Imagination Technologies
+ *
+ * Copyright (c) 2025 MIPS
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/module.h"
+#include "hw/riscv/cps.h"
+#include "hw/qdev-properties.h"
+#include "system/reset.h"
+#include "hw/intc/riscv_aclint.h"
+#include "hw/intc/riscv_aplic.h"
+#include "hw/intc/riscv_imsic.h"
+#include "hw/pci/msi.h"
+
+static void riscv_cps_init(Object *obj)
+{
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+ RISCVCPSState *s = RISCV_CPS(obj);
+
+ /*
+ * Cover entire address space as there do not seem to be any
+ * constraints for the base address of CPC .
+ */
+ memory_region_init(&s->container, obj, "mips-cps-container", UINT64_MAX);
+ sysbus_init_mmio(sbd, &s->container);
+}
+
+static void main_cpu_reset(void *opaque)
+{
+ RISCVCPU *cpu = opaque;
+ CPUState *cs = CPU(cpu);
+
+ cpu_reset(cs);
+}
+
+static void riscv_cps_realize(DeviceState *dev, Error **errp)
+{
+ RISCVCPSState *s = RISCV_CPS(dev);
+ RISCVCPU *cpu;
+ int i;
+
+ /* Allocate CPU array */
+ s->cpus = g_new0(CPUState *, s->num_vp);
+
+ /* Set up cpu_index and mhartid for avaiable CPUs. */
+ int harts_in_cluster = s->num_hart * s->num_core;
+ int num_of_clusters = s->num_vp / harts_in_cluster;
+ for (i = 0; i < s->num_vp; i++) {
+ cpu = RISCV_CPU(object_new(s->cpu_type));
+
+ /* All VPs are halted on reset. Leave powering up to CPC. */
+ object_property_set_bool(OBJECT(cpu), "start-powered-off", true,
+ &error_abort);
+
+ if (!qdev_realize_and_unref(DEVICE(cpu), NULL, errp)) {
+ return;
+ }
+
+ /* Store CPU in array */
+ s->cpus[i] = CPU(cpu);
+
+ /* Set up mhartid */
+ int cluster_id = i / harts_in_cluster;
+ int hart_id = (i % harts_in_cluster) % s->num_hart;
+ int core_id = (i % harts_in_cluster) / s->num_hart;
+ int mhartid = (cluster_id << MHARTID_CLUSTER_SHIFT) +
+ (core_id << MHARTID_CORE_SHIFT) +
+ (hart_id << MHARTID_HART_SHIFT);
+ cpu->env.mhartid = mhartid;
+ qemu_register_reset(main_cpu_reset, cpu);
+ }
+
+ /* Cluster Power Controller */
+ object_initialize_child(OBJECT(dev), "cpc", &s->cpc, TYPE_RISCV_CPC);
+ object_property_set_uint(OBJECT(&s->cpc), "cluster-id", 0,
+ &error_abort);
+ object_property_set_uint(OBJECT(&s->cpc), "num-vp", s->num_vp,
+ &error_abort);
+ object_property_set_uint(OBJECT(&s->cpc), "num-hart", s->num_hart,
+ &error_abort);
+ object_property_set_uint(OBJECT(&s->cpc), "num-core", s->num_core,
+ &error_abort);
+ object_property_set_int(OBJECT(&s->cpc), "vp-start-running", 1,
+ &error_abort);
+
+ /* Pass CPU array to CPC */
+ s->cpc.cpus = s->cpus;
+
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpc), errp)) {
+ return;
+ }
+
+ memory_region_add_subregion(&s->container, 0,
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpc), 0));
+
+ /* Global Configuration Registers */
+ object_initialize_child(OBJECT(dev), "gcr", &s->gcr, TYPE_RISCV_GCR);
+ object_property_set_uint(OBJECT(&s->gcr), "cluster-id", 0,
+ &error_abort);
+ object_property_set_uint(OBJECT(&s->gcr), "num-vp", s->num_vp,
+ &error_abort);
+ object_property_set_int(OBJECT(&s->gcr), "gcr-rev", 0xa00,
+ &error_abort);
+ object_property_set_int(OBJECT(&s->gcr), "gcr-base", s->gcr_base,
+ &error_abort);
+ object_property_set_link(OBJECT(&s->gcr), "cpc", OBJECT(&s->cpc.mr),
+ &error_abort);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->gcr), errp)) {
+ return;
+ }
+
+ memory_region_add_subregion(&s->container, s->gcr_base,
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gcr), 0));
+
+ for (i = 0; i < num_of_clusters; i++) {
+ uint64_t cm_base = GLOBAL_CM_BASE + (CM_SIZE * i);
+ uint32_t hartid_base = i << MHARTID_CLUSTER_SHIFT;
+ s->aplic = riscv_aplic_create(cm_base + AIA_PLIC_M_OFFSET,
+ AIA_PLIC_M_SIZE,
+ hartid_base, /* hartid_base */
+ MAX_HARTS, /* num_harts */
+ APLIC_NUM_SOURCES,
+ APLIC_NUM_PRIO_BITS,
+ false, true, NULL);
+ riscv_aplic_create(cm_base + AIA_PLIC_S_OFFSET,
+ AIA_PLIC_S_SIZE,
+ hartid_base, /* hartid_base */
+ MAX_HARTS, /* num_harts */
+ APLIC_NUM_SOURCES,
+ APLIC_NUM_PRIO_BITS,
+ false, false, s->aplic);
+ /* PLIC changes msi_nonbroken to ture. We revert the change. */
+ msi_nonbroken = false;
+ riscv_aclint_swi_create(cm_base + AIA_CLINT_OFFSET,
+ hartid_base, MAX_HARTS, false);
+ riscv_aclint_mtimer_create(cm_base + AIA_CLINT_OFFSET +
+ RISCV_ACLINT_SWI_SIZE,
+ RISCV_ACLINT_DEFAULT_MTIMER_SIZE,
+ hartid_base,
+ MAX_HARTS,
+ RISCV_ACLINT_DEFAULT_MTIMECMP,
+ RISCV_ACLINT_DEFAULT_MTIME,
+ RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, false);
+ }
+}
+
+static const Property riscv_cps_properties[] = {
+ DEFINE_PROP_UINT32("num-vp", RISCVCPSState, num_vp, 1),
+ DEFINE_PROP_UINT32("num-hart", RISCVCPSState, num_hart, 1),
+ DEFINE_PROP_UINT32("num-core", RISCVCPSState, num_core, 1),
+ DEFINE_PROP_UINT64("gcr-base", RISCVCPSState, gcr_base, GCR_BASE_ADDR),
+ DEFINE_PROP_STRING("cpu-type", RISCVCPSState, cpu_type),
+};
+
+static void riscv_cps_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->realize = riscv_cps_realize;
+ device_class_set_props(dc, riscv_cps_properties);
+}
+
+static const TypeInfo riscv_cps_info = {
+ .name = TYPE_RISCV_CPS,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(RISCVCPSState),
+ .instance_init = riscv_cps_init,
+ .class_init = riscv_cps_class_init,
+};
+
+static void riscv_cps_register_types(void)
+{
+ type_register_static(&riscv_cps_info);
+}
+
+type_init(riscv_cps_register_types)
diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
index c22f3a7216..78caaf84a3 100644
--- a/hw/riscv/meson.build
+++ b/hw/riscv/meson.build
@@ -14,4 +14,6 @@ riscv_ss.add(when: 'CONFIG_RISCV_IOMMU', if_true: files(
'riscv-iommu.c', 'riscv-iommu-pci.c', 'riscv-iommu-sys.c', 'riscv-iommu-hpm.c'))
riscv_ss.add(when: 'CONFIG_MICROBLAZE_V', if_true: files('microblaze-v-generic.c'))
+riscv_ss.add(when: 'CONFIG_RISCV_CPS', if_true: files('cps.c'))
+
hw_arch += {'riscv': riscv_ss}
diff --git a/include/hw/riscv/cps.h b/include/hw/riscv/cps.h
new file mode 100644
index 0000000000..4886a01ec9
--- /dev/null
+++ b/include/hw/riscv/cps.h
@@ -0,0 +1,76 @@
+/*
+ * Coherent Processing System emulation.
+ *
+ * Copyright (c) 2016 Imagination Technologies
+ *
+ * Copyright (c) 2025 MIPS
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ */
+
+#ifndef RISCV_CPS_H
+#define RISCV_CPS_H
+
+#include "hw/sysbus.h"
+#include "hw/misc/riscv_cmgcr.h"
+#include "hw/misc/riscv_cpc.h"
+#include "target/riscv/cpu.h"
+#include "qom/object.h"
+
+#define TYPE_RISCV_CPS "riscv-cps"
+OBJECT_DECLARE_SIMPLE_TYPE(RISCVCPSState, RISCV_CPS)
+
+/* The model supports up to 64 harts. */
+#define MAX_HARTS 64
+
+/* The global CM base for the boston-aia model. */
+#define GLOBAL_CM_BASE 0x16100000
+/* The CM block is 512 KiB. */
+#define CM_SIZE (1 << 19)
+
+/* The mhartid bits has cluster at bit 16, core at bit 4, and hart at
+ bit 0. */
+#define MHARTID_CLUSTER_SHIFT 16
+#define MHARTID_CORE_SHIFT 4
+#define MHARTID_HART_SHIFT 0
+
+#define APLIC_NUM_SOURCES 0x35 /* Arbitray maximum number of interrupts. */
+#define APLIC_NUM_PRIO_BITS 3
+#define AIA_PLIC_M_OFFSET 0x40000
+#define AIA_PLIC_M_SIZE 0x8000
+#define AIA_PLIC_S_OFFSET 0x60000
+#define AIA_PLIC_S_SIZE 0x8000
+#define AIA_CLINT_OFFSET 0x50000
+
+typedef struct RISCVCPSState {
+ SysBusDevice parent_obj;
+
+ uint32_t num_vp;
+ uint32_t num_hart;
+ uint32_t num_core;
+ uint64_t gcr_base;
+ char *cpu_type;
+
+ MemoryRegion container;
+ RISCVGCRState gcr;
+ RISCVCPCState cpc;
+
+ DeviceState *aplic;
+ CPUState **cpus;
+} RISCVCPSState;
+
+#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v6 11/14] hw/riscv: Add support for MIPS Boston-aia board mode
2025-07-17 9:38 [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
` (9 preceding siblings ...)
2025-07-17 9:38 ` [PATCH v6 10/14] hw/riscv: Add support for RISCV CPS Djordje Todorovic
@ 2025-07-17 9:38 ` Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 13/14] riscv/boston-aia: Add an e1000e NIC in slot 0 func 1 Djordje Todorovic
` (5 subsequent siblings)
16 siblings, 0 replies; 44+ messages in thread
From: Djordje Todorovic @ 2025-07-17 9:38 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com,
philmd@linaro.org, Djordje Todorovic
The board model supports up to 64 harts with MIPS CPS, MIPS GCR,
MIPS CPC, AIA plic, and AIA clint devices. The model can create
boot code, if there is no -bios parameter. We can specify -smp x,
cores=y,thread=z.
Ex: Use 4 cores and 2 threads with each core to
have 8 smp cpus as follows.
qemu-system-riscv64 -cpu mips-p8700 \
-m 2G -M boston-aia \
-smp 8,cores=4,threads=2 -kernel fw_payload.bin \
-drive file=rootfs.ext2,format=raw -serial stdio
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
---
configs/devices/riscv64-softmmu/default.mak | 1 +
docs/system/riscv/mips.rst | 20 +
docs/system/target-riscv.rst | 1 +
hw/riscv/Kconfig | 6 +
hw/riscv/boston-aia.c | 484 ++++++++++++++++++++
hw/riscv/meson.build | 1 +
6 files changed, 513 insertions(+)
create mode 100644 docs/system/riscv/mips.rst
create mode 100644 hw/riscv/boston-aia.c
diff --git a/configs/devices/riscv64-softmmu/default.mak b/configs/devices/riscv64-softmmu/default.mak
index 39ed3a0061..2f4f92b978 100644
--- a/configs/devices/riscv64-softmmu/default.mak
+++ b/configs/devices/riscv64-softmmu/default.mak
@@ -11,3 +11,4 @@
# CONFIG_RISCV_VIRT=n
# CONFIG_MICROCHIP_PFSOC=n
# CONFIG_SHAKTI_C=n
+# CONFIG_MIPS_BOSTON_AIA=n
diff --git a/docs/system/riscv/mips.rst b/docs/system/riscv/mips.rst
new file mode 100644
index 0000000000..97096421e1
--- /dev/null
+++ b/docs/system/riscv/mips.rst
@@ -0,0 +1,20 @@
+Boards for RISC-V Processors by MIPS
+====================================
+
+RISC-V processors developed by MIPS support Boston-aia board model. The board
+model supports up to 64 harts with MIPS CPS, MIPS GCR, MIPS CPC, AIA plic,
+and AIA clint devices. The model can create boot code, if there is no
+```-bios``` parameter. Also, we can specify ```-smp x,cores=y,thread=z```.
+
+Running Linux kernel
+--------------------
+
+For example, to use 4 cores and 2 threads with each core to have 8 smp cpus,
+that runs on the ```mips-p8700``` CPU, run qemu as follows:
+
+.. code-block:: bash
+
+ qemu-system-riscv64 -cpu mips-p8700 \
+ -m 2G -M boston-aia \
+ -smp 8,cores=4,threads=2 -kernel fw_payload.bin \
+ -drive file=rootfs.ext2,format=raw -serial stdio
diff --git a/docs/system/target-riscv.rst b/docs/system/target-riscv.rst
index 95457af130..9e11bb25c9 100644
--- a/docs/system/target-riscv.rst
+++ b/docs/system/target-riscv.rst
@@ -68,6 +68,7 @@ undocumented; you can get a complete list by running
riscv/microblaze-v-generic
riscv/microchip-icicle-kit
+ riscv/mips
riscv/shakti-c
riscv/sifive_u
riscv/virt
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index e6a0ac1fa1..047c6d8ae7 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -119,3 +119,9 @@ config SPIKE
select HTIF
select RISCV_ACLINT
select SIFIVE_PLIC
+
+config MIPS_BOSTON_AIA
+ bool
+ default y
+ select PCI_EXPRESS
+ select PCI_EXPRESS_XILINX
diff --git a/hw/riscv/boston-aia.c b/hw/riscv/boston-aia.c
new file mode 100644
index 0000000000..e31b0509ca
--- /dev/null
+++ b/hw/riscv/boston-aia.c
@@ -0,0 +1,484 @@
+/*
+ * MIPS Boston-aia development board emulation.
+ *
+ * Copyright (c) 2016 Imagination Technologies
+ *
+ * Copyright (c) 2025 MIPS
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+*/
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+
+#include "hw/boards.h"
+#include "hw/char/serial-mm.h"
+#include "hw/ide/pci.h"
+#include "hw/ide/ahci-pci.h"
+#include "hw/loader.h"
+#include "hw/riscv/cps.h"
+#include "hw/pci-host/xilinx-pcie.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qemu/log.h"
+#include "chardev/char.h"
+#include "system/address-spaces.h"
+#include "system/device_tree.h"
+#include "system/system.h"
+#include "system/qtest.h"
+#include "system/runstate.h"
+
+#include <libfdt.h>
+#include "qom/object.h"
+
+#define TYPE_MIPS_BOSTON_AIA "mips-boston-aia"
+typedef struct BostonState BostonState;
+DECLARE_INSTANCE_CHECKER(BostonState, BOSTON,
+ TYPE_MIPS_BOSTON_AIA)
+
+enum {
+ BOSTON_PCIE2,
+ BOSTON_PCIE2_MMIO,
+ BOSTON_PLATREG,
+ BOSTON_UART,
+ BOSTON_LCD,
+ BOSTON_FLASH,
+ BOSTON_HIGHDDR,
+};
+
+static const MemMapEntry boston_memmap[] = {
+ [BOSTON_PCIE2] = { 0x14000000, 0x2000000 },
+ [BOSTON_PCIE2_MMIO] = { 0x16000000, 0x100000 },
+ [BOSTON_PLATREG] = { 0x17ffd000, 0x1000 },
+ [BOSTON_UART] = { 0x17ffe000, 0x20 },
+ [BOSTON_LCD] = { 0x17fff000, 0x8 },
+ [BOSTON_FLASH] = { 0x18000000, 0x8000000 },
+ [BOSTON_HIGHDDR] = { 0x80000000, 0x0 },
+};
+
+/* Interrupt numbers for APLIC. */
+#define UART_INT 4
+#define PCIE2_INT 7
+
+struct BostonState {
+ SysBusDevice parent_obj;
+
+ MachineState *mach;
+ RISCVCPSState cps;
+ SerialMM *uart;
+
+ CharBackend lcd_display;
+ char lcd_content[8];
+ bool lcd_inited;
+};
+
+enum boston_plat_reg {
+ PLAT_FPGA_BUILD = 0x00,
+ PLAT_CORE_CL = 0x04,
+ PLAT_WRAPPER_CL = 0x08,
+ PLAT_SYSCLK_STATUS = 0x0c,
+ PLAT_SOFTRST_CTL = 0x10,
+#define PLAT_SOFTRST_CTL_SYSRESET (1 << 4)
+ PLAT_DDR3_STATUS = 0x14,
+#define PLAT_DDR3_STATUS_LOCKED (1 << 0)
+#define PLAT_DDR3_STATUS_CALIBRATED (1 << 2)
+#define PLAT_DDR3_INTERFACE_RESET (1 << 3)
+ PLAT_PCIE_STATUS = 0x18,
+#define PLAT_PCIE_STATUS_PCIE0_LOCKED (1 << 0)
+#define PLAT_PCIE_STATUS_PCIE1_LOCKED (1 << 8)
+#define PLAT_PCIE_STATUS_PCIE2_LOCKED (1 << 16)
+ PLAT_FLASH_CTL = 0x1c,
+ PLAT_SPARE0 = 0x20,
+ PLAT_SPARE1 = 0x24,
+ PLAT_SPARE2 = 0x28,
+ PLAT_SPARE3 = 0x2c,
+ PLAT_MMCM_DIV = 0x30,
+#define PLAT_MMCM_DIV_CLK0DIV_SHIFT 0
+#define PLAT_MMCM_DIV_INPUT_SHIFT 8
+#define PLAT_MMCM_DIV_MUL_SHIFT 16
+#define PLAT_MMCM_DIV_CLK1DIV_SHIFT 24
+ PLAT_BUILD_CFG = 0x34,
+#define PLAT_BUILD_CFG_IOCU_EN (1 << 0)
+#define PLAT_BUILD_CFG_PCIE0_EN (1 << 1)
+#define PLAT_BUILD_CFG_PCIE1_EN (1 << 2)
+#define PLAT_BUILD_CFG_PCIE2_EN (1 << 3)
+ PLAT_DDR_CFG = 0x38,
+#define PLAT_DDR_CFG_SIZE (0xf << 0)
+#define PLAT_DDR_CFG_MHZ (0xfff << 4)
+ PLAT_NOC_PCIE0_ADDR = 0x3c,
+ PLAT_NOC_PCIE1_ADDR = 0x40,
+ PLAT_NOC_PCIE2_ADDR = 0x44,
+ PLAT_SYS_CTL = 0x48,
+};
+
+static void boston_lcd_event(void *opaque, QEMUChrEvent event)
+{
+ BostonState *s = opaque;
+ if (event == CHR_EVENT_OPENED && !s->lcd_inited) {
+ qemu_chr_fe_printf(&s->lcd_display, " ");
+ s->lcd_inited = true;
+ }
+}
+
+static uint64_t boston_lcd_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+ BostonState *s = opaque;
+ uint64_t val = 0;
+
+ switch (size) {
+ case 8:
+ val |= (uint64_t)s->lcd_content[(addr + 7) & 0x7] << 56;
+ val |= (uint64_t)s->lcd_content[(addr + 6) & 0x7] << 48;
+ val |= (uint64_t)s->lcd_content[(addr + 5) & 0x7] << 40;
+ val |= (uint64_t)s->lcd_content[(addr + 4) & 0x7] << 32;
+ /* fall through */
+ case 4:
+ val |= (uint64_t)s->lcd_content[(addr + 3) & 0x7] << 24;
+ val |= (uint64_t)s->lcd_content[(addr + 2) & 0x7] << 16;
+ /* fall through */
+ case 2:
+ val |= (uint64_t)s->lcd_content[(addr + 1) & 0x7] << 8;
+ /* fall through */
+ case 1:
+ val |= (uint64_t)s->lcd_content[(addr + 0) & 0x7];
+ break;
+ }
+
+ return val;
+}
+
+static void boston_lcd_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+ BostonState *s = opaque;
+
+ switch (size) {
+ case 8:
+ s->lcd_content[(addr + 7) & 0x7] = val >> 56;
+ s->lcd_content[(addr + 6) & 0x7] = val >> 48;
+ s->lcd_content[(addr + 5) & 0x7] = val >> 40;
+ s->lcd_content[(addr + 4) & 0x7] = val >> 32;
+ /* fall through */
+ case 4:
+ s->lcd_content[(addr + 3) & 0x7] = val >> 24;
+ s->lcd_content[(addr + 2) & 0x7] = val >> 16;
+ /* fall through */
+ case 2:
+ s->lcd_content[(addr + 1) & 0x7] = val >> 8;
+ /* fall through */
+ case 1:
+ s->lcd_content[(addr + 0) & 0x7] = val;
+ break;
+ }
+
+ qemu_chr_fe_printf(&s->lcd_display,
+ "\r%-8.8s", s->lcd_content);
+}
+
+static const MemoryRegionOps boston_lcd_ops = {
+ .read = boston_lcd_read,
+ .write = boston_lcd_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static uint64_t boston_platreg_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+ BostonState *s = opaque;
+ uint32_t gic_freq, val;
+
+ if (size != 4) {
+ qemu_log_mask(LOG_UNIMP, "%uB platform register read\n", size);
+ return 0;
+ }
+
+ switch (addr & 0xffff) {
+ case PLAT_FPGA_BUILD:
+ case PLAT_CORE_CL:
+ case PLAT_WRAPPER_CL:
+ return 0;
+ case PLAT_DDR3_STATUS:
+ return PLAT_DDR3_STATUS_LOCKED | PLAT_DDR3_STATUS_CALIBRATED
+ | PLAT_DDR3_INTERFACE_RESET;
+ case PLAT_MMCM_DIV:
+ gic_freq = 25000000 / 1000000;
+ val = gic_freq << PLAT_MMCM_DIV_INPUT_SHIFT;
+ val |= 1 << PLAT_MMCM_DIV_MUL_SHIFT;
+ val |= 1 << PLAT_MMCM_DIV_CLK0DIV_SHIFT;
+ val |= 1 << PLAT_MMCM_DIV_CLK1DIV_SHIFT;
+ return val;
+ case PLAT_BUILD_CFG:
+ val = PLAT_BUILD_CFG_PCIE0_EN;
+ val |= PLAT_BUILD_CFG_PCIE1_EN;
+ val |= PLAT_BUILD_CFG_PCIE2_EN;
+ return val;
+ case PLAT_DDR_CFG:
+ val = s->mach->ram_size / GiB;
+ assert(!(val & ~PLAT_DDR_CFG_SIZE));
+ val |= PLAT_DDR_CFG_MHZ;
+ return val;
+ default:
+ qemu_log_mask(LOG_UNIMP, "Read platform register 0x%" HWADDR_PRIx "\n",
+ addr & 0xffff);
+ return 0;
+ }
+}
+
+static void boston_platreg_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+ if (size != 4) {
+ qemu_log_mask(LOG_UNIMP, "%uB platform register write\n", size);
+ return;
+ }
+
+ switch (addr & 0xffff) {
+ case PLAT_FPGA_BUILD:
+ case PLAT_CORE_CL:
+ case PLAT_WRAPPER_CL:
+ case PLAT_DDR3_STATUS:
+ case PLAT_PCIE_STATUS:
+ case PLAT_MMCM_DIV:
+ case PLAT_BUILD_CFG:
+ case PLAT_DDR_CFG:
+ /* read only */
+ break;
+ case PLAT_SOFTRST_CTL:
+ if (val & PLAT_SOFTRST_CTL_SYSRESET) {
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+ }
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "Write platform register 0x%" HWADDR_PRIx
+ " = 0x%" PRIx64 "\n", addr & 0xffff, val);
+ break;
+ }
+}
+
+static const MemoryRegionOps boston_platreg_ops = {
+ .read = boston_platreg_read,
+ .write = boston_platreg_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const TypeInfo boston_device = {
+ .name = TYPE_MIPS_BOSTON_AIA,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(BostonState),
+};
+
+static void boston_register_types(void)
+{
+ type_register_static(&boston_device);
+}
+type_init(boston_register_types)
+
+#define NUM_INSNS 6
+static void gen_firmware(uint32_t *p)
+{
+ int i;
+ uint32_t reset_vec[NUM_INSNS] = {
+ /* CM relocate */
+ 0x1fb802b7, /* li t0,0x1fb80000 */
+ 0x16100337, /* li t1,0x16100000 */
+ 0x0062b423, /* sd t1,8(t0) */
+ /* Jump to 0x80000000 */
+ 0x00100293, /* li t0,1 */
+ 0x01f29293, /* slli t0,t0,1f */
+ 0x00028067 /* jr t0 */
+ };
+
+ for (i = 0; i < NUM_INSNS; i++) {
+ *p++ = reset_vec[i];
+ }
+}
+
+static inline XilinxPCIEHost *
+xilinx_pcie_init(MemoryRegion *sys_mem, uint32_t bus_nr,
+ hwaddr cfg_base, uint64_t cfg_size,
+ hwaddr mmio_base, uint64_t mmio_size,
+ qemu_irq irq)
+{
+ DeviceState *dev;
+ MemoryRegion *cfg, *mmio;
+
+ dev = qdev_new(TYPE_XILINX_PCIE_HOST);
+
+ qdev_prop_set_uint32(dev, "bus_nr", bus_nr);
+ qdev_prop_set_uint64(dev, "cfg_base", cfg_base);
+ qdev_prop_set_uint64(dev, "cfg_size", cfg_size);
+ qdev_prop_set_uint64(dev, "mmio_base", mmio_base);
+ qdev_prop_set_uint64(dev, "mmio_size", mmio_size);
+
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+
+ cfg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
+ memory_region_add_subregion_overlap(sys_mem, cfg_base, cfg, 0);
+
+ mmio = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
+ memory_region_add_subregion_overlap(sys_mem, 0, mmio, 0);
+
+ qdev_connect_gpio_out_named(dev, "interrupt_out", 0, irq);
+
+ return XILINX_PCIE_HOST(dev);
+}
+
+static void boston_mach_init(MachineState *machine)
+{
+ DeviceState *dev;
+ BostonState *s;
+ MemoryRegion *flash, *ddr_low_alias, *lcd, *platreg;
+ MemoryRegion *sys_mem = get_system_memory();
+ XilinxPCIEHost *pcie2;
+ PCIDevice *pdev;
+ AHCIPCIState *ich9;
+ DriveInfo *hd[6];
+ Chardev *chr;
+ int fw_size;
+
+ if ((machine->ram_size % GiB) ||
+ (machine->ram_size > (4 * GiB))) {
+ error_report("Memory size must be 1GB, 2GB, 3GB, or 4GB");
+ exit(1);
+ }
+
+ if (machine->smp.cpus / machine->smp.cores / machine->smp.threads > 1) {
+ error_report("Invalid -smp x,cores=y,threads=z. The max number of clusters "
+ "supported is 1");
+ exit(1);
+ }
+
+ dev = qdev_new(TYPE_MIPS_BOSTON_AIA);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+
+ s = BOSTON(dev);
+ s->mach = machine;
+
+ object_initialize_child(OBJECT(machine), "cps", &s->cps, TYPE_RISCV_CPS);
+ object_property_set_str(OBJECT(&s->cps), "cpu-type", machine->cpu_type,
+ &error_fatal);
+ object_property_set_uint(OBJECT(&s->cps), "num-vp", machine->smp.cpus,
+ &error_fatal);
+ object_property_set_uint(OBJECT(&s->cps), "num-hart", machine->smp.threads,
+ &error_fatal);
+ object_property_set_uint(OBJECT(&s->cps), "num-core", machine->smp.cores,
+ &error_fatal);
+ object_property_set_uint(OBJECT(&s->cps), "gcr-base", GCR_BASE_ADDR,
+ &error_fatal);
+ sysbus_realize(SYS_BUS_DEVICE(&s->cps), &error_fatal);
+
+ sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->cps), 0, 0, 1);
+
+ flash = g_new(MemoryRegion, 1);
+ memory_region_init_rom(flash, NULL, "boston.flash",
+ boston_memmap[BOSTON_FLASH].size, &error_fatal);
+ memory_region_add_subregion_overlap(sys_mem,
+ boston_memmap[BOSTON_FLASH].base,
+ flash, 0);
+
+ memory_region_add_subregion_overlap(sys_mem,
+ boston_memmap[BOSTON_HIGHDDR].base,
+ machine->ram, 0);
+
+ ddr_low_alias = g_new(MemoryRegion, 1);
+ memory_region_init_alias(ddr_low_alias, NULL, "boston_low.ddr",
+ machine->ram, 0,
+ MIN(machine->ram_size, (256 * MiB)));
+ memory_region_add_subregion_overlap(sys_mem, 0, ddr_low_alias, 0);
+
+ pcie2 = xilinx_pcie_init(sys_mem, 2,
+ boston_memmap[BOSTON_PCIE2].base,
+ boston_memmap[BOSTON_PCIE2].size,
+ boston_memmap[BOSTON_PCIE2_MMIO].base,
+ boston_memmap[BOSTON_PCIE2_MMIO].size,
+ qdev_get_gpio_in(s->cps.aplic, PCIE2_INT));
+
+ platreg = g_new(MemoryRegion, 1);
+ memory_region_init_io(platreg, NULL, &boston_platreg_ops, s,
+ "boston-platregs",
+ boston_memmap[BOSTON_PLATREG].size);
+ memory_region_add_subregion_overlap(sys_mem,
+ boston_memmap[BOSTON_PLATREG].base, platreg, 0);
+
+ s->uart = serial_mm_init(sys_mem, boston_memmap[BOSTON_UART].base, 2,
+ qdev_get_gpio_in(s->cps.aplic, UART_INT), 10000000,
+ serial_hd(0), DEVICE_NATIVE_ENDIAN);
+
+ lcd = g_new(MemoryRegion, 1);
+ memory_region_init_io(lcd, NULL, &boston_lcd_ops, s, "boston-lcd", 0x8);
+ memory_region_add_subregion_overlap(sys_mem,
+ boston_memmap[BOSTON_LCD].base, lcd, 0);
+
+ chr = qemu_chr_new("lcd", "vc:320x240", NULL);
+ qemu_chr_fe_init(&s->lcd_display, chr, NULL);
+ qemu_chr_fe_set_handlers(&s->lcd_display, NULL, NULL,
+ boston_lcd_event, NULL, s, NULL, true);
+
+ pdev = pci_create_simple_multifunction(&PCI_BRIDGE(&pcie2->root)->sec_bus,
+ PCI_DEVFN(0, 0), TYPE_ICH9_AHCI);
+ ich9 = ICH9_AHCI(pdev);
+ g_assert(ARRAY_SIZE(hd) == ich9->ahci.ports);
+ ide_drive_get(hd, ich9->ahci.ports);
+ ahci_ide_create_devs(&ich9->ahci, hd);
+
+ if (machine->firmware) {
+ fw_size = load_image_targphys(machine->firmware,
+ 0x1fc00000, 4 * MiB);
+ if (fw_size == -1) {
+ error_report("unable to load firmware image '%s'",
+ machine->firmware);
+ exit(1);
+ }
+ if (machine->kernel_filename) {
+ fw_size = load_image_targphys(machine->kernel_filename,
+ 0x80000000, 64 * MiB);
+ if (fw_size == -1) {
+ error_report("unable to load kernel image '%s'",
+ machine->kernel_filename);
+ exit(1);
+ }
+ }
+ } else if (machine->kernel_filename) {
+ fw_size = load_image_targphys(machine->kernel_filename,
+ 0x80000000, 64 * MiB);
+ if (fw_size == -1) {
+ error_report("unable to load kernel image '%s'",
+ machine->kernel_filename);
+ exit(1);
+ }
+
+ gen_firmware(memory_region_get_ram_ptr(flash) + 0x7c00000);
+ } else if (!qtest_enabled()) {
+ error_report("Please provide either a -kernel or -bios argument");
+ exit(1);
+ }
+}
+
+static void boston_mach_class_init(MachineClass *mc)
+{
+ mc->desc = "MIPS Boston-aia";
+ mc->init = boston_mach_init;
+ mc->block_default_type = IF_IDE;
+ mc->default_ram_size = 2 * GiB;
+ mc->default_ram_id = "boston.ddr";
+ mc->max_cpus = MAX_HARTS;
+ mc->default_cpu_type = TYPE_RISCV_CPU_MIPS_P8700;
+}
+
+DEFINE_MACHINE("boston-aia", boston_mach_class_init)
diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
index 78caaf84a3..7a18d55504 100644
--- a/hw/riscv/meson.build
+++ b/hw/riscv/meson.build
@@ -15,5 +15,6 @@ riscv_ss.add(when: 'CONFIG_RISCV_IOMMU', if_true: files(
riscv_ss.add(when: 'CONFIG_MICROBLAZE_V', if_true: files('microblaze-v-generic.c'))
riscv_ss.add(when: 'CONFIG_RISCV_CPS', if_true: files('cps.c'))
+riscv_ss.add(when: 'CONFIG_MIPS_BOSTON_AIA', if_true: files('boston-aia.c'))
hw_arch += {'riscv': riscv_ss}
--
2.34.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v6 12/14] hw/pci: Allow explicit function numbers in pci
2025-07-17 9:38 [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
` (11 preceding siblings ...)
2025-07-17 9:38 ` [PATCH v6 13/14] riscv/boston-aia: Add an e1000e NIC in slot 0 func 1 Djordje Todorovic
@ 2025-07-17 9:38 ` Djordje Todorovic
2025-08-08 16:29 ` Philippe Mathieu-Daudé
2025-07-17 9:38 ` [PATCH v6 14/14] test/functional: Add test for boston-aia board Djordje Todorovic
` (3 subsequent siblings)
16 siblings, 1 reply; 44+ messages in thread
From: Djordje Todorovic @ 2025-07-17 9:38 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com,
philmd@linaro.org, Djordje Todorovic
Since there is no pch_gbe emulation, we could be using func other
than 0 when adding new devices to specific boards.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
---
hw/pci/pci.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index f5ab510697..23f7f02837 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -974,14 +974,15 @@ static int pci_parse_devaddr(const char *addr, int *domp, int *busp,
slot = val;
- if (funcp != NULL) {
- if (*e != '.')
+ if (funcp != NULL && *e != 0) {
+ if (*e != '.') {
return -1;
-
+ }
p = e + 1;
val = strtoul(p, &e, 16);
- if (e == p)
+ if (e == p) {
return -1;
+ }
func = val;
}
@@ -2045,13 +2046,15 @@ bool pci_init_nic_in_slot(PCIBus *rootbus, const char *model,
int dom, busnr, devfn;
PCIDevice *pci_dev;
unsigned slot;
+
PCIBus *bus;
if (!nd) {
return false;
}
- if (!devaddr || pci_parse_devaddr(devaddr, &dom, &busnr, &slot, NULL) < 0) {
+ unsigned func;
+ if (!devaddr || pci_parse_devaddr(devaddr, &dom, &busnr, &slot, &func) < 0) {
error_report("Invalid PCI device address %s for device %s",
devaddr, model);
exit(1);
@@ -2062,7 +2065,7 @@ bool pci_init_nic_in_slot(PCIBus *rootbus, const char *model,
exit(1);
}
- devfn = PCI_DEVFN(slot, 0);
+ devfn = PCI_DEVFN(slot, func);
bus = pci_find_bus_nr(rootbus, busnr);
if (!bus) {
--
2.34.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v6 13/14] riscv/boston-aia: Add an e1000e NIC in slot 0 func 1
2025-07-17 9:38 [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
` (10 preceding siblings ...)
2025-07-17 9:38 ` [PATCH v6 11/14] hw/riscv: Add support for MIPS Boston-aia board mode Djordje Todorovic
@ 2025-07-17 9:38 ` Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 12/14] hw/pci: Allow explicit function numbers in pci Djordje Todorovic
` (4 subsequent siblings)
16 siblings, 0 replies; 44+ messages in thread
From: Djordje Todorovic @ 2025-07-17 9:38 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com,
philmd@linaro.org, Djordje Todorovic
The Boston AIA board needs a basic GbE NIC. There is no PCH GbE
device emulation, so use an `e1000e` instead. We place it in
**slot 0, function 1** in order not to conflict with the existing
AHCI device in slot 0 func 0.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
---
hw/riscv/boston-aia.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/hw/riscv/boston-aia.c b/hw/riscv/boston-aia.c
index e31b0509ca..9be66167f0 100644
--- a/hw/riscv/boston-aia.c
+++ b/hw/riscv/boston-aia.c
@@ -437,6 +437,11 @@ static void boston_mach_init(MachineState *machine)
ide_drive_get(hd, ich9->ahci.ports);
ahci_ide_create_devs(&ich9->ahci, hd);
+ /* Create e1000e using slot 0 func 1 */
+ pci_init_nic_in_slot(&PCI_BRIDGE(&pcie2->root)->sec_bus, "e1000e", NULL,
+ "00.1");
+ pci_init_nic_devices(&PCI_BRIDGE(&pcie2->root)->sec_bus, "e1000e");
+
if (machine->firmware) {
fw_size = load_image_targphys(machine->firmware,
0x1fc00000, 4 * MiB);
--
2.34.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v6 14/14] test/functional: Add test for boston-aia board
2025-07-17 9:38 [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
` (12 preceding siblings ...)
2025-07-17 9:38 ` [PATCH v6 12/14] hw/pci: Allow explicit function numbers in pci Djordje Todorovic
@ 2025-07-17 9:38 ` Djordje Todorovic
2025-08-08 16:32 ` Philippe Mathieu-Daudé
2025-08-05 10:10 ` [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
` (2 subsequent siblings)
16 siblings, 1 reply; 44+ messages in thread
From: Djordje Todorovic @ 2025-07-17 9:38 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com,
philmd@linaro.org, Djordje Todorovic
Add functional test for Boston AIA board. The P8700 RISC-V based
CPU by MIPS supports it at the moment.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
---
tests/functional/meson.build | 1 +
tests/functional/test_riscv64_boston.py | 78 +++++++++++++++++++++++++
2 files changed, 79 insertions(+)
create mode 100755 tests/functional/test_riscv64_boston.py
diff --git a/tests/functional/meson.build b/tests/functional/meson.build
index 52b4706cfe..317e085bfb 100644
--- a/tests/functional/meson.build
+++ b/tests/functional/meson.build
@@ -259,6 +259,7 @@ tests_riscv32_system_thorough = [
tests_riscv64_system_quick = [
'migration',
'riscv_opensbi',
+ 'riscv64_boston',
]
tests_riscv64_system_thorough = [
diff --git a/tests/functional/test_riscv64_boston.py b/tests/functional/test_riscv64_boston.py
new file mode 100755
index 0000000000..eb5dd07b79
--- /dev/null
+++ b/tests/functional/test_riscv64_boston.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python3
+#
+# Boston board test for RISC-V P8700 processor by MIPS
+#
+# Copyright (c) 2025 MIPS
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+
+from qemu_test import QemuSystemTest
+
+class RiscvBostonTest(QemuSystemTest):
+ """
+ Test the boston-aia board with P8700 processor
+ """
+
+ timeout = 10
+
+ def test_boston_memory_constraints(self):
+ """
+ Test that boston-aia board enforces memory size constraints
+ """
+ # Test invalid memory size
+ self.set_machine('boston-aia')
+ self.vm.add_args('-cpu', 'mips-p8700')
+ self.vm.add_args('-m', '512M') # Invalid size
+ self.vm.add_args('-nographic')
+ self.vm.set_qmp_monitor(enabled=False)
+ self.vm.launch()
+ self.vm.wait()
+
+ # Should fail due to invalid memory size
+ self.assertEqual(self.vm.exitcode(), 1)
+ log = self.vm.get_log()
+ self.assertIn("Memory size must be 1GB, 2GB, 3GB, or 4GB", log)
+
+ def test_boston_requires_kernel(self):
+ """
+ Test that boston-aia board requires a kernel or bios
+ """
+ self.set_machine('boston-aia')
+ self.vm.add_args('-cpu', 'mips-p8700')
+ self.vm.add_args('-m', '1G') # Valid size
+ self.vm.add_args('-nographic')
+ # No kernel or bios specified
+ self.vm.set_qmp_monitor(enabled=False)
+ self.vm.launch()
+ self.vm.wait()
+
+ # Should fail due to missing kernel/bios
+ self.assertEqual(self.vm.exitcode(), 1)
+ log = self.vm.get_log()
+ self.assertIn("Please provide either a -kernel or -bios argument", log)
+
+ def test_boston_cpu_count(self):
+ """
+ Test various CPU counts for boston-aia board
+ """
+ cpu_counts = [1, 2, 4, 8]
+
+ for cpus in cpu_counts:
+ with self.subTest(cpus=cpus):
+ self.set_machine('boston-aia')
+ self.vm.add_args('-cpu', 'mips-p8700')
+ self.vm.add_args('-smp', str(cpus))
+ self.vm.add_args('-m', '1G')
+ self.vm.add_args('-nographic')
+ self.vm.set_qmp_monitor(enabled=False)
+ self.vm.launch()
+ self.vm.wait()
+
+ # Board should fail due to missing kernel, not CPU count
+ self.assertEqual(self.vm.exitcode(), 1)
+ log = self.vm.get_log()
+ self.assertIn("Please provide either a -kernel or -bios argument", log)
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
--
2.34.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* Re: [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU
2025-07-17 9:38 [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
` (13 preceding siblings ...)
2025-07-17 9:38 ` [PATCH v6 14/14] test/functional: Add test for boston-aia board Djordje Todorovic
@ 2025-08-05 10:10 ` Djordje Todorovic
2025-08-07 18:35 ` Daniel Henrique Barboza
2025-08-08 16:42 ` Philippe Mathieu-Daudé
16 siblings, 0 replies; 44+ messages in thread
From: Djordje Todorovic @ 2025-08-05 10:10 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com,
philmd@linaro.org
Hi,
Is there any additional comment on this?
Thanks a lot!
Djordje
On 17. 7. 25. 11:38, Djordje Todorovic wrote:
> I addressed several comments in this version, major ones:
> - split CPC / CMGCR into separated changes
> - split CPS into a separated change
> - added functional tests for boston-aia board
>
> Djordje Todorovic (14):
> hw/intc: Allow gaps in hartids for aclint and aplic
> target/riscv: Add cpu_set_exception_base
> target/riscv: Add MIPS P8700 CPU
> target/riscv: Add MIPS P8700 CSRs
> target/riscv: Add mips.ccmov instruction
> target/riscv: Add mips.pref instruction
> target/riscv: Add Xmipslsp instructions
> hw/misc: Add RISC-V CMGCR device implementation
> hw/misc: Add RISC-V CPC device implementation
> hw/riscv: Add support for RISCV CPS
> hw/riscv: Add support for MIPS Boston-aia board mode
> hw/pci: Allow explicit function numbers in pci
> riscv/boston-aia: Add an e1000e NIC in slot 0 func 1
> test/functional: Add test for boston-aia board
>
> configs/devices/riscv64-softmmu/default.mak | 1 +
> docs/system/riscv/mips.rst | 20 +
> docs/system/target-riscv.rst | 1 +
> hw/intc/riscv_aclint.c | 21 +-
> hw/intc/riscv_aplic.c | 11 +-
> hw/misc/Kconfig | 20 +
> hw/misc/meson.build | 3 +
> hw/misc/riscv_cmgcr.c | 234 ++++++++++
> hw/misc/riscv_cpc.c | 239 ++++++++++
> hw/pci/pci.c | 15 +-
> hw/riscv/Kconfig | 6 +
> hw/riscv/boston-aia.c | 489 ++++++++++++++++++++
> hw/riscv/cps.c | 197 ++++++++
> hw/riscv/meson.build | 3 +
> include/hw/misc/riscv_cmgcr.h | 49 ++
> include/hw/misc/riscv_cpc.h | 73 +++
> include/hw/riscv/cps.h | 76 +++
> target/riscv/cpu-qom.h | 1 +
> target/riscv/cpu.c | 40 ++
> target/riscv/cpu.h | 7 +
> target/riscv/cpu_cfg.h | 6 +
> target/riscv/cpu_cfg_fields.h.inc | 3 +
> target/riscv/cpu_vendorid.h | 1 +
> target/riscv/insn_trans/trans_xmips.c.inc | 142 ++++++
> target/riscv/meson.build | 2 +
> target/riscv/mips_csr.c | 228 +++++++++
> target/riscv/translate.c | 3 +
> target/riscv/xmips.decode | 35 ++
> tests/functional/meson.build | 1 +
> tests/functional/test_riscv64_boston.py | 78 ++++
> 30 files changed, 1994 insertions(+), 11 deletions(-)
> create mode 100644 docs/system/riscv/mips.rst
> create mode 100644 hw/misc/riscv_cmgcr.c
> create mode 100644 hw/misc/riscv_cpc.c
> create mode 100644 hw/riscv/boston-aia.c
> create mode 100644 hw/riscv/cps.c
> create mode 100644 include/hw/misc/riscv_cmgcr.h
> create mode 100644 include/hw/misc/riscv_cpc.h
> create mode 100644 include/hw/riscv/cps.h
> create mode 100644 target/riscv/insn_trans/trans_xmips.c.inc
> create mode 100644 target/riscv/mips_csr.c
> create mode 100644 target/riscv/xmips.decode
> create mode 100755 tests/functional/test_riscv64_boston.py
>
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU
2025-07-17 9:38 [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
` (14 preceding siblings ...)
2025-08-05 10:10 ` [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
@ 2025-08-07 18:35 ` Daniel Henrique Barboza
2025-09-01 8:07 ` Djordje Todorovic
2025-08-08 16:42 ` Philippe Mathieu-Daudé
16 siblings, 1 reply; 44+ messages in thread
From: Daniel Henrique Barboza @ 2025-08-07 18:35 UTC (permalink / raw)
To: Djordje Todorovic, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, philmd@linaro.org
Hi,
I have provided reviews and acks on the v4 review:
https://lore.kernel.org/qemu-riscv/20250625141732.59084-1-djordje.todorovic@htecgroup.com/
I also gave one additional ack/review in patch 8 in v5:
https://lore.kernel.org/qemu-riscv/20250703104925.112688-1-djordje.todorovic@htecgroup.com/
I see no acks in any patches in this version.
The common practice is to include any reviewed-by/acked-by tags received in the commit
msg of each patch when submitting a new version, letting other ppl know that the patch
was already looked at once. Unless you make changes in the patch and the review gave
before is now invalid - then in this case you drop the tag and a new review is
required.
Unless you completely changed all the patches and all the reviews doesn't apply
anymore, please re-send this series with the acks/reviewed-by tags in the patches.
From my estimation this series is supposed to have 2-3 patches missing review only.
Thanks,
Daniel
On 7/17/25 6:38 AM, Djordje Todorovic wrote:
> I addressed several comments in this version, major ones:
> - split CPC / CMGCR into separated changes
> - split CPS into a separated change
> - added functional tests for boston-aia board
>
> Djordje Todorovic (14):
> hw/intc: Allow gaps in hartids for aclint and aplic
> target/riscv: Add cpu_set_exception_base
> target/riscv: Add MIPS P8700 CPU
> target/riscv: Add MIPS P8700 CSRs
> target/riscv: Add mips.ccmov instruction
> target/riscv: Add mips.pref instruction
> target/riscv: Add Xmipslsp instructions
> hw/misc: Add RISC-V CMGCR device implementation
> hw/misc: Add RISC-V CPC device implementation
> hw/riscv: Add support for RISCV CPS
> hw/riscv: Add support for MIPS Boston-aia board mode
> hw/pci: Allow explicit function numbers in pci
> riscv/boston-aia: Add an e1000e NIC in slot 0 func 1
> test/functional: Add test for boston-aia board
>
> configs/devices/riscv64-softmmu/default.mak | 1 +
> docs/system/riscv/mips.rst | 20 +
> docs/system/target-riscv.rst | 1 +
> hw/intc/riscv_aclint.c | 21 +-
> hw/intc/riscv_aplic.c | 11 +-
> hw/misc/Kconfig | 20 +
> hw/misc/meson.build | 3 +
> hw/misc/riscv_cmgcr.c | 234 ++++++++++
> hw/misc/riscv_cpc.c | 239 ++++++++++
> hw/pci/pci.c | 15 +-
> hw/riscv/Kconfig | 6 +
> hw/riscv/boston-aia.c | 489 ++++++++++++++++++++
> hw/riscv/cps.c | 197 ++++++++
> hw/riscv/meson.build | 3 +
> include/hw/misc/riscv_cmgcr.h | 49 ++
> include/hw/misc/riscv_cpc.h | 73 +++
> include/hw/riscv/cps.h | 76 +++
> target/riscv/cpu-qom.h | 1 +
> target/riscv/cpu.c | 40 ++
> target/riscv/cpu.h | 7 +
> target/riscv/cpu_cfg.h | 6 +
> target/riscv/cpu_cfg_fields.h.inc | 3 +
> target/riscv/cpu_vendorid.h | 1 +
> target/riscv/insn_trans/trans_xmips.c.inc | 142 ++++++
> target/riscv/meson.build | 2 +
> target/riscv/mips_csr.c | 228 +++++++++
> target/riscv/translate.c | 3 +
> target/riscv/xmips.decode | 35 ++
> tests/functional/meson.build | 1 +
> tests/functional/test_riscv64_boston.py | 78 ++++
> 30 files changed, 1994 insertions(+), 11 deletions(-)
> create mode 100644 docs/system/riscv/mips.rst
> create mode 100644 hw/misc/riscv_cmgcr.c
> create mode 100644 hw/misc/riscv_cpc.c
> create mode 100644 hw/riscv/boston-aia.c
> create mode 100644 hw/riscv/cps.c
> create mode 100644 include/hw/misc/riscv_cmgcr.h
> create mode 100644 include/hw/misc/riscv_cpc.h
> create mode 100644 include/hw/riscv/cps.h
> create mode 100644 target/riscv/insn_trans/trans_xmips.c.inc
> create mode 100644 target/riscv/mips_csr.c
> create mode 100644 target/riscv/xmips.decode
> create mode 100755 tests/functional/test_riscv64_boston.py
>
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 01/14] hw/intc: Allow gaps in hartids for aclint and aplic
2025-07-17 9:38 ` [PATCH v6 01/14] hw/intc: Allow gaps in hartids for aclint and aplic Djordje Todorovic
@ 2025-08-08 15:52 ` Philippe Mathieu-Daudé
2025-09-01 8:17 ` Djordje Todorovic
0 siblings, 1 reply; 44+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-08-08 15:52 UTC (permalink / raw)
To: Djordje Todorovic, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 17/7/25 11:38, Djordje Todorovic wrote:
> This is needed for riscv based CPUs by MIPS since those may have
> sparse hart-ID layouts. ACLINT and APLIC still assume a dense
> range, and if a hart is missing, this causes NULL derefs.
>
> Signed-off-by: Chao-ying Fu <cfu@mips.com>
> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
> ---
> hw/intc/riscv_aclint.c | 21 +++++++++++++++++++--
> hw/intc/riscv_aplic.c | 11 ++++++++---
> 2 files changed, 27 insertions(+), 5 deletions(-)
>
> diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
> index b0139f03f5..22ac4133d5 100644
> --- a/hw/intc/riscv_aclint.c
> +++ b/hw/intc/riscv_aclint.c
> @@ -292,7 +292,13 @@ static void riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp)
> s->timecmp = g_new0(uint64_t, s->num_harts);
> /* Claim timer interrupt bits */
> for (i = 0; i < s->num_harts; i++) {
> - RISCVCPU *cpu = RISCV_CPU(cpu_by_arch_id(s->hartid_base + i));
> + CPUState *cpu_by_hartid = cpu_by_arch_id(s->hartid_base + i);
> + if (cpu_by_hartid == NULL) {
> + qemu_log_mask(LOG_GUEST_ERROR, "aclint-mtimer: invalid hartid: %u",
> + s->hartid_base + i);
DeviceRealize() handlers are part of machine modelling, not guest uses.
IOW, triggering this is a programming mistake, so we should just
abort() here.
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 08/14] hw/misc: Add RISC-V CMGCR device implementation
2025-07-17 9:38 ` [PATCH v6 08/14] hw/misc: Add RISC-V CMGCR device implementation Djordje Todorovic
@ 2025-08-08 16:00 ` Philippe Mathieu-Daudé
2025-08-08 16:07 ` Philippe Mathieu-Daudé
2025-09-01 8:24 ` Djordje Todorovic
2025-08-08 16:05 ` Philippe Mathieu-Daudé
1 sibling, 2 replies; 44+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-08-08 16:00 UTC (permalink / raw)
To: Djordje Todorovic, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 17/7/25 11:38, Djordje Todorovic wrote:
> Add RISC-V implementation of the Coherent Manager Global Control
> Register (CMGCR) device. It is based on the existing MIPS CMGCR
> implementation but adapted for RISC-V systems.
>
> The CMGCR device provides global system control for multi-core
> configurations in RISC-V systems.
>
> This is needed for the MIPS BOSTON AIA board.
>
> Signed-off-by: Chao-ying Fu <cfu@mips.com>
> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
> ---
> hw/misc/Kconfig | 10 ++
> hw/misc/meson.build | 2 +
> hw/misc/riscv_cmgcr.c | 234 ++++++++++++++++++++++++++++++++++
> include/hw/misc/riscv_cmgcr.h | 49 +++++++
> 4 files changed, 295 insertions(+)
> create mode 100644 hw/misc/riscv_cmgcr.c
> create mode 100644 include/hw/misc/riscv_cmgcr.h
> +static void riscv_gcr_realize(DeviceState *dev, Error **errp)
> +{
> + RISCVGCRState *s = RISCV_GCR(dev);
Please report an error for invalid num_vps values (0 or >MAX).
> +
> + /* Create local set of registers for each VP */
> + s->vps = g_new(RISCVGCRVPState, s->num_vps);
> +}
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 07/14] target/riscv: Add Xmipslsp instructions
2025-07-17 9:38 ` [PATCH v6 07/14] target/riscv: Add Xmipslsp instructions Djordje Todorovic
@ 2025-08-08 16:02 ` Philippe Mathieu-Daudé
2025-09-01 8:20 ` Djordje Todorovic
2025-09-01 8:30 ` Djordje Todorovic
0 siblings, 2 replies; 44+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-08-08 16:02 UTC (permalink / raw)
To: Djordje Todorovic, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 17/7/25 11:38, Djordje Todorovic wrote:
> Add MIPS P8700 ldp, lwp, sdp, swp instructions.
>
> Signed-off-by: Chao-ying Fu <cfu@mips.com>
> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
> ---
> target/riscv/cpu.c | 3 +
> target/riscv/cpu_cfg.h | 2 +-
> target/riscv/cpu_cfg_fields.h.inc | 1 +
> target/riscv/insn_trans/trans_xmips.c.inc | 84 +++++++++++++++++++++++
> target/riscv/xmips.decode | 23 +++++++
> 5 files changed, 112 insertions(+), 1 deletion(-)
> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> index 9734963035..f35d477f27 100644
> --- a/target/riscv/cpu_cfg.h
> +++ b/target/riscv/cpu_cfg.h
> @@ -39,7 +39,7 @@ static inline bool always_true_p(const RISCVCPUConfig *cfg __attribute__((__unus
>
> static inline bool has_xmips_p(const RISCVCPUConfig *cfg)
> {
> - return cfg->ext_xmipscbop || cfg->ext_xmipscmov;
> + return cfg->ext_xmipscbop || cfg->ext_xmipscmov || cfg->ext_xmipslsp;
Checking for any XMIPS instruction implemented to return vendor
extension presence seems odd. Can you implement them separately?
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 08/14] hw/misc: Add RISC-V CMGCR device implementation
2025-07-17 9:38 ` [PATCH v6 08/14] hw/misc: Add RISC-V CMGCR device implementation Djordje Todorovic
2025-08-08 16:00 ` Philippe Mathieu-Daudé
@ 2025-08-08 16:05 ` Philippe Mathieu-Daudé
2025-09-01 8:22 ` Djordje Todorovic
1 sibling, 1 reply; 44+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-08-08 16:05 UTC (permalink / raw)
To: Djordje Todorovic, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 17/7/25 11:38, Djordje Todorovic wrote:
> Add RISC-V implementation of the Coherent Manager Global Control
> Register (CMGCR) device. It is based on the existing MIPS CMGCR
> implementation but adapted for RISC-V systems.
>
> The CMGCR device provides global system control for multi-core
> configurations in RISC-V systems.
>
> This is needed for the MIPS BOSTON AIA board.
>
> Signed-off-by: Chao-ying Fu <cfu@mips.com>
> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
> ---
> hw/misc/Kconfig | 10 ++
> hw/misc/meson.build | 2 +
> hw/misc/riscv_cmgcr.c | 234 ++++++++++++++++++++++++++++++++++
> include/hw/misc/riscv_cmgcr.h | 49 +++++++
> 4 files changed, 295 insertions(+)
> create mode 100644 hw/misc/riscv_cmgcr.c
> create mode 100644 include/hw/misc/riscv_cmgcr.h
>
> diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
> index ec0fa5aa9f..e3fce37c01 100644
> --- a/hw/misc/Kconfig
> +++ b/hw/misc/Kconfig
> @@ -108,6 +108,16 @@ config STM32L4X5_RCC
> config MIPS_ITU
> bool
>
> +config RISCV_CMGCR
> + bool
> + default n
$ git grep 'default n' $(git ls-files|fgrep Kconfig) | wc -l
0
I remember asking that already but maybe it was a different
series... Why don't you want this automatically selected by
default? All our codebase does it, why change suddenly?
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 08/14] hw/misc: Add RISC-V CMGCR device implementation
2025-08-08 16:00 ` Philippe Mathieu-Daudé
@ 2025-08-08 16:07 ` Philippe Mathieu-Daudé
2025-09-01 8:24 ` Djordje Todorovic
2025-09-01 8:24 ` Djordje Todorovic
1 sibling, 1 reply; 44+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-08-08 16:07 UTC (permalink / raw)
To: Djordje Todorovic, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 8/8/25 18:00, Philippe Mathieu-Daudé wrote:
> On 17/7/25 11:38, Djordje Todorovic wrote:
>> Add RISC-V implementation of the Coherent Manager Global Control
>> Register (CMGCR) device. It is based on the existing MIPS CMGCR
>> implementation but adapted for RISC-V systems.
>>
>> The CMGCR device provides global system control for multi-core
>> configurations in RISC-V systems.
>>
>> This is needed for the MIPS BOSTON AIA board.
>>
>> Signed-off-by: Chao-ying Fu <cfu@mips.com>
>> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
>> ---
>> hw/misc/Kconfig | 10 ++
>> hw/misc/meson.build | 2 +
>> hw/misc/riscv_cmgcr.c | 234 ++++++++++++++++++++++++++++++++++
>> include/hw/misc/riscv_cmgcr.h | 49 +++++++
>> 4 files changed, 295 insertions(+)
>> create mode 100644 hw/misc/riscv_cmgcr.c
>> create mode 100644 include/hw/misc/riscv_cmgcr.h
>
>
>> +static void riscv_gcr_realize(DeviceState *dev, Error **errp)
>> +{
>> + RISCVGCRState *s = RISCV_GCR(dev);
>
> Please report an error for invalid num_vps values (0 or >MAX).
Per the next patch:
#define VPS_MAX 64
Is it possible to have a config with 7, 24 or 35 vps?
>
>> +
>> + /* Create local set of registers for each VP */
>> + s->vps = g_new(RISCVGCRVPState, s->num_vps);
>> +}
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 09/14] hw/misc: Add RISC-V CPC device implementation
2025-07-17 9:38 ` [PATCH v6 09/14] hw/misc: Add RISC-V CPC " Djordje Todorovic
@ 2025-08-08 16:21 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 44+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-08-08 16:21 UTC (permalink / raw)
To: Djordje Todorovic, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 17/7/25 11:38, Djordje Todorovic wrote:
> Add RISC-V implementation of the Cluster Power Controller (CPC) device.
> It is based on the existing MIPS CPC implementations but adapted for
> RISC-V systems.
>
> The CPC device manages power control for CPU clusters in RISC-V
> systems.
>
> This is needed for the MIPS BOSTON AIA board.
>
> Signed-off-by: Chao-ying Fu <cfu@mips.com>
> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
> ---
> hw/misc/Kconfig | 5 +
> hw/misc/meson.build | 1 +
> hw/misc/riscv_cpc.c | 239 ++++++++++++++++++++++++++++++++++++
> include/hw/misc/riscv_cpc.h | 73 +++++++++++
> 4 files changed, 318 insertions(+)
> create mode 100644 hw/misc/riscv_cpc.c
> create mode 100644 include/hw/misc/riscv_cpc.h
> diff --git a/hw/misc/riscv_cpc.c b/hw/misc/riscv_cpc.c
> new file mode 100644
> index 0000000000..424562d7be
> --- /dev/null
> +++ b/hw/misc/riscv_cpc.c
> @@ -0,0 +1,239 @@
> +/*
> + * Cluster Power Controller emulation
> + *
> + * Copyright (c) 2016 Imagination Technologies
> + *
> + * Copyright (c) 2025 MIPS
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see <http://www.gnu.org/licenses/>.
> + *
> + * SPDX-License-Identifier: LGPL-2.1-or-later
> + *
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "cpu.h"
> +#include "qemu/log.h"
> +#include "qemu/module.h"
> +#include "qemu/timer.h"
> +#include "hw/sysbus.h"
> +#include "migration/vmstate.h"
> +
> +#include "hw/misc/riscv_cpc.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/intc/riscv_aclint.h"
> +#include "hw/resettable.h"
> +
> +static inline uint64_t cpc_vp_run_mask(RISCVCPCState *cpc)
> +{
> + if (cpc->num_vp == 64) {
> + return 0xffffffffffffffff;
> + }
> + return (1ULL << cpc->num_vp) - 1;
return MAKE_64BIT_MASK(0, cpc->num_vp);
> +}
> +
> +static void riscv_cpu_reset_async_work(CPUState *cs, run_on_cpu_data data)
> +{
> + RISCVCPCState *cpc = (RISCVCPCState *) data.host_ptr;
> + int i;
> +
> + cpu_reset(cs);
> + cs->halted = 0;
> +
> + /* Find this CPU's index in the CPC's CPU array */
> + for (i = 0; i < cpc->num_vp; i++) {
> + if (cpc->cpus[i] == cs) {
> + cpc->vp_running |= 1ULL << i;
|= BIT_ULL(i);
> + break;
> + }
> + }
> +}
> +
> +static void cpc_run_vp(RISCVCPCState *cpc, uint64_t vp_run)
Please rename as 'vps_mask' or 'vps_run_mask'.
> +{
> + int i;
Rename as 'vp'?
> +
> + for (i = 0; i < cpc->num_vp; i++) {
> + CPUState *cs = cpc->cpus[i];
> + uint64_t mask = 1ULL << i;
> + if (mask & vp_run & ~cpc->vp_running) {
Double masking is not easy to review. Clearer as (IMHO):
if (!extract64(vps_run_mask, vp, 1)) {
continue;
}
if (extract64(cpc->vp_running, vp, 1)) {
continue;
}
> + /*
> + * To avoid racing with a CPU we are just kicking off.
> + * We do the final bit of preparation for the work in
> + * the target CPUs context.
> + */
> + async_safe_run_on_cpu(cs, riscv_cpu_reset_async_work,
> + RUN_ON_CPU_HOST_PTR(cpc));
> + }
> + }
> +}
> +
> +static void cpc_stop_vp(RISCVCPCState *cpc, uint64_t vp_stop)
> +{
> + int i;
> +
> + for (i = 0; i < cpc->num_vp; i++) {
> + CPUState *cs = cpc->cpus[i];
> + uint64_t mask = 1ULL << i;
> + if (mask & vp_stop & cpc->vp_running) {
Ditto.
> + cpu_interrupt(cs, CPU_INTERRUPT_HALT);
> + cpc->vp_running &= ~mask;
> + }
> + }
> +}
> +static void riscv_cpc_realize(DeviceState *dev, Error **errp)
> +{
> + RISCVCPCState *s = RISCV_CPC(dev);
> +
> + if (s->vp_start_running > cpc_vp_run_mask(s)) {
if (s->vp_start_running & ~cpc_vp_run_mask(s)) {
> + error_setg(errp,
> + "incorrect vp_start_running 0x%" PRIx64 " for num_vp = %d",
> + s->vp_running, s->num_vp);
> + return;
> + }
> +}
> +
> +static void riscv_cpc_reset_hold(Object *obj, ResetType type)
> +{
> + RISCVCPCState *s = RISCV_CPC(obj);
> +
> + /* Reflect the fact that all VPs are halted on reset */
> + s->vp_running = 0;
> +
> + /* Put selected VPs into run state */
> + cpc_run_vp(s, s->vp_start_running);
> +}
> +
> +static const VMStateDescription vmstate_riscv_cpc = {
> + .name = "xmips-cpc",
> + .version_id = 0,
> + .minimum_version_id = 0,
> + .fields = (VMStateField[]) {
> + VMSTATE_UINT64(vp_running, RISCVCPCState),
> + VMSTATE_END_OF_LIST()
> + },
> +};
> +
> +static const Property riscv_cpc_properties[] = {
> + DEFINE_PROP_UINT32("cluster-id", RISCVCPCState, cluster_id, 0x0),
> + DEFINE_PROP_UINT32("num-vp", RISCVCPCState, num_vp, 0x1),
> + DEFINE_PROP_UINT32("num-hart", RISCVCPCState, num_hart, 0x1),
> + DEFINE_PROP_UINT32("num-core", RISCVCPCState, num_core, 0x1),
> + DEFINE_PROP_UINT64("vp-start-running", RISCVCPCState, vp_start_running, 0x1),
Use 'mask' in property name.
> +};
> +typedef struct RISCVCPCState {
> + SysBusDevice parent_obj;
> +
> + uint32_t cluster_id;
> + uint32_t num_vp;
> + uint32_t num_hart;
> + uint32_t num_core;
> + uint64_t vp_start_running; /* VPs running from restart */
Please add _mask suffix. Use plural?
> +
> + MemoryRegion mr;
> + uint64_t vp_running; /* Indicates which VPs are in the run state */
Please add _mask suffix. Use plural? 'vps_running_mask'
or 'running_vps_mask'?
> +
> + /* Array of CPUs managed by this CPC */
> + CPUState **cpus;
> +} RISCVCPCState;
> +
> +#endif /* RISCV_CPC_H */
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 10/14] hw/riscv: Add support for RISCV CPS
2025-07-17 9:38 ` [PATCH v6 10/14] hw/riscv: Add support for RISCV CPS Djordje Todorovic
@ 2025-08-08 16:26 ` Philippe Mathieu-Daudé
2025-09-01 8:30 ` Djordje Todorovic
0 siblings, 1 reply; 44+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-08-08 16:26 UTC (permalink / raw)
To: Djordje Todorovic, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 17/7/25 11:38, Djordje Todorovic wrote:
> Add support for the Coherent Processing System for RISC-V.
> This enables SMP support for RISC-V boards that require
> cache-coherent multiprocessor systems.
>
> Signed-off-by: Chao-ying Fu <cfu@mips.com>
> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
> ---
> hw/misc/Kconfig | 5 ++
> hw/riscv/cps.c | 197 +++++++++++++++++++++++++++++++++++++++++
> hw/riscv/meson.build | 2 +
> include/hw/riscv/cps.h | 76 ++++++++++++++++
> 4 files changed, 280 insertions(+)
> create mode 100644 hw/riscv/cps.c
> create mode 100644 include/hw/riscv/cps.h
> +static void main_cpu_reset(void *opaque)
> +{
> + RISCVCPU *cpu = opaque;
> + CPUState *cs = CPU(cpu);
If you call in [*]:
qemu_register_reset(main_cpu_reset, s->cpus[i]);
then here you can just do:
CPUState *cs = opaque;
> +
> + cpu_reset(cs);
> +}
> +
> +static void riscv_cps_realize(DeviceState *dev, Error **errp)
> +{
> + RISCVCPSState *s = RISCV_CPS(dev);
> + RISCVCPU *cpu;
> + int i;
> +
Please check num_vp range.
> + /* Allocate CPU array */
> + s->cpus = g_new0(CPUState *, s->num_vp);
> +
> + /* Set up cpu_index and mhartid for avaiable CPUs. */
> + int harts_in_cluster = s->num_hart * s->num_core;
> + int num_of_clusters = s->num_vp / harts_in_cluster;
> + for (i = 0; i < s->num_vp; i++) {
> + cpu = RISCV_CPU(object_new(s->cpu_type));
> +
> + /* All VPs are halted on reset. Leave powering up to CPC. */
> + object_property_set_bool(OBJECT(cpu), "start-powered-off", true,
> + &error_abort);
> +
> + if (!qdev_realize_and_unref(DEVICE(cpu), NULL, errp)) {
> + return;
> + }
> +
> + /* Store CPU in array */
> + s->cpus[i] = CPU(cpu);
> +
> + /* Set up mhartid */
> + int cluster_id = i / harts_in_cluster;
> + int hart_id = (i % harts_in_cluster) % s->num_hart;
> + int core_id = (i % harts_in_cluster) / s->num_hart;
> + int mhartid = (cluster_id << MHARTID_CLUSTER_SHIFT) +
> + (core_id << MHARTID_CORE_SHIFT) +
> + (hart_id << MHARTID_HART_SHIFT);
> + cpu->env.mhartid = mhartid;
> + qemu_register_reset(main_cpu_reset, cpu);
[*]
> + }
> +
> + /* Cluster Power Controller */
> + object_initialize_child(OBJECT(dev), "cpc", &s->cpc, TYPE_RISCV_CPC);
> + object_property_set_uint(OBJECT(&s->cpc), "cluster-id", 0,
> + &error_abort);
> + object_property_set_uint(OBJECT(&s->cpc), "num-vp", s->num_vp,
> + &error_abort);
> + object_property_set_uint(OBJECT(&s->cpc), "num-hart", s->num_hart,
> + &error_abort);
> + object_property_set_uint(OBJECT(&s->cpc), "num-core", s->num_core,
> + &error_abort);
> + object_property_set_int(OBJECT(&s->cpc), "vp-start-running", 1,
> + &error_abort);
(1 is already the default)
> +
> + /* Pass CPU array to CPC */
> + s->cpc.cpus = s->cpus;
Please do that using a link property.
> +
> + if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpc), errp)) {
> + return;
> + }
> +
> + memory_region_add_subregion(&s->container, 0,
> + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpc), 0));
> +
> + /* Global Configuration Registers */
> + object_initialize_child(OBJECT(dev), "gcr", &s->gcr, TYPE_RISCV_GCR);
> + object_property_set_uint(OBJECT(&s->gcr), "cluster-id", 0,
> + &error_abort);
> + object_property_set_uint(OBJECT(&s->gcr), "num-vp", s->num_vp,
> + &error_abort);
> + object_property_set_int(OBJECT(&s->gcr), "gcr-rev", 0xa00,
> + &error_abort);
> + object_property_set_int(OBJECT(&s->gcr), "gcr-base", s->gcr_base,
> + &error_abort);
> + object_property_set_link(OBJECT(&s->gcr), "cpc", OBJECT(&s->cpc.mr),
> + &error_abort);
> + if (!sysbus_realize(SYS_BUS_DEVICE(&s->gcr), errp)) {
> + return;
> + }
> +
> + memory_region_add_subregion(&s->container, s->gcr_base,
> + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gcr), 0));
> +
> + for (i = 0; i < num_of_clusters; i++) {
> + uint64_t cm_base = GLOBAL_CM_BASE + (CM_SIZE * i);
> + uint32_t hartid_base = i << MHARTID_CLUSTER_SHIFT;
> + s->aplic = riscv_aplic_create(cm_base + AIA_PLIC_M_OFFSET,
> + AIA_PLIC_M_SIZE,
> + hartid_base, /* hartid_base */
> + MAX_HARTS, /* num_harts */
> + APLIC_NUM_SOURCES,
> + APLIC_NUM_PRIO_BITS,
> + false, true, NULL);
> + riscv_aplic_create(cm_base + AIA_PLIC_S_OFFSET,
> + AIA_PLIC_S_SIZE,
> + hartid_base, /* hartid_base */
> + MAX_HARTS, /* num_harts */
> + APLIC_NUM_SOURCES,
> + APLIC_NUM_PRIO_BITS,
> + false, false, s->aplic);
> + /* PLIC changes msi_nonbroken to ture. We revert the change. */
> + msi_nonbroken = false;
> + riscv_aclint_swi_create(cm_base + AIA_CLINT_OFFSET,
> + hartid_base, MAX_HARTS, false);
> + riscv_aclint_mtimer_create(cm_base + AIA_CLINT_OFFSET +
> + RISCV_ACLINT_SWI_SIZE,
> + RISCV_ACLINT_DEFAULT_MTIMER_SIZE,
> + hartid_base,
> + MAX_HARTS,
> + RISCV_ACLINT_DEFAULT_MTIMECMP,
> + RISCV_ACLINT_DEFAULT_MTIME,
> + RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, false);
> + }
> +}
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 12/14] hw/pci: Allow explicit function numbers in pci
2025-07-17 9:38 ` [PATCH v6 12/14] hw/pci: Allow explicit function numbers in pci Djordje Todorovic
@ 2025-08-08 16:29 ` Philippe Mathieu-Daudé
2025-09-01 8:31 ` Djordje Todorovic
0 siblings, 1 reply; 44+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-08-08 16:29 UTC (permalink / raw)
To: Djordje Todorovic, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 17/7/25 11:38, Djordje Todorovic wrote:
> Since there is no pch_gbe emulation, we could be using func other
> than 0 when adding new devices to specific boards.
>
> Signed-off-by: Chao-ying Fu <cfu@mips.com>
> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
> ---
> hw/pci/pci.c | 15 +++++++++------
> 1 file changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> index f5ab510697..23f7f02837 100644
> --- a/hw/pci/pci.c
> +++ b/hw/pci/pci.c
> @@ -974,14 +974,15 @@ static int pci_parse_devaddr(const char *addr, int *domp, int *busp,
>
> slot = val;
>
> - if (funcp != NULL) {
> - if (*e != '.')
> + if (funcp != NULL && *e != 0) {
> + if (*e != '.') {
> return -1;
> -
> + }
> p = e + 1;
> val = strtoul(p, &e, 16);
> - if (e == p)
> + if (e == p) {
> return -1;
> + }
>
> func = val;
> }
> @@ -2045,13 +2046,15 @@ bool pci_init_nic_in_slot(PCIBus *rootbus, const char *model,
> int dom, busnr, devfn;
> PCIDevice *pci_dev;
> unsigned slot;
> +
[*]
> PCIBus *bus;
>
> if (!nd) {
> return false;
> }
>
> - if (!devaddr || pci_parse_devaddr(devaddr, &dom, &busnr, &slot, NULL) < 0) {
> + unsigned func;
Declare 'func' earlier in [*], otherwise LGTM.
> + if (!devaddr || pci_parse_devaddr(devaddr, &dom, &busnr, &slot, &func) < 0) {
> error_report("Invalid PCI device address %s for device %s",
> devaddr, model);
> exit(1);
> @@ -2062,7 +2065,7 @@ bool pci_init_nic_in_slot(PCIBus *rootbus, const char *model,
> exit(1);
> }
>
> - devfn = PCI_DEVFN(slot, 0);
> + devfn = PCI_DEVFN(slot, func);
>
> bus = pci_find_bus_nr(rootbus, busnr);
> if (!bus) {
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 14/14] test/functional: Add test for boston-aia board
2025-07-17 9:38 ` [PATCH v6 14/14] test/functional: Add test for boston-aia board Djordje Todorovic
@ 2025-08-08 16:32 ` Philippe Mathieu-Daudé
2025-09-01 8:35 ` Djordje Todorovic
0 siblings, 1 reply; 44+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-08-08 16:32 UTC (permalink / raw)
To: Djordje Todorovic, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com,
Thomas Huth
Hi,
On 17/7/25 11:38, Djordje Todorovic wrote:
> Add functional test for Boston AIA board. The P8700 RISC-V based
> CPU by MIPS supports it at the moment.
>
> Signed-off-by: Chao-ying Fu <cfu@mips.com>
> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
> ---
> tests/functional/meson.build | 1 +
> tests/functional/test_riscv64_boston.py | 78 +++++++++++++++++++++++++
> 2 files changed, 79 insertions(+)
> create mode 100755 tests/functional/test_riscv64_boston.py
> diff --git a/tests/functional/test_riscv64_boston.py b/tests/functional/test_riscv64_boston.py
> new file mode 100755
> index 0000000000..eb5dd07b79
> --- /dev/null
> +++ b/tests/functional/test_riscv64_boston.py
> @@ -0,0 +1,78 @@
> +#!/usr/bin/env python3
> +#
> +# Boston board test for RISC-V P8700 processor by MIPS
> +#
> +# Copyright (c) 2025 MIPS
> +#
> +# SPDX-License-Identifier: LGPL-2.1-or-later
> +#
> +
> +from qemu_test import QemuSystemTest
> +
> +class RiscvBostonTest(QemuSystemTest):
> + """
> + Test the boston-aia board with P8700 processor
> + """
> +
> + timeout = 10
> +
> + def test_boston_memory_constraints(self):
> + """
> + Test that boston-aia board enforces memory size constraints
> + """
> + # Test invalid memory size
> + self.set_machine('boston-aia')
> + self.vm.add_args('-cpu', 'mips-p8700')
> + self.vm.add_args('-m', '512M') # Invalid size
> + self.vm.add_args('-nographic')
> + self.vm.set_qmp_monitor(enabled=False)
> + self.vm.launch()
> + self.vm.wait()
> +
> + # Should fail due to invalid memory size
> + self.assertEqual(self.vm.exitcode(), 1)
> + log = self.vm.get_log()
> + self.assertIn("Memory size must be 1GB, 2GB, 3GB, or 4GB", log)
> +
> + def test_boston_requires_kernel(self):
> + """
> + Test that boston-aia board requires a kernel or bios
> + """
> + self.set_machine('boston-aia')
> + self.vm.add_args('-cpu', 'mips-p8700')
> + self.vm.add_args('-m', '1G') # Valid size
> + self.vm.add_args('-nographic')
> + # No kernel or bios specified
> + self.vm.set_qmp_monitor(enabled=False)
> + self.vm.launch()
> + self.vm.wait()
> +
> + # Should fail due to missing kernel/bios
> + self.assertEqual(self.vm.exitcode(), 1)
> + log = self.vm.get_log()
> + self.assertIn("Please provide either a -kernel or -bios argument", log)
> +
> + def test_boston_cpu_count(self):
> + """
> + Test various CPU counts for boston-aia board
> + """
> + cpu_counts = [1, 2, 4, 8]
> +
> + for cpus in cpu_counts:
> + with self.subTest(cpus=cpus):
> + self.set_machine('boston-aia')
> + self.vm.add_args('-cpu', 'mips-p8700')
> + self.vm.add_args('-smp', str(cpus))
> + self.vm.add_args('-m', '1G')
> + self.vm.add_args('-nographic')
> + self.vm.set_qmp_monitor(enabled=False)
> + self.vm.launch()
> + self.vm.wait()
> +
> + # Board should fail due to missing kernel, not CPU count
> + self.assertEqual(self.vm.exitcode(), 1)
> + log = self.vm.get_log()
> + self.assertIn("Please provide either a -kernel or -bios argument", log)
> +
> +if __name__ == '__main__':
> + QemuSystemTest.main()
Thanks for testing these constraints, but can we have guest code
actually exercising the code path to the XMIPS instructions?
Also code testing powering VPs up/down, to cover CPS, GCR and CPC.
Code using the e1000e card would be awesome ;)
Thanks,
Phil.
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU
2025-07-17 9:38 [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
` (15 preceding siblings ...)
2025-08-07 18:35 ` Daniel Henrique Barboza
@ 2025-08-08 16:42 ` Philippe Mathieu-Daudé
2025-09-01 8:15 ` Djordje Todorovic
16 siblings, 1 reply; 44+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-08-08 16:42 UTC (permalink / raw)
To: Djordje Todorovic, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
Hi,
On 17/7/25 11:38, Djordje Todorovic wrote:
> I addressed several comments in this version, major ones:
> - split CPC / CMGCR into separated changes
> - split CPS into a separated change
> - added functional tests for boston-aia board
>
> Djordje Todorovic (14):
> hw/misc: Add RISC-V CMGCR device implementation
> hw/misc: Add RISC-V CPC device implementation
> hw/riscv: Add support for RISCV CPS
I'm not keen on having theses models duplicated with the
MIPS ones. Are the IPs really different? They are just
dealing with bit masks to stop/start VPs AFAICT.
Could we model them with plain CPUState objects instead?
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 03/14] target/riscv: Add MIPS P8700 CPU
2025-07-17 9:38 ` [PATCH v6 03/14] target/riscv: Add MIPS P8700 CPU Djordje Todorovic
@ 2025-08-08 17:02 ` Philippe Mathieu-Daudé
2025-09-01 8:17 ` Djordje Todorovic
0 siblings, 1 reply; 44+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-08-08 17:02 UTC (permalink / raw)
To: Djordje Todorovic, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 17/7/25 11:38, Djordje Todorovic wrote:
> Introduce P8700 CPU by MIPS.
>
> Signed-off-by: Chao-ying Fu <cfu@mips.com>
> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
> ---
> target/riscv/cpu-qom.h | 1 +
> target/riscv/cpu.c | 15 +++++++++++++++
> target/riscv/cpu_vendorid.h | 1 +
> 3 files changed, 17 insertions(+)
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index e584bdc5ac..401c0f6c7d 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -3180,6 +3180,21 @@ static const TypeInfo riscv_cpu_type_infos[] = {
> .cfg.max_satp_mode = VM_1_10_SV39,
> ),
>
Can we add the datasheet link here?
/* https://mips.com/products/hardware/p8700/ */
> + DEFINE_RISCV_CPU(TYPE_RISCV_CPU_MIPS_P8700, TYPE_RISCV_VENDOR_CPU,
> + .misa_mxl_max = MXL_RV64,
> + .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU,
> + .priv_spec = PRIV_VERSION_1_12_0,
> + .cfg.max_satp_mode = VM_1_10_SV48,
> + .cfg.ext_zifencei = true,
> + .cfg.ext_zicsr = true,
> + .cfg.mmu = true,
> + .cfg.pmp = true,
> + .cfg.ext_zba = true,
> + .cfg.ext_zbb = true,
> + .cfg.marchid = 0x8000000000000201,
> + .cfg.mvendorid = MIPS_VENDOR_ID,
> + ),
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU
2025-08-07 18:35 ` Daniel Henrique Barboza
@ 2025-09-01 8:07 ` Djordje Todorovic
0 siblings, 0 replies; 44+ messages in thread
From: Djordje Todorovic @ 2025-09-01 8:07 UTC (permalink / raw)
To: Daniel Henrique Barboza, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, philmd@linaro.org
Hi Daniel,
Thank you for your comments!
I will follow this.
Best,
Djordje
On 7. 8. 25. 20:35, Daniel Henrique Barboza wrote:
> CAUTION: This email originated from outside of the organization. Do
> not click links or open attachments unless you recognize the sender
> and know the content is safe.
>
>
> Hi,
>
> I have provided reviews and acks on the v4 review:
>
> https://lore.kernel.org/qemu-riscv/20250625141732.59084-1-djordje.todorovic@htecgroup.com/
>
>
> I also gave one additional ack/review in patch 8 in v5:
>
> https://lore.kernel.org/qemu-riscv/20250703104925.112688-1-djordje.todorovic@htecgroup.com/
>
>
> I see no acks in any patches in this version.
>
> The common practice is to include any reviewed-by/acked-by tags
> received in the commit
> msg of each patch when submitting a new version, letting other ppl
> know that the patch
> was already looked at once. Unless you make changes in the patch and
> the review gave
> before is now invalid - then in this case you drop the tag and a new
> review is
> required.
>
> Unless you completely changed all the patches and all the reviews
> doesn't apply
> anymore, please re-send this series with the acks/reviewed-by tags in
> the patches.
> From my estimation this series is supposed to have 2-3 patches missing
> review only.
>
>
> Thanks,
>
> Daniel
>
>
>
>
> On 7/17/25 6:38 AM, Djordje Todorovic wrote:
>> I addressed several comments in this version, major ones:
>> - split CPC / CMGCR into separated changes
>> - split CPS into a separated change
>> - added functional tests for boston-aia board
>>
>> Djordje Todorovic (14):
>> hw/intc: Allow gaps in hartids for aclint and aplic
>> target/riscv: Add cpu_set_exception_base
>> target/riscv: Add MIPS P8700 CPU
>> target/riscv: Add MIPS P8700 CSRs
>> target/riscv: Add mips.ccmov instruction
>> target/riscv: Add mips.pref instruction
>> target/riscv: Add Xmipslsp instructions
>> hw/misc: Add RISC-V CMGCR device implementation
>> hw/misc: Add RISC-V CPC device implementation
>> hw/riscv: Add support for RISCV CPS
>> hw/riscv: Add support for MIPS Boston-aia board mode
>> hw/pci: Allow explicit function numbers in pci
>> riscv/boston-aia: Add an e1000e NIC in slot 0 func 1
>> test/functional: Add test for boston-aia board
>>
>> configs/devices/riscv64-softmmu/default.mak | 1 +
>> docs/system/riscv/mips.rst | 20 +
>> docs/system/target-riscv.rst | 1 +
>> hw/intc/riscv_aclint.c | 21 +-
>> hw/intc/riscv_aplic.c | 11 +-
>> hw/misc/Kconfig | 20 +
>> hw/misc/meson.build | 3 +
>> hw/misc/riscv_cmgcr.c | 234 ++++++++++
>> hw/misc/riscv_cpc.c | 239 ++++++++++
>> hw/pci/pci.c | 15 +-
>> hw/riscv/Kconfig | 6 +
>> hw/riscv/boston-aia.c | 489 ++++++++++++++++++++
>> hw/riscv/cps.c | 197 ++++++++
>> hw/riscv/meson.build | 3 +
>> include/hw/misc/riscv_cmgcr.h | 49 ++
>> include/hw/misc/riscv_cpc.h | 73 +++
>> include/hw/riscv/cps.h | 76 +++
>> target/riscv/cpu-qom.h | 1 +
>> target/riscv/cpu.c | 40 ++
>> target/riscv/cpu.h | 7 +
>> target/riscv/cpu_cfg.h | 6 +
>> target/riscv/cpu_cfg_fields.h.inc | 3 +
>> target/riscv/cpu_vendorid.h | 1 +
>> target/riscv/insn_trans/trans_xmips.c.inc | 142 ++++++
>> target/riscv/meson.build | 2 +
>> target/riscv/mips_csr.c | 228 +++++++++
>> target/riscv/translate.c | 3 +
>> target/riscv/xmips.decode | 35 ++
>> tests/functional/meson.build | 1 +
>> tests/functional/test_riscv64_boston.py | 78 ++++
>> 30 files changed, 1994 insertions(+), 11 deletions(-)
>> create mode 100644 docs/system/riscv/mips.rst
>> create mode 100644 hw/misc/riscv_cmgcr.c
>> create mode 100644 hw/misc/riscv_cpc.c
>> create mode 100644 hw/riscv/boston-aia.c
>> create mode 100644 hw/riscv/cps.c
>> create mode 100644 include/hw/misc/riscv_cmgcr.h
>> create mode 100644 include/hw/misc/riscv_cpc.h
>> create mode 100644 include/hw/riscv/cps.h
>> create mode 100644 target/riscv/insn_trans/trans_xmips.c.inc
>> create mode 100644 target/riscv/mips_csr.c
>> create mode 100644 target/riscv/xmips.decode
>> create mode 100755 tests/functional/test_riscv64_boston.py
>>
>
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU
2025-08-08 16:42 ` Philippe Mathieu-Daudé
@ 2025-09-01 8:15 ` Djordje Todorovic
0 siblings, 0 replies; 44+ messages in thread
From: Djordje Todorovic @ 2025-09-01 8:15 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
Hi Philippe,
We have considered implementing it as one module, but there
are changes between MIPS and RISC-V implementations that
make that very hard. For example, the reset base for CPC is
automatically set up for p8700.
I have addressed your comments regarding v6, and I am
preparing v7 for sending.
Thanks,
Djordje
On 8. 8. 25. 18:42, Philippe Mathieu-Daudé wrote:
> CAUTION: This email originated from outside of the organization. Do
> not click links or open attachments unless you recognize the sender
> and know the content is safe.
>
>
> Hi,
>
> On 17/7/25 11:38, Djordje Todorovic wrote:
>> I addressed several comments in this version, major ones:
>> - split CPC / CMGCR into separated changes
>> - split CPS into a separated change
>> - added functional tests for boston-aia board
>>
>> Djordje Todorovic (14):
>
>> hw/misc: Add RISC-V CMGCR device implementation
>> hw/misc: Add RISC-V CPC device implementation
>> hw/riscv: Add support for RISCV CPS
> I'm not keen on having theses models duplicated with the
> MIPS ones. Are the IPs really different? They are just
> dealing with bit masks to stop/start VPs AFAICT.
>
> Could we model them with plain CPUState objects instead?
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 01/14] hw/intc: Allow gaps in hartids for aclint and aplic
2025-08-08 15:52 ` Philippe Mathieu-Daudé
@ 2025-09-01 8:17 ` Djordje Todorovic
2025-09-01 11:05 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 44+ messages in thread
From: Djordje Todorovic @ 2025-09-01 8:17 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 8. 8. 25. 17:52, Philippe Mathieu-Daudé wrote:
> CAUTION: This email originated from outside of the organization. Do
> not click links or open attachments unless you recognize the sender
> and know the content is safe.
>
>
> On 17/7/25 11:38, Djordje Todorovic wrote:
>> This is needed for riscv based CPUs by MIPS since those may have
>> sparse hart-ID layouts. ACLINT and APLIC still assume a dense
>> range, and if a hart is missing, this causes NULL derefs.
>>
>> Signed-off-by: Chao-ying Fu <cfu@mips.com>
>> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
>> ---
>> hw/intc/riscv_aclint.c | 21 +++++++++++++++++++--
>> hw/intc/riscv_aplic.c | 11 ++++++++---
>> 2 files changed, 27 insertions(+), 5 deletions(-)
>>
>> diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
>> index b0139f03f5..22ac4133d5 100644
>> --- a/hw/intc/riscv_aclint.c
>> +++ b/hw/intc/riscv_aclint.c
>> @@ -292,7 +292,13 @@ static void
>> riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp)
>> s->timecmp = g_new0(uint64_t, s->num_harts);
>> /* Claim timer interrupt bits */
>> for (i = 0; i < s->num_harts; i++) {
>> - RISCVCPU *cpu = RISCV_CPU(cpu_by_arch_id(s->hartid_base + i));
>> + CPUState *cpu_by_hartid = cpu_by_arch_id(s->hartid_base + i);
>> + if (cpu_by_hartid == NULL) {
>> + qemu_log_mask(LOG_GUEST_ERROR, "aclint-mtimer: invalid
>> hartid: %u",
>> + s->hartid_base + i);
>
> DeviceRealize() handlers are part of machine modelling, not guest uses.
>
> IOW, triggering this is a programming mistake, so we should just
> abort() here.
Well, if we do it that way, our Boston board target for P8700 cannot run.
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 03/14] target/riscv: Add MIPS P8700 CPU
2025-08-08 17:02 ` Philippe Mathieu-Daudé
@ 2025-09-01 8:17 ` Djordje Todorovic
0 siblings, 0 replies; 44+ messages in thread
From: Djordje Todorovic @ 2025-09-01 8:17 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 8. 8. 25. 19:02, Philippe Mathieu-Daudé wrote:
> CAUTION: This email originated from outside of the organization. Do
> not click links or open attachments unless you recognize the sender
> and know the content is safe.
>
>
> On 17/7/25 11:38, Djordje Todorovic wrote:
>> Introduce P8700 CPU by MIPS.
>>
>> Signed-off-by: Chao-ying Fu <cfu@mips.com>
>> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
>> ---
>> target/riscv/cpu-qom.h | 1 +
>> target/riscv/cpu.c | 15 +++++++++++++++
>> target/riscv/cpu_vendorid.h | 1 +
>> 3 files changed, 17 insertions(+)
>
>
>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>> index e584bdc5ac..401c0f6c7d 100644
>> --- a/target/riscv/cpu.c
>> +++ b/target/riscv/cpu.c
>> @@ -3180,6 +3180,21 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>> .cfg.max_satp_mode = VM_1_10_SV39,
>> ),
>>
>
> Can we add the datasheet link here?
>
> /* https://mips.com/products/hardware/p8700/ */
>
Yes, I will add it in v7.
>> + DEFINE_RISCV_CPU(TYPE_RISCV_CPU_MIPS_P8700, TYPE_RISCV_VENDOR_CPU,
>> + .misa_mxl_max = MXL_RV64,
>> + .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU,
>> + .priv_spec = PRIV_VERSION_1_12_0,
>> + .cfg.max_satp_mode = VM_1_10_SV48,
>> + .cfg.ext_zifencei = true,
>> + .cfg.ext_zicsr = true,
>> + .cfg.mmu = true,
>> + .cfg.pmp = true,
>> + .cfg.ext_zba = true,
>> + .cfg.ext_zbb = true,
>> + .cfg.marchid = 0x8000000000000201,
>> + .cfg.mvendorid = MIPS_VENDOR_ID,
>> + ),
>
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 07/14] target/riscv: Add Xmipslsp instructions
2025-08-08 16:02 ` Philippe Mathieu-Daudé
@ 2025-09-01 8:20 ` Djordje Todorovic
2025-09-01 8:30 ` Djordje Todorovic
1 sibling, 0 replies; 44+ messages in thread
From: Djordje Todorovic @ 2025-09-01 8:20 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 8. 8. 25. 18:02, Philippe Mathieu-Daudé wrote:
> CAUTION: This email originated from outside of the organization. Do
> not click links or open attachments unless you recognize the sender
> and know the content is safe.
>
>
> On 17/7/25 11:38, Djordje Todorovic wrote:
>> Add MIPS P8700 ldp, lwp, sdp, swp instructions.
>>
>> Signed-off-by: Chao-ying Fu <cfu@mips.com>
>> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
>> ---
>> target/riscv/cpu.c | 3 +
>> target/riscv/cpu_cfg.h | 2 +-
>> target/riscv/cpu_cfg_fields.h.inc | 1 +
>> target/riscv/insn_trans/trans_xmips.c.inc | 84 +++++++++++++++++++++++
>> target/riscv/xmips.decode | 23 +++++++
>> 5 files changed, 112 insertions(+), 1 deletion(-)
>
>
>> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
>> index 9734963035..f35d477f27 100644
>> --- a/target/riscv/cpu_cfg.h
>> +++ b/target/riscv/cpu_cfg.h
>> @@ -39,7 +39,7 @@ static inline bool always_true_p(const
>> RISCVCPUConfig *cfg __attribute__((__unus
>>
>> static inline bool has_xmips_p(const RISCVCPUConfig *cfg)
>> {
>> - return cfg->ext_xmipscbop || cfg->ext_xmipscmov;
>> + return cfg->ext_xmipscbop || cfg->ext_xmipscmov ||
>> cfg->ext_xmipslsp;
>
> Checking for any XMIPS instruction implemented to return vendor
> extension presence seems odd. Can you implement them separately?
We followed what has already been upstreamed for xthead in the same file.
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 08/14] hw/misc: Add RISC-V CMGCR device implementation
2025-08-08 16:05 ` Philippe Mathieu-Daudé
@ 2025-09-01 8:22 ` Djordje Todorovic
0 siblings, 0 replies; 44+ messages in thread
From: Djordje Todorovic @ 2025-09-01 8:22 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 8. 8. 25. 18:05, Philippe Mathieu-Daudé wrote:
> CAUTION: This email originated from outside of the organization. Do
> not click links or open attachments unless you recognize the sender
> and know the content is safe.
>
>
> On 17/7/25 11:38, Djordje Todorovic wrote:
>> Add RISC-V implementation of the Coherent Manager Global Control
>> Register (CMGCR) device. It is based on the existing MIPS CMGCR
>> implementation but adapted for RISC-V systems.
>>
>> The CMGCR device provides global system control for multi-core
>> configurations in RISC-V systems.
>>
>> This is needed for the MIPS BOSTON AIA board.
>>
>> Signed-off-by: Chao-ying Fu <cfu@mips.com>
>> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
>> ---
>> hw/misc/Kconfig | 10 ++
>> hw/misc/meson.build | 2 +
>> hw/misc/riscv_cmgcr.c | 234 ++++++++++++++++++++++++++++++++++
>> include/hw/misc/riscv_cmgcr.h | 49 +++++++
>> 4 files changed, 295 insertions(+)
>> create mode 100644 hw/misc/riscv_cmgcr.c
>> create mode 100644 include/hw/misc/riscv_cmgcr.h
>>
>> diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
>> index ec0fa5aa9f..e3fce37c01 100644
>> --- a/hw/misc/Kconfig
>> +++ b/hw/misc/Kconfig
>> @@ -108,6 +108,16 @@ config STM32L4X5_RCC
>> config MIPS_ITU
>> bool
>>
>> +config RISCV_CMGCR
>> + bool
>> + default n
>
> $ git grep 'default n' $(git ls-files|fgrep Kconfig) | wc -l
> 0
>
> I remember asking that already but maybe it was a different
> series... Why don't you want this automatically selected by
> default? All our codebase does it, why change suddenly?
I agree, will apply this in v7 as well. Thanks!
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 08/14] hw/misc: Add RISC-V CMGCR device implementation
2025-08-08 16:07 ` Philippe Mathieu-Daudé
@ 2025-09-01 8:24 ` Djordje Todorovic
2025-09-01 10:53 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 44+ messages in thread
From: Djordje Todorovic @ 2025-09-01 8:24 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 8. 8. 25. 18:07, Philippe Mathieu-Daudé wrote:
> CAUTION: This email originated from outside of the organization. Do
> not click links or open attachments unless you recognize the sender
> and know the content is safe.
>
>
> On 8/8/25 18:00, Philippe Mathieu-Daudé wrote:
>> On 17/7/25 11:38, Djordje Todorovic wrote:
>>> Add RISC-V implementation of the Coherent Manager Global Control
>>> Register (CMGCR) device. It is based on the existing MIPS CMGCR
>>> implementation but adapted for RISC-V systems.
>>>
>>> The CMGCR device provides global system control for multi-core
>>> configurations in RISC-V systems.
>>>
>>> This is needed for the MIPS BOSTON AIA board.
>>>
>>> Signed-off-by: Chao-ying Fu <cfu@mips.com>
>>> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
>>> ---
>>> hw/misc/Kconfig | 10 ++
>>> hw/misc/meson.build | 2 +
>>> hw/misc/riscv_cmgcr.c | 234
>>> ++++++++++++++++++++++++++++++++++
>>> include/hw/misc/riscv_cmgcr.h | 49 +++++++
>>> 4 files changed, 295 insertions(+)
>>> create mode 100644 hw/misc/riscv_cmgcr.c
>>> create mode 100644 include/hw/misc/riscv_cmgcr.h
>>
>>
>>> +static void riscv_gcr_realize(DeviceState *dev, Error **errp)
>>> +{
>>> + RISCVGCRState *s = RISCV_GCR(dev);
>>
>> Please report an error for invalid num_vps values (0 or >MAX).
>
> Per the next patch:
>
> #define VPS_MAX 64
>
> Is it possible to have a config with 7, 24 or 35 vps?
>
64 is maximum, and we can have fewer than 64 vps.
So, yes, it is possible to have that configuration.
>>
>>> +
>>> + /* Create local set of registers for each VP */
>>> + s->vps = g_new(RISCVGCRVPState, s->num_vps);
>>> +}
>
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 08/14] hw/misc: Add RISC-V CMGCR device implementation
2025-08-08 16:00 ` Philippe Mathieu-Daudé
2025-08-08 16:07 ` Philippe Mathieu-Daudé
@ 2025-09-01 8:24 ` Djordje Todorovic
1 sibling, 0 replies; 44+ messages in thread
From: Djordje Todorovic @ 2025-09-01 8:24 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 8. 8. 25. 18:00, Philippe Mathieu-Daudé wrote:
> CAUTION: This email originated from outside of the organization. Do
> not click links or open attachments unless you recognize the sender
> and know the content is safe.
>
>
> On 17/7/25 11:38, Djordje Todorovic wrote:
>> Add RISC-V implementation of the Coherent Manager Global Control
>> Register (CMGCR) device. It is based on the existing MIPS CMGCR
>> implementation but adapted for RISC-V systems.
>>
>> The CMGCR device provides global system control for multi-core
>> configurations in RISC-V systems.
>>
>> This is needed for the MIPS BOSTON AIA board.
>>
>> Signed-off-by: Chao-ying Fu <cfu@mips.com>
>> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
>> ---
>> hw/misc/Kconfig | 10 ++
>> hw/misc/meson.build | 2 +
>> hw/misc/riscv_cmgcr.c | 234 ++++++++++++++++++++++++++++++++++
>> include/hw/misc/riscv_cmgcr.h | 49 +++++++
>> 4 files changed, 295 insertions(+)
>> create mode 100644 hw/misc/riscv_cmgcr.c
>> create mode 100644 include/hw/misc/riscv_cmgcr.h
>
>
>> +static void riscv_gcr_realize(DeviceState *dev, Error **errp)
>> +{
>> + RISCVGCRState *s = RISCV_GCR(dev);
>
> Please report an error for invalid num_vps values (0 or >MAX).
>
I will do it in v7. Thanks!
>> +
>> + /* Create local set of registers for each VP */
>> + s->vps = g_new(RISCVGCRVPState, s->num_vps);
>> +}
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 07/14] target/riscv: Add Xmipslsp instructions
2025-08-08 16:02 ` Philippe Mathieu-Daudé
2025-09-01 8:20 ` Djordje Todorovic
@ 2025-09-01 8:30 ` Djordje Todorovic
2025-09-01 11:09 ` Philippe Mathieu-Daudé
1 sibling, 1 reply; 44+ messages in thread
From: Djordje Todorovic @ 2025-09-01 8:30 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 8. 8. 25. 18:02, Philippe Mathieu-Daudé wrote:
> CAUTION: This email originated from outside of the organization. Do
> not click links or open attachments unless you recognize the sender
> and know the content is safe.
>
>
> On 17/7/25 11:38, Djordje Todorovic wrote:
>> Add MIPS P8700 ldp, lwp, sdp, swp instructions.
>>
>> Signed-off-by: Chao-ying Fu <cfu@mips.com>
>> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
>> ---
>> target/riscv/cpu.c | 3 +
>> target/riscv/cpu_cfg.h | 2 +-
>> target/riscv/cpu_cfg_fields.h.inc | 1 +
>> target/riscv/insn_trans/trans_xmips.c.inc | 84 +++++++++++++++++++++++
>> target/riscv/xmips.decode | 23 +++++++
>> 5 files changed, 112 insertions(+), 1 deletion(-)
>
>
>> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
>> index 9734963035..f35d477f27 100644
>> --- a/target/riscv/cpu_cfg.h
>> +++ b/target/riscv/cpu_cfg.h
>> @@ -39,7 +39,7 @@ static inline bool always_true_p(const
>> RISCVCPUConfig *cfg __attribute__((__unus
>>
>> static inline bool has_xmips_p(const RISCVCPUConfig *cfg)
>> {
>> - return cfg->ext_xmipscbop || cfg->ext_xmipscmov;
>> + return cfg->ext_xmipscbop || cfg->ext_xmipscmov ||
>> cfg->ext_xmipslsp;
>
> Checking for any XMIPS instruction implemented to return vendor
> extension presence seems odd. Can you implement them separately?
And I tried several options, but it only made the code even "more off" :(
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 10/14] hw/riscv: Add support for RISCV CPS
2025-08-08 16:26 ` Philippe Mathieu-Daudé
@ 2025-09-01 8:30 ` Djordje Todorovic
0 siblings, 0 replies; 44+ messages in thread
From: Djordje Todorovic @ 2025-09-01 8:30 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 8. 8. 25. 18:26, Philippe Mathieu-Daudé wrote:
> CAUTION: This email originated from outside of the organization. Do
> not click links or open attachments unless you recognize the sender
> and know the content is safe.
>
>
> On 17/7/25 11:38, Djordje Todorovic wrote:
>> Add support for the Coherent Processing System for RISC-V.
>> This enables SMP support for RISC-V boards that require
>> cache-coherent multiprocessor systems.
>>
>> Signed-off-by: Chao-ying Fu <cfu@mips.com>
>> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
>> ---
>> hw/misc/Kconfig | 5 ++
>> hw/riscv/cps.c | 197 +++++++++++++++++++++++++++++++++++++++++
>> hw/riscv/meson.build | 2 +
>> include/hw/riscv/cps.h | 76 ++++++++++++++++
>> 4 files changed, 280 insertions(+)
>> create mode 100644 hw/riscv/cps.c
>> create mode 100644 include/hw/riscv/cps.h
>
>
>> +static void main_cpu_reset(void *opaque)
>> +{
>> + RISCVCPU *cpu = opaque;
>> + CPUState *cs = CPU(cpu);
>
> If you call in [*]:
>
> qemu_register_reset(main_cpu_reset, s->cpus[i]);
>
> then here you can just do:
>
> CPUState *cs = opaque;
>
>> +
>> + cpu_reset(cs);
>> +}
>> +
>> +static void riscv_cps_realize(DeviceState *dev, Error **errp)
>> +{
>> + RISCVCPSState *s = RISCV_CPS(dev);
>> + RISCVCPU *cpu;
>> + int i;
>> +
>
> Please check num_vp range.
>
>> + /* Allocate CPU array */
>> + s->cpus = g_new0(CPUState *, s->num_vp);
>> +
>> + /* Set up cpu_index and mhartid for avaiable CPUs. */
>> + int harts_in_cluster = s->num_hart * s->num_core;
>> + int num_of_clusters = s->num_vp / harts_in_cluster;
>> + for (i = 0; i < s->num_vp; i++) {
>> + cpu = RISCV_CPU(object_new(s->cpu_type));
>> +
>> + /* All VPs are halted on reset. Leave powering up to CPC. */
>> + object_property_set_bool(OBJECT(cpu), "start-powered-off",
>> true,
>> + &error_abort);
>> +
>> + if (!qdev_realize_and_unref(DEVICE(cpu), NULL, errp)) {
>> + return;
>> + }
>> +
>> + /* Store CPU in array */
>> + s->cpus[i] = CPU(cpu);
>> +
>> + /* Set up mhartid */
>> + int cluster_id = i / harts_in_cluster;
>> + int hart_id = (i % harts_in_cluster) % s->num_hart;
>> + int core_id = (i % harts_in_cluster) / s->num_hart;
>> + int mhartid = (cluster_id << MHARTID_CLUSTER_SHIFT) +
>> + (core_id << MHARTID_CORE_SHIFT) +
>> + (hart_id << MHARTID_HART_SHIFT);
>> + cpu->env.mhartid = mhartid;
>> + qemu_register_reset(main_cpu_reset, cpu);
>
> [*]
>
>> + }
>> +
>> + /* Cluster Power Controller */
>> + object_initialize_child(OBJECT(dev), "cpc", &s->cpc,
>> TYPE_RISCV_CPC);
>> + object_property_set_uint(OBJECT(&s->cpc), "cluster-id", 0,
>> + &error_abort);
>> + object_property_set_uint(OBJECT(&s->cpc), "num-vp", s->num_vp,
>> + &error_abort);
>> + object_property_set_uint(OBJECT(&s->cpc), "num-hart", s->num_hart,
>> + &error_abort);
>> + object_property_set_uint(OBJECT(&s->cpc), "num-core", s->num_core,
>> + &error_abort);
>> + object_property_set_int(OBJECT(&s->cpc), "vp-start-running", 1,
>> + &error_abort);
>
> (1 is already the default)
>
>> +
>> + /* Pass CPU array to CPC */
>> + s->cpc.cpus = s->cpus;
>
> Please do that using a link property.
>
>> +
>> + if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpc), errp)) {
>> + return;
>> + }
>> +
>> + memory_region_add_subregion(&s->container, 0,
>> + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpc), 0));
>> +
>> + /* Global Configuration Registers */
>> + object_initialize_child(OBJECT(dev), "gcr", &s->gcr,
>> TYPE_RISCV_GCR);
>> + object_property_set_uint(OBJECT(&s->gcr), "cluster-id", 0,
>> + &error_abort);
>> + object_property_set_uint(OBJECT(&s->gcr), "num-vp", s->num_vp,
>> + &error_abort);
>> + object_property_set_int(OBJECT(&s->gcr), "gcr-rev", 0xa00,
>> + &error_abort);
>> + object_property_set_int(OBJECT(&s->gcr), "gcr-base", s->gcr_base,
>> + &error_abort);
>> + object_property_set_link(OBJECT(&s->gcr), "cpc",
>> OBJECT(&s->cpc.mr),
>> + &error_abort);
>> + if (!sysbus_realize(SYS_BUS_DEVICE(&s->gcr), errp)) {
>> + return;
>> + }
>> +
>> + memory_region_add_subregion(&s->container, s->gcr_base,
>> + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gcr), 0));
>> +
>> + for (i = 0; i < num_of_clusters; i++) {
>> + uint64_t cm_base = GLOBAL_CM_BASE + (CM_SIZE * i);
>> + uint32_t hartid_base = i << MHARTID_CLUSTER_SHIFT;
>> + s->aplic = riscv_aplic_create(cm_base + AIA_PLIC_M_OFFSET,
>> + AIA_PLIC_M_SIZE,
>> + hartid_base, /* hartid_base */
>> + MAX_HARTS, /* num_harts */
>> + APLIC_NUM_SOURCES,
>> + APLIC_NUM_PRIO_BITS,
>> + false, true, NULL);
>> + riscv_aplic_create(cm_base + AIA_PLIC_S_OFFSET,
>> + AIA_PLIC_S_SIZE,
>> + hartid_base, /* hartid_base */
>> + MAX_HARTS, /* num_harts */
>> + APLIC_NUM_SOURCES,
>> + APLIC_NUM_PRIO_BITS,
>> + false, false, s->aplic);
>> + /* PLIC changes msi_nonbroken to ture. We revert the change. */
>> + msi_nonbroken = false;
>> + riscv_aclint_swi_create(cm_base + AIA_CLINT_OFFSET,
>> + hartid_base, MAX_HARTS, false);
>> + riscv_aclint_mtimer_create(cm_base + AIA_CLINT_OFFSET +
>> + RISCV_ACLINT_SWI_SIZE,
>> + RISCV_ACLINT_DEFAULT_MTIMER_SIZE,
>> + hartid_base,
>> + MAX_HARTS,
>> + RISCV_ACLINT_DEFAULT_MTIMECMP,
>> + RISCV_ACLINT_DEFAULT_MTIME,
>> + RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, false);
>> + }
>> +}
Thank you! I will address it within v7.
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 12/14] hw/pci: Allow explicit function numbers in pci
2025-08-08 16:29 ` Philippe Mathieu-Daudé
@ 2025-09-01 8:31 ` Djordje Todorovic
0 siblings, 0 replies; 44+ messages in thread
From: Djordje Todorovic @ 2025-09-01 8:31 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 8. 8. 25. 18:29, Philippe Mathieu-Daudé wrote:
> CAUTION: This email originated from outside of the organization. Do
> not click links or open attachments unless you recognize the sender
> and know the content is safe.
>
>
> On 17/7/25 11:38, Djordje Todorovic wrote:
>> Since there is no pch_gbe emulation, we could be using func other
>> than 0 when adding new devices to specific boards.
>>
>> Signed-off-by: Chao-ying Fu <cfu@mips.com>
>> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
>> ---
>> hw/pci/pci.c | 15 +++++++++------
>> 1 file changed, 9 insertions(+), 6 deletions(-)
>>
>> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
>> index f5ab510697..23f7f02837 100644
>> --- a/hw/pci/pci.c
>> +++ b/hw/pci/pci.c
>> @@ -974,14 +974,15 @@ static int pci_parse_devaddr(const char *addr,
>> int *domp, int *busp,
>>
>> slot = val;
>>
>> - if (funcp != NULL) {
>> - if (*e != '.')
>> + if (funcp != NULL && *e != 0) {
>> + if (*e != '.') {
>> return -1;
>> -
>> + }
>> p = e + 1;
>> val = strtoul(p, &e, 16);
>> - if (e == p)
>> + if (e == p) {
>> return -1;
>> + }
>>
>> func = val;
>> }
>> @@ -2045,13 +2046,15 @@ bool pci_init_nic_in_slot(PCIBus *rootbus,
>> const char *model,
>> int dom, busnr, devfn;
>> PCIDevice *pci_dev;
>> unsigned slot;
>> +
>
> [*]
>
>> PCIBus *bus;
>>
>> if (!nd) {
>> return false;
>> }
>>
>> - if (!devaddr || pci_parse_devaddr(devaddr, &dom, &busnr, &slot,
>> NULL) < 0) {
>> + unsigned func;
>
> Declare 'func' earlier in [*], otherwise LGTM.
>
>> + if (!devaddr || pci_parse_devaddr(devaddr, &dom, &busnr, &slot,
>> &func) < 0) {
>> error_report("Invalid PCI device address %s for device %s",
>> devaddr, model);
>> exit(1);
>> @@ -2062,7 +2065,7 @@ bool pci_init_nic_in_slot(PCIBus *rootbus,
>> const char *model,
>> exit(1);
>> }
>>
>> - devfn = PCI_DEVFN(slot, 0);
>> + devfn = PCI_DEVFN(slot, func);
>>
>> bus = pci_find_bus_nr(rootbus, busnr);
>> if (!bus) {
>
Thank you! I will address this in v7.
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 14/14] test/functional: Add test for boston-aia board
2025-08-08 16:32 ` Philippe Mathieu-Daudé
@ 2025-09-01 8:35 ` Djordje Todorovic
0 siblings, 0 replies; 44+ messages in thread
From: Djordje Todorovic @ 2025-09-01 8:35 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com,
Thomas Huth
On 8. 8. 25. 18:32, Philippe Mathieu-Daudé wrote:
> CAUTION: This email originated from outside of the organization. Do
> not click links or open attachments unless you recognize the sender
> and know the content is safe.
>
>
> Hi,
>
> On 17/7/25 11:38, Djordje Todorovic wrote:
>> Add functional test for Boston AIA board. The P8700 RISC-V based
>> CPU by MIPS supports it at the moment.
>>
>> Signed-off-by: Chao-ying Fu <cfu@mips.com>
>> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
>> ---
>> tests/functional/meson.build | 1 +
>> tests/functional/test_riscv64_boston.py | 78 +++++++++++++++++++++++++
>> 2 files changed, 79 insertions(+)
>> create mode 100755 tests/functional/test_riscv64_boston.py
>
>
>> diff --git a/tests/functional/test_riscv64_boston.py
>> b/tests/functional/test_riscv64_boston.py
>> new file mode 100755
>> index 0000000000..eb5dd07b79
>> --- /dev/null
>> +++ b/tests/functional/test_riscv64_boston.py
>> @@ -0,0 +1,78 @@
>> +#!/usr/bin/env python3
>> +#
>> +# Boston board test for RISC-V P8700 processor by MIPS
>> +#
>> +# Copyright (c) 2025 MIPS
>> +#
>> +# SPDX-License-Identifier: LGPL-2.1-or-later
>> +#
>> +
>> +from qemu_test import QemuSystemTest
>> +
>> +class RiscvBostonTest(QemuSystemTest):
>> + """
>> + Test the boston-aia board with P8700 processor
>> + """
>> +
>> + timeout = 10
>> +
>> + def test_boston_memory_constraints(self):
>> + """
>> + Test that boston-aia board enforces memory size constraints
>> + """
>> + # Test invalid memory size
>> + self.set_machine('boston-aia')
>> + self.vm.add_args('-cpu', 'mips-p8700')
>> + self.vm.add_args('-m', '512M') # Invalid size
>> + self.vm.add_args('-nographic')
>> + self.vm.set_qmp_monitor(enabled=False)
>> + self.vm.launch()
>> + self.vm.wait()
>> +
>> + # Should fail due to invalid memory size
>> + self.assertEqual(self.vm.exitcode(), 1)
>> + log = self.vm.get_log()
>> + self.assertIn("Memory size must be 1GB, 2GB, 3GB, or 4GB", log)
>> +
>> + def test_boston_requires_kernel(self):
>> + """
>> + Test that boston-aia board requires a kernel or bios
>> + """
>> + self.set_machine('boston-aia')
>> + self.vm.add_args('-cpu', 'mips-p8700')
>> + self.vm.add_args('-m', '1G') # Valid size
>> + self.vm.add_args('-nographic')
>> + # No kernel or bios specified
>> + self.vm.set_qmp_monitor(enabled=False)
>> + self.vm.launch()
>> + self.vm.wait()
>> +
>> + # Should fail due to missing kernel/bios
>> + self.assertEqual(self.vm.exitcode(), 1)
>> + log = self.vm.get_log()
>> + self.assertIn("Please provide either a -kernel or -bios
>> argument", log)
>> +
>> + def test_boston_cpu_count(self):
>> + """
>> + Test various CPU counts for boston-aia board
>> + """
>> + cpu_counts = [1, 2, 4, 8]
>> +
>> + for cpus in cpu_counts:
>> + with self.subTest(cpus=cpus):
>> + self.set_machine('boston-aia')
>> + self.vm.add_args('-cpu', 'mips-p8700')
>> + self.vm.add_args('-smp', str(cpus))
>> + self.vm.add_args('-m', '1G')
>> + self.vm.add_args('-nographic')
>> + self.vm.set_qmp_monitor(enabled=False)
>> + self.vm.launch()
>> + self.vm.wait()
>> +
>> + # Board should fail due to missing kernel, not CPU
>> count
>> + self.assertEqual(self.vm.exitcode(), 1)
>> + log = self.vm.get_log()
>> + self.assertIn("Please provide either a -kernel or
>> -bios argument", log)
>> +
>> +if __name__ == '__main__':
>> + QemuSystemTest.main()
>
> Thanks for testing these constraints, but can we have guest code
> actually exercising the code path to the XMIPS instructions?
>
> Also code testing powering VPs up/down, to cover CPS, GCR and CPC.
>
> Code using the e1000e card would be awesome ;)
>
> Thanks,
>
> Phil.
Thanks a lot Phil! :)
I agree.
We created https://github.com/MIPS/linux-test-downloads/, and I will
follow what was done for other architectures and make a proper test
that checks Linux boot that contains XMIPS instructions as well as
to cover other features we are adding here.
Will be part of v7.
Best,
Djordje
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 08/14] hw/misc: Add RISC-V CMGCR device implementation
2025-09-01 8:24 ` Djordje Todorovic
@ 2025-09-01 10:53 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 44+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-09-01 10:53 UTC (permalink / raw)
To: Djordje Todorovic, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 1/9/25 10:24, Djordje Todorovic wrote:
>
> On 8. 8. 25. 18:07, Philippe Mathieu-Daudé wrote:
>> CAUTION: This email originated from outside of the organization. Do
>> not click links or open attachments unless you recognize the sender
>> and know the content is safe.
>>
>>
>> On 8/8/25 18:00, Philippe Mathieu-Daudé wrote:
>>> On 17/7/25 11:38, Djordje Todorovic wrote:
>>>> Add RISC-V implementation of the Coherent Manager Global Control
>>>> Register (CMGCR) device. It is based on the existing MIPS CMGCR
>>>> implementation but adapted for RISC-V systems.
>>>>
>>>> The CMGCR device provides global system control for multi-core
>>>> configurations in RISC-V systems.
>>>>
>>>> This is needed for the MIPS BOSTON AIA board.
>>>>
>>>> Signed-off-by: Chao-ying Fu <cfu@mips.com>
>>>> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
>>>> ---
>>>> hw/misc/Kconfig | 10 ++
>>>> hw/misc/meson.build | 2 +
>>>> hw/misc/riscv_cmgcr.c | 234
>>>> ++++++++++++++++++++++++++++++++++
>>>> include/hw/misc/riscv_cmgcr.h | 49 +++++++
>>>> 4 files changed, 295 insertions(+)
>>>> create mode 100644 hw/misc/riscv_cmgcr.c
>>>> create mode 100644 include/hw/misc/riscv_cmgcr.h
>>>
>>>
>>>> +static void riscv_gcr_realize(DeviceState *dev, Error **errp)
>>>> +{
>>>> + RISCVGCRState *s = RISCV_GCR(dev);
>>>
>>> Please report an error for invalid num_vps values (0 or >MAX).
>>
>> Per the next patch:
>>
>> #define VPS_MAX 64
>>
>> Is it possible to have a config with 7, 24 or 35 vps?
>>
> 64 is maximum, and we can have fewer than 64 vps.
> So, yes, it is possible to have that configuration.
Please provide a test with 7 and 35 VPs then.
Thanks!
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 01/14] hw/intc: Allow gaps in hartids for aclint and aplic
2025-09-01 8:17 ` Djordje Todorovic
@ 2025-09-01 11:05 ` Philippe Mathieu-Daudé
2025-09-03 12:35 ` Djordje Todorovic
0 siblings, 1 reply; 44+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-09-01 11:05 UTC (permalink / raw)
To: Djordje Todorovic, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 1/9/25 10:17, Djordje Todorovic wrote:
> On 8. 8. 25. 17:52, Philippe Mathieu-Daudé wrote:
>
>> CAUTION: This email originated from outside of the organization. Do
>> not click links or open attachments unless you recognize the sender
>> and know the content is safe.
>>
>>
>> On 17/7/25 11:38, Djordje Todorovic wrote:
>>> This is needed for riscv based CPUs by MIPS since those may have
>>> sparse hart-ID layouts. ACLINT and APLIC still assume a dense
>>> range, and if a hart is missing, this causes NULL derefs.
>>>
>>> Signed-off-by: Chao-ying Fu <cfu@mips.com>
>>> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
>>> ---
>>> hw/intc/riscv_aclint.c | 21 +++++++++++++++++++--
>>> hw/intc/riscv_aplic.c | 11 ++++++++---
>>> 2 files changed, 27 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
>>> index b0139f03f5..22ac4133d5 100644
>>> --- a/hw/intc/riscv_aclint.c
>>> +++ b/hw/intc/riscv_aclint.c
>>> @@ -292,7 +292,13 @@ static void
>>> riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp)
>>> s->timecmp = g_new0(uint64_t, s->num_harts);
>>> /* Claim timer interrupt bits */
>>> for (i = 0; i < s->num_harts; i++) {
>>> - RISCVCPU *cpu = RISCV_CPU(cpu_by_arch_id(s->hartid_base + i));
>>> + CPUState *cpu_by_hartid = cpu_by_arch_id(s->hartid_base + i);
>>> + if (cpu_by_hartid == NULL) {
>>> + qemu_log_mask(LOG_GUEST_ERROR, "aclint-mtimer: invalid
>>> hartid: %u",
>>> + s->hartid_base + i);
>>
>> DeviceRealize() handlers are part of machine modelling, not guest uses.
>>
>> IOW, triggering this is a programming mistake, so we should just
>> abort() here.
>
> Well, if we do it that way, our Boston board target for P8700 cannot run.
So the problem is elsewhere :)
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 07/14] target/riscv: Add Xmipslsp instructions
2025-09-01 8:30 ` Djordje Todorovic
@ 2025-09-01 11:09 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 44+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-09-01 11:09 UTC (permalink / raw)
To: Djordje Todorovic, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 1/9/25 10:30, Djordje Todorovic wrote:
>
> On 8. 8. 25. 18:02, Philippe Mathieu-Daudé wrote:
>> CAUTION: This email originated from outside of the organization. Do
>> not click links or open attachments unless you recognize the sender
>> and know the content is safe.
>>
>>
>> On 17/7/25 11:38, Djordje Todorovic wrote:
>>> Add MIPS P8700 ldp, lwp, sdp, swp instructions.
>>>
>>> Signed-off-by: Chao-ying Fu <cfu@mips.com>
>>> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
>>> ---
>>> target/riscv/cpu.c | 3 +
>>> target/riscv/cpu_cfg.h | 2 +-
>>> target/riscv/cpu_cfg_fields.h.inc | 1 +
>>> target/riscv/insn_trans/trans_xmips.c.inc | 84 +++++++++++++++++++++++
>>> target/riscv/xmips.decode | 23 +++++++
>>> 5 files changed, 112 insertions(+), 1 deletion(-)
>>
>>
>>> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
>>> index 9734963035..f35d477f27 100644
>>> --- a/target/riscv/cpu_cfg.h
>>> +++ b/target/riscv/cpu_cfg.h
>>> @@ -39,7 +39,7 @@ static inline bool always_true_p(const
>>> RISCVCPUConfig *cfg __attribute__((__unus
>>>
>>> static inline bool has_xmips_p(const RISCVCPUConfig *cfg)
>>> {
>>> - return cfg->ext_xmipscbop || cfg->ext_xmipscmov;
>>> + return cfg->ext_xmipscbop || cfg->ext_xmipscmov ||
>>> cfg->ext_xmipslsp;
>>
>> Checking for any XMIPS instruction implemented to return vendor
>> extension presence seems odd. Can you implement them separately?
>
> And I tried several options, but it only made the code even "more off" :(
OK, maybe this is the correct way to go then.
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH v6 01/14] hw/intc: Allow gaps in hartids for aclint and aplic
2025-09-01 11:05 ` Philippe Mathieu-Daudé
@ 2025-09-03 12:35 ` Djordje Todorovic
0 siblings, 0 replies; 44+ messages in thread
From: Djordje Todorovic @ 2025-09-03 12:35 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, cfu@mips.com, mst@redhat.com,
marcel.apfelbaum@gmail.com, dbarboza@ventanamicro.com
On 1. 9. 25. 13:05, Philippe Mathieu-Daudé wrote:
> CAUTION: This email originated from outside of the organization. Do
> not click links or open attachments unless you recognize the sender
> and know the content is safe.
>
>
> On 1/9/25 10:17, Djordje Todorovic wrote:
>> On 8. 8. 25. 17:52, Philippe Mathieu-Daudé wrote:
>>
>>> CAUTION: This email originated from outside of the organization. Do
>>> not click links or open attachments unless you recognize the sender
>>> and know the content is safe.
>>>
>>>
>>> On 17/7/25 11:38, Djordje Todorovic wrote:
>>>> This is needed for riscv based CPUs by MIPS since those may have
>>>> sparse hart-ID layouts. ACLINT and APLIC still assume a dense
>>>> range, and if a hart is missing, this causes NULL derefs.
>>>>
>>>> Signed-off-by: Chao-ying Fu <cfu@mips.com>
>>>> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
>>>> ---
>>>> hw/intc/riscv_aclint.c | 21 +++++++++++++++++++--
>>>> hw/intc/riscv_aplic.c | 11 ++++++++---
>>>> 2 files changed, 27 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
>>>> index b0139f03f5..22ac4133d5 100644
>>>> --- a/hw/intc/riscv_aclint.c
>>>> +++ b/hw/intc/riscv_aclint.c
>>>> @@ -292,7 +292,13 @@ static void
>>>> riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp)
>>>> s->timecmp = g_new0(uint64_t, s->num_harts);
>>>> /* Claim timer interrupt bits */
>>>> for (i = 0; i < s->num_harts; i++) {
>>>> - RISCVCPU *cpu = RISCV_CPU(cpu_by_arch_id(s->hartid_base +
>>>> i));
>>>> + CPUState *cpu_by_hartid = cpu_by_arch_id(s->hartid_base + i);
>>>> + if (cpu_by_hartid == NULL) {
>>>> + qemu_log_mask(LOG_GUEST_ERROR, "aclint-mtimer: invalid
>>>> hartid: %u",
>>>> + s->hartid_base + i);
>>>
>>> DeviceRealize() handlers are part of machine modelling, not guest uses.
>>>
>>> IOW, triggering this is a programming mistake, so we should just
>>> abort() here.
>>
>> Well, if we do it that way, our Boston board target for P8700 cannot
>> run.
>
> So the problem is elsewhere :)
I see. Would something like this be acceptable:
--- a/hw/intc/riscv_aclint.c
+++ b/hw/intc/riscv_aclint.c
@@ -279,7 +279,7 @@ static const Property
riscv_aclint_mtimer_properties[] = {
static void riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp)
{
RISCVAclintMTimerState *s = RISCV_ACLINT_MTIMER(dev);
- int i;
+ CPUState *cpu;
memory_region_init_io(&s->mmio, OBJECT(dev), &riscv_aclint_mtimer_ops,
s, TYPE_RISCV_ACLINT_MTIMER, s->aperture_size);
@@ -291,18 +291,15 @@ static void
riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp)
s->timers = g_new0(QEMUTimer *, s->num_harts);
s->timecmp = g_new0(uint64_t, s->num_harts);
/* Claim timer interrupt bits */
- for (i = 0; i < s->num_harts; i++) {
- CPUState *cpu_by_hartid = cpu_by_arch_id(s->hartid_base + i);
- if (cpu_by_hartid == NULL) {
- qemu_log_mask(LOG_GUEST_ERROR, "aclint-mtimer: invalid
hartid: %u",
- s->hartid_base + i);
- continue;
- }
- RISCVCPU *cpu = RISCV_CPU(cpu_by_hartid);
- if (riscv_cpu_claim_interrupts(cpu, MIP_MTIP) < 0) {
- error_report("MTIP already claimed");
- exit(1);
- }
+ CPU_FOREACH(cpu) {
+ if (cpu == NULL)
+ abort();
+
+ RISCVCPU *cpu_riscv = RISCV_CPU(cpu);
+ if (riscv_cpu_claim_interrupts(cpu_riscv, MIP_MTIP) < 0) {
+ error_report("MTIP already claimed");
+ exit(1);
+ }
}
}
Thanks,
Djordje
^ permalink raw reply [flat|nested] 44+ messages in thread
end of thread, other threads:[~2025-09-03 12:36 UTC | newest]
Thread overview: 44+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-17 9:38 [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 01/14] hw/intc: Allow gaps in hartids for aclint and aplic Djordje Todorovic
2025-08-08 15:52 ` Philippe Mathieu-Daudé
2025-09-01 8:17 ` Djordje Todorovic
2025-09-01 11:05 ` Philippe Mathieu-Daudé
2025-09-03 12:35 ` Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 02/14] target/riscv: Add cpu_set_exception_base Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 03/14] target/riscv: Add MIPS P8700 CPU Djordje Todorovic
2025-08-08 17:02 ` Philippe Mathieu-Daudé
2025-09-01 8:17 ` Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 04/14] target/riscv: Add MIPS P8700 CSRs Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 05/14] target/riscv: Add mips.ccmov instruction Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 06/14] target/riscv: Add mips.pref instruction Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 08/14] hw/misc: Add RISC-V CMGCR device implementation Djordje Todorovic
2025-08-08 16:00 ` Philippe Mathieu-Daudé
2025-08-08 16:07 ` Philippe Mathieu-Daudé
2025-09-01 8:24 ` Djordje Todorovic
2025-09-01 10:53 ` Philippe Mathieu-Daudé
2025-09-01 8:24 ` Djordje Todorovic
2025-08-08 16:05 ` Philippe Mathieu-Daudé
2025-09-01 8:22 ` Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 09/14] hw/misc: Add RISC-V CPC " Djordje Todorovic
2025-08-08 16:21 ` Philippe Mathieu-Daudé
2025-07-17 9:38 ` [PATCH v6 07/14] target/riscv: Add Xmipslsp instructions Djordje Todorovic
2025-08-08 16:02 ` Philippe Mathieu-Daudé
2025-09-01 8:20 ` Djordje Todorovic
2025-09-01 8:30 ` Djordje Todorovic
2025-09-01 11:09 ` Philippe Mathieu-Daudé
2025-07-17 9:38 ` [PATCH v6 10/14] hw/riscv: Add support for RISCV CPS Djordje Todorovic
2025-08-08 16:26 ` Philippe Mathieu-Daudé
2025-09-01 8:30 ` Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 11/14] hw/riscv: Add support for MIPS Boston-aia board mode Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 13/14] riscv/boston-aia: Add an e1000e NIC in slot 0 func 1 Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 12/14] hw/pci: Allow explicit function numbers in pci Djordje Todorovic
2025-08-08 16:29 ` Philippe Mathieu-Daudé
2025-09-01 8:31 ` Djordje Todorovic
2025-07-17 9:38 ` [PATCH v6 14/14] test/functional: Add test for boston-aia board Djordje Todorovic
2025-08-08 16:32 ` Philippe Mathieu-Daudé
2025-09-01 8:35 ` Djordje Todorovic
2025-08-05 10:10 ` [PATCH v6 00/14] riscv: Add support for MIPS P8700 CPU Djordje Todorovic
2025-08-07 18:35 ` Daniel Henrique Barboza
2025-09-01 8:07 ` Djordje Todorovic
2025-08-08 16:42 ` Philippe Mathieu-Daudé
2025-09-01 8:15 ` Djordje Todorovic
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).