Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/awilliam/tags/vfio-update-20210…
Browse files Browse the repository at this point in the history
…713.0' into staging

VFIO update 2021-07-13

 * Coverity fix to discard listener (David Hildenbrand)

 * MSI-X PBA quirk for BAIDU VFs, additional helper use cases (Cai Huoqing)

# gpg: Signature made Tue 13 Jul 2021 22:19:35 BST
# gpg:                using RSA key 42F6C04E540BD1A99E7B8A90239B9B6E3BB08B22
# gpg:                issuer "alex.williamson@redhat.com"
# gpg: Good signature from "Alex Williamson <alex.williamson@redhat.com>" [full]
# gpg:                 aka "Alex Williamson <alex@shazbot.org>" [full]
# gpg:                 aka "Alex Williamson <alwillia@redhat.com>" [full]
# gpg:                 aka "Alex Williamson <alex.l.williamson@gmail.com>" [full]
# Primary key fingerprint: 42F6 C04E 540B D1A9 9E7B  8A90 239B 9B6E 3BB0 8B22

* remotes/awilliam/tags/vfio-update-20210713.0:
  vfio/pci: Add pba_offset PCI quirk for BAIDU KUNLUN AI processor
  vfio/pci: Change to use vfio_pci_is()
  vfio: Fix CID 1458134 in vfio_register_ram_discard_listener()
  hw/riscv: opentitan: Add the flash alias
  hw/riscv: opentitan: Add the unimplement rv_core_ibex_peri
  char: ibex_uart: Update the register layout
  hw/riscv: sifive_u: Make sure firmware info is 8-byte aligned
  hw/riscv: sifive_u: Correct the CLINT timebase frequency
  docs/system: riscv: Update Microchip Icicle Kit for direct kernel boot
  target/riscv: hardwire bits in hideleg and hedeleg
  docs/system: riscv: Add documentation for virt machine
  docs/system: riscv: Fix CLINT name in the sifive_u doc
  target/riscv: csr: Remove redundant check in fp csr read/write routines
  target/riscv: pmp: Fix some typos

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Jul 14, 2021
2 parents a9649a7 + fefc186 commit 731d506
Show file tree
Hide file tree
Showing 13 changed files with 248 additions and 55 deletions.
54 changes: 47 additions & 7 deletions docs/system/riscv/microchip-icicle-kit.rst
Expand Up @@ -47,13 +47,13 @@ The user provided DTB should have the following requirements:

QEMU follows below truth table to select which payload to execute:

===== ========== =======
-bios -kernel payload
===== ========== =======
N N HSS
Y don't care HSS
N Y kernel
===== ========== =======
===== ========== ========== =======
-bios -kernel -dtb payload
===== ========== ========== =======
N N don't care HSS
Y don't care don't care HSS
N Y Y kernel
===== ========== ========== =======

The memory is set to 1537 MiB by default which is the minimum required high
memory size by HSS. A sanity check on ram size is performed in the machine
Expand Down Expand Up @@ -106,4 +106,44 @@ HSS output is on the first serial port (stdio) and U-Boot outputs on the
second serial port. U-Boot will automatically load the Linux kernel from
the SD card image.

Direct Kernel Boot
------------------

Sometimes we just want to test booting a new kernel, and transforming the
kernel image to the format required by the HSS bootflow is tedious. We can
use '-kernel' for direct kernel booting just like other RISC-V machines do.

In this mode, the OpenSBI fw_dynamic BIOS image for 'generic' platform is
used to boot an S-mode payload like U-Boot or OS kernel directly.

For example, the following commands show building a U-Boot image from U-Boot
mainline v2021.07 for the Microchip Icicle Kit board:

.. code-block:: bash
$ export CROSS_COMPILE=riscv64-linux-
$ make microchip_mpfs_icicle_defconfig
Then we can boot the machine by:

.. code-block:: bash
$ qemu-system-riscv64 -M microchip-icicle-kit -smp 5 -m 2G \
-sd path/to/sdcard.img \
-nic user,model=cadence_gem \
-nic tap,ifname=tap,model=cadence_gem,script=no \
-display none -serial stdio \
-kernel path/to/u-boot/build/dir/u-boot.bin \
-dtb path/to/u-boot/build/dir/u-boot.dtb
CAVEATS:

* Check the "stdout-path" property in the /chosen node in the DTB to determine
which serial port is used for the serial console, e.g.: if the console is set
to the second serial port, change to use "-serial null -serial stdio".
* The default U-Boot configuration uses CONFIG_OF_SEPARATE hence the ELF image
``u-boot`` cannot be passed to "-kernel" as it does not contain the DTB hence
``u-boot.bin`` has to be used which does contain one. To use the ELF image,
we need to change to CONFIG_OF_EMBED or CONFIG_OF_PRIOR_STAGE.

.. _HSS: https://github.com/polarfire-soc/hart-software-services
2 changes: 1 addition & 1 deletion docs/system/riscv/sifive_u.rst
Expand Up @@ -11,7 +11,7 @@ The ``sifive_u`` machine supports the following devices:

* 1 E51 / E31 core
* Up to 4 U54 / U34 cores
* Core Level Interruptor (CLINT)
* Core Local Interruptor (CLINT)
* Platform-Level Interrupt Controller (PLIC)
* Power, Reset, Clock, Interrupt (PRCI)
* L2 Loosely Integrated Memory (L2-LIM)
Expand Down
138 changes: 138 additions & 0 deletions docs/system/riscv/virt.rst
@@ -0,0 +1,138 @@
'virt' Generic Virtual Platform (``virt``)
==========================================

The `virt` board is a platform which does not correspond to any real hardware;
it is designed for use in virtual machines. It is the recommended board type
if you simply want to run a guest such as Linux and do not care about
reproducing the idiosyncrasies and limitations of a particular bit of
real-world hardware.

Supported devices
-----------------

The ``virt`` machine supports the following devices:

* Up to 8 generic RV32GC/RV64GC cores, with optional extensions
* Core Local Interruptor (CLINT)
* Platform-Level Interrupt Controller (PLIC)
* CFI parallel NOR flash memory
* 1 NS16550 compatible UART
* 1 Google Goldfish RTC
* 1 SiFive Test device
* 8 virtio-mmio transport devices
* 1 generic PCIe host bridge
* The fw_cfg device that allows a guest to obtain data from QEMU

Note that the default CPU is a generic RV32GC/RV64GC. Optional extensions
can be enabled via command line parameters, e.g.: ``-cpu rv64,x-h=true``
enables the hypervisor extension for RV64.

Hardware configuration information
----------------------------------

The ``virt`` machine automatically generates a device tree blob ("dtb")
which it passes to the guest, if there is no ``-dtb`` option. This provides
information about the addresses, interrupt lines and other configuration of
the various devices in the system. Guest software should discover the devices
that are present in the generated DTB.

If users want to provide their own DTB, they can use the ``-dtb`` option.
These DTBs should have the following requirements:

* The number of subnodes of the /cpus node should match QEMU's ``-smp`` option
* The /memory reg size should match QEMU’s selected ram_size via ``-m``
* Should contain a node for the CLINT device with a compatible string
"riscv,clint0" if using with OpenSBI BIOS images

Boot options
------------

The ``virt`` machine can start using the standard -kernel functionality
for loading a Linux kernel, a VxWorks kernel, an S-mode U-Boot bootloader
with the default OpenSBI firmware image as the -bios. It also supports
the recommended RISC-V bootflow: U-Boot SPL (M-mode) loads OpenSBI fw_dynamic
firmware and U-Boot proper (S-mode), using the standard -bios functionality.

Running Linux kernel
--------------------

Linux mainline v5.12 release is tested at the time of writing. To build a
Linux mainline kernel that can be booted by the ``virt`` machine in
64-bit mode, simply configure the kernel using the defconfig configuration:

.. code-block:: bash
$ export ARCH=riscv
$ export CROSS_COMPILE=riscv64-linux-
$ make defconfig
$ make
To boot the newly built Linux kernel in QEMU with the ``virt`` machine:

.. code-block:: bash
$ qemu-system-riscv64 -M virt -smp 4 -m 2G \
-display none -serial stdio \
-kernel arch/riscv/boot/Image \
-initrd /path/to/rootfs.cpio \
-append "root=/dev/ram"
To build a Linux mainline kernel that can be booted by the ``virt`` machine
in 32-bit mode, use the rv32_defconfig configuration. A patch is required to
fix the 32-bit boot issue for Linux kernel v5.12.

.. code-block:: bash
$ export ARCH=riscv
$ export CROSS_COMPILE=riscv64-linux-
$ curl https://patchwork.kernel.org/project/linux-riscv/patch/20210627135117.28641-1-bmeng.cn@gmail.com/mbox/ > riscv.patch
$ git am riscv.patch
$ make rv32_defconfig
$ make
Replace ``qemu-system-riscv64`` with ``qemu-system-riscv32`` in the command
line above to boot the 32-bit Linux kernel. A rootfs image containing 32-bit
applications shall be used in order for kernel to boot to user space.

Running U-Boot
--------------

U-Boot mainline v2021.04 release is tested at the time of writing. To build an
S-mode U-Boot bootloader that can be booted by the ``virt`` machine, use
the qemu-riscv64_smode_defconfig with similar commands as described above for Linux:

.. code-block:: bash
$ export CROSS_COMPILE=riscv64-linux-
$ make qemu-riscv64_smode_defconfig
Boot the 64-bit U-Boot S-mode image directly:

.. code-block:: bash
$ qemu-system-riscv64 -M virt -smp 4 -m 2G \
-display none -serial stdio \
-kernel /path/to/u-boot.bin
To test booting U-Boot SPL which in M-mode, which in turn loads a FIT image
that bundles OpenSBI fw_dynamic firmware and U-Boot proper (S-mode) together,
build the U-Boot images using riscv64_spl_defconfig:

.. code-block:: bash
$ export CROSS_COMPILE=riscv64-linux-
$ export OPENSBI=/path/to/opensbi-riscv64-generic-fw_dynamic.bin
$ make qemu-riscv64_spl_defconfig
The minimal QEMU commands to run U-Boot SPL are:

.. code-block:: bash
$ qemu-system-riscv64 -M virt -smp 4 -m 2G \
-display none -serial stdio \
-bios /path/to/u-boot-spl \
-device loader,file=/path/to/u-boot.itb,addr=0x80200000
To test 32-bit U-Boot images, switch to use qemu-riscv32_smode_defconfig and
riscv32_spl_defconfig builds, and replace ``qemu-system-riscv64`` with
``qemu-system-riscv32`` in the command lines above to boot the 32-bit U-Boot.
1 change: 1 addition & 0 deletions docs/system/target-riscv.rst
Expand Up @@ -69,6 +69,7 @@ undocumented; you can get a complete list by running
riscv/microchip-icicle-kit
riscv/shakti-c
riscv/sifive_u
riscv/virt

RISC-V CPU firmware
-------------------
Expand Down
19 changes: 10 additions & 9 deletions hw/char/ibex_uart.c
Expand Up @@ -42,7 +42,8 @@ REG32(INTR_STATE, 0x00)
FIELD(INTR_STATE, RX_OVERFLOW, 3, 1)
REG32(INTR_ENABLE, 0x04)
REG32(INTR_TEST, 0x08)
REG32(CTRL, 0x0C)
REG32(ALERT_TEST, 0x0C)
REG32(CTRL, 0x10)
FIELD(CTRL, TX_ENABLE, 0, 1)
FIELD(CTRL, RX_ENABLE, 1, 1)
FIELD(CTRL, NF, 2, 1)
Expand All @@ -52,25 +53,25 @@ REG32(CTRL, 0x0C)
FIELD(CTRL, PARITY_ODD, 7, 1)
FIELD(CTRL, RXBLVL, 8, 2)
FIELD(CTRL, NCO, 16, 16)
REG32(STATUS, 0x10)
REG32(STATUS, 0x14)
FIELD(STATUS, TXFULL, 0, 1)
FIELD(STATUS, RXFULL, 1, 1)
FIELD(STATUS, TXEMPTY, 2, 1)
FIELD(STATUS, RXIDLE, 4, 1)
FIELD(STATUS, RXEMPTY, 5, 1)
REG32(RDATA, 0x14)
REG32(WDATA, 0x18)
REG32(FIFO_CTRL, 0x1c)
REG32(RDATA, 0x18)
REG32(WDATA, 0x1C)
REG32(FIFO_CTRL, 0x20)
FIELD(FIFO_CTRL, RXRST, 0, 1)
FIELD(FIFO_CTRL, TXRST, 1, 1)
FIELD(FIFO_CTRL, RXILVL, 2, 3)
FIELD(FIFO_CTRL, TXILVL, 5, 2)
REG32(FIFO_STATUS, 0x20)
REG32(FIFO_STATUS, 0x24)
FIELD(FIFO_STATUS, TXLVL, 0, 5)
FIELD(FIFO_STATUS, RXLVL, 16, 5)
REG32(OVRD, 0x24)
REG32(VAL, 0x28)
REG32(TIMEOUT_CTRL, 0x2c)
REG32(OVRD, 0x28)
REG32(VAL, 0x2C)
REG32(TIMEOUT_CTRL, 0x30)

static void ibex_uart_update_irqs(IbexUartState *s)
{
Expand Down
9 changes: 9 additions & 0 deletions hw/riscv/opentitan.c
Expand Up @@ -58,6 +58,8 @@ static const MemMapEntry ibex_memmap[] = {
[IBEX_DEV_ALERT_HANDLER] = { 0x411b0000, 0x1000 },
[IBEX_DEV_NMI_GEN] = { 0x411c0000, 0x1000 },
[IBEX_DEV_OTBN] = { 0x411d0000, 0x10000 },
[IBEX_DEV_PERI] = { 0x411f0000, 0x10000 },
[IBEX_DEV_FLASH_VIRTUAL] = { 0x80000000, 0x80000 },
};

static void opentitan_board_init(MachineState *machine)
Expand Down Expand Up @@ -133,8 +135,13 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
/* Flash memory */
memory_region_init_rom(&s->flash_mem, OBJECT(dev_soc), "riscv.lowrisc.ibex.flash",
memmap[IBEX_DEV_FLASH].size, &error_fatal);
memory_region_init_alias(&s->flash_alias, OBJECT(dev_soc),
"riscv.lowrisc.ibex.flash_virtual", &s->flash_mem, 0,
memmap[IBEX_DEV_FLASH_VIRTUAL].size);
memory_region_add_subregion(sys_mem, memmap[IBEX_DEV_FLASH].base,
&s->flash_mem);
memory_region_add_subregion(sys_mem, memmap[IBEX_DEV_FLASH_VIRTUAL].base,
&s->flash_alias);

/* PLIC */
if (!sysbus_realize(SYS_BUS_DEVICE(&s->plic), errp)) {
Expand Down Expand Up @@ -217,6 +224,8 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
memmap[IBEX_DEV_NMI_GEN].base, memmap[IBEX_DEV_NMI_GEN].size);
create_unimplemented_device("riscv.lowrisc.ibex.otbn",
memmap[IBEX_DEV_OTBN].base, memmap[IBEX_DEV_OTBN].size);
create_unimplemented_device("riscv.lowrisc.ibex.peri",
memmap[IBEX_DEV_PERI].base, memmap[IBEX_DEV_PERI].size);
}

static void lowrisc_ibex_soc_class_init(ObjectClass *oc, void *data)
Expand Down
12 changes: 8 additions & 4 deletions hw/riscv/sifive_u.c
Expand Up @@ -62,6 +62,9 @@

#include <libfdt.h>

/* CLINT timebase frequency */
#define CLINT_TIMEBASE_FREQ 1000000

static const MemMapEntry sifive_u_memmap[] = {
[SIFIVE_U_DEV_DEBUG] = { 0x0, 0x100 },
[SIFIVE_U_DEV_MROM] = { 0x1000, 0xf000 },
Expand Down Expand Up @@ -165,7 +168,7 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,

qemu_fdt_add_subnode(fdt, "/cpus");
qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency",
SIFIVE_CLINT_TIMEBASE_FREQ);
CLINT_TIMEBASE_FREQ);
qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);

Expand Down Expand Up @@ -599,17 +602,18 @@ static void sifive_u_machine_init(MachineState *machine)
}

/* reset vector */
uint32_t reset_vec[11] = {
uint32_t reset_vec[12] = {
s->msel, /* MSEL pin state */
0x00000297, /* 1: auipc t0, %pcrel_hi(fw_dyn) */
0x02828613, /* addi a2, t0, %pcrel_lo(1b) */
0x02c28613, /* addi a2, t0, %pcrel_lo(1b) */
0xf1402573, /* csrr a0, mhartid */
0,
0,
0x00028067, /* jr t0 */
start_addr, /* start: .dword */
start_addr_hi32,
fdt_load_addr, /* fdt_laddr: .dword */
0x00000000,
0x00000000,
/* fw_dyn: */
};
Expand Down Expand Up @@ -847,7 +851,7 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
sifive_clint_create(memmap[SIFIVE_U_DEV_CLINT].base,
memmap[SIFIVE_U_DEV_CLINT].size, 0, ms->smp.cpus,
SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
SIFIVE_CLINT_TIMEBASE_FREQ, false);
CLINT_TIMEBASE_FREQ, false);

if (!sysbus_realize(SYS_BUS_DEVICE(&s->prci), errp)) {
return;
Expand Down
3 changes: 2 additions & 1 deletion hw/vfio/common.c
Expand Up @@ -783,7 +783,8 @@ static void vfio_register_ram_discard_listener(VFIOContainer *container,
section->mr);

g_assert(vrdl->granularity && is_power_of_2(vrdl->granularity));
g_assert(vrdl->granularity >= 1 << ctz64(container->pgsizes));
g_assert(container->pgsizes &&
vrdl->granularity >= 1ULL << ctz64(container->pgsizes));

ram_discard_listener_init(&vrdl->listener,
vfio_ram_discard_notify_populate,
Expand Down
12 changes: 10 additions & 2 deletions hw/vfio/pci.c
Expand Up @@ -1499,6 +1499,14 @@ static void vfio_msix_early_setup(VFIOPCIDevice *vdev, Error **errp)
if (vdev->vendor_id == PCI_VENDOR_ID_CHELSIO &&
(vdev->device_id & 0xff00) == 0x5800) {
msix->pba_offset = 0x1000;
/*
* BAIDU KUNLUN Virtual Function devices for KUNLUN AI processor
* return an incorrect value of 0x460000 for the VF PBA offset while
* the BAR itself is only 0x10000. The correct value is 0xb400.
*/
} else if (vfio_pci_is(vdev, PCI_VENDOR_ID_BAIDU,
PCI_DEVICE_ID_KUNLUN_VF)) {
msix->pba_offset = 0xb400;
} else if (vdev->msix_relo == OFF_AUTOPCIBAR_OFF) {
error_setg(errp, "hardware reports invalid configuration, "
"MSIX PBA outside of specified BAR");
Expand Down Expand Up @@ -3058,14 +3066,14 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
}
}

if (vdev->vendor_id == PCI_VENDOR_ID_NVIDIA) {
if (vfio_pci_is(vdev, PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID)) {
ret = vfio_pci_nvidia_v100_ram_init(vdev, errp);
if (ret && ret != -ENODEV) {
error_report("Failed to setup NVIDIA V100 GPU RAM");
}
}

if (vdev->vendor_id == PCI_VENDOR_ID_IBM) {
if (vfio_pci_is(vdev, PCI_VENDOR_ID_IBM, PCI_ANY_ID)) {
ret = vfio_pci_nvlink2_init(vdev, errp);
if (ret && ret != -ENODEV) {
error_report("Failed to setup NVlink2 bridge");
Expand Down
3 changes: 3 additions & 0 deletions include/hw/pci/pci_ids.h
Expand Up @@ -227,6 +227,9 @@
#define PCI_VENDOR_ID_FREESCALE 0x1957
#define PCI_DEVICE_ID_MPC8533E 0x0030

#define PCI_VENDOR_ID_BAIDU 0x1d22
#define PCI_DEVICE_ID_KUNLUN_VF 0x3685

#define PCI_VENDOR_ID_INTEL 0x8086
#define PCI_DEVICE_ID_INTEL_82378 0x0484
#define PCI_DEVICE_ID_INTEL_82441 0x1237
Expand Down

0 comments on commit 731d506

Please sign in to comment.