diff options
| -rw-r--r-- | hw/core/loader.c | 15 | ||||
| -rw-r--r-- | hw/core/uboot_image.h | 213 | ||||
| -rw-r--r-- | hw/intc/riscv_aclint.c | 3 | ||||
| -rw-r--r-- | hw/riscv/opentitan.c | 2 | ||||
| -rw-r--r-- | hw/riscv/sifive_e.c | 2 | ||||
| -rw-r--r-- | hw/riscv/sifive_u.c | 28 | ||||
| -rw-r--r-- | hw/riscv/spike.c | 2 | ||||
| -rw-r--r-- | hw/riscv/virt.c | 27 | ||||
| -rw-r--r-- | hw/vfio/pci-quirks.c | 34 | ||||
| -rw-r--r-- | qga/commands-posix.c | 123 | ||||
| -rw-r--r-- | qga/commands-win32.c | 11 | ||||
| -rw-r--r-- | qga/main.c | 2 | ||||
| -rw-r--r-- | qga/qapi-schema.json | 86 | ||||
| -rw-r--r-- | target/riscv/cpu.c | 91 | ||||
| -rw-r--r-- | target/riscv/cpu.h | 12 | ||||
| -rw-r--r-- | target/riscv/cpu_helper.c | 4 | ||||
| -rw-r--r-- | target/riscv/csr.c | 26 | ||||
| -rw-r--r-- | target/riscv/insn_trans/trans_rvv.c.inc | 58 | ||||
| -rw-r--r-- | target/riscv/translate.c | 17 | ||||
| -rw-r--r-- | tests/docker/dockerfiles/fedora-win32-cross.docker | 2 | ||||
| -rw-r--r-- | tests/docker/dockerfiles/fedora-win64-cross.docker | 2 |
21 files changed, 549 insertions, 211 deletions
diff --git a/hw/core/loader.c b/hw/core/loader.c index 8167301f04..edde657ac3 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -696,6 +696,21 @@ static int load_uboot_image(const char *filename, hwaddr *ep, hwaddr *loadaddr, if (is_linux) { if (hdr->ih_os == IH_OS_LINUX) { *is_linux = 1; + } else if (hdr->ih_os == IH_OS_VXWORKS) { + /* + * VxWorks 7 uses the same boot interface as the Linux kernel + * on Arm (64-bit only), PowerPC and RISC-V architectures. + */ + switch (hdr->ih_arch) { + case IH_ARCH_ARM64: + case IH_ARCH_PPC: + case IH_ARCH_RISCV: + *is_linux = 1; + break; + default: + *is_linux = 0; + break; + } } else { *is_linux = 0; } diff --git a/hw/core/uboot_image.h b/hw/core/uboot_image.h index 608022de6e..18ac293359 100644 --- a/hw/core/uboot_image.h +++ b/hw/core/uboot_image.h @@ -1,23 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* + * (C) Copyright 2008 Semihalf + * * (C) Copyright 2000-2005 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program 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 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/>. - * ******************************************************************** * NOTE: This header file defines an interface to U-Boot. Including * this (unmodified) header file in another file is considered normal @@ -31,50 +17,83 @@ /* * Operating System Codes + * + * The following are exposed to uImage header. + * New IDs *MUST* be appended at the end of the list and *NEVER* + * inserted for backward compatibility. */ -#define IH_OS_INVALID 0 /* Invalid OS */ -#define IH_OS_OPENBSD 1 /* OpenBSD */ -#define IH_OS_NETBSD 2 /* NetBSD */ -#define IH_OS_FREEBSD 3 /* FreeBSD */ -#define IH_OS_4_4BSD 4 /* 4.4BSD */ -#define IH_OS_LINUX 5 /* Linux */ -#define IH_OS_SVR4 6 /* SVR4 */ -#define IH_OS_ESIX 7 /* Esix */ -#define IH_OS_SOLARIS 8 /* Solaris */ -#define IH_OS_IRIX 9 /* Irix */ -#define IH_OS_SCO 10 /* SCO */ -#define IH_OS_DELL 11 /* Dell */ -#define IH_OS_NCR 12 /* NCR */ -#define IH_OS_LYNXOS 13 /* LynxOS */ -#define IH_OS_VXWORKS 14 /* VxWorks */ -#define IH_OS_PSOS 15 /* pSOS */ -#define IH_OS_QNX 16 /* QNX */ -#define IH_OS_U_BOOT 17 /* Firmware */ -#define IH_OS_RTEMS 18 /* RTEMS */ -#define IH_OS_ARTOS 19 /* ARTOS */ -#define IH_OS_UNITY 20 /* Unity OS */ +enum { + IH_OS_INVALID = 0, /* Invalid OS */ + IH_OS_OPENBSD, /* OpenBSD */ + IH_OS_NETBSD, /* NetBSD */ + IH_OS_FREEBSD, /* FreeBSD */ + IH_OS_4_4BSD, /* 4.4BSD */ + IH_OS_LINUX, /* Linux */ + IH_OS_SVR4, /* SVR4 */ + IH_OS_ESIX, /* Esix */ + IH_OS_SOLARIS, /* Solaris */ + IH_OS_IRIX, /* Irix */ + IH_OS_SCO, /* SCO */ + IH_OS_DELL, /* Dell */ + IH_OS_NCR, /* NCR */ + IH_OS_LYNXOS, /* LynxOS */ + IH_OS_VXWORKS, /* VxWorks */ + IH_OS_PSOS, /* pSOS */ + IH_OS_QNX, /* QNX */ + IH_OS_U_BOOT, /* Firmware */ + IH_OS_RTEMS, /* RTEMS */ + IH_OS_ARTOS, /* ARTOS */ + IH_OS_UNITY, /* Unity OS */ + IH_OS_INTEGRITY, /* INTEGRITY */ + IH_OS_OSE, /* OSE */ + IH_OS_PLAN9, /* Plan 9 */ + IH_OS_OPENRTOS, /* OpenRTOS */ + IH_OS_ARM_TRUSTED_FIRMWARE, /* ARM Trusted Firmware */ + IH_OS_TEE, /* Trusted Execution Environment */ + IH_OS_OPENSBI, /* RISC-V OpenSBI */ + IH_OS_EFI, /* EFI Firmware (e.g. GRUB2) */ + + IH_OS_COUNT, +}; /* * CPU Architecture Codes (supported by Linux) + * + * The following are exposed to uImage header. + * New IDs *MUST* be appended at the end of the list and *NEVER* + * inserted for backward compatibility. */ -#define IH_CPU_INVALID 0 /* Invalid CPU */ -#define IH_CPU_ALPHA 1 /* Alpha */ -#define IH_CPU_ARM 2 /* ARM */ -#define IH_CPU_I386 3 /* Intel x86 */ -#define IH_CPU_IA64 4 /* IA64 */ -#define IH_CPU_MIPS 5 /* MIPS */ -#define IH_CPU_MIPS64 6 /* MIPS 64 Bit */ -#define IH_CPU_PPC 7 /* PowerPC */ -#define IH_CPU_S390 8 /* IBM S390 */ -#define IH_CPU_SH 9 /* SuperH */ -#define IH_CPU_SPARC 10 /* Sparc */ -#define IH_CPU_SPARC64 11 /* Sparc 64 Bit */ -#define IH_CPU_M68K 12 /* M68K */ -#define IH_CPU_NIOS 13 /* Nios-32 */ -#define IH_CPU_MICROBLAZE 14 /* MicroBlaze */ -#define IH_CPU_NIOS2 15 /* Nios-II */ -#define IH_CPU_BLACKFIN 16 /* Blackfin */ -#define IH_CPU_AVR32 17 /* AVR32 */ +enum { + IH_ARCH_INVALID = 0, /* Invalid CPU */ + IH_ARCH_ALPHA, /* Alpha */ + IH_ARCH_ARM, /* ARM */ + IH_ARCH_I386, /* Intel x86 */ + IH_ARCH_IA64, /* IA64 */ + IH_ARCH_MIPS, /* MIPS */ + IH_ARCH_MIPS64, /* MIPS 64 Bit */ + IH_ARCH_PPC, /* PowerPC */ + IH_ARCH_S390, /* IBM S390 */ + IH_ARCH_SH, /* SuperH */ + IH_ARCH_SPARC, /* Sparc */ + IH_ARCH_SPARC64, /* Sparc 64 Bit */ + IH_ARCH_M68K, /* M68K */ + IH_ARCH_NIOS, /* Nios-32 */ + IH_ARCH_MICROBLAZE, /* MicroBlaze */ + IH_ARCH_NIOS2, /* Nios-II */ + IH_ARCH_BLACKFIN, /* Blackfin */ + IH_ARCH_AVR32, /* AVR32 */ + IH_ARCH_ST200, /* STMicroelectronics ST200 */ + IH_ARCH_SANDBOX, /* Sandbox architecture (test only) */ + IH_ARCH_NDS32, /* ANDES Technology - NDS32 */ + IH_ARCH_OPENRISC, /* OpenRISC 1000 */ + IH_ARCH_ARM64, /* ARM64 */ + IH_ARCH_ARC, /* Synopsys DesignWare ARC */ + IH_ARCH_X86_64, /* AMD x86_64, Intel and Via */ + IH_ARCH_XTENSA, /* Xtensa */ + IH_ARCH_RISCV, /* RISC-V */ + + IH_ARCH_COUNT, +}; /* * Image Types @@ -113,33 +132,85 @@ * U-Boot's command interpreter; this feature is especially * useful when you configure U-Boot to use a real shell (hush) * as command interpreter (=> Shell Scripts). + * + * The following are exposed to uImage header. + * New IDs *MUST* be appended at the end of the list and *NEVER* + * inserted for backward compatibility. */ -#define IH_TYPE_INVALID 0 /* Invalid Image */ -#define IH_TYPE_STANDALONE 1 /* Standalone Program */ -#define IH_TYPE_KERNEL 2 /* OS Kernel Image */ -#define IH_TYPE_RAMDISK 3 /* RAMDisk Image */ -#define IH_TYPE_MULTI 4 /* Multi-File Image */ -#define IH_TYPE_FIRMWARE 5 /* Firmware Image */ -#define IH_TYPE_SCRIPT 6 /* Script file */ -#define IH_TYPE_FILESYSTEM 7 /* Filesystem Image (any type) */ -#define IH_TYPE_FLATDT 8 /* Binary Flat Device Tree Blob */ -#define IH_TYPE_KERNEL_NOLOAD 14 /* OS Kernel Image (noload) */ +enum { + IH_TYPE_INVALID = 0, /* Invalid Image */ + IH_TYPE_STANDALONE, /* Standalone Program */ + IH_TYPE_KERNEL, /* OS Kernel Image */ + IH_TYPE_RAMDISK, /* RAMDisk Image */ + IH_TYPE_MULTI, /* Multi-File Image */ + IH_TYPE_FIRMWARE, /* Firmware Image */ + IH_TYPE_SCRIPT, /* Script file */ + IH_TYPE_FILESYSTEM, /* Filesystem Image (any type) */ + IH_TYPE_FLATDT, /* Binary Flat Device Tree Blob */ + IH_TYPE_KWBIMAGE, /* Kirkwood Boot Image */ + IH_TYPE_IMXIMAGE, /* Freescale IMXBoot Image */ + IH_TYPE_UBLIMAGE, /* Davinci UBL Image */ + IH_TYPE_OMAPIMAGE, /* TI OMAP Config Header Image */ + IH_TYPE_AISIMAGE, /* TI Davinci AIS Image */ + /* OS Kernel Image, can run from any load address */ + IH_TYPE_KERNEL_NOLOAD, + IH_TYPE_PBLIMAGE, /* Freescale PBL Boot Image */ + IH_TYPE_MXSIMAGE, /* Freescale MXSBoot Image */ + IH_TYPE_GPIMAGE, /* TI Keystone GPHeader Image */ + IH_TYPE_ATMELIMAGE, /* ATMEL ROM bootable Image */ + IH_TYPE_SOCFPGAIMAGE, /* Altera SOCFPGA CV/AV Preloader */ + IH_TYPE_X86_SETUP, /* x86 setup.bin Image */ + IH_TYPE_LPC32XXIMAGE, /* x86 setup.bin Image */ + IH_TYPE_LOADABLE, /* A list of typeless images */ + IH_TYPE_RKIMAGE, /* Rockchip Boot Image */ + IH_TYPE_RKSD, /* Rockchip SD card */ + IH_TYPE_RKSPI, /* Rockchip SPI image */ + IH_TYPE_ZYNQIMAGE, /* Xilinx Zynq Boot Image */ + IH_TYPE_ZYNQMPIMAGE, /* Xilinx ZynqMP Boot Image */ + IH_TYPE_ZYNQMPBIF, /* Xilinx ZynqMP Boot Image (bif) */ + IH_TYPE_FPGA, /* FPGA Image */ + IH_TYPE_VYBRIDIMAGE, /* VYBRID .vyb Image */ + IH_TYPE_TEE, /* Trusted Execution Environment OS Image */ + IH_TYPE_FIRMWARE_IVT, /* Firmware Image with HABv4 IVT */ + IH_TYPE_PMMC, /* TI Power Management Micro-Controller Firmware */ + IH_TYPE_STM32IMAGE, /* STMicroelectronics STM32 Image */ + IH_TYPE_SOCFPGAIMAGE_V1, /* Altera SOCFPGA A10 Preloader */ + IH_TYPE_MTKIMAGE, /* MediaTek BootROM loadable Image */ + IH_TYPE_IMX8MIMAGE, /* Freescale IMX8MBoot Image */ + IH_TYPE_IMX8IMAGE, /* Freescale IMX8Boot Image */ + IH_TYPE_COPRO, /* Coprocessor Image for remoteproc*/ + IH_TYPE_SUNXI_EGON, /* Allwinner eGON Boot Image */ + + IH_TYPE_COUNT, /* Number of image types */ +}; /* * Compression Types + * + * The following are exposed to uImage header. + * New IDs *MUST* be appended at the end of the list and *NEVER* + * inserted for backward compatibility. */ -#define IH_COMP_NONE 0 /* No Compression Used */ -#define IH_COMP_GZIP 1 /* gzip Compression Used */ -#define IH_COMP_BZIP2 2 /* bzip2 Compression Used */ +enum { + IH_COMP_NONE = 0, /* No Compression Used */ + IH_COMP_GZIP, /* gzip Compression Used */ + IH_COMP_BZIP2, /* bzip2 Compression Used */ + IH_COMP_LZMA, /* lzma Compression Used */ + IH_COMP_LZO, /* lzo Compression Used */ + IH_COMP_LZ4, /* lz4 Compression Used */ + IH_COMP_ZSTD, /* zstd Compression Used */ + + IH_COMP_COUNT, +}; #define IH_MAGIC 0x27051956 /* Image Magic Number */ #define IH_NMLEN 32 /* Image Name Length */ /* - * all data in network byte order (aka natural aka bigendian) + * Legacy format image header, + * all data in network byte order (aka natural aka bigendian). */ - typedef struct uboot_image_header { uint32_t ih_magic; /* Image Header Magic Number */ uint32_t ih_hcrc; /* Image Header CRC Checksum */ diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c index 0412edc982..e6bceceefd 100644 --- a/hw/intc/riscv_aclint.c +++ b/hw/intc/riscv_aclint.c @@ -233,7 +233,8 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr, continue; } riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), - i, env->timecmp); + mtimer->hartid_base + i, + env->timecmp); } return; } diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c index 2d401dcb23..4495a2c039 100644 --- a/hw/riscv/opentitan.c +++ b/hw/riscv/opentitan.c @@ -142,7 +142,7 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp) object_property_set_int(OBJECT(&s->cpus), "num-harts", ms->smp.cpus, &error_abort); object_property_set_int(OBJECT(&s->cpus), "resetvec", 0x8080, &error_abort); - sysbus_realize(SYS_BUS_DEVICE(&s->cpus), &error_abort); + sysbus_realize(SYS_BUS_DEVICE(&s->cpus), &error_fatal); /* Boot ROM */ memory_region_init_rom(&s->rom, OBJECT(dev_soc), "riscv.lowrisc.ibex.rom", diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c index dcb87b6cfd..d65d2fd869 100644 --- a/hw/riscv/sifive_e.c +++ b/hw/riscv/sifive_e.c @@ -195,7 +195,7 @@ static void sifive_e_soc_realize(DeviceState *dev, Error **errp) object_property_set_str(OBJECT(&s->cpus), "cpu-type", ms->cpu_type, &error_abort); - sysbus_realize(SYS_BUS_DEVICE(&s->cpus), &error_abort); + sysbus_realize(SYS_BUS_DEVICE(&s->cpus), &error_fatal); /* Mask ROM */ memory_region_init_rom(&s->mask_rom, OBJECT(dev), "riscv.sifive.e.mrom", diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index cc8c7637cb..e4c814a3ea 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -713,36 +713,20 @@ static void sifive_u_machine_set_start_in_flash(Object *obj, bool value, Error * s->start_in_flash = value; } -static void sifive_u_machine_get_uint32_prop(Object *obj, Visitor *v, - const char *name, void *opaque, - Error **errp) -{ - visit_type_uint32(v, name, (uint32_t *)opaque, errp); -} - -static void sifive_u_machine_set_uint32_prop(Object *obj, Visitor *v, - const char *name, void *opaque, - Error **errp) -{ - visit_type_uint32(v, name, (uint32_t *)opaque, errp); -} - static void sifive_u_machine_instance_init(Object *obj) { SiFiveUState *s = RISCV_U_MACHINE(obj); s->start_in_flash = false; s->msel = 0; - object_property_add(obj, "msel", "uint32", - sifive_u_machine_get_uint32_prop, - sifive_u_machine_set_uint32_prop, NULL, &s->msel); + object_property_add_uint32_ptr(obj, "msel", &s->msel, + OBJ_PROP_FLAG_READWRITE); object_property_set_description(obj, "msel", "Mode Select (MSEL[3:0]) pin state"); s->serial = OTP_SERIAL; - object_property_add(obj, "serial", "uint32", - sifive_u_machine_get_uint32_prop, - sifive_u_machine_set_uint32_prop, NULL, &s->serial); + object_property_add_uint32_ptr(obj, "serial", &s->serial, + OBJ_PROP_FLAG_READWRITE); object_property_set_description(obj, "serial", "Board serial number"); } @@ -830,8 +814,8 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp) qdev_prop_set_string(DEVICE(&s->u_cpus), "cpu-type", s->cpu_type); qdev_prop_set_uint64(DEVICE(&s->u_cpus), "resetvec", 0x1004); - sysbus_realize(SYS_BUS_DEVICE(&s->e_cpus), &error_abort); - sysbus_realize(SYS_BUS_DEVICE(&s->u_cpus), &error_abort); + sysbus_realize(SYS_BUS_DEVICE(&s->e_cpus), &error_fatal); + sysbus_realize(SYS_BUS_DEVICE(&s->u_cpus), &error_fatal); /* * The cluster must be realized after the RISC-V hart array container, * as the container's CPU object is only created on realize, and the diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index 068ba3493e..e41b6aa9f0 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -230,7 +230,7 @@ static void spike_board_init(MachineState *machine) base_hartid, &error_abort); object_property_set_int(OBJECT(&s->soc[i]), "num-harts", hart_count, &error_abort); - sysbus_realize(SYS_BUS_DEVICE(&s->soc[i]), &error_abort); + sysbus_realize(SYS_BUS_DEVICE(&s->soc[i]), &error_fatal); /* Core Local Interruptor (timer and IPI) for each socket */ riscv_aclint_swi_create( diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 3326f4db96..293e9c95b7 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -478,10 +478,12 @@ static void create_fdt_socket_plic(RISCVVirtState *s, qemu_fdt_setprop_cell(mc->fdt, plic_name, "phandle", plic_phandles[socket]); - platform_bus_add_all_fdt_nodes(mc->fdt, plic_name, - memmap[VIRT_PLATFORM_BUS].base, - memmap[VIRT_PLATFORM_BUS].size, - VIRT_PLATFORM_BUS_IRQ); + if (!socket) { + platform_bus_add_all_fdt_nodes(mc->fdt, plic_name, + memmap[VIRT_PLATFORM_BUS].base, + memmap[VIRT_PLATFORM_BUS].size, + VIRT_PLATFORM_BUS_IRQ); + } g_free(plic_name); @@ -561,11 +563,6 @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap, } qemu_fdt_setprop_cell(mc->fdt, imsic_name, "phandle", *msi_m_phandle); - platform_bus_add_all_fdt_nodes(mc->fdt, imsic_name, - memmap[VIRT_PLATFORM_BUS].base, - memmap[VIRT_PLATFORM_BUS].size, - VIRT_PLATFORM_BUS_IRQ); - g_free(imsic_name); /* S-level IMSIC node */ @@ -704,10 +701,12 @@ static void create_fdt_socket_aplic(RISCVVirtState *s, riscv_socket_fdt_write_id(mc, mc->fdt, aplic_name, socket); qemu_fdt_setprop_cell(mc->fdt, aplic_name, "phandle", aplic_s_phandle); - platform_bus_add_all_fdt_nodes(mc->fdt, aplic_name, - memmap[VIRT_PLATFORM_BUS].base, - memmap[VIRT_PLATFORM_BUS].size, - VIRT_PLATFORM_BUS_IRQ); + if (!socket) { + platform_bus_add_all_fdt_nodes(mc->fdt, aplic_name, + memmap[VIRT_PLATFORM_BUS].base, + memmap[VIRT_PLATFORM_BUS].size, + VIRT_PLATFORM_BUS_IRQ); + } g_free(aplic_name); @@ -1351,7 +1350,7 @@ static void virt_machine_init(MachineState *machine) base_hartid, &error_abort); object_property_set_int(OBJECT(&s->soc[i]), "num-harts", hart_count, &error_abort); - sysbus_realize(SYS_BUS_DEVICE(&s->soc[i]), &error_abort); + sysbus_realize(SYS_BUS_DEVICE(&s->soc[i]), &error_fatal); if (!kvm_enabled()) { if (s->have_aclint) { diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c index 0cf69a8c6d..f0147a050a 100644 --- a/hw/vfio/pci-quirks.c +++ b/hw/vfio/pci-quirks.c @@ -1565,22 +1565,6 @@ static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, Error **errp) return 0; } -static void vfio_pci_nvlink2_get_tgt(Object *obj, Visitor *v, - const char *name, - void *opaque, Error **errp) -{ - uint64_t tgt = (uintptr_t) opaque; - visit_type_uint64(v, name, &tgt, errp); -} - -static void vfio_pci_nvlink2_get_link_speed(Object *obj, Visitor *v, - const char *name, - void *opaque, Error **errp) -{ - uint32_t link_speed = (uint32_t)(uintptr_t) opaque; - visit_type_uint32(v, name, &link_speed, errp); -} - int vfio_pci_nvidia_v100_ram_init(VFIOPCIDevice *vdev, Error **errp) { int ret; @@ -1618,9 +1602,9 @@ int vfio_pci_nvidia_v100_ram_init(VFIOPCIDevice *vdev, Error **errp) nv2reg->size, p); QLIST_INSERT_HEAD(&vdev->bars[0].quirks, quirk, next); - object_property_add(OBJECT(vdev), "nvlink2-tgt", "uint64", - vfio_pci_nvlink2_get_tgt, NULL, NULL, - (void *) (uintptr_t) cap->tgt); + object_property_add_uint64_ptr(OBJECT(vdev), "nvlink2-tgt", + (uint64_t *) &cap->tgt, + OBJ_PROP_FLAG_READ); trace_vfio_pci_nvidia_gpu_setup_quirk(vdev->vbasedev.name, cap->tgt, nv2reg->size); free_exit: @@ -1679,15 +1663,15 @@ int vfio_pci_nvlink2_init(VFIOPCIDevice *vdev, Error **errp) QLIST_INSERT_HEAD(&vdev->bars[0].quirks, quirk, next); } - object_property_add(OBJECT(vdev), "nvlink2-tgt", "uint64", - vfio_pci_nvlink2_get_tgt, NULL, NULL, - (void *) (uintptr_t) captgt->tgt); + object_property_add_uint64_ptr(OBJECT(vdev), "nvlink2-tgt", + (uint64_t *) &captgt->tgt, + OBJ_PROP_FLAG_READ); trace_vfio_pci_nvlink2_setup_quirk_ssatgt(vdev->vbasedev.name, captgt->tgt, atsdreg->size); - object_property_add(OBJECT(vdev), "nvlink2-link-speed", "uint32", - vfio_pci_nvlink2_get_link_speed, NULL, NULL, - (void *) (uintptr_t) capspeed->link_speed); + object_property_add_uint32_ptr(OBJECT(vdev), "nvlink2-link-speed", + &capspeed->link_speed, + OBJ_PROP_FLAG_READ); trace_vfio_pci_nvlink2_setup_quirk_lnkspd(vdev->vbasedev.name, capspeed->link_speed); free_exit: diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 69f209af87..12b50b7124 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -2783,6 +2783,122 @@ GuestMemoryBlockInfo *qmp_guest_get_memory_block_info(Error **errp) return info; } +#define MAX_NAME_LEN 128 +static GuestDiskStatsInfoList *guest_get_diskstats(Error **errp) +{ +#ifdef CONFIG_LINUX + GuestDiskStatsInfoList *head = NULL, **tail = &head; + const char *diskstats = "/proc/diskstats"; + FILE *fp; + size_t n; + char *line = NULL; + + fp = fopen(diskstats, "r"); + if (fp == NULL) { + error_setg_errno(errp, errno, "open(\"%s\")", diskstats); + return NULL; + } + + while (getline(&line, &n, fp) != -1) { + g_autofree GuestDiskStatsInfo *diskstatinfo = NULL; + g_autofree GuestDiskStats *diskstat = NULL; + char dev_name[MAX_NAME_LEN]; + unsigned int ios_pgr, tot_ticks, rq_ticks, wr_ticks, dc_ticks, fl_ticks; + unsigned long rd_ios, rd_merges_or_rd_sec, rd_ticks_or_wr_sec, wr_ios; + unsigned long wr_merges, rd_sec_or_wr_ios, wr_sec; + unsigned long dc_ios, dc_merges, dc_sec, fl_ios; + unsigned int major, minor; + int i; + + i = sscanf(line, "%u %u %s %lu %lu %lu" + "%lu %lu %lu %lu %u %u %u %u" + "%lu %lu %lu %u %lu %u", + &major, &minor, dev_name, + &rd_ios, &rd_merges_or_rd_sec, &rd_sec_or_wr_ios, + &rd_ticks_or_wr_sec, &wr_ios, &wr_merges, &wr_sec, + &wr_ticks, &ios_pgr, &tot_ticks, &rq_ticks, + &dc_ios, &dc_merges, &dc_sec, &dc_ticks, + &fl_ios, &fl_ticks); + + if (i < 7) { + continue; + } + + diskstatinfo = g_new0(GuestDiskStatsInfo, 1); + diskstatinfo->name = g_strdup(dev_name); + diskstatinfo->major = major; + diskstatinfo->minor = minor; + + diskstat = g_new0(GuestDiskStats, 1); + if (i == 7) { + diskstat->has_read_ios = true; + diskstat->read_ios = rd_ios; + diskstat->has_read_sectors = true; + diskstat->read_sectors = rd_merges_or_rd_sec; + diskstat->has_write_ios = true; + diskstat->write_ios = rd_sec_or_wr_ios; + diskstat->has_write_sectors = true; + diskstat->write_sectors = rd_ticks_or_wr_sec; + } + if (i >= 14) { + diskstat->has_read_ios = true; + diskstat->read_ios = rd_ios; + diskstat->has_read_sectors = true; + diskstat->read_sectors = rd_sec_or_wr_ios; + diskstat->has_read_merges = true; + diskstat->read_merges = rd_merges_or_rd_sec; + diskstat->has_read_ticks = true; + diskstat->read_ticks = rd_ticks_or_wr_sec; + diskstat->has_write_ios = true; + diskstat->write_ios = wr_ios; + diskstat->has_write_sectors = true; + diskstat->write_sectors = wr_sec; + diskstat->has_write_merges = true; + diskstat->write_merges = wr_merges; + diskstat->has_write_ticks = true; + diskstat->write_ticks = wr_ticks; + diskstat->has_ios_pgr = true; + diskstat->ios_pgr = ios_pgr; + diskstat->has_total_ticks = true; + diskstat->total_ticks = tot_ticks; + diskstat->has_weight_ticks = true; + diskstat->weight_ticks = rq_ticks; + } + if (i >= 18) { + diskstat->has_discard_ios = true; + diskstat->discard_ios = dc_ios; + diskstat->has_discard_merges = true; + diskstat->discard_merges = dc_merges; + diskstat->has_discard_sectors = true; + diskstat->discard_sectors = dc_sec; + diskstat->has_discard_ticks = true; + diskstat->discard_ticks = dc_ticks; + } + if (i >= 20) { + diskstat->has_flush_ios = true; + diskstat->flush_ios = fl_ios; + diskstat->has_flush_ticks = true; + diskstat->flush_ticks = fl_ticks; + } + + diskstatinfo->stats = g_steal_pointer(&diskstat); + QAPI_LIST_APPEND(tail, diskstatinfo); + diskstatinfo = NULL; + } + free(line); + fclose(fp); + return head; +#else + g_debug("disk stats reporting available only for Linux"); + return NULL; +#endif +} + +GuestDiskStatsInfoList *qmp_guest_get_diskstats(Error **errp) +{ + return guest_get_diskstats(errp); +} + #else /* defined(__linux__) */ void qmp_guest_suspend_disk(Error **errp) @@ -3131,6 +3247,13 @@ GuestDiskInfoList *qmp_guest_get_disks(Error **errp) return NULL; } +GuestDiskStatsInfoList *qmp_guest_get_diskstats(Error **errp) +{ + error_setg(errp, QERR_UNSUPPORTED); + return NULL; +} + + #endif /* CONFIG_FSFREEZE */ #if !defined(CONFIG_FSTRIM) diff --git a/qga/commands-win32.c b/qga/commands-win32.c index d56b5fd2a7..36f94c0f9c 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -490,6 +490,11 @@ static GuestDiskBusType win2qemu[] = { #if (_WIN32_WINNT >= 0x0601) [BusTypeVirtual] = GUEST_DISK_BUS_TYPE_VIRTUAL, [BusTypeFileBackedVirtual] = GUEST_DISK_BUS_TYPE_FILE_BACKED_VIRTUAL, + /* + * BusTypeSpaces currently is not suported + */ + [BusTypeSpaces] = GUEST_DISK_BUS_TYPE_UNKNOWN, + [BusTypeNvme] = GUEST_DISK_BUS_TYPE_NVME, #endif }; @@ -2532,3 +2537,9 @@ char *qga_get_host_name(Error **errp) return g_utf16_to_utf8(tmp, size, NULL, NULL, NULL); } + +GuestDiskStatsInfoList *qmp_guest_get_diskstats(Error **errp) +{ + error_setg(errp, QERR_UNSUPPORTED); + return NULL; +} diff --git a/qga/main.c b/qga/main.c index 3b9546c185..c373fec3ee 100644 --- a/qga/main.c +++ b/qga/main.c @@ -1271,6 +1271,8 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation) g_log_set_fatal_mask(NULL, G_LOG_LEVEL_ERROR); ga_enable_logging(s); + g_debug("Guest agent version %s started", QEMU_FULL_VERSION); + #ifdef _WIN32 /* On win32 the state directory is application specific (be it the default * or a user override). We got past the command line parsing; let's create diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json index f989597b0c..9fa20e791b 100644 --- a/qga/qapi-schema.json +++ b/qga/qapi-schema.json @@ -1490,3 +1490,89 @@ { 'command': 'guest-ssh-remove-authorized-keys', 'data': { 'username': 'str', 'keys': ['str'] }, 'if': 'CONFIG_POSIX' } + +## +# @GuestDiskStats: +# +# @read-sectors: sectors read +# +# @read-ios: reads completed successfully +# +# @read-merges: read requests merged +# +# @write-sectors: sectors written +# +# @write-ios: writes completed +# +# @write-merges: write requests merged +# +# @discard-sectors: sectors discarded +# +# @discard-ios: discards completed successfully +# +# @discard-merges: discard requests merged +# +# @flush-ios: flush requests completed successfully +# +# @read-ticks: time spent reading(ms) +# +# @write-ticks: time spent writing(ms) +# +# @discard-ticks: time spent discarding(ms) +# +# @flush-ticks: time spent flushing(ms) +# +# @ios-pgr: number of I/Os currently in flight +# +# @total-ticks: time spent doing I/Os (ms) +# +# @weight-ticks: weighted time spent doing I/Os since the last update of this field(ms) +# +# Since: 7.1 +## +{ 'struct': 'GuestDiskStats', + 'data': {'*read-sectors': 'uint64', + '*read-ios': 'uint64', + '*read-merges': 'uint64', + '*write-sectors': 'uint64', + '*write-ios': 'uint64', + '*write-merges': 'uint64', + '*discard-sectors': 'uint64', + '*discard-ios': 'uint64', + '*discard-merges': 'uint64', + '*flush-ios': 'uint64', + '*read-ticks': 'uint64', + '*write-ticks': 'uint64', + '*discard-ticks': 'uint64', + '*flush-ticks': 'uint64', + '*ios-pgr': 'uint64', + '*total-ticks': 'uint64', + '*weight-ticks': 'uint64' + } } + +## +# @GuestDiskStatsInfo: +# +# @name disk name +# +# @major major device number of disk +# +# @minor minor device number of disk +## +{ 'struct': 'GuestDiskStatsInfo', + 'data': {'name': 'str', + 'major': 'uint64', + 'minor': 'uint64', + 'stats': 'GuestDiskStats' } } + +## +# @guest-get-diskstats: +# +# Retrieve information about disk stats. +# Returns: List of disk stats of guest. +# +# Since: 7.1 +## +{ 'command': 'guest-get-diskstats', + 'returns': ['GuestDiskStatsInfo'] +} diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index ccacdee215..a91253d4bd 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -37,7 +37,7 @@ #define RISCV_CPU_MARCHID ((QEMU_VERSION_MAJOR << 16) | \ (QEMU_VERSION_MINOR << 8) | \ (QEMU_VERSION_MICRO)) -#define RISCV_CPU_MIPID RISCV_CPU_MARCHID +#define RISCV_CPU_MIMPID RISCV_CPU_MARCHID static const char riscv_single_letter_exts[] = "IEMAFDQCPVH"; @@ -406,6 +406,7 @@ void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb, } else { env->pc = data[0]; } + env->bins = data[1]; } static void riscv_cpu_reset(DeviceState *dev) @@ -445,6 +446,7 @@ static void riscv_cpu_reset(DeviceState *dev) env->mcause = 0; env->miclaim = MIP_SGEIP; env->pc = env->resetvec; + env->bins = 0; env->two_stage_lookup = false; /* Initialized default priorities of local interrupts. */ @@ -584,6 +586,20 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) uint32_t ext = 0; /* Do some ISA extension error checking */ + if (cpu->cfg.ext_g && !(cpu->cfg.ext_i && cpu->cfg.ext_m && + cpu->cfg.ext_a && cpu->cfg.ext_f && + cpu->cfg.ext_d && + cpu->cfg.ext_icsr && cpu->cfg.ext_ifencei)) { + warn_report("Setting G will also set IMAFD_Zicsr_Zifencei"); + cpu->cfg.ext_i = true; + cpu->cfg.ext_m = true; + cpu->cfg.ext_a = true; + cpu->cfg.ext_f = true; + cpu->cfg.ext_d = true; + cpu->cfg.ext_icsr = true; + cpu->cfg.ext_ifencei = true; + } + if (cpu->cfg.ext_i && cpu->cfg.ext_e) { error_setg(errp, "I and E extensions are incompatible"); @@ -596,22 +612,49 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) return; } - if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m & - cpu->cfg.ext_a & cpu->cfg.ext_f & - cpu->cfg.ext_d)) { - warn_report("Setting G will also set IMAFD"); - cpu->cfg.ext_i = true; - cpu->cfg.ext_m = true; - cpu->cfg.ext_a = true; - cpu->cfg.ext_f = true; - cpu->cfg.ext_d = true; + if (cpu->cfg.ext_f && !cpu->cfg.ext_icsr) { + error_setg(errp, "F extension requires Zicsr"); + return; + } + + if ((cpu->cfg.ext_zfh || cpu->cfg.ext_zfhmin) && !cpu->cfg.ext_f) { + error_setg(errp, "Zfh/Zfhmin extensions require F extension"); + return; + } + + if (cpu->cfg.ext_d && !cpu->cfg.ext_f) { + error_setg(errp, "D extension requires F extension"); + return; + } + + if (cpu->cfg.ext_v && !cpu->cfg.ext_d) { + error_setg(errp, "V extension requires D extension"); + return; } + if ((cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) && !cpu->cfg.ext_f) { + error_setg(errp, "Zve32f/Zve64f extensions require F extension"); + return; + } + + /* Set the ISA extensions, checks should have happened above */ if (cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinx || cpu->cfg.ext_zhinxmin) { cpu->cfg.ext_zfinx = true; } + if (cpu->cfg.ext_zfinx) { + if (!cpu->cfg.ext_icsr) { + error_setg(errp, "Zfinx extension requires Zicsr"); + return; + } + if (cpu->cfg.ext_f) { + error_setg(errp, + "Zfinx cannot be supported together with F extension"); + return; + } + } + if (cpu->cfg.ext_zk) { cpu->cfg.ext_zkn = true; cpu->cfg.ext_zkr = true; @@ -635,7 +678,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) cpu->cfg.ext_zksh = true; } - /* Set the ISA extensions, checks should have happened above */ if (cpu->cfg.ext_i) { ext |= RVI; } @@ -706,20 +748,9 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) } set_vext_version(env, vext_version); } - if ((cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) && !cpu->cfg.ext_f) { - error_setg(errp, "Zve32f/Zve64f extension depends upon RVF."); - return; - } if (cpu->cfg.ext_j) { ext |= RVJ; } - if (cpu->cfg.ext_zfinx && ((ext & (RVF | RVD)) || cpu->cfg.ext_zfh || - cpu->cfg.ext_zfhmin)) { - error_setg(errp, - "'Zfinx' cannot be supported together with 'F', 'D', 'Zfh'," - " 'Zfhmin'"); - return; - } set_misa(env, env->misa_mxl, ext); } @@ -812,7 +843,7 @@ static Property riscv_cpu_properties[] = { /* Defaults for standard extensions */ DEFINE_PROP_BOOL("i", RISCVCPU, cfg.ext_i, true), DEFINE_PROP_BOOL("e", RISCVCPU, cfg.ext_e, false), - DEFINE_PROP_BOOL("g", RISCVCPU, cfg.ext_g, true), + DEFINE_PROP_BOOL("g", RISCVCPU, cfg.ext_g, false), DEFINE_PROP_BOOL("m", RISCVCPU, cfg.ext_m, true), DEFINE_PROP_BOOL("a", RISCVCPU, cfg.ext_a, true), DEFINE_PROP_BOOL("f", RISCVCPU, cfg.ext_f, true), @@ -840,7 +871,7 @@ static Property riscv_cpu_properties[] = { DEFINE_PROP_UINT32("mvendorid", RISCVCPU, cfg.mvendorid, 0), DEFINE_PROP_UINT64("marchid", RISCVCPU, cfg.marchid, RISCV_CPU_MARCHID), - DEFINE_PROP_UINT64("mipid", RISCVCPU, cfg.mipid, RISCV_CPU_MIPID), + DEFINE_PROP_UINT64("mimpid", RISCVCPU, cfg.mimpid, RISCV_CPU_MIMPID), DEFINE_PROP_BOOL("svinval", RISCVCPU, cfg.ext_svinval, false), DEFINE_PROP_BOOL("svnapot", RISCVCPU, cfg.ext_svnapot, false), @@ -879,6 +910,8 @@ static Property riscv_cpu_properties[] = { DEFINE_PROP_BOOL("x-aia", RISCVCPU, cfg.aia, false), DEFINE_PROP_UINT64("resetvec", RISCVCPU, cfg.resetvec, DEFAULT_RSTVEC), + + DEFINE_PROP_BOOL("short-isa-string", RISCVCPU, cfg.short_isa_string, false), DEFINE_PROP_END_OF_LIST(), }; @@ -996,11 +1029,11 @@ static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str, int max_str_len) * extensions by an underscore. */ struct isa_ext_data isa_edata_arr[] = { + ISA_EDATA_ENTRY(zicsr, ext_icsr), + ISA_EDATA_ENTRY(zifencei, ext_ifencei), ISA_EDATA_ENTRY(zfh, ext_zfh), ISA_EDATA_ENTRY(zfhmin, ext_zfhmin), ISA_EDATA_ENTRY(zfinx, ext_zfinx), - ISA_EDATA_ENTRY(zhinx, ext_zhinx), - ISA_EDATA_ENTRY(zhinxmin, ext_zhinxmin), ISA_EDATA_ENTRY(zdinx, ext_zdinx), ISA_EDATA_ENTRY(zba, ext_zba), ISA_EDATA_ENTRY(zbb, ext_zbb), @@ -1021,6 +1054,8 @@ static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str, int max_str_len) ISA_EDATA_ENTRY(zkt, ext_zkt), ISA_EDATA_ENTRY(zve32f, ext_zve32f), ISA_EDATA_ENTRY(zve64f, ext_zve64f), + ISA_EDATA_ENTRY(zhinx, ext_zhinx), + ISA_EDATA_ENTRY(zhinxmin, ext_zhinxmin), ISA_EDATA_ENTRY(svinval, ext_svinval), ISA_EDATA_ENTRY(svnapot, ext_svnapot), ISA_EDATA_ENTRY(svpbmt, ext_svpbmt), @@ -1049,7 +1084,9 @@ char *riscv_isa_string(RISCVCPU *cpu) } } *p = '\0'; - riscv_isa_string_ext(cpu, &isa_str, maxlen); + if (!cpu->cfg.short_isa_string) { + riscv_isa_string_ext(cpu, &isa_str, maxlen); + } return isa_str; } diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index fe6c9a2c92..f08c3e8813 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -30,6 +30,12 @@ #define TCG_GUEST_DEFAULT_MO 0 +/* + * RISC-V-specific extra insn start words: + * 1: Original instruction opcode + */ +#define TARGET_INSN_START_EXTRA_WORDS 1 + #define TYPE_RISCV_CPU "riscv-cpu" #define RISCV_CPU_TYPE_SUFFIX "-" TYPE_RISCV_CPU @@ -140,7 +146,7 @@ struct CPUArchState { target_ulong frm; target_ulong badaddr; - uint32_t bins; + target_ulong bins; target_ulong guest_phys_fault_addr; @@ -408,7 +414,7 @@ struct RISCVCPUConfig { uint32_t mvendorid; uint64_t marchid; - uint64_t mipid; + uint64_t mimpid; /* Vendor-specific custom extensions */ bool ext_XVentanaCondOps; @@ -425,6 +431,8 @@ struct RISCVCPUConfig { bool aia; bool debug; uint64_t resetvec; + + bool short_isa_string; }; typedef struct RISCVCPUConfig RISCVCPUConfig; diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index e1aa4f2097..d99fac9d2d 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -1367,10 +1367,11 @@ void riscv_cpu_do_interrupt(CPUState *cs) case RISCV_EXCP_INST_PAGE_FAULT: case RISCV_EXCP_LOAD_PAGE_FAULT: case RISCV_EXCP_STORE_PAGE_FAULT: - write_gva = true; + write_gva = env->two_stage_lookup; tval = env->badaddr; break; case RISCV_EXCP_ILLEGAL_INST: + case RISCV_EXCP_VIRT_INSTRUCTION_FAULT: tval = env->bins; break; default: @@ -1434,7 +1435,6 @@ void riscv_cpu_do_interrupt(CPUState *cs) /* Trap into HS mode */ env->hstatus = set_field(env->hstatus, HSTATUS_SPV, false); htval = env->guest_phys_fault_addr; - write_gva = false; } env->hstatus = set_field(env->hstatus, HSTATUS_GVA, write_gva); } diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 3500e07f92..6dbe9b541f 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -674,13 +674,13 @@ static RISCVException read_marchid(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } -static RISCVException read_mipid(CPURISCVState *env, int csrno, - target_ulong *val) +static RISCVException read_mimpid(CPURISCVState *env, int csrno, + target_ulong *val) { CPUState *cs = env_cpu(env); RISCVCPU *cpu = RISCV_CPU(cs); - *val = cpu->cfg.mipid; + *val = cpu->cfg.mimpid; return RISCV_EXCP_NONE; } @@ -3139,20 +3139,24 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env, int read_only = get_field(csrno, 0xC00) == 3; int csr_min_priv = csr_ops[csrno].min_priv_ver; #if !defined(CONFIG_USER_ONLY) - int effective_priv = env->priv; + int csr_priv, effective_priv = env->priv; - if (riscv_has_ext(env, RVH) && - env->priv == PRV_S && - !riscv_cpu_virt_enabled(env)) { + if (riscv_has_ext(env, RVH) && env->priv == PRV_S) { /* - * We are in S mode without virtualisation, therefore we are in HS Mode. + * We are in either HS or VS mode. * Add 1 to the effective privledge level to allow us to access the - * Hypervisor CSRs. + * Hypervisor CSRs. The `hmode` predicate will determine if access + * should be allowed(HS) or if a virtual instruction exception should be + * raised(VS). */ effective_priv++; } - if (!env->debugger && (effective_priv < get_field(csrno, 0x300))) { + csr_priv = get_field(csrno, 0x300); + if (!env->debugger && (effective_priv < csr_priv)) { + if (csr_priv == (PRV_S + 1) && riscv_cpu_virt_enabled(env)) { + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; + } return RISCV_EXCP_ILLEGAL_INST; } #endif @@ -3372,7 +3376,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { /* Machine Information Registers */ [CSR_MVENDORID] = { "mvendorid", any, read_mvendorid }, [CSR_MARCHID] = { "marchid", any, read_marchid }, - [CSR_MIMPID] = { "mimpid", any, read_mipid }, + [CSR_MIMPID] = { "mimpid", any, read_mimpid }, [CSR_MHARTID] = { "mhartid", any, read_mhartid }, [CSR_MCONFIGPTR] = { "mconfigptr", any, read_zero, diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc index 90327509f7..391c61fe93 100644 --- a/target/riscv/insn_trans/trans_rvv.c.inc +++ b/target/riscv/insn_trans/trans_rvv.c.inc @@ -1118,10 +1118,10 @@ GEN_VEXT_TRANS(vle64ff_v, MO_64, r2nfvm, ldff_op, ld_us_check) typedef void gen_helper_ldst_whole(TCGv_ptr, TCGv, TCGv_env, TCGv_i32); static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf, - gen_helper_ldst_whole *fn, DisasContext *s, - bool is_store) + uint32_t width, gen_helper_ldst_whole *fn, + DisasContext *s, bool is_store) { - uint32_t evl = (s->cfg_ptr->vlen / 8) * nf / (1 << s->sew); + uint32_t evl = (s->cfg_ptr->vlen / 8) * nf / width; TCGLabel *over = gen_new_label(); tcg_gen_brcondi_tl(TCG_COND_GEU, cpu_vstart, evl, over); @@ -1153,38 +1153,42 @@ static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf, * load and store whole register instructions ignore vtype and vl setting. * Thus, we don't need to check vill bit. (Section 7.9) */ -#define GEN_LDST_WHOLE_TRANS(NAME, ARG_NF, IS_STORE) \ +#define GEN_LDST_WHOLE_TRANS(NAME, ARG_NF, WIDTH, IS_STORE) \ static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \ { \ if (require_rvv(s) && \ QEMU_IS_ALIGNED(a->rd, ARG_NF)) { \ - return ldst_whole_trans(a->rd, a->rs1, ARG_NF, gen_helper_##NAME, \ - s, IS_STORE); \ + return ldst_whole_trans(a->rd, a->rs1, ARG_NF, WIDTH, \ + gen_helper_##NAME, s, IS_STORE); \ } \ return false; \ } -GEN_LDST_WHOLE_TRANS(vl1re8_v, 1, false) -GEN_LDST_WHOLE_TRANS(vl1re16_v, 1, false) -GEN_LDST_WHOLE_TRANS(vl1re32_v, 1, false) -GEN_LDST_WHOLE_TRANS(vl1re64_v, 1, false) -GEN_LDST_WHOLE_TRANS(vl2re8_v, 2, false) -GEN_LDST_WHOLE_TRANS(vl2re16_v, 2, false) -GEN_LDST_WHOLE_TRANS(vl2re32_v, 2, false) -GEN_LDST_WHOLE_TRANS(vl2re64_v, 2, false) -GEN_LDST_WHOLE_TRANS(vl4re8_v, 4, false) -GEN_LDST_WHOLE_TRANS(vl4re16_v, 4, false) -GEN_LDST_WHOLE_TRANS(vl4re32_v, 4, false) -GEN_LDST_WHOLE_TRANS(vl4re64_v, 4, false) -GEN_LDST_WHOLE_TRANS(vl8re8_v, 8, false) -GEN_LDST_WHOLE_TRANS(vl8re16_v, 8, false) -GEN_LDST_WHOLE_TRANS(vl8re32_v, 8, false) -GEN_LDST_WHOLE_TRANS(vl8re64_v, 8, false) - -GEN_LDST_WHOLE_TRANS(vs1r_v, 1, true) -GEN_LDST_WHOLE_TRANS(vs2r_v, 2, true) -GEN_LDST_WHOLE_TRANS(vs4r_v, 4, true) -GEN_LDST_WHOLE_TRANS(vs8r_v, 8, true) +GEN_LDST_WHOLE_TRANS(vl1re8_v, 1, 1, false) +GEN_LDST_WHOLE_TRANS(vl1re16_v, 1, 2, false) +GEN_LDST_WHOLE_TRANS(vl1re32_v, 1, 4, false) +GEN_LDST_WHOLE_TRANS(vl1re64_v, 1, 8, false) +GEN_LDST_WHOLE_TRANS(vl2re8_v, 2, 1, false) +GEN_LDST_WHOLE_TRANS(vl2re16_v, 2, 2, false) +GEN_LDST_WHOLE_TRANS(vl2re32_v, 2, 4, false) +GEN_LDST_WHOLE_TRANS(vl2re64_v, 2, 8, false) +GEN_LDST_WHOLE_TRANS(vl4re8_v, 4, 1, false) +GEN_LDST_WHOLE_TRANS(vl4re16_v, 4, 2, false) +GEN_LDST_WHOLE_TRANS(vl4re32_v, 4, 4, false) +GEN_LDST_WHOLE_TRANS(vl4re64_v, 4, 8, false) +GEN_LDST_WHOLE_TRANS(vl8re8_v, 8, 1, false) +GEN_LDST_WHOLE_TRANS(vl8re16_v, 8, 2, false) +GEN_LDST_WHOLE_TRANS(vl8re32_v, 8, 4, false) +GEN_LDST_WHOLE_TRANS(vl8re64_v, 8, 8, false) + +/* + * The vector whole register store instructions are encoded similar to + * unmasked unit-stride store of elements with EEW=8. + */ +GEN_LDST_WHOLE_TRANS(vs1r_v, 1, 1, true) +GEN_LDST_WHOLE_TRANS(vs2r_v, 2, 1, true) +GEN_LDST_WHOLE_TRANS(vs4r_v, 4, 1, true) +GEN_LDST_WHOLE_TRANS(vs8r_v, 8, 1, true) /* *** Vector Integer Arithmetic Instructions diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 0cd1d9ee94..55a4713af2 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -107,6 +107,8 @@ typedef struct DisasContext { /* PointerMasking extension */ bool pm_mask_enabled; bool pm_base_enabled; + /* TCG of the current insn_start */ + TCGOp *insn_start; } DisasContext; static inline bool has_ext(DisasContext *ctx, uint32_t ext) @@ -236,9 +238,6 @@ static void generate_exception_mtval(DisasContext *ctx, int excp) static void gen_exception_illegal(DisasContext *ctx) { - tcg_gen_st_i32(tcg_constant_i32(ctx->opcode), cpu_env, - offsetof(CPURISCVState, bins)); - generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST); } @@ -1017,6 +1016,13 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc) /* Include decoders for factored-out extensions */ #include "decode-XVentanaCondOps.c.inc" +static inline void decode_save_opc(DisasContext *ctx, target_ulong opc) +{ + assert(ctx->insn_start != NULL); + tcg_set_insn_start_param(ctx->insn_start, 1, opc); + ctx->insn_start = NULL; +} + static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode) { /* @@ -1033,6 +1039,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode) /* Check for compressed insn */ if (extract16(opcode, 0, 2) != 3) { + decode_save_opc(ctx, opcode); if (!has_ext(ctx, RVC)) { gen_exception_illegal(ctx); } else { @@ -1047,6 +1054,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode) opcode32 = deposit32(opcode32, 16, 16, translator_lduw(env, &ctx->base, ctx->base.pc_next + 2)); + decode_save_opc(ctx, opcode32); ctx->opcode = opcode32; ctx->pc_succ_insn = ctx->base.pc_next + 4; @@ -1113,7 +1121,8 @@ static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) { DisasContext *ctx = container_of(dcbase, DisasContext, base); - tcg_gen_insn_start(ctx->base.pc_next); + tcg_gen_insn_start(ctx->base.pc_next, 0); + ctx->insn_start = tcg_last_op(); } static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) diff --git a/tests/docker/dockerfiles/fedora-win32-cross.docker b/tests/docker/dockerfiles/fedora-win32-cross.docker index 84a8f5524d..a06bd29e8e 100644 --- a/tests/docker/dockerfiles/fedora-win32-cross.docker +++ b/tests/docker/dockerfiles/fedora-win32-cross.docker @@ -1,4 +1,4 @@ -FROM registry.fedoraproject.org/fedora:33 +FROM registry.fedoraproject.org/fedora:35 # Please keep this list sorted alphabetically ENV PACKAGES \ diff --git a/tests/docker/dockerfiles/fedora-win64-cross.docker b/tests/docker/dockerfiles/fedora-win64-cross.docker index d7ed8eb1cf..b71624330f 100644 --- a/tests/docker/dockerfiles/fedora-win64-cross.docker +++ b/tests/docker/dockerfiles/fedora-win64-cross.docker @@ -1,4 +1,4 @@ -FROM registry.fedoraproject.org/fedora:33 +FROM registry.fedoraproject.org/fedora:35 # Please keep this list sorted alphabetically ENV PACKAGES \ |