mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'pull-riscv-to-apply-20250704' of https://github.com/alistair23/qemu into staging
Second RISC-V PR for 10.1 * sstc extension fixes * Fix zama16b order in isa_edata_arr * Profile handling fixes * Extend PMP region up to 64 * Remove capital 'Z' CPU properties * Add missing named features * Support atomic instruction fetch (Ziccif) * Add max_satp_mode from host cpu * Extend and configure PMP region count * Fix PPN field of Translation-reponse register * Use qemu_chr_fe_write_all() in DBCN_CONSOLE_WRITE_BYTE * Fix fcvt.s.bf16 NaN box checking * Avoid infinite delay of async xmit function * Device tree reg cleanups * Add Kunminghu CPU and platform * Fix missing exit TB flow for ldff_trans * Fix migration failure when aia is configured as aplic-imsic * Fix MEPC/SEPC bit masking for IALIGN * Add a property to set vill bit on reserved usage of vsetvli instruction * Add Svrsw60t59b extension support # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCgAdFiEEaukCtqfKh31tZZKWr3yVEwxTgBMFAmhntt4ACgkQr3yVEwxT # gBMaCQ/9E+LeRY59nz3K3XXUw6XLBfaDECXbKzIn0GM1yXeWTX4dB2h2hoGWdu3R # CRPxWHECN7CeJhd2J23eLfOi+fTUeppJBeR7TcGyoXVC+y0knZv/clQ3OvMFYcgV # xjzzu1yipQlXwY+kmDZ6qL5up/Q+faw7tRaePZaJheRGYpVRnjoKUZq5fe4Ug4RU # Xg6Di86eYyk+Jo0g2exvtzy1rX2eBp7Hz200wWiH5Z1B+3NzgMUHrHuJfNAz8zAt # n8uvruvaLGGtWcQJauRXlAELR6k9tmkfq1Mbqf3FK6muaQCtFD7PXXnjL/rU/z20 # hhxj0psOhBJLd0W5wQ3vLnDf6Wve9zmUdTR9kI0Kt3xUUdfeBuzKcU06F/G8wEsZ # 2sIYQqt0mxoJboY2lpje7TO4H9gvAf76WBOV10FV2gWsqWu2rZQ6herdq3YZYkHX # purUTgyjHn4jl2Y3Kzj0Gq1SHo0yaA/sD6xNR8X+JqljSruDxtOFU7wkKBbewoIg # OSfwemjRUVsPQZ958042ntwJt81v1604Oky8JSFr5eCFx/aoLJ1vDYh7BKZAogNH # uB/YigGq9+/MVzqJpZI+kZkd+1nzaizeL0FUPRTq0jFA2u+vc3J3svQ/jNXDH2c+ # 5nGuhbkvT0ptmVMBqFV2vjPh6+ScR8t03wHdQ4PmDoXC3o9zbbU= # =CfRy # -----END PGP SIGNATURE----- # gpg: Signature made Fri 04 Jul 2025 07:11:26 EDT # gpg: using RSA key 6AE902B6A7CA877D6D659296AF7C95130C538013 # gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 6AE9 02B6 A7CA 877D 6D65 9296 AF7C 9513 0C53 8013 * tag 'pull-riscv-to-apply-20250704' of https://github.com/alistair23/qemu: (40 commits) target: riscv: Add Svrsw60t59b extension support target/riscv: Add a property to set vill bit on reserved usage of vsetvli instruction tests/tcg/riscv64: Add test for MEPC bit masking target/riscv: Fix MEPC/SEPC bit masking for IALIGN migration: Fix migration failure when aia is configured as aplic-imsic target/riscv: rvv: Fix missing exit TB flow for ldff_trans hw/riscv: Initial support for BOSC's Xiangshan Kunminghu FPGA prototype target/riscv: Add BOSC's Xiangshan Kunminghu CPU hw/riscv/virt: Use setprop_sized_cells for pcie hw/riscv/virt: Use setprop_sized_cells for iommu hw/riscv/virt: Use setprop_sized_cells for rtc hw/riscv/virt: Use setprop_sized_cells for uart hw/riscv/virt: Use setprop_sized_cells for reset hw/riscv/virt: Use setprop_sized_cells for virtio hw/riscv/virt: Use setprop_sized_cells for plic hw/riscv/virt: Use setprop_sized_cells for aclint hw/riscv/virt: Use setprop_sized_cells for aplic hw/riscv/virt: Use setprop_sized_cells for memory hw/riscv/virt: Use setprop_sized_cells for clint hw/riscv/virt: Fix clint base address type ... Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
@@ -1701,6 +1701,13 @@ S: Maintained
|
||||
F: hw/riscv/microblaze-v-generic.c
|
||||
F: docs/system/riscv/microblaze-v-generic.rst
|
||||
|
||||
Xiangshan Kunminghu
|
||||
M: Ran Wang <wangran@bosc.ac.cn>
|
||||
S: Maintained
|
||||
F: docs/system/riscv/xiangshan-kunminghu.rst
|
||||
F: hw/riscv/xiangshan_kmh.c
|
||||
F: include/hw/riscv/xiangshan_kmh.h
|
||||
|
||||
RX Machines
|
||||
-----------
|
||||
rx-gdbsim
|
||||
|
||||
@@ -11,3 +11,4 @@
|
||||
# CONFIG_RISCV_VIRT=n
|
||||
# CONFIG_MICROCHIP_PFSOC=n
|
||||
# CONFIG_SHAKTI_C=n
|
||||
# CONFIG_XIANGSHAN_KUNMINGHU=n
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
BOSC Xiangshan Kunminghu FPGA prototype platform (``xiangshan-kunminghu``)
|
||||
==========================================================================
|
||||
The ``xiangshan-kunminghu`` machine is compatible with our FPGA prototype
|
||||
platform.
|
||||
|
||||
XiangShan is an open-source high-performance RISC-V processor project.
|
||||
The third generation processor is called Kunminghu. Kunminghu is a 64-bit
|
||||
RV64GCBSUHV processor core. More information can be found in our Github
|
||||
repository:
|
||||
https://github.com/OpenXiangShan/XiangShan
|
||||
|
||||
Supported devices
|
||||
-----------------
|
||||
The ``xiangshan-kunminghu`` machine supports the following devices:
|
||||
|
||||
* Up to 16 xiangshan-kunminghu cores
|
||||
* Core Local Interruptor (CLINT)
|
||||
* Incoming MSI Controller (IMSIC)
|
||||
* Advanced Platform-Level Interrupt Controller (APLIC)
|
||||
* 1 UART
|
||||
|
||||
Boot options
|
||||
------------
|
||||
The ``xiangshan-kunminghu`` machine can start using the standard ``-bios``
|
||||
functionality for loading the boot image. You need to compile and link
|
||||
the firmware, kernel, and Device Tree (FDT) into a single binary file,
|
||||
such as ``fw_payload.bin``.
|
||||
|
||||
Running
|
||||
-------
|
||||
Below is an example command line for running the ``xiangshan-kunminghu``
|
||||
machine:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ qemu-system-riscv64 -machine xiangshan-kunminghu \
|
||||
-smp 16 -m 16G \
|
||||
-bios path/to/opensbi/platform/generic/firmware/fw_payload.bin \
|
||||
-nographic
|
||||
@@ -71,6 +71,7 @@ undocumented; you can get a complete list by running
|
||||
riscv/shakti-c
|
||||
riscv/sifive_u
|
||||
riscv/virt
|
||||
riscv/xiangshan-kunminghu
|
||||
|
||||
RISC-V CPU firmware
|
||||
-------------------
|
||||
|
||||
@@ -128,8 +128,10 @@ static void sifive_uart_write_tx_fifo(SiFiveUARTState *s, const uint8_t *buf,
|
||||
s->txfifo |= SIFIVE_UART_TXFIFO_FULL;
|
||||
}
|
||||
|
||||
timer_mod(s->fifo_trigger_handle, current_time +
|
||||
TX_INTERRUPT_TRIGGER_DELAY_NS);
|
||||
if (!timer_pending(s->fifo_trigger_handle)) {
|
||||
timer_mod(s->fifo_trigger_handle, current_time +
|
||||
TX_INTERRUPT_TRIGGER_DELAY_NS);
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "qemu/module.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "target/riscv/cpu.h"
|
||||
#include "target/riscv/time_helper.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/intc/riscv_aclint.h"
|
||||
#include "qemu/timer.h"
|
||||
@@ -240,6 +241,10 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
|
||||
riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu),
|
||||
mtimer->hartid_base + i,
|
||||
mtimer->timecmp[i]);
|
||||
riscv_timer_write_timecmp(env, env->stimer, env->stimecmp, 0, MIP_STIP);
|
||||
riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
|
||||
env->htimedelta, MIP_VSTIP);
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
+10
-2
@@ -962,10 +962,18 @@ static const Property riscv_aplic_properties[] = {
|
||||
DEFINE_PROP_BOOL("mmode", RISCVAPLICState, mmode, 0),
|
||||
};
|
||||
|
||||
static bool riscv_aplic_state_needed(void *opaque)
|
||||
{
|
||||
RISCVAPLICState *aplic = opaque;
|
||||
|
||||
return riscv_use_emulated_aplic(aplic->msimode);
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_riscv_aplic = {
|
||||
.name = "riscv_aplic",
|
||||
.version_id = 2,
|
||||
.minimum_version_id = 2,
|
||||
.version_id = 3,
|
||||
.minimum_version_id = 3,
|
||||
.needed = riscv_aplic_state_needed,
|
||||
.fields = (const VMStateField[]) {
|
||||
VMSTATE_UINT32(domaincfg, RISCVAPLICState),
|
||||
VMSTATE_UINT32(mmsicfgaddr, RISCVAPLICState),
|
||||
|
||||
@@ -398,10 +398,16 @@ static const Property riscv_imsic_properties[] = {
|
||||
DEFINE_PROP_UINT32("num-irqs", RISCVIMSICState, num_irqs, 0),
|
||||
};
|
||||
|
||||
static bool riscv_imsic_state_needed(void *opaque)
|
||||
{
|
||||
return !kvm_irqchip_in_kernel();
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_riscv_imsic = {
|
||||
.name = "riscv_imsic",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.version_id = 2,
|
||||
.minimum_version_id = 2,
|
||||
.needed = riscv_imsic_state_needed,
|
||||
.fields = (const VMStateField[]) {
|
||||
VMSTATE_VARRAY_UINT32(eidelivery, RISCVIMSICState,
|
||||
num_pages, 0,
|
||||
|
||||
@@ -119,3 +119,12 @@ config SPIKE
|
||||
select HTIF
|
||||
select RISCV_ACLINT
|
||||
select SIFIVE_PLIC
|
||||
|
||||
config XIANGSHAN_KUNMINGHU
|
||||
bool
|
||||
default y
|
||||
depends on RISCV64
|
||||
select RISCV_ACLINT
|
||||
select RISCV_APLIC
|
||||
select RISCV_IMSIC
|
||||
select SERIAL_MM
|
||||
|
||||
@@ -13,5 +13,6 @@ riscv_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c'))
|
||||
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_XIANGSHAN_KUNMINGHU', if_true: files('xiangshan_kmh.c'))
|
||||
|
||||
hw_arch += {'riscv': riscv_ss}
|
||||
|
||||
@@ -79,6 +79,7 @@ struct riscv_iommu_pq_record {
|
||||
#define RISCV_IOMMU_CAP_SV39 BIT_ULL(9)
|
||||
#define RISCV_IOMMU_CAP_SV48 BIT_ULL(10)
|
||||
#define RISCV_IOMMU_CAP_SV57 BIT_ULL(11)
|
||||
#define RISCV_IOMMU_CAP_SVRSW60T59B BIT_ULL(14)
|
||||
#define RISCV_IOMMU_CAP_SV32X4 BIT_ULL(16)
|
||||
#define RISCV_IOMMU_CAP_SV39X4 BIT_ULL(17)
|
||||
#define RISCV_IOMMU_CAP_SV48X4 BIT_ULL(18)
|
||||
|
||||
@@ -1935,11 +1935,7 @@ static void riscv_iommu_process_dbg(RISCVIOMMUState *s)
|
||||
iova = RISCV_IOMMU_TR_RESPONSE_FAULT | (((uint64_t) fault) << 10);
|
||||
} else {
|
||||
iova = iotlb.translated_addr & ~iotlb.addr_mask;
|
||||
iova >>= TARGET_PAGE_BITS;
|
||||
iova &= RISCV_IOMMU_TR_RESPONSE_PPN;
|
||||
|
||||
/* We do not support superpages (> 4kbs) for now */
|
||||
iova &= ~RISCV_IOMMU_TR_RESPONSE_S;
|
||||
iova = set_field(0, RISCV_IOMMU_TR_RESPONSE_PPN, PPN_DOWN(iova));
|
||||
}
|
||||
riscv_iommu_reg_set64(s, RISCV_IOMMU_REG_TR_RESPONSE, iova);
|
||||
}
|
||||
@@ -2355,7 +2351,8 @@ static void riscv_iommu_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
if (s->enable_g_stage) {
|
||||
s->cap |= RISCV_IOMMU_CAP_SV32X4 | RISCV_IOMMU_CAP_SV39X4 |
|
||||
RISCV_IOMMU_CAP_SV48X4 | RISCV_IOMMU_CAP_SV57X4;
|
||||
RISCV_IOMMU_CAP_SV48X4 | RISCV_IOMMU_CAP_SV57X4 |
|
||||
RISCV_IOMMU_CAP_SVRSW60T59B;
|
||||
}
|
||||
|
||||
if (s->hpm_cntrs > 0) {
|
||||
|
||||
+32
-34
@@ -311,8 +311,7 @@ static void create_fdt_socket_memory(RISCVVirtState *s, int socket)
|
||||
size = riscv_socket_mem_size(ms, socket);
|
||||
mem_name = g_strdup_printf("/memory@%"HWADDR_PRIx, addr);
|
||||
qemu_fdt_add_subnode(ms->fdt, mem_name);
|
||||
qemu_fdt_setprop_cells(ms->fdt, mem_name, "reg",
|
||||
addr >> 32, addr, size >> 32, size);
|
||||
qemu_fdt_setprop_sized_cells(ms->fdt, mem_name, "reg", 2, addr, 2, size);
|
||||
qemu_fdt_setprop_string(ms->fdt, mem_name, "device_type", "memory");
|
||||
riscv_socket_fdt_write_id(ms, mem_name, socket);
|
||||
}
|
||||
@@ -324,7 +323,7 @@ static void create_fdt_socket_clint(RISCVVirtState *s,
|
||||
int cpu;
|
||||
g_autofree char *clint_name = NULL;
|
||||
g_autofree uint32_t *clint_cells = NULL;
|
||||
unsigned long clint_addr;
|
||||
hwaddr clint_addr;
|
||||
MachineState *ms = MACHINE(s);
|
||||
static const char * const clint_compat[2] = {
|
||||
"sifive,clint0", "riscv,clint0"
|
||||
@@ -340,14 +339,14 @@ static void create_fdt_socket_clint(RISCVVirtState *s,
|
||||
}
|
||||
|
||||
clint_addr = s->memmap[VIRT_CLINT].base +
|
||||
(s->memmap[VIRT_CLINT].size * socket);
|
||||
clint_name = g_strdup_printf("/soc/clint@%lx", clint_addr);
|
||||
s->memmap[VIRT_CLINT].size * socket;
|
||||
clint_name = g_strdup_printf("/soc/clint@%"HWADDR_PRIx, clint_addr);
|
||||
qemu_fdt_add_subnode(ms->fdt, clint_name);
|
||||
qemu_fdt_setprop_string_array(ms->fdt, clint_name, "compatible",
|
||||
(char **)&clint_compat,
|
||||
ARRAY_SIZE(clint_compat));
|
||||
qemu_fdt_setprop_cells(ms->fdt, clint_name, "reg",
|
||||
0x0, clint_addr, 0x0, s->memmap[VIRT_CLINT].size);
|
||||
qemu_fdt_setprop_sized_cells(ms->fdt, clint_name, "reg",
|
||||
2, clint_addr, 2, s->memmap[VIRT_CLINT].size);
|
||||
qemu_fdt_setprop(ms->fdt, clint_name, "interrupts-extended",
|
||||
clint_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
|
||||
riscv_socket_fdt_write_id(ms, clint_name, socket);
|
||||
@@ -388,8 +387,8 @@ static void create_fdt_socket_aclint(RISCVVirtState *s,
|
||||
qemu_fdt_add_subnode(ms->fdt, name);
|
||||
qemu_fdt_setprop_string(ms->fdt, name, "compatible",
|
||||
"riscv,aclint-mswi");
|
||||
qemu_fdt_setprop_cells(ms->fdt, name, "reg",
|
||||
0x0, addr, 0x0, RISCV_ACLINT_SWI_SIZE);
|
||||
qemu_fdt_setprop_sized_cells(ms->fdt, name, "reg",
|
||||
2, addr, 2, RISCV_ACLINT_SWI_SIZE);
|
||||
qemu_fdt_setprop(ms->fdt, name, "interrupts-extended",
|
||||
aclint_mswi_cells, aclint_cells_size);
|
||||
qemu_fdt_setprop(ms->fdt, name, "interrupt-controller", NULL, 0);
|
||||
@@ -411,11 +410,11 @@ static void create_fdt_socket_aclint(RISCVVirtState *s,
|
||||
qemu_fdt_add_subnode(ms->fdt, name);
|
||||
qemu_fdt_setprop_string(ms->fdt, name, "compatible",
|
||||
"riscv,aclint-mtimer");
|
||||
qemu_fdt_setprop_cells(ms->fdt, name, "reg",
|
||||
0x0, addr + RISCV_ACLINT_DEFAULT_MTIME,
|
||||
0x0, size - RISCV_ACLINT_DEFAULT_MTIME,
|
||||
0x0, addr + RISCV_ACLINT_DEFAULT_MTIMECMP,
|
||||
0x0, RISCV_ACLINT_DEFAULT_MTIME);
|
||||
qemu_fdt_setprop_sized_cells(ms->fdt, name, "reg",
|
||||
2, addr + RISCV_ACLINT_DEFAULT_MTIME,
|
||||
2, size - RISCV_ACLINT_DEFAULT_MTIME,
|
||||
2, addr + RISCV_ACLINT_DEFAULT_MTIMECMP,
|
||||
2, RISCV_ACLINT_DEFAULT_MTIME);
|
||||
qemu_fdt_setprop(ms->fdt, name, "interrupts-extended",
|
||||
aclint_mtimer_cells, aclint_cells_size);
|
||||
riscv_socket_fdt_write_id(ms, name, socket);
|
||||
@@ -429,8 +428,8 @@ static void create_fdt_socket_aclint(RISCVVirtState *s,
|
||||
qemu_fdt_add_subnode(ms->fdt, name);
|
||||
qemu_fdt_setprop_string(ms->fdt, name, "compatible",
|
||||
"riscv,aclint-sswi");
|
||||
qemu_fdt_setprop_cells(ms->fdt, name, "reg",
|
||||
0x0, addr, 0x0, s->memmap[VIRT_ACLINT_SSWI].size);
|
||||
qemu_fdt_setprop_sized_cells(ms->fdt, name, "reg",
|
||||
2, addr, 2, s->memmap[VIRT_ACLINT_SSWI].size);
|
||||
qemu_fdt_setprop(ms->fdt, name, "interrupts-extended",
|
||||
aclint_sswi_cells, aclint_cells_size);
|
||||
qemu_fdt_setprop(ms->fdt, name, "interrupt-controller", NULL, 0);
|
||||
@@ -494,8 +493,8 @@ static void create_fdt_socket_plic(RISCVVirtState *s,
|
||||
s->soc[socket].num_harts * sizeof(uint32_t) * 4);
|
||||
}
|
||||
|
||||
qemu_fdt_setprop_cells(ms->fdt, plic_name, "reg",
|
||||
0x0, plic_addr, 0x0, s->memmap[VIRT_PLIC].size);
|
||||
qemu_fdt_setprop_sized_cells(ms->fdt, plic_name, "reg",
|
||||
2, plic_addr, 2, s->memmap[VIRT_PLIC].size);
|
||||
qemu_fdt_setprop_cell(ms->fdt, plic_name, "riscv,ndev",
|
||||
VIRT_IRQCHIP_NUM_SOURCES - 1);
|
||||
riscv_socket_fdt_write_id(ms, plic_name, socket);
|
||||
@@ -656,8 +655,8 @@ static void create_fdt_one_aplic(RISCVVirtState *s, int socket,
|
||||
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent", msi_phandle);
|
||||
}
|
||||
|
||||
qemu_fdt_setprop_cells(ms->fdt, aplic_name, "reg",
|
||||
0x0, aplic_addr, 0x0, aplic_size);
|
||||
qemu_fdt_setprop_sized_cells(ms->fdt, aplic_name, "reg",
|
||||
2, aplic_addr, 2, aplic_size);
|
||||
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,num-sources",
|
||||
VIRT_IRQCHIP_NUM_SOURCES);
|
||||
|
||||
@@ -857,9 +856,7 @@ static void create_fdt_virtio(RISCVVirtState *s, uint32_t irq_virtio_phandle)
|
||||
|
||||
qemu_fdt_add_subnode(ms->fdt, name);
|
||||
qemu_fdt_setprop_string(ms->fdt, name, "compatible", "virtio,mmio");
|
||||
qemu_fdt_setprop_cells(ms->fdt, name, "reg",
|
||||
0x0, addr,
|
||||
0x0, size);
|
||||
qemu_fdt_setprop_sized_cells(ms->fdt, name, "reg", 2, addr, 2, size);
|
||||
qemu_fdt_setprop_cell(ms->fdt, name, "interrupt-parent",
|
||||
irq_virtio_phandle);
|
||||
if (s->aia_type == VIRT_AIA_TYPE_NONE) {
|
||||
@@ -897,8 +894,8 @@ static void create_fdt_pcie(RISCVVirtState *s,
|
||||
if (s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) {
|
||||
qemu_fdt_setprop_cell(ms->fdt, name, "msi-parent", msi_pcie_phandle);
|
||||
}
|
||||
qemu_fdt_setprop_cells(ms->fdt, name, "reg", 0,
|
||||
s->memmap[VIRT_PCIE_ECAM].base, 0, s->memmap[VIRT_PCIE_ECAM].size);
|
||||
qemu_fdt_setprop_sized_cells(ms->fdt, name, "reg", 2,
|
||||
s->memmap[VIRT_PCIE_ECAM].base, 2, s->memmap[VIRT_PCIE_ECAM].size);
|
||||
qemu_fdt_setprop_sized_cells(ms->fdt, name, "ranges",
|
||||
1, FDT_PCI_RANGE_IOPORT, 2, 0,
|
||||
2, s->memmap[VIRT_PCIE_PIO].base, 2, s->memmap[VIRT_PCIE_PIO].size,
|
||||
@@ -935,8 +932,9 @@ static void create_fdt_reset(RISCVVirtState *s, uint32_t *phandle)
|
||||
qemu_fdt_setprop_string_array(ms->fdt, name, "compatible",
|
||||
(char **)&compat, ARRAY_SIZE(compat));
|
||||
}
|
||||
qemu_fdt_setprop_cells(ms->fdt, name, "reg",
|
||||
0x0, s->memmap[VIRT_TEST].base, 0x0, s->memmap[VIRT_TEST].size);
|
||||
qemu_fdt_setprop_sized_cells(ms->fdt, name, "reg",
|
||||
2, s->memmap[VIRT_TEST].base,
|
||||
2, s->memmap[VIRT_TEST].size);
|
||||
qemu_fdt_setprop_cell(ms->fdt, name, "phandle", test_phandle);
|
||||
test_phandle = qemu_fdt_get_phandle(ms->fdt, name);
|
||||
g_free(name);
|
||||
@@ -968,9 +966,9 @@ static void create_fdt_uart(RISCVVirtState *s,
|
||||
s->memmap[VIRT_UART0].base);
|
||||
qemu_fdt_add_subnode(ms->fdt, name);
|
||||
qemu_fdt_setprop_string(ms->fdt, name, "compatible", "ns16550a");
|
||||
qemu_fdt_setprop_cells(ms->fdt, name, "reg",
|
||||
0x0, s->memmap[VIRT_UART0].base,
|
||||
0x0, s->memmap[VIRT_UART0].size);
|
||||
qemu_fdt_setprop_sized_cells(ms->fdt, name, "reg",
|
||||
2, s->memmap[VIRT_UART0].base,
|
||||
2, s->memmap[VIRT_UART0].size);
|
||||
qemu_fdt_setprop_cell(ms->fdt, name, "clock-frequency", 3686400);
|
||||
qemu_fdt_setprop_cell(ms->fdt, name, "interrupt-parent", irq_mmio_phandle);
|
||||
if (s->aia_type == VIRT_AIA_TYPE_NONE) {
|
||||
@@ -994,8 +992,9 @@ static void create_fdt_rtc(RISCVVirtState *s,
|
||||
qemu_fdt_add_subnode(ms->fdt, name);
|
||||
qemu_fdt_setprop_string(ms->fdt, name, "compatible",
|
||||
"google,goldfish-rtc");
|
||||
qemu_fdt_setprop_cells(ms->fdt, name, "reg",
|
||||
0x0, s->memmap[VIRT_RTC].base, 0x0, s->memmap[VIRT_RTC].size);
|
||||
qemu_fdt_setprop_sized_cells(ms->fdt, name, "reg",
|
||||
2, s->memmap[VIRT_RTC].base,
|
||||
2, s->memmap[VIRT_RTC].size);
|
||||
qemu_fdt_setprop_cell(ms->fdt, name, "interrupt-parent",
|
||||
irq_mmio_phandle);
|
||||
if (s->aia_type == VIRT_AIA_TYPE_NONE) {
|
||||
@@ -1089,8 +1088,7 @@ static void create_fdt_iommu_sys(RISCVVirtState *s, uint32_t irq_chip,
|
||||
qemu_fdt_setprop_cell(fdt, iommu_node, "#iommu-cells", 1);
|
||||
qemu_fdt_setprop_cell(fdt, iommu_node, "phandle", iommu_phandle);
|
||||
|
||||
qemu_fdt_setprop_cells(fdt, iommu_node, "reg",
|
||||
addr >> 32, addr, size >> 32, size);
|
||||
qemu_fdt_setprop_sized_cells(fdt, iommu_node, "reg", 2, addr, 2, size);
|
||||
qemu_fdt_setprop_cell(fdt, iommu_node, "interrupt-parent", irq_chip);
|
||||
|
||||
qemu_fdt_setprop_cells(fdt, iommu_node, "interrupts",
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* QEMU RISC-V Board Compatible with the Xiangshan Kunminghu
|
||||
* FPGA prototype platform
|
||||
*
|
||||
* Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC)
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*
|
||||
* Provides a board compatible with the Xiangshan Kunminghu
|
||||
* FPGA prototype platform:
|
||||
*
|
||||
* 0) UART (16550A)
|
||||
* 1) CLINT (Core-Local Interruptor)
|
||||
* 2) IMSIC (Incoming MSI Controller)
|
||||
* 3) APLIC (Advanced Platform-Level Interrupt Controller)
|
||||
*
|
||||
* More information can be found in our Github repository:
|
||||
* https://github.com/OpenXiangShan/XiangShan
|
||||
*
|
||||
* 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 "qapi/error.h"
|
||||
#include "system/address-spaces.h"
|
||||
#include "hw/boards.h"
|
||||
#include "hw/char/serial-mm.h"
|
||||
#include "hw/intc/riscv_aclint.h"
|
||||
#include "hw/intc/riscv_aplic.h"
|
||||
#include "hw/intc/riscv_imsic.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/riscv/boot.h"
|
||||
#include "hw/riscv/xiangshan_kmh.h"
|
||||
#include "hw/riscv/riscv_hart.h"
|
||||
#include "system/system.h"
|
||||
|
||||
static const MemMapEntry xiangshan_kmh_memmap[] = {
|
||||
[XIANGSHAN_KMH_ROM] = { 0x1000, 0xF000 },
|
||||
[XIANGSHAN_KMH_UART0] = { 0x310B0000, 0x10000 },
|
||||
[XIANGSHAN_KMH_CLINT] = { 0x38000000, 0x10000 },
|
||||
[XIANGSHAN_KMH_APLIC_M] = { 0x31100000, 0x4000 },
|
||||
[XIANGSHAN_KMH_APLIC_S] = { 0x31120000, 0x4000 },
|
||||
[XIANGSHAN_KMH_IMSIC_M] = { 0x3A800000, 0x10000 },
|
||||
[XIANGSHAN_KMH_IMSIC_S] = { 0x3B000000, 0x80000 },
|
||||
[XIANGSHAN_KMH_DRAM] = { 0x80000000, 0x0 },
|
||||
};
|
||||
|
||||
static DeviceState *xiangshan_kmh_create_aia(uint32_t num_harts)
|
||||
{
|
||||
int i;
|
||||
const MemMapEntry *memmap = xiangshan_kmh_memmap;
|
||||
hwaddr addr = 0;
|
||||
DeviceState *aplic_m = NULL;
|
||||
|
||||
/* M-level IMSICs */
|
||||
addr = memmap[XIANGSHAN_KMH_IMSIC_M].base;
|
||||
for (i = 0; i < num_harts; i++) {
|
||||
riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0), i, true,
|
||||
1, XIANGSHAN_KMH_IMSIC_NUM_IDS);
|
||||
}
|
||||
|
||||
/* S-level IMSICs */
|
||||
addr = memmap[XIANGSHAN_KMH_IMSIC_S].base;
|
||||
for (i = 0; i < num_harts; i++) {
|
||||
riscv_imsic_create(addr +
|
||||
i * IMSIC_HART_SIZE(XIANGSHAN_KMH_IMSIC_GUEST_BITS),
|
||||
i, false, 1 + XIANGSHAN_KMH_IMSIC_GUEST_BITS,
|
||||
XIANGSHAN_KMH_IMSIC_NUM_IDS);
|
||||
}
|
||||
|
||||
/* M-level APLIC */
|
||||
aplic_m = riscv_aplic_create(memmap[XIANGSHAN_KMH_APLIC_M].base,
|
||||
memmap[XIANGSHAN_KMH_APLIC_M].size,
|
||||
0, 0, XIANGSHAN_KMH_APLIC_NUM_SOURCES,
|
||||
1, true, true, NULL);
|
||||
|
||||
/* S-level APLIC */
|
||||
riscv_aplic_create(memmap[XIANGSHAN_KMH_APLIC_S].base,
|
||||
memmap[XIANGSHAN_KMH_APLIC_S].size,
|
||||
0, 0, XIANGSHAN_KMH_APLIC_NUM_SOURCES,
|
||||
1, true, false, aplic_m);
|
||||
|
||||
return aplic_m;
|
||||
}
|
||||
|
||||
static void xiangshan_kmh_soc_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
MachineState *ms = MACHINE(qdev_get_machine());
|
||||
XiangshanKmhSoCState *s = XIANGSHAN_KMH_SOC(dev);
|
||||
const MemMapEntry *memmap = xiangshan_kmh_memmap;
|
||||
MemoryRegion *system_memory = get_system_memory();
|
||||
uint32_t num_harts = ms->smp.cpus;
|
||||
|
||||
qdev_prop_set_uint32(DEVICE(&s->cpus), "num-harts", num_harts);
|
||||
qdev_prop_set_uint32(DEVICE(&s->cpus), "hartid-base", 0);
|
||||
qdev_prop_set_string(DEVICE(&s->cpus), "cpu-type",
|
||||
TYPE_RISCV_CPU_XIANGSHAN_KMH);
|
||||
sysbus_realize(SYS_BUS_DEVICE(&s->cpus), &error_fatal);
|
||||
|
||||
/* AIA */
|
||||
s->irqchip = xiangshan_kmh_create_aia(num_harts);
|
||||
|
||||
/* UART */
|
||||
serial_mm_init(system_memory, memmap[XIANGSHAN_KMH_UART0].base, 2,
|
||||
qdev_get_gpio_in(s->irqchip, XIANGSHAN_KMH_UART0_IRQ),
|
||||
115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
|
||||
|
||||
/* CLINT */
|
||||
riscv_aclint_swi_create(memmap[XIANGSHAN_KMH_CLINT].base,
|
||||
0, num_harts, false);
|
||||
riscv_aclint_mtimer_create(memmap[XIANGSHAN_KMH_CLINT].base +
|
||||
RISCV_ACLINT_SWI_SIZE,
|
||||
RISCV_ACLINT_DEFAULT_MTIMER_SIZE,
|
||||
0, num_harts, RISCV_ACLINT_DEFAULT_MTIMECMP,
|
||||
RISCV_ACLINT_DEFAULT_MTIME,
|
||||
XIANGSHAN_KMH_CLINT_TIMEBASE_FREQ, true);
|
||||
|
||||
/* ROM */
|
||||
memory_region_init_rom(&s->rom, OBJECT(dev), "xiangshan.kunminghu.rom",
|
||||
memmap[XIANGSHAN_KMH_ROM].size, &error_fatal);
|
||||
memory_region_add_subregion(system_memory,
|
||||
memmap[XIANGSHAN_KMH_ROM].base, &s->rom);
|
||||
}
|
||||
|
||||
static void xiangshan_kmh_soc_class_init(ObjectClass *klass, const void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->realize = xiangshan_kmh_soc_realize;
|
||||
dc->user_creatable = false;
|
||||
}
|
||||
|
||||
static void xiangshan_kmh_soc_instance_init(Object *obj)
|
||||
{
|
||||
XiangshanKmhSoCState *s = XIANGSHAN_KMH_SOC(obj);
|
||||
|
||||
object_initialize_child(obj, "cpus", &s->cpus, TYPE_RISCV_HART_ARRAY);
|
||||
}
|
||||
|
||||
static const TypeInfo xiangshan_kmh_soc_info = {
|
||||
.name = TYPE_XIANGSHAN_KMH_SOC,
|
||||
.parent = TYPE_DEVICE,
|
||||
.instance_size = sizeof(XiangshanKmhSoCState),
|
||||
.instance_init = xiangshan_kmh_soc_instance_init,
|
||||
.class_init = xiangshan_kmh_soc_class_init,
|
||||
};
|
||||
|
||||
static void xiangshan_kmh_soc_register_types(void)
|
||||
{
|
||||
type_register_static(&xiangshan_kmh_soc_info);
|
||||
}
|
||||
type_init(xiangshan_kmh_soc_register_types)
|
||||
|
||||
static void xiangshan_kmh_machine_init(MachineState *machine)
|
||||
{
|
||||
XiangshanKmhState *s = XIANGSHAN_KMH_MACHINE(machine);
|
||||
const MemMapEntry *memmap = xiangshan_kmh_memmap;
|
||||
MemoryRegion *system_memory = get_system_memory();
|
||||
hwaddr start_addr = memmap[XIANGSHAN_KMH_DRAM].base;
|
||||
|
||||
/* Initialize SoC */
|
||||
object_initialize_child(OBJECT(machine), "soc", &s->soc,
|
||||
TYPE_XIANGSHAN_KMH_SOC);
|
||||
qdev_realize(DEVICE(&s->soc), NULL, &error_fatal);
|
||||
|
||||
/* Register RAM */
|
||||
memory_region_add_subregion(system_memory,
|
||||
memmap[XIANGSHAN_KMH_DRAM].base,
|
||||
machine->ram);
|
||||
|
||||
/* ROM reset vector */
|
||||
riscv_setup_rom_reset_vec(machine, &s->soc.cpus,
|
||||
start_addr,
|
||||
memmap[XIANGSHAN_KMH_ROM].base,
|
||||
memmap[XIANGSHAN_KMH_ROM].size, 0, 0);
|
||||
if (machine->firmware) {
|
||||
riscv_load_firmware(machine->firmware, &start_addr, NULL);
|
||||
}
|
||||
|
||||
/* Note: dtb has been integrated into firmware(OpenSBI) when compiling */
|
||||
}
|
||||
|
||||
static void xiangshan_kmh_machine_class_init(ObjectClass *klass, const void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(klass);
|
||||
static const char *const valid_cpu_types[] = {
|
||||
TYPE_RISCV_CPU_XIANGSHAN_KMH,
|
||||
NULL
|
||||
};
|
||||
|
||||
mc->desc = "RISC-V Board compatible with the Xiangshan " \
|
||||
"Kunminghu FPGA prototype platform";
|
||||
mc->init = xiangshan_kmh_machine_init;
|
||||
mc->max_cpus = XIANGSHAN_KMH_MAX_CPUS;
|
||||
mc->default_cpu_type = TYPE_RISCV_CPU_XIANGSHAN_KMH;
|
||||
mc->valid_cpu_types = valid_cpu_types;
|
||||
mc->default_ram_id = "xiangshan.kunminghu.ram";
|
||||
}
|
||||
|
||||
static const TypeInfo xiangshan_kmh_machine_info = {
|
||||
.name = TYPE_XIANGSHAN_KMH_MACHINE,
|
||||
.parent = TYPE_MACHINE,
|
||||
.instance_size = sizeof(XiangshanKmhState),
|
||||
.class_init = xiangshan_kmh_machine_class_init,
|
||||
};
|
||||
|
||||
static void xiangshan_kmh_machine_register_types(void)
|
||||
{
|
||||
type_register_static(&xiangshan_kmh_machine_info);
|
||||
}
|
||||
type_init(xiangshan_kmh_machine_register_types)
|
||||
@@ -0,0 +1,68 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
/*
|
||||
* QEMU RISC-V Board Compatible with the Xiangshan Kunminghu
|
||||
* FPGA prototype platform
|
||||
*
|
||||
* Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_XIANGSHAN_KMH_H
|
||||
#define HW_XIANGSHAN_KMH_H
|
||||
|
||||
#include "hw/boards.h"
|
||||
#include "hw/riscv/riscv_hart.h"
|
||||
|
||||
#define XIANGSHAN_KMH_MAX_CPUS 16
|
||||
|
||||
typedef struct XiangshanKmhSoCState {
|
||||
/*< private >*/
|
||||
DeviceState parent_obj;
|
||||
|
||||
/*< public >*/
|
||||
RISCVHartArrayState cpus;
|
||||
DeviceState *irqchip;
|
||||
MemoryRegion rom;
|
||||
} XiangshanKmhSoCState;
|
||||
|
||||
#define TYPE_XIANGSHAN_KMH_SOC "xiangshan.kunminghu.soc"
|
||||
DECLARE_INSTANCE_CHECKER(XiangshanKmhSoCState, XIANGSHAN_KMH_SOC,
|
||||
TYPE_XIANGSHAN_KMH_SOC)
|
||||
|
||||
typedef struct XiangshanKmhState {
|
||||
/*< private >*/
|
||||
MachineState parent_obj;
|
||||
|
||||
/*< public >*/
|
||||
XiangshanKmhSoCState soc;
|
||||
} XiangshanKmhState;
|
||||
|
||||
#define TYPE_XIANGSHAN_KMH_MACHINE MACHINE_TYPE_NAME("xiangshan-kunminghu")
|
||||
DECLARE_INSTANCE_CHECKER(XiangshanKmhState, XIANGSHAN_KMH_MACHINE,
|
||||
TYPE_XIANGSHAN_KMH_MACHINE)
|
||||
|
||||
enum {
|
||||
XIANGSHAN_KMH_ROM,
|
||||
XIANGSHAN_KMH_UART0,
|
||||
XIANGSHAN_KMH_CLINT,
|
||||
XIANGSHAN_KMH_APLIC_M,
|
||||
XIANGSHAN_KMH_APLIC_S,
|
||||
XIANGSHAN_KMH_IMSIC_M,
|
||||
XIANGSHAN_KMH_IMSIC_S,
|
||||
XIANGSHAN_KMH_DRAM,
|
||||
};
|
||||
|
||||
enum {
|
||||
XIANGSHAN_KMH_UART0_IRQ = 10,
|
||||
};
|
||||
|
||||
/* Indicating Timebase-freq (1MHZ) */
|
||||
#define XIANGSHAN_KMH_CLINT_TIMEBASE_FREQ 1000000
|
||||
|
||||
#define XIANGSHAN_KMH_IMSIC_NUM_IDS 255
|
||||
#define XIANGSHAN_KMH_IMSIC_NUM_GUESTS 7
|
||||
#define XIANGSHAN_KMH_IMSIC_GUEST_BITS 3
|
||||
|
||||
#define XIANGSHAN_KMH_APLIC_NUM_SOURCES 96
|
||||
|
||||
#endif
|
||||
@@ -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_XIANGSHAN_KMH RISCV_CPU_TYPE_NAME("xiangshan-kunminghu")
|
||||
#define TYPE_RISCV_CPU_HOST RISCV_CPU_TYPE_NAME("host")
|
||||
|
||||
OBJECT_DECLARE_CPU_TYPE(RISCVCPU, RISCVCPUClass, RISCV_CPU)
|
||||
|
||||
+122
-22
@@ -127,8 +127,8 @@ const RISCVIsaExtData isa_edata_arr[] = {
|
||||
ISA_EXT_DATA_ENTRY(zaamo, PRIV_VERSION_1_12_0, ext_zaamo),
|
||||
ISA_EXT_DATA_ENTRY(zabha, PRIV_VERSION_1_13_0, ext_zabha),
|
||||
ISA_EXT_DATA_ENTRY(zacas, PRIV_VERSION_1_12_0, ext_zacas),
|
||||
ISA_EXT_DATA_ENTRY(zama16b, PRIV_VERSION_1_13_0, ext_zama16b),
|
||||
ISA_EXT_DATA_ENTRY(zalrsc, PRIV_VERSION_1_12_0, ext_zalrsc),
|
||||
ISA_EXT_DATA_ENTRY(zama16b, PRIV_VERSION_1_13_0, ext_zama16b),
|
||||
ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
|
||||
ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
|
||||
ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin),
|
||||
@@ -189,6 +189,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
|
||||
ISA_EXT_DATA_ENTRY(zvkt, PRIV_VERSION_1_12_0, ext_zvkt),
|
||||
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
|
||||
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
|
||||
ISA_EXT_DATA_ENTRY(sdtrig, PRIV_VERSION_1_12_0, debug),
|
||||
ISA_EXT_DATA_ENTRY(shcounterenw, PRIV_VERSION_1_12_0, has_priv_1_12),
|
||||
ISA_EXT_DATA_ENTRY(sha, PRIV_VERSION_1_12_0, ext_sha),
|
||||
ISA_EXT_DATA_ENTRY(shgatpa, PRIV_VERSION_1_12_0, has_priv_1_12),
|
||||
@@ -216,6 +217,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
|
||||
ISA_EXT_DATA_ENTRY(ssnpm, PRIV_VERSION_1_13_0, ext_ssnpm),
|
||||
ISA_EXT_DATA_ENTRY(sspm, PRIV_VERSION_1_13_0, ext_sspm),
|
||||
ISA_EXT_DATA_ENTRY(ssstateen, PRIV_VERSION_1_12_0, ext_ssstateen),
|
||||
ISA_EXT_DATA_ENTRY(ssstrict, PRIV_VERSION_1_12_0, has_priv_1_12),
|
||||
ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
|
||||
ISA_EXT_DATA_ENTRY(sstvala, PRIV_VERSION_1_12_0, has_priv_1_12),
|
||||
ISA_EXT_DATA_ENTRY(sstvecd, PRIV_VERSION_1_12_0, has_priv_1_12),
|
||||
@@ -228,6 +230,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
|
||||
ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
|
||||
ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot),
|
||||
ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt),
|
||||
ISA_EXT_DATA_ENTRY(svrsw60t59b, PRIV_VERSION_1_13_0, ext_svrsw60t59b),
|
||||
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(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba),
|
||||
@@ -1117,6 +1120,7 @@ static void riscv_cpu_init(Object *obj)
|
||||
cpu->cfg.cbom_blocksize = 64;
|
||||
cpu->cfg.cbop_blocksize = 64;
|
||||
cpu->cfg.cboz_blocksize = 64;
|
||||
cpu->cfg.pmp_regions = 16;
|
||||
cpu->env.vext_ver = VEXT_VERSION_1_00_0;
|
||||
cpu->cfg.max_satp_mode = -1;
|
||||
|
||||
@@ -1282,6 +1286,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
|
||||
MULTI_EXT_CFG_BOOL("svinval", ext_svinval, false),
|
||||
MULTI_EXT_CFG_BOOL("svnapot", ext_svnapot, false),
|
||||
MULTI_EXT_CFG_BOOL("svpbmt", ext_svpbmt, false),
|
||||
MULTI_EXT_CFG_BOOL("svrsw60t59b", ext_svrsw60t59b, false),
|
||||
MULTI_EXT_CFG_BOOL("svvptc", ext_svvptc, true),
|
||||
|
||||
MULTI_EXT_CFG_BOOL("zicntr", ext_zicntr, true),
|
||||
@@ -1375,35 +1380,28 @@ const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
|
||||
* 'Named features' is the name we give to extensions that we
|
||||
* don't want to expose to users. They are either immutable
|
||||
* (always enabled/disable) or they'll vary depending on
|
||||
* the resulting CPU state. They have riscv,isa strings
|
||||
* and priv_ver like regular extensions.
|
||||
* the resulting CPU state.
|
||||
*
|
||||
* Some of them are always enabled depending on priv version
|
||||
* of the CPU and are declared directly in isa_edata_arr[].
|
||||
* The ones listed here have special checks during finalize()
|
||||
* time and require their own flags like regular extensions.
|
||||
* See riscv_cpu_update_named_features() for more info.
|
||||
*/
|
||||
const RISCVCPUMultiExtConfig riscv_cpu_named_features[] = {
|
||||
MULTI_EXT_CFG_BOOL("zic64b", ext_zic64b, true),
|
||||
MULTI_EXT_CFG_BOOL("ssstateen", ext_ssstateen, true),
|
||||
MULTI_EXT_CFG_BOOL("sha", ext_sha, true),
|
||||
|
||||
/*
|
||||
* 'ziccrse' has its own flag because the KVM driver
|
||||
* wants to enable/disable it on its own accord.
|
||||
*/
|
||||
MULTI_EXT_CFG_BOOL("ziccrse", ext_ziccrse, true),
|
||||
|
||||
{ },
|
||||
};
|
||||
|
||||
/* Deprecated entries marked for future removal */
|
||||
const RISCVCPUMultiExtConfig riscv_cpu_deprecated_exts[] = {
|
||||
MULTI_EXT_CFG_BOOL("Zifencei", ext_zifencei, true),
|
||||
MULTI_EXT_CFG_BOOL("Zicsr", ext_zicsr, true),
|
||||
MULTI_EXT_CFG_BOOL("Zihintntl", ext_zihintntl, true),
|
||||
MULTI_EXT_CFG_BOOL("Zihintpause", ext_zihintpause, true),
|
||||
MULTI_EXT_CFG_BOOL("Zawrs", ext_zawrs, true),
|
||||
MULTI_EXT_CFG_BOOL("Zfa", ext_zfa, true),
|
||||
MULTI_EXT_CFG_BOOL("Zfh", ext_zfh, false),
|
||||
MULTI_EXT_CFG_BOOL("Zfhmin", ext_zfhmin, false),
|
||||
MULTI_EXT_CFG_BOOL("Zve32f", ext_zve32f, false),
|
||||
MULTI_EXT_CFG_BOOL("Zve64f", ext_zve64f, false),
|
||||
MULTI_EXT_CFG_BOOL("Zve64d", ext_zve64d, false),
|
||||
|
||||
{ },
|
||||
};
|
||||
|
||||
static void cpu_set_prop_err(RISCVCPU *cpu, const char *propname,
|
||||
Error **errp)
|
||||
{
|
||||
@@ -1568,6 +1566,46 @@ static const PropertyInfo prop_pmp = {
|
||||
.set = prop_pmp_set,
|
||||
};
|
||||
|
||||
static void prop_num_pmp_regions_set(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
RISCVCPU *cpu = RISCV_CPU(obj);
|
||||
uint8_t value;
|
||||
|
||||
visit_type_uint8(v, name, &value, errp);
|
||||
|
||||
if (cpu->cfg.pmp_regions != value && riscv_cpu_is_vendor(obj)) {
|
||||
cpu_set_prop_err(cpu, name, errp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cpu->env.priv_ver < PRIV_VERSION_1_12_0 && value > OLD_MAX_RISCV_PMPS) {
|
||||
error_setg(errp, "Number of PMP regions exceeds maximum available");
|
||||
return;
|
||||
} else if (value > MAX_RISCV_PMPS) {
|
||||
error_setg(errp, "Number of PMP regions exceeds maximum available");
|
||||
return;
|
||||
}
|
||||
|
||||
cpu_option_add_user_setting(name, value);
|
||||
cpu->cfg.pmp_regions = value;
|
||||
}
|
||||
|
||||
static void prop_num_pmp_regions_get(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
uint8_t value = RISCV_CPU(obj)->cfg.pmp_regions;
|
||||
|
||||
visit_type_uint8(v, name, &value, errp);
|
||||
}
|
||||
|
||||
static const PropertyInfo prop_num_pmp_regions = {
|
||||
.type = "uint8",
|
||||
.description = "num-pmp-regions",
|
||||
.get = prop_num_pmp_regions_get,
|
||||
.set = prop_num_pmp_regions_set,
|
||||
};
|
||||
|
||||
static int priv_spec_from_str(const char *priv_spec_str)
|
||||
{
|
||||
int priv_version = -1;
|
||||
@@ -2567,6 +2605,7 @@ static const Property riscv_cpu_properties[] = {
|
||||
|
||||
{.name = "mmu", .info = &prop_mmu},
|
||||
{.name = "pmp", .info = &prop_pmp},
|
||||
{.name = "num-pmp-regions", .info = &prop_num_pmp_regions},
|
||||
|
||||
{.name = "priv_spec", .info = &prop_priv_spec},
|
||||
{.name = "vext_spec", .info = &prop_vext_spec},
|
||||
@@ -2595,6 +2634,7 @@ static const Property riscv_cpu_properties[] = {
|
||||
DEFINE_PROP_BOOL("rvv_ta_all_1s", RISCVCPU, cfg.rvv_ta_all_1s, false),
|
||||
DEFINE_PROP_BOOL("rvv_ma_all_1s", RISCVCPU, cfg.rvv_ma_all_1s, false),
|
||||
DEFINE_PROP_BOOL("rvv_vl_half_avl", RISCVCPU, cfg.rvv_vl_half_avl, false),
|
||||
DEFINE_PROP_BOOL("rvv_vsetvl_x0_vill", RISCVCPU, cfg.rvv_vsetvl_x0_vill, false),
|
||||
|
||||
/*
|
||||
* write_misa() is marked as experimental for now so mark
|
||||
@@ -2937,7 +2977,8 @@ static const TypeInfo riscv_cpu_type_infos[] = {
|
||||
.cfg.max_satp_mode = VM_1_10_MBARE,
|
||||
.cfg.ext_zifencei = true,
|
||||
.cfg.ext_zicsr = true,
|
||||
.cfg.pmp = true
|
||||
.cfg.pmp = true,
|
||||
.cfg.pmp_regions = 8
|
||||
),
|
||||
|
||||
DEFINE_ABSTRACT_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_U, TYPE_RISCV_VENDOR_CPU,
|
||||
@@ -2948,7 +2989,8 @@ static const TypeInfo riscv_cpu_type_infos[] = {
|
||||
.cfg.ext_zifencei = true,
|
||||
.cfg.ext_zicsr = true,
|
||||
.cfg.mmu = true,
|
||||
.cfg.pmp = true
|
||||
.cfg.pmp = true,
|
||||
.cfg.pmp_regions = 8
|
||||
),
|
||||
|
||||
#if defined(TARGET_RISCV32) || \
|
||||
@@ -3167,6 +3209,64 @@ static const TypeInfo riscv_cpu_type_infos[] = {
|
||||
.cfg.max_satp_mode = VM_1_10_SV39,
|
||||
),
|
||||
|
||||
DEFINE_RISCV_CPU(TYPE_RISCV_CPU_XIANGSHAN_KMH, TYPE_RISCV_VENDOR_CPU,
|
||||
.misa_mxl_max = MXL_RV64,
|
||||
.misa_ext = RVG | RVC | RVB | RVS | RVU | RVH | RVV,
|
||||
.priv_spec = PRIV_VERSION_1_13_0,
|
||||
/*
|
||||
* The RISC-V Instruction Set Manual: Volume I
|
||||
* Unprivileged Architecture
|
||||
*/
|
||||
.cfg.ext_zicntr = true,
|
||||
.cfg.ext_zihpm = true,
|
||||
.cfg.ext_zihintntl = true,
|
||||
.cfg.ext_zihintpause = true,
|
||||
.cfg.ext_zimop = true,
|
||||
.cfg.ext_zcmop = true,
|
||||
.cfg.ext_zicond = true,
|
||||
.cfg.ext_zawrs = true,
|
||||
.cfg.ext_zacas = true,
|
||||
.cfg.ext_zfh = true,
|
||||
.cfg.ext_zfa = true,
|
||||
.cfg.ext_zcb = true,
|
||||
.cfg.ext_zbc = true,
|
||||
.cfg.ext_zvfh = true,
|
||||
.cfg.ext_zkn = true,
|
||||
.cfg.ext_zks = true,
|
||||
.cfg.ext_zkt = true,
|
||||
.cfg.ext_zvbb = true,
|
||||
.cfg.ext_zvkt = true,
|
||||
/*
|
||||
* The RISC-V Instruction Set Manual: Volume II
|
||||
* Privileged Architecture
|
||||
*/
|
||||
.cfg.ext_smstateen = true,
|
||||
.cfg.ext_smcsrind = true,
|
||||
.cfg.ext_sscsrind = true,
|
||||
.cfg.ext_svnapot = true,
|
||||
.cfg.ext_svpbmt = true,
|
||||
.cfg.ext_svinval = true,
|
||||
.cfg.ext_sstc = true,
|
||||
.cfg.ext_sscofpmf = true,
|
||||
.cfg.ext_ssdbltrp = true,
|
||||
.cfg.ext_ssnpm = true,
|
||||
.cfg.ext_smnpm = true,
|
||||
.cfg.ext_smmpm = true,
|
||||
.cfg.ext_sspm = true,
|
||||
.cfg.ext_supm = true,
|
||||
/* The RISC-V Advanced Interrupt Architecture */
|
||||
.cfg.ext_smaia = true,
|
||||
.cfg.ext_ssaia = true,
|
||||
/* RVA23 Profiles */
|
||||
.cfg.ext_zicbom = true,
|
||||
.cfg.ext_zicbop = true,
|
||||
.cfg.ext_zicboz = true,
|
||||
.cfg.ext_svade = true,
|
||||
.cfg.mmu = true,
|
||||
.cfg.pmp = true,
|
||||
.cfg.max_satp_mode = VM_1_10_SV48,
|
||||
),
|
||||
|
||||
#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,
|
||||
|
||||
+17
-2
@@ -82,7 +82,22 @@ typedef struct riscv_cpu_profile {
|
||||
struct riscv_cpu_profile *s_parent;
|
||||
const char *name;
|
||||
uint32_t misa_ext;
|
||||
/*
|
||||
* The profile is enabled/disabled via command line or
|
||||
* via cpu_init(). Enabling a profile will add all its
|
||||
* mandatory extensions in the CPU during init().
|
||||
*/
|
||||
bool enabled;
|
||||
/*
|
||||
* The profile is present in the CPU, i.e. the current set of
|
||||
* CPU extensions complies with it. A profile can be enabled
|
||||
* and not present (e.g. the user disabled a mandatory extension)
|
||||
* and the other way around (e.g. all mandatory extensions are
|
||||
* present in a non-profile CPU).
|
||||
*
|
||||
* QMP uses this flag.
|
||||
*/
|
||||
bool present;
|
||||
bool user_set;
|
||||
int priv_spec;
|
||||
int satp_mode;
|
||||
@@ -159,7 +174,8 @@ extern RISCVCPUImpliedExtsRule *riscv_multi_ext_implied_rules[];
|
||||
|
||||
#define MMU_USER_IDX 3
|
||||
|
||||
#define MAX_RISCV_PMPS (16)
|
||||
#define MAX_RISCV_PMPS (64)
|
||||
#define OLD_MAX_RISCV_PMPS (16)
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
#include "pmp.h"
|
||||
@@ -936,7 +952,6 @@ extern const RISCVCPUMultiExtConfig riscv_cpu_extensions[];
|
||||
extern const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[];
|
||||
extern const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[];
|
||||
extern const RISCVCPUMultiExtConfig riscv_cpu_named_features[];
|
||||
extern const RISCVCPUMultiExtConfig riscv_cpu_deprecated_exts[];
|
||||
|
||||
typedef struct isa_ext_data {
|
||||
const char *name;
|
||||
|
||||
+62
-1
@@ -372,6 +372,18 @@
|
||||
#define CSR_PMPCFG1 0x3a1
|
||||
#define CSR_PMPCFG2 0x3a2
|
||||
#define CSR_PMPCFG3 0x3a3
|
||||
#define CSR_PMPCFG4 0x3a4
|
||||
#define CSR_PMPCFG5 0x3a5
|
||||
#define CSR_PMPCFG6 0x3a6
|
||||
#define CSR_PMPCFG7 0x3a7
|
||||
#define CSR_PMPCFG8 0x3a8
|
||||
#define CSR_PMPCFG9 0x3a9
|
||||
#define CSR_PMPCFG10 0x3aa
|
||||
#define CSR_PMPCFG11 0x3ab
|
||||
#define CSR_PMPCFG12 0x3ac
|
||||
#define CSR_PMPCFG13 0x3ad
|
||||
#define CSR_PMPCFG14 0x3ae
|
||||
#define CSR_PMPCFG15 0x3af
|
||||
#define CSR_PMPADDR0 0x3b0
|
||||
#define CSR_PMPADDR1 0x3b1
|
||||
#define CSR_PMPADDR2 0x3b2
|
||||
@@ -388,6 +400,54 @@
|
||||
#define CSR_PMPADDR13 0x3bd
|
||||
#define CSR_PMPADDR14 0x3be
|
||||
#define CSR_PMPADDR15 0x3bf
|
||||
#define CSR_PMPADDR16 0x3c0
|
||||
#define CSR_PMPADDR17 0x3c1
|
||||
#define CSR_PMPADDR18 0x3c2
|
||||
#define CSR_PMPADDR19 0x3c3
|
||||
#define CSR_PMPADDR20 0x3c4
|
||||
#define CSR_PMPADDR21 0x3c5
|
||||
#define CSR_PMPADDR22 0x3c6
|
||||
#define CSR_PMPADDR23 0x3c7
|
||||
#define CSR_PMPADDR24 0x3c8
|
||||
#define CSR_PMPADDR25 0x3c9
|
||||
#define CSR_PMPADDR26 0x3ca
|
||||
#define CSR_PMPADDR27 0x3cb
|
||||
#define CSR_PMPADDR28 0x3cc
|
||||
#define CSR_PMPADDR29 0x3cd
|
||||
#define CSR_PMPADDR30 0x3ce
|
||||
#define CSR_PMPADDR31 0x3cf
|
||||
#define CSR_PMPADDR32 0x3d0
|
||||
#define CSR_PMPADDR33 0x3d1
|
||||
#define CSR_PMPADDR34 0x3d2
|
||||
#define CSR_PMPADDR35 0x3d3
|
||||
#define CSR_PMPADDR36 0x3d4
|
||||
#define CSR_PMPADDR37 0x3d5
|
||||
#define CSR_PMPADDR38 0x3d6
|
||||
#define CSR_PMPADDR39 0x3d7
|
||||
#define CSR_PMPADDR40 0x3d8
|
||||
#define CSR_PMPADDR41 0x3d9
|
||||
#define CSR_PMPADDR42 0x3da
|
||||
#define CSR_PMPADDR43 0x3db
|
||||
#define CSR_PMPADDR44 0x3dc
|
||||
#define CSR_PMPADDR45 0x3dd
|
||||
#define CSR_PMPADDR46 0x3de
|
||||
#define CSR_PMPADDR47 0x3df
|
||||
#define CSR_PMPADDR48 0x3e0
|
||||
#define CSR_PMPADDR49 0x3e1
|
||||
#define CSR_PMPADDR50 0x3e2
|
||||
#define CSR_PMPADDR51 0x3e3
|
||||
#define CSR_PMPADDR52 0x3e4
|
||||
#define CSR_PMPADDR53 0x3e5
|
||||
#define CSR_PMPADDR54 0x3e6
|
||||
#define CSR_PMPADDR55 0x3e7
|
||||
#define CSR_PMPADDR56 0x3e8
|
||||
#define CSR_PMPADDR57 0x3e9
|
||||
#define CSR_PMPADDR58 0x3ea
|
||||
#define CSR_PMPADDR59 0x3eb
|
||||
#define CSR_PMPADDR60 0x3ec
|
||||
#define CSR_PMPADDR61 0x3ed
|
||||
#define CSR_PMPADDR62 0x3ee
|
||||
#define CSR_PMPADDR63 0x3ef
|
||||
|
||||
/* RNMI */
|
||||
#define CSR_MNSCRATCH 0x740
|
||||
@@ -675,7 +735,8 @@ typedef enum {
|
||||
#define PTE_SOFT 0x300 /* Reserved for Software */
|
||||
#define PTE_PBMT 0x6000000000000000ULL /* Page-based memory types */
|
||||
#define PTE_N 0x8000000000000000ULL /* NAPOT translation */
|
||||
#define PTE_RESERVED 0x1FC0000000000000ULL /* Reserved bits */
|
||||
#define PTE_RESERVED(svrsw60t59b) \
|
||||
(svrsw60t59b ? 0x07C0000000000000ULL : 0x1FC0000000000000ULL) /* Reserved bits */
|
||||
#define PTE_ATTR (PTE_N | PTE_PBMT) /* All attributes bits */
|
||||
|
||||
/* Page table PPN shift amount */
|
||||
|
||||
@@ -57,6 +57,7 @@ BOOL_FIELD(ext_svadu)
|
||||
BOOL_FIELD(ext_svinval)
|
||||
BOOL_FIELD(ext_svnapot)
|
||||
BOOL_FIELD(ext_svpbmt)
|
||||
BOOL_FIELD(ext_svrsw60t59b)
|
||||
BOOL_FIELD(ext_svvptc)
|
||||
BOOL_FIELD(ext_svukte)
|
||||
BOOL_FIELD(ext_zdinx)
|
||||
@@ -114,6 +115,7 @@ BOOL_FIELD(ext_supm)
|
||||
BOOL_FIELD(rvv_ta_all_1s)
|
||||
BOOL_FIELD(rvv_ma_all_1s)
|
||||
BOOL_FIELD(rvv_vl_half_avl)
|
||||
BOOL_FIELD(rvv_vsetvl_x0_vill)
|
||||
/* Named features */
|
||||
BOOL_FIELD(ext_svade)
|
||||
BOOL_FIELD(ext_zic64b)
|
||||
@@ -163,6 +165,7 @@ TYPED_FIELD(uint16_t, elen, 0)
|
||||
TYPED_FIELD(uint16_t, cbom_blocksize, 0)
|
||||
TYPED_FIELD(uint16_t, cbop_blocksize, 0)
|
||||
TYPED_FIELD(uint16_t, cboz_blocksize, 0)
|
||||
TYPED_FIELD(uint8_t, pmp_regions, 0)
|
||||
|
||||
TYPED_FIELD(int8_t, max_satp_mode, -1)
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user