* Re: [PATCH] Add vhost-user-spi and vhost-user-spi-pci devices
2024-07-12 3:42 [PATCH] Add vhost-user-spi and vhost-user-spi-pci devices Haixu Cui
@ 2024-08-06 3:33 ` Haixu Cui
2024-08-26 9:04 ` Haixu Cui
2024-08-27 17:14 ` Alex Bennée
2 siblings, 0 replies; 7+ messages in thread
From: Haixu Cui @ 2024-08-06 3:33 UTC (permalink / raw)
To: qemu-devel, viresh.kumar, alex.bennee; +Cc: quic_ztu, quic_tsoni
Hi,
Can anyone please review the patch? Thank you so much.
Best Regards
Haixu Cui
On 7/12/2024 11:42 AM, Haixu Cui wrote:
> This work is based on the virtio-spi spec, virtio-spi driver introduced by
> the following patch series:
> - https://github.com/oasis-tcs/virtio-spec/tree/virtio-1.4/device-types/spi
> - https://lwn.net/Articles/966715/
>
> To test with rust-vmm vhost-user-spi daemon, start the vhost-daemon firstly:
> vhost-device-spi --socket-path=vspi.sock --socket-count=1 --device "/dev/spidev0.0"
>
> Then invoke qemu with the following parameters:
> qemu-system-aarch64 -m 1G \
> -chardev socket,path=/home/root/vspi.sock0,id=vspi \
> -device vhost-user-spi-pci,chardev=vspi,id=spi \
> -object memory-backend-file,id=mem,size=1G,mem-path=/dev/shm,share=on \
> -numa node,memdev=mem
> ...
>
> Signed-off-by: Haixu Cui <quic_haixcui@quicinc.com>
> ---
> hw/virtio/Kconfig | 5 +
> hw/virtio/meson.build | 3 +
> hw/virtio/vhost-user-spi-pci.c | 69 ++++++++
> hw/virtio/vhost-user-spi.c | 66 +++++++
> hw/virtio/virtio.c | 4 +-
> include/hw/virtio/vhost-user-spi.h | 25 +++
> include/standard-headers/linux/virtio_ids.h | 1 +
> include/standard-headers/linux/virtio_spi.h | 186 ++++++++++++++++++++
> 8 files changed, 358 insertions(+), 1 deletion(-)
> create mode 100644 hw/virtio/vhost-user-spi-pci.c
> create mode 100644 hw/virtio/vhost-user-spi.c
> create mode 100644 include/hw/virtio/vhost-user-spi.h
> create mode 100644 include/standard-headers/linux/virtio_spi.h
>
> diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
> index aa63ff7fd4..d5857651e5 100644
> --- a/hw/virtio/Kconfig
> +++ b/hw/virtio/Kconfig
> @@ -110,3 +110,8 @@ config VHOST_USER_SCMI
> bool
> default y
> depends on VIRTIO && VHOST_USER
> +
> +config VHOST_USER_SPI
> + bool
> + default y
> + depends on VIRTIO && VHOST_USER
> diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
> index 621fc65454..42296219e5 100644
> --- a/hw/virtio/meson.build
> +++ b/hw/virtio/meson.build
> @@ -26,6 +26,7 @@ if have_vhost
> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: files('vhost-user-rng.c'))
> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_SND', if_true: files('vhost-user-snd.c'))
> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_INPUT', if_true: files('vhost-user-input.c'))
> + system_virtio_ss.add(when: 'CONFIG_VHOST_USER_SPI', if_true: files('vhost-user-spi.c'))
>
> # PCI Stubs
> system_virtio_ss.add(when: 'CONFIG_VIRTIO_PCI', if_true: files('vhost-user-device-pci.c'))
> @@ -39,6 +40,8 @@ if have_vhost
> if_true: files('vhost-user-snd-pci.c'))
> system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_INPUT'],
> if_true: files('vhost-user-input-pci.c'))
> + system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_SPI'],
> + if_true: files('vhost-user-spi-pci.c'))
> endif
> if have_vhost_vdpa
> system_virtio_ss.add(files('vhost-vdpa.c'))
> diff --git a/hw/virtio/vhost-user-spi-pci.c b/hw/virtio/vhost-user-spi-pci.c
> new file mode 100644
> index 0000000000..3565d526af
> --- /dev/null
> +++ b/hw/virtio/vhost-user-spi-pci.c
> @@ -0,0 +1,69 @@
> +/*
> + * Vhost-user spi virtio device PCI glue
> + *
> + * Copyright(c) 2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/virtio/vhost-user-spi.h"
> +#include "hw/virtio/virtio-pci.h"
> +
> +struct VHostUserSPIPCI {
> + VirtIOPCIProxy parent_obj;
> + VHostUserSPI vdev;
> +};
> +
> +typedef struct VHostUserSPIPCI VHostUserSPIPCI;
> +
> +#define TYPE_VHOST_USER_SPI_PCI "vhost-user-spi-pci-base"
> +
> +DECLARE_INSTANCE_CHECKER(VHostUserSPIPCI, VHOST_USER_SPI_PCI,
> + TYPE_VHOST_USER_SPI_PCI)
> +
> +static void vhost_user_spi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
> +{
> + VHostUserSPIPCI *dev = VHOST_USER_SPI_PCI(vpci_dev);
> + DeviceState *vdev = DEVICE(&dev->vdev);
> +
> + vpci_dev->nvectors = 1;
> + qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
> +}
> +
> +static void vhost_user_spi_pci_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
> + PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
> + k->realize = vhost_user_spi_pci_realize;
> + set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
> + pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
> + pcidev_k->device_id = 0; /* Set by virtio-pci based on virtio id */
> + pcidev_k->revision = 0x00;
> + pcidev_k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
> +}
> +
> +static void vhost_user_spi_pci_instance_init(Object *obj)
> +{
> + VHostUserSPIPCI *dev = VHOST_USER_SPI_PCI(obj);
> +
> + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
> + TYPE_VHOST_USER_SPI);
> +}
> +
> +static const VirtioPCIDeviceTypeInfo vhost_user_spi_pci_info = {
> + .base_name = TYPE_VHOST_USER_SPI_PCI,
> + .non_transitional_name = "vhost-user-spi-pci",
> + .instance_size = sizeof(VHostUserSPIPCI),
> + .instance_init = vhost_user_spi_pci_instance_init,
> + .class_init = vhost_user_spi_pci_class_init,
> +};
> +
> +static void vhost_user_spi_pci_register(void)
> +{
> + virtio_pci_types_register(&vhost_user_spi_pci_info);
> +}
> +
> +type_init(vhost_user_spi_pci_register);
> diff --git a/hw/virtio/vhost-user-spi.c b/hw/virtio/vhost-user-spi.c
> new file mode 100644
> index 0000000000..e138b8b53b
> --- /dev/null
> +++ b/hw/virtio/vhost-user-spi.c
> @@ -0,0 +1,66 @@
> +/*
> + * Vhost-user spi virtio device
> + *
> + * Copyright(c) 2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/virtio/virtio-bus.h"
> +#include "hw/virtio/vhost-user-spi.h"
> +#include "qemu/error-report.h"
> +#include "standard-headers/linux/virtio_ids.h"
> +#include "standard-headers/linux/virtio_spi.h"
> +
> +static Property vspi_properties[] = {
> + DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
> + DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void vspi_realize(DeviceState *dev, Error **errp)
> +{
> + VHostUserBase *vub = VHOST_USER_BASE(dev);
> + VHostUserBaseClass *vubc = VHOST_USER_BASE_GET_CLASS(dev);
> +
> + /* Fixed for SPI */
> + vub->virtio_id = VIRTIO_ID_SPI;
> + vub->num_vqs = 1;
> + vub->vq_size = 4;
> + vub->config_size = sizeof(struct virtio_spi_config);
> +
> + vubc->parent_realize(dev, errp);
> +}
> +
> +static const VMStateDescription vu_spi_vmstate = {
> + .name = "vhost-user-spi",
> + .unmigratable = 1,
> +};
> +
> +static void vu_spi_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass);
> +
> + dc->vmsd = &vu_spi_vmstate;
> + device_class_set_props(dc, vspi_properties);
> + device_class_set_parent_realize(dc, vspi_realize,
> + &vubc->parent_realize);
> + set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
> +}
> +
> +static const TypeInfo vu_spi_info = {
> + .name = TYPE_VHOST_USER_SPI,
> + .parent = TYPE_VHOST_USER_BASE,
> + .instance_size = sizeof(VHostUserSPI),
> + .class_init = vu_spi_class_init,
> +};
> +
> +static void vu_spi_register_types(void)
> +{
> + type_register_static(&vu_spi_info);
> +}
> +
> +type_init(vu_spi_register_types)
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 583a224163..689e2e21e7 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -46,6 +46,7 @@
> #include "standard-headers/linux/virtio_iommu.h"
> #include "standard-headers/linux/virtio_mem.h"
> #include "standard-headers/linux/virtio_vsock.h"
> +#include "standard-headers/linux/virtio_spi.h"
>
> /*
> * Maximum size of virtio device config space
> @@ -194,7 +195,8 @@ const char *virtio_device_names[] = {
> [VIRTIO_ID_PARAM_SERV] = "virtio-param-serv",
> [VIRTIO_ID_AUDIO_POLICY] = "virtio-audio-pol",
> [VIRTIO_ID_BT] = "virtio-bluetooth",
> - [VIRTIO_ID_GPIO] = "virtio-gpio"
> + [VIRTIO_ID_GPIO] = "virtio-gpio",
> + [VIRTIO_ID_SPI] = "virtio-spi"
> };
>
> static const char *virtio_id_to_name(uint16_t device_id)
> diff --git a/include/hw/virtio/vhost-user-spi.h b/include/hw/virtio/vhost-user-spi.h
> new file mode 100644
> index 0000000000..d6967d8431
> --- /dev/null
> +++ b/include/hw/virtio/vhost-user-spi.h
> @@ -0,0 +1,25 @@
> +/*
> + * Vhost-user spi virtio device
> + *
> + * Copyright(c) 2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef QEMU_VHOST_USER_SPI_H
> +#define QEMU_VHOST_USER_SPI_H
> +
> +#include "hw/virtio/virtio.h"
> +#include "hw/virtio/vhost.h"
> +#include "hw/virtio/vhost-user.h"
> +#include "hw/virtio/vhost-user-base.h"
> +
> +#define TYPE_VHOST_USER_SPI "vhost-user-spi-device"
> +
> +OBJECT_DECLARE_SIMPLE_TYPE(VHostUserSPI, VHOST_USER_SPI)
> +
> +struct VHostUserSPI {
> + VHostUserBase parent_obj;
> +};
> +
> +#endif /* QEMU_VHOST_USER_SPI_H */
> diff --git a/include/standard-headers/linux/virtio_ids.h b/include/standard-headers/linux/virtio_ids.h
> index 7aa2eb7662..601d387c5a 100644
> --- a/include/standard-headers/linux/virtio_ids.h
> +++ b/include/standard-headers/linux/virtio_ids.h
> @@ -68,6 +68,7 @@
> #define VIRTIO_ID_AUDIO_POLICY 39 /* virtio audio policy */
> #define VIRTIO_ID_BT 40 /* virtio bluetooth */
> #define VIRTIO_ID_GPIO 41 /* virtio gpio */
> +#define VIRTIO_ID_SPI 45 /* virtio spi */
>
> /*
> * Virtio Transitional IDs
> diff --git a/include/standard-headers/linux/virtio_spi.h b/include/standard-headers/linux/virtio_spi.h
> new file mode 100644
> index 0000000000..6631827bfa
> --- /dev/null
> +++ b/include/standard-headers/linux/virtio_spi.h
> @@ -0,0 +1,186 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later WITH Linux-syscall-note */
> +/*
> + * Definitions for virtio SPI Controller
> + *
> + * Copyright (c) 2021 Intel Corporation. All rights reserved.
> + */
> +
> +#ifndef _LINUX_VIRTIO_SPI_H
> +#define _LINUX_VIRTIO_SPI_H
> +
> +#include "standard-headers/linux/const.h"
> +#include "standard-headers/linux/types.h"
> +
> +/* Sample data on trailing clock edge */
> +#define VIRTIO_SPI_CPHA (1 << 0)
> +/* Clock is high when IDLE */
> +#define VIRTIO_SPI_CPOL (1 << 1)
> +/* Chip Select is active high */
> +#define VIRTIO_SPI_CS_HIGH (1 << 2)
> +/* Transmit LSB first */
> +#define VIRTIO_SPI_MODE_LSB_FIRST (1 << 3)
> +/* Loopback mode */
> +#define VIRTIO_SPI_MODE_LOOP (1 << 4)
> +
> +/*
> + * All config fields are read-only for the Virtio SPI driver
> + *
> + * @cs_max_number: maximum number of chipselect the host SPI controller
> + * supports.
> + * @cs_change_supported: indicates if the host SPI controller supports to toggle
> + * chipselect after each transfer in one message:
> + * 0: unsupported, chipselect will be kept in active state throughout the
> + * message transaction;
> + * 1: supported.
> + * Note: Message here contains a sequence of SPI transfers.
> + * @tx_nbits_supported: indicates the supported number of bit for writing:
> + * bit 0: DUAL (2-bit transfer), 1 for supported
> + * bit 1: QUAD (4-bit transfer), 1 for supported
> + * bit 2: OCTAL (8-bit transfer), 1 for supported
> + * other bits are reserved as 0, 1-bit transfer is always supported.
> + * @rx_nbits_supported: indicates the supported number of bit for reading:
> + * bit 0: DUAL (2-bit transfer), 1 for supported
> + * bit 1: QUAD (4-bit transfer), 1 for supported
> + * bit 2: OCTAL (8-bit transfer), 1 for supported
> + * other bits are reserved as 0, 1-bit transfer is always supported.
> + * @bits_per_word_mask: mask indicating which values of bits_per_word are
> + * supported. If not set, no limitation for bits_per_word.
> + * @mode_func_supported: indicates the following features are supported or not:
> + * bit 0-1: CPHA feature
> + * 0b00: invalid, should support as least one CPHA setting
> + * 0b01: supports CPHA=0 only
> + * 0b10: supports CPHA=1 only
> + * 0b11: supports CPHA=0 and CPHA=1.
> + * bit 2-3: CPOL feature
> + * 0b00: invalid, should support as least one CPOL setting
> + * 0b01: supports CPOL=0 only
> + * 0b10: supports CPOL=1 only
> + * 0b11: supports CPOL=0 and CPOL=1.
> + * bit 4: chipselect active high feature, 0 for unsupported and 1 for
> + * supported, chipselect active low should always be supported.
> + * bit 5: LSB first feature, 0 for unsupported and 1 for supported,
> + * MSB first should always be supported.
> + * bit 6: loopback mode feature, 0 for unsupported and 1 for supported,
> + * normal mode should always be supported.
> + * @max_freq_hz: the maximum clock rate supported in Hz unit, 0 means no
> + * limitation for transfer speed.
> + * @max_word_delay_ns: the maximum word delay supported in ns unit,
> + * 0 means word delay feature is unsupported.
> + * Note: Just as one message contains a sequence of transfers,
> + * one transfer may contain a sequence of words.
> + * @max_cs_setup_ns: the maximum delay supported after chipselect is asserted,
> + * in ns unit, 0 means delay is not supported to introduce after chipselect is
> + * asserted.
> + * @max_cs_hold_ns: the maximum delay supported before chipselect is deasserted,
> + * in ns unit, 0 means delay is not supported to introduce before chipselect
> + * is deasserted.
> + * @max_cs_incative_ns: maximum delay supported after chipselect is deasserted,
> + * in ns unit, 0 means delay is not supported to introduce after chipselect is
> + * deasserted.
> + */
> +struct virtio_spi_config {
> + /* # of /dev/spidev<bus_num>.CS with CS=0..chip_select_max_number -1 */
> + uint8_t cs_max_number;
> + uint8_t cs_change_supported;
> +#define VIRTIO_SPI_RX_TX_SUPPORT_DUAL (1 << 0)
> +#define VIRTIO_SPI_RX_TX_SUPPORT_QUAD (1 << 1)
> +#define VIRTIO_SPI_RX_TX_SUPPORT_OCTAL (1 << 2)
> + uint8_t tx_nbits_supported;
> + uint8_t rx_nbits_supported;
> + uint32_t bits_per_word_mask;
> +#define VIRTIO_SPI_MF_SUPPORT_CPHA_0 (1 << 0)
> +#define VIRTIO_SPI_MF_SUPPORT_CPHA_1 (1 << 1)
> +#define VIRTIO_SPI_MF_SUPPORT_CPOL_0 (1 << 2)
> +#define VIRTIO_SPI_MF_SUPPORT_CPOL_1 (1 << 3)
> +#define VIRTIO_SPI_MF_SUPPORT_CS_HIGH (1 << 4)
> +#define VIRTIO_SPI_MF_SUPPORT_LSB_FIRST (1 << 5)
> +#define VIRTIO_SPI_MF_SUPPORT_LOOPBACK (1 << 6)
> + uint32_t mode_func_supported;
> + uint32_t max_freq_hz;
> + uint32_t max_word_delay_ns;
> + uint32_t max_cs_setup_ns;
> + uint32_t max_cs_hold_ns;
> + uint32_t max_cs_inactive_ns;
> +};
> +
> +/*
> + * @chip_select_id: chipselect index the SPI transfer used.
> + *
> + * @bits_per_word: the number of bits in each SPI transfer word.
> + *
> + * @cs_change: whether to deselect device after finishing this transfer
> + * before starting the next transfer, 0 means cs keep asserted and
> + * 1 means cs deasserted then asserted again.
> + *
> + * @tx_nbits: bus width for write transfer.
> + * 0,1: bus width is 1, also known as SINGLE
> + * 2 : bus width is 2, also known as DUAL
> + * 4 : bus width is 4, also known as QUAD
> + * 8 : bus width is 8, also known as OCTAL
> + * other values are invalid.
> + *
> + * @rx_nbits: bus width for read transfer.
> + * 0,1: bus width is 1, also known as SINGLE
> + * 2 : bus width is 2, also known as DUAL
> + * 4 : bus width is 4, also known as QUAD
> + * 8 : bus width is 8, also known as OCTAL
> + * other values are invalid.
> + *
> + * @reserved: for future use.
> + *
> + * @mode: SPI transfer mode.
> + * bit 0: CPHA, determines the timing (i.e. phase) of the data
> + * bits relative to the clock pulses.For CPHA=0, the
> + * "out" side changes the data on the trailing edge of the
> + * preceding clock cycle, while the "in" side captures the data
> + * on (or shortly after) the leading edge of the clock cycle.
> + * For CPHA=1, the "out" side changes the data on the leading
> + * edge of the current clock cycle, while the "in" side
> + * captures the data on (or shortly after) the trailing edge of
> + * the clock cycle.
> + * bit 1: CPOL, determines the polarity of the clock. CPOL=0 is a
> + * clock which idles at 0, and each cycle consists of a pulse
> + * of 1. CPOL=1 is a clock which idles at 1, and each cycle
> + * consists of a pulse of 0.
> + * bit 2: CS_HIGH, if 1, chip select active high, else active low.
> + * bit 3: LSB_FIRST, determines per-word bits-on-wire, if 0, MSB
> + * first, else LSB first.
> + * bit 4: LOOP, loopback mode.
> + *
> + * @freq: the transfer speed in Hz.
> + *
> + * @word_delay_ns: delay to be inserted between consecutive words of a
> + * transfer, in ns unit.
> + *
> + * @cs_setup_ns: delay to be introduced after CS is asserted, in ns
> + * unit.
> + *
> + * @cs_delay_hold_ns: delay to be introduced before CS is deasserted
> + * for each transfer, in ns unit.
> + *
> + * @cs_change_delay_inactive_ns: delay to be introduced after CS is
> + * deasserted and before next asserted, in ns unit.
> + */
> +struct spi_transfer_head {
> + uint8_t chip_select_id;
> + uint8_t bits_per_word;
> + uint8_t cs_change;
> + uint8_t tx_nbits;
> + uint8_t rx_nbits;
> + uint8_t reserved[3];
> + uint32_t mode;
> + uint32_t freq;
> + uint32_t word_delay_ns;
> + uint32_t cs_setup_ns;
> + uint32_t cs_delay_hold_ns;
> + uint32_t cs_change_delay_inactive_ns;
> +};
> +
> +struct spi_transfer_result {
> +#define VIRTIO_SPI_TRANS_OK 0
> +#define VIRTIO_SPI_PARAM_ERR 1
> +#define VIRTIO_SPI_TRANS_ERR 2
> + uint8_t status;
> +};
> +
> +#endif /* _LINUX_VIRTIO_SPI_H */
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Add vhost-user-spi and vhost-user-spi-pci devices
2024-07-12 3:42 [PATCH] Add vhost-user-spi and vhost-user-spi-pci devices Haixu Cui
2024-08-06 3:33 ` Haixu Cui
@ 2024-08-26 9:04 ` Haixu Cui
2024-08-27 17:14 ` Alex Bennée
2 siblings, 0 replies; 7+ messages in thread
From: Haixu Cui @ 2024-08-26 9:04 UTC (permalink / raw)
To: qemu-devel, viresh.kumar, alex.bennee, Michael S. Tsirkin,
mathieu.poirier, mzamazal
Cc: quic_ztu, quic_tsoni
Hi team,
I've added the vhost-user-spi patch here to support virtio-spi in
qemu. You are the experts on both virtio and vhost-user, can you please
help review the patch. Thanks a lot.
Best Regards
On 7/12/2024 11:42 AM, Haixu Cui wrote:
> This work is based on the virtio-spi spec, virtio-spi driver introduced by
> the following patch series:
> - https://github.com/oasis-tcs/virtio-spec/tree/virtio-1.4/device-types/spi
> - https://lwn.net/Articles/966715/
>
> To test with rust-vmm vhost-user-spi daemon, start the vhost-daemon firstly:
> vhost-device-spi --socket-path=vspi.sock --socket-count=1 --device "/dev/spidev0.0"
>
> Then invoke qemu with the following parameters:
> qemu-system-aarch64 -m 1G \
> -chardev socket,path=/home/root/vspi.sock0,id=vspi \
> -device vhost-user-spi-pci,chardev=vspi,id=spi \
> -object memory-backend-file,id=mem,size=1G,mem-path=/dev/shm,share=on \
> -numa node,memdev=mem
> ...
>
> Signed-off-by: Haixu Cui <quic_haixcui@quicinc.com>
> ---
> hw/virtio/Kconfig | 5 +
> hw/virtio/meson.build | 3 +
> hw/virtio/vhost-user-spi-pci.c | 69 ++++++++
> hw/virtio/vhost-user-spi.c | 66 +++++++
> hw/virtio/virtio.c | 4 +-
> include/hw/virtio/vhost-user-spi.h | 25 +++
> include/standard-headers/linux/virtio_ids.h | 1 +
> include/standard-headers/linux/virtio_spi.h | 186 ++++++++++++++++++++
> 8 files changed, 358 insertions(+), 1 deletion(-)
> create mode 100644 hw/virtio/vhost-user-spi-pci.c
> create mode 100644 hw/virtio/vhost-user-spi.c
> create mode 100644 include/hw/virtio/vhost-user-spi.h
> create mode 100644 include/standard-headers/linux/virtio_spi.h
>
> diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
> index aa63ff7fd4..d5857651e5 100644
> --- a/hw/virtio/Kconfig
> +++ b/hw/virtio/Kconfig
> @@ -110,3 +110,8 @@ config VHOST_USER_SCMI
> bool
> default y
> depends on VIRTIO && VHOST_USER
> +
> +config VHOST_USER_SPI
> + bool
> + default y
> + depends on VIRTIO && VHOST_USER
> diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
> index 621fc65454..42296219e5 100644
> --- a/hw/virtio/meson.build
> +++ b/hw/virtio/meson.build
> @@ -26,6 +26,7 @@ if have_vhost
> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: files('vhost-user-rng.c'))
> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_SND', if_true: files('vhost-user-snd.c'))
> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_INPUT', if_true: files('vhost-user-input.c'))
> + system_virtio_ss.add(when: 'CONFIG_VHOST_USER_SPI', if_true: files('vhost-user-spi.c'))
>
> # PCI Stubs
> system_virtio_ss.add(when: 'CONFIG_VIRTIO_PCI', if_true: files('vhost-user-device-pci.c'))
> @@ -39,6 +40,8 @@ if have_vhost
> if_true: files('vhost-user-snd-pci.c'))
> system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_INPUT'],
> if_true: files('vhost-user-input-pci.c'))
> + system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_SPI'],
> + if_true: files('vhost-user-spi-pci.c'))
> endif
> if have_vhost_vdpa
> system_virtio_ss.add(files('vhost-vdpa.c'))
> diff --git a/hw/virtio/vhost-user-spi-pci.c b/hw/virtio/vhost-user-spi-pci.c
> new file mode 100644
> index 0000000000..3565d526af
> --- /dev/null
> +++ b/hw/virtio/vhost-user-spi-pci.c
> @@ -0,0 +1,69 @@
> +/*
> + * Vhost-user spi virtio device PCI glue
> + *
> + * Copyright(c) 2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/virtio/vhost-user-spi.h"
> +#include "hw/virtio/virtio-pci.h"
> +
> +struct VHostUserSPIPCI {
> + VirtIOPCIProxy parent_obj;
> + VHostUserSPI vdev;
> +};
> +
> +typedef struct VHostUserSPIPCI VHostUserSPIPCI;
> +
> +#define TYPE_VHOST_USER_SPI_PCI "vhost-user-spi-pci-base"
> +
> +DECLARE_INSTANCE_CHECKER(VHostUserSPIPCI, VHOST_USER_SPI_PCI,
> + TYPE_VHOST_USER_SPI_PCI)
> +
> +static void vhost_user_spi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
> +{
> + VHostUserSPIPCI *dev = VHOST_USER_SPI_PCI(vpci_dev);
> + DeviceState *vdev = DEVICE(&dev->vdev);
> +
> + vpci_dev->nvectors = 1;
> + qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
> +}
> +
> +static void vhost_user_spi_pci_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
> + PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
> + k->realize = vhost_user_spi_pci_realize;
> + set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
> + pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
> + pcidev_k->device_id = 0; /* Set by virtio-pci based on virtio id */
> + pcidev_k->revision = 0x00;
> + pcidev_k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
> +}
> +
> +static void vhost_user_spi_pci_instance_init(Object *obj)
> +{
> + VHostUserSPIPCI *dev = VHOST_USER_SPI_PCI(obj);
> +
> + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
> + TYPE_VHOST_USER_SPI);
> +}
> +
> +static const VirtioPCIDeviceTypeInfo vhost_user_spi_pci_info = {
> + .base_name = TYPE_VHOST_USER_SPI_PCI,
> + .non_transitional_name = "vhost-user-spi-pci",
> + .instance_size = sizeof(VHostUserSPIPCI),
> + .instance_init = vhost_user_spi_pci_instance_init,
> + .class_init = vhost_user_spi_pci_class_init,
> +};
> +
> +static void vhost_user_spi_pci_register(void)
> +{
> + virtio_pci_types_register(&vhost_user_spi_pci_info);
> +}
> +
> +type_init(vhost_user_spi_pci_register);
> diff --git a/hw/virtio/vhost-user-spi.c b/hw/virtio/vhost-user-spi.c
> new file mode 100644
> index 0000000000..e138b8b53b
> --- /dev/null
> +++ b/hw/virtio/vhost-user-spi.c
> @@ -0,0 +1,66 @@
> +/*
> + * Vhost-user spi virtio device
> + *
> + * Copyright(c) 2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/virtio/virtio-bus.h"
> +#include "hw/virtio/vhost-user-spi.h"
> +#include "qemu/error-report.h"
> +#include "standard-headers/linux/virtio_ids.h"
> +#include "standard-headers/linux/virtio_spi.h"
> +
> +static Property vspi_properties[] = {
> + DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
> + DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void vspi_realize(DeviceState *dev, Error **errp)
> +{
> + VHostUserBase *vub = VHOST_USER_BASE(dev);
> + VHostUserBaseClass *vubc = VHOST_USER_BASE_GET_CLASS(dev);
> +
> + /* Fixed for SPI */
> + vub->virtio_id = VIRTIO_ID_SPI;
> + vub->num_vqs = 1;
> + vub->vq_size = 4;
> + vub->config_size = sizeof(struct virtio_spi_config);
> +
> + vubc->parent_realize(dev, errp);
> +}
> +
> +static const VMStateDescription vu_spi_vmstate = {
> + .name = "vhost-user-spi",
> + .unmigratable = 1,
> +};
> +
> +static void vu_spi_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass);
> +
> + dc->vmsd = &vu_spi_vmstate;
> + device_class_set_props(dc, vspi_properties);
> + device_class_set_parent_realize(dc, vspi_realize,
> + &vubc->parent_realize);
> + set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
> +}
> +
> +static const TypeInfo vu_spi_info = {
> + .name = TYPE_VHOST_USER_SPI,
> + .parent = TYPE_VHOST_USER_BASE,
> + .instance_size = sizeof(VHostUserSPI),
> + .class_init = vu_spi_class_init,
> +};
> +
> +static void vu_spi_register_types(void)
> +{
> + type_register_static(&vu_spi_info);
> +}
> +
> +type_init(vu_spi_register_types)
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 583a224163..689e2e21e7 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -46,6 +46,7 @@
> #include "standard-headers/linux/virtio_iommu.h"
> #include "standard-headers/linux/virtio_mem.h"
> #include "standard-headers/linux/virtio_vsock.h"
> +#include "standard-headers/linux/virtio_spi.h"
>
> /*
> * Maximum size of virtio device config space
> @@ -194,7 +195,8 @@ const char *virtio_device_names[] = {
> [VIRTIO_ID_PARAM_SERV] = "virtio-param-serv",
> [VIRTIO_ID_AUDIO_POLICY] = "virtio-audio-pol",
> [VIRTIO_ID_BT] = "virtio-bluetooth",
> - [VIRTIO_ID_GPIO] = "virtio-gpio"
> + [VIRTIO_ID_GPIO] = "virtio-gpio",
> + [VIRTIO_ID_SPI] = "virtio-spi"
> };
>
> static const char *virtio_id_to_name(uint16_t device_id)
> diff --git a/include/hw/virtio/vhost-user-spi.h b/include/hw/virtio/vhost-user-spi.h
> new file mode 100644
> index 0000000000..d6967d8431
> --- /dev/null
> +++ b/include/hw/virtio/vhost-user-spi.h
> @@ -0,0 +1,25 @@
> +/*
> + * Vhost-user spi virtio device
> + *
> + * Copyright(c) 2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef QEMU_VHOST_USER_SPI_H
> +#define QEMU_VHOST_USER_SPI_H
> +
> +#include "hw/virtio/virtio.h"
> +#include "hw/virtio/vhost.h"
> +#include "hw/virtio/vhost-user.h"
> +#include "hw/virtio/vhost-user-base.h"
> +
> +#define TYPE_VHOST_USER_SPI "vhost-user-spi-device"
> +
> +OBJECT_DECLARE_SIMPLE_TYPE(VHostUserSPI, VHOST_USER_SPI)
> +
> +struct VHostUserSPI {
> + VHostUserBase parent_obj;
> +};
> +
> +#endif /* QEMU_VHOST_USER_SPI_H */
> diff --git a/include/standard-headers/linux/virtio_ids.h b/include/standard-headers/linux/virtio_ids.h
> index 7aa2eb7662..601d387c5a 100644
> --- a/include/standard-headers/linux/virtio_ids.h
> +++ b/include/standard-headers/linux/virtio_ids.h
> @@ -68,6 +68,7 @@
> #define VIRTIO_ID_AUDIO_POLICY 39 /* virtio audio policy */
> #define VIRTIO_ID_BT 40 /* virtio bluetooth */
> #define VIRTIO_ID_GPIO 41 /* virtio gpio */
> +#define VIRTIO_ID_SPI 45 /* virtio spi */
>
> /*
> * Virtio Transitional IDs
> diff --git a/include/standard-headers/linux/virtio_spi.h b/include/standard-headers/linux/virtio_spi.h
> new file mode 100644
> index 0000000000..6631827bfa
> --- /dev/null
> +++ b/include/standard-headers/linux/virtio_spi.h
> @@ -0,0 +1,186 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later WITH Linux-syscall-note */
> +/*
> + * Definitions for virtio SPI Controller
> + *
> + * Copyright (c) 2021 Intel Corporation. All rights reserved.
> + */
> +
> +#ifndef _LINUX_VIRTIO_SPI_H
> +#define _LINUX_VIRTIO_SPI_H
> +
> +#include "standard-headers/linux/const.h"
> +#include "standard-headers/linux/types.h"
> +
> +/* Sample data on trailing clock edge */
> +#define VIRTIO_SPI_CPHA (1 << 0)
> +/* Clock is high when IDLE */
> +#define VIRTIO_SPI_CPOL (1 << 1)
> +/* Chip Select is active high */
> +#define VIRTIO_SPI_CS_HIGH (1 << 2)
> +/* Transmit LSB first */
> +#define VIRTIO_SPI_MODE_LSB_FIRST (1 << 3)
> +/* Loopback mode */
> +#define VIRTIO_SPI_MODE_LOOP (1 << 4)
> +
> +/*
> + * All config fields are read-only for the Virtio SPI driver
> + *
> + * @cs_max_number: maximum number of chipselect the host SPI controller
> + * supports.
> + * @cs_change_supported: indicates if the host SPI controller supports to toggle
> + * chipselect after each transfer in one message:
> + * 0: unsupported, chipselect will be kept in active state throughout the
> + * message transaction;
> + * 1: supported.
> + * Note: Message here contains a sequence of SPI transfers.
> + * @tx_nbits_supported: indicates the supported number of bit for writing:
> + * bit 0: DUAL (2-bit transfer), 1 for supported
> + * bit 1: QUAD (4-bit transfer), 1 for supported
> + * bit 2: OCTAL (8-bit transfer), 1 for supported
> + * other bits are reserved as 0, 1-bit transfer is always supported.
> + * @rx_nbits_supported: indicates the supported number of bit for reading:
> + * bit 0: DUAL (2-bit transfer), 1 for supported
> + * bit 1: QUAD (4-bit transfer), 1 for supported
> + * bit 2: OCTAL (8-bit transfer), 1 for supported
> + * other bits are reserved as 0, 1-bit transfer is always supported.
> + * @bits_per_word_mask: mask indicating which values of bits_per_word are
> + * supported. If not set, no limitation for bits_per_word.
> + * @mode_func_supported: indicates the following features are supported or not:
> + * bit 0-1: CPHA feature
> + * 0b00: invalid, should support as least one CPHA setting
> + * 0b01: supports CPHA=0 only
> + * 0b10: supports CPHA=1 only
> + * 0b11: supports CPHA=0 and CPHA=1.
> + * bit 2-3: CPOL feature
> + * 0b00: invalid, should support as least one CPOL setting
> + * 0b01: supports CPOL=0 only
> + * 0b10: supports CPOL=1 only
> + * 0b11: supports CPOL=0 and CPOL=1.
> + * bit 4: chipselect active high feature, 0 for unsupported and 1 for
> + * supported, chipselect active low should always be supported.
> + * bit 5: LSB first feature, 0 for unsupported and 1 for supported,
> + * MSB first should always be supported.
> + * bit 6: loopback mode feature, 0 for unsupported and 1 for supported,
> + * normal mode should always be supported.
> + * @max_freq_hz: the maximum clock rate supported in Hz unit, 0 means no
> + * limitation for transfer speed.
> + * @max_word_delay_ns: the maximum word delay supported in ns unit,
> + * 0 means word delay feature is unsupported.
> + * Note: Just as one message contains a sequence of transfers,
> + * one transfer may contain a sequence of words.
> + * @max_cs_setup_ns: the maximum delay supported after chipselect is asserted,
> + * in ns unit, 0 means delay is not supported to introduce after chipselect is
> + * asserted.
> + * @max_cs_hold_ns: the maximum delay supported before chipselect is deasserted,
> + * in ns unit, 0 means delay is not supported to introduce before chipselect
> + * is deasserted.
> + * @max_cs_incative_ns: maximum delay supported after chipselect is deasserted,
> + * in ns unit, 0 means delay is not supported to introduce after chipselect is
> + * deasserted.
> + */
> +struct virtio_spi_config {
> + /* # of /dev/spidev<bus_num>.CS with CS=0..chip_select_max_number -1 */
> + uint8_t cs_max_number;
> + uint8_t cs_change_supported;
> +#define VIRTIO_SPI_RX_TX_SUPPORT_DUAL (1 << 0)
> +#define VIRTIO_SPI_RX_TX_SUPPORT_QUAD (1 << 1)
> +#define VIRTIO_SPI_RX_TX_SUPPORT_OCTAL (1 << 2)
> + uint8_t tx_nbits_supported;
> + uint8_t rx_nbits_supported;
> + uint32_t bits_per_word_mask;
> +#define VIRTIO_SPI_MF_SUPPORT_CPHA_0 (1 << 0)
> +#define VIRTIO_SPI_MF_SUPPORT_CPHA_1 (1 << 1)
> +#define VIRTIO_SPI_MF_SUPPORT_CPOL_0 (1 << 2)
> +#define VIRTIO_SPI_MF_SUPPORT_CPOL_1 (1 << 3)
> +#define VIRTIO_SPI_MF_SUPPORT_CS_HIGH (1 << 4)
> +#define VIRTIO_SPI_MF_SUPPORT_LSB_FIRST (1 << 5)
> +#define VIRTIO_SPI_MF_SUPPORT_LOOPBACK (1 << 6)
> + uint32_t mode_func_supported;
> + uint32_t max_freq_hz;
> + uint32_t max_word_delay_ns;
> + uint32_t max_cs_setup_ns;
> + uint32_t max_cs_hold_ns;
> + uint32_t max_cs_inactive_ns;
> +};
> +
> +/*
> + * @chip_select_id: chipselect index the SPI transfer used.
> + *
> + * @bits_per_word: the number of bits in each SPI transfer word.
> + *
> + * @cs_change: whether to deselect device after finishing this transfer
> + * before starting the next transfer, 0 means cs keep asserted and
> + * 1 means cs deasserted then asserted again.
> + *
> + * @tx_nbits: bus width for write transfer.
> + * 0,1: bus width is 1, also known as SINGLE
> + * 2 : bus width is 2, also known as DUAL
> + * 4 : bus width is 4, also known as QUAD
> + * 8 : bus width is 8, also known as OCTAL
> + * other values are invalid.
> + *
> + * @rx_nbits: bus width for read transfer.
> + * 0,1: bus width is 1, also known as SINGLE
> + * 2 : bus width is 2, also known as DUAL
> + * 4 : bus width is 4, also known as QUAD
> + * 8 : bus width is 8, also known as OCTAL
> + * other values are invalid.
> + *
> + * @reserved: for future use.
> + *
> + * @mode: SPI transfer mode.
> + * bit 0: CPHA, determines the timing (i.e. phase) of the data
> + * bits relative to the clock pulses.For CPHA=0, the
> + * "out" side changes the data on the trailing edge of the
> + * preceding clock cycle, while the "in" side captures the data
> + * on (or shortly after) the leading edge of the clock cycle.
> + * For CPHA=1, the "out" side changes the data on the leading
> + * edge of the current clock cycle, while the "in" side
> + * captures the data on (or shortly after) the trailing edge of
> + * the clock cycle.
> + * bit 1: CPOL, determines the polarity of the clock. CPOL=0 is a
> + * clock which idles at 0, and each cycle consists of a pulse
> + * of 1. CPOL=1 is a clock which idles at 1, and each cycle
> + * consists of a pulse of 0.
> + * bit 2: CS_HIGH, if 1, chip select active high, else active low.
> + * bit 3: LSB_FIRST, determines per-word bits-on-wire, if 0, MSB
> + * first, else LSB first.
> + * bit 4: LOOP, loopback mode.
> + *
> + * @freq: the transfer speed in Hz.
> + *
> + * @word_delay_ns: delay to be inserted between consecutive words of a
> + * transfer, in ns unit.
> + *
> + * @cs_setup_ns: delay to be introduced after CS is asserted, in ns
> + * unit.
> + *
> + * @cs_delay_hold_ns: delay to be introduced before CS is deasserted
> + * for each transfer, in ns unit.
> + *
> + * @cs_change_delay_inactive_ns: delay to be introduced after CS is
> + * deasserted and before next asserted, in ns unit.
> + */
> +struct spi_transfer_head {
> + uint8_t chip_select_id;
> + uint8_t bits_per_word;
> + uint8_t cs_change;
> + uint8_t tx_nbits;
> + uint8_t rx_nbits;
> + uint8_t reserved[3];
> + uint32_t mode;
> + uint32_t freq;
> + uint32_t word_delay_ns;
> + uint32_t cs_setup_ns;
> + uint32_t cs_delay_hold_ns;
> + uint32_t cs_change_delay_inactive_ns;
> +};
> +
> +struct spi_transfer_result {
> +#define VIRTIO_SPI_TRANS_OK 0
> +#define VIRTIO_SPI_PARAM_ERR 1
> +#define VIRTIO_SPI_TRANS_ERR 2
> + uint8_t status;
> +};
> +
> +#endif /* _LINUX_VIRTIO_SPI_H */
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Add vhost-user-spi and vhost-user-spi-pci devices
2024-07-12 3:42 [PATCH] Add vhost-user-spi and vhost-user-spi-pci devices Haixu Cui
2024-08-06 3:33 ` Haixu Cui
2024-08-26 9:04 ` Haixu Cui
@ 2024-08-27 17:14 ` Alex Bennée
2024-09-02 8:57 ` Haixu Cui
2 siblings, 1 reply; 7+ messages in thread
From: Alex Bennée @ 2024-08-27 17:14 UTC (permalink / raw)
To: Haixu Cui; +Cc: qemu-devel, viresh.kumar, quic_ztu, quic_tsoni
Haixu Cui <quic_haixcui@quicinc.com> writes:
Apologies for the delay in getting to this.
> This work is based on the virtio-spi spec, virtio-spi driver introduced by
> the following patch series:
> - https://github.com/oasis-tcs/virtio-spec/tree/virtio-1.4/device-types/spi
> - https://lwn.net/Articles/966715/
>
> To test with rust-vmm vhost-user-spi daemon, start the vhost-daemon firstly:
> vhost-device-spi --socket-path=vspi.sock --socket-count=1 --device "/dev/spidev0.0"
I'm struggling to test this on my main dev box. Are there any dummy SPI
modules for the kernel for testing? Otherwise we could consider
implementing something similar to "mock_gpio" for the rust-vmm
vhost-user-spi backend?
> Then invoke qemu with the following parameters:
> qemu-system-aarch64 -m 1G \
> -chardev socket,path=/home/root/vspi.sock0,id=vspi \
> -device vhost-user-spi-pci,chardev=vspi,id=spi \
> -object memory-backend-file,id=mem,size=1G,mem-path=/dev/shm,share=on \
> -numa node,memdev=mem
> ...
>
> Signed-off-by: Haixu Cui <quic_haixcui@quicinc.com>
> ---
> hw/virtio/Kconfig | 5 +
> hw/virtio/meson.build | 3 +
> hw/virtio/vhost-user-spi-pci.c | 69 ++++++++
> hw/virtio/vhost-user-spi.c | 66 +++++++
> hw/virtio/virtio.c | 4 +-
> include/hw/virtio/vhost-user-spi.h | 25 +++
> include/standard-headers/linux/virtio_ids.h | 1 +
> include/standard-headers/linux/virtio_spi.h | 186 ++++++++++++++++++++
> 8 files changed, 358 insertions(+), 1 deletion(-)
> create mode 100644 hw/virtio/vhost-user-spi-pci.c
> create mode 100644 hw/virtio/vhost-user-spi.c
> create mode 100644 include/hw/virtio/vhost-user-spi.h
> create mode 100644 include/standard-headers/linux/virtio_spi.h
Generally we want separate headers patches for the importing of headers.
Doubly so in this case because I can't see the SPI definitions in the
current Linux master. So:
- 1/2 - Import headers for SPI (!merge until upstream)
- 2/2 - Implement vhost-user stub for virtio-spi
>
> diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
> index aa63ff7fd4..d5857651e5 100644
> --- a/hw/virtio/Kconfig
> +++ b/hw/virtio/Kconfig
> @@ -110,3 +110,8 @@ config VHOST_USER_SCMI
> bool
> default y
> depends on VIRTIO && VHOST_USER
> +
> +config VHOST_USER_SPI
> + bool
> + default y
> + depends on VIRTIO && VHOST_USER
> diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
> index 621fc65454..42296219e5 100644
> --- a/hw/virtio/meson.build
> +++ b/hw/virtio/meson.build
> @@ -26,6 +26,7 @@ if have_vhost
> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: files('vhost-user-rng.c'))
> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_SND', if_true: files('vhost-user-snd.c'))
> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_INPUT', if_true: files('vhost-user-input.c'))
> + system_virtio_ss.add(when: 'CONFIG_VHOST_USER_SPI', if_true: files('vhost-user-spi.c'))
>
> # PCI Stubs
> system_virtio_ss.add(when: 'CONFIG_VIRTIO_PCI', if_true: files('vhost-user-device-pci.c'))
> @@ -39,6 +40,8 @@ if have_vhost
> if_true: files('vhost-user-snd-pci.c'))
> system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_INPUT'],
> if_true: files('vhost-user-input-pci.c'))
> + system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_SPI'],
> + if_true: files('vhost-user-spi-pci.c'))
> endif
> if have_vhost_vdpa
> system_virtio_ss.add(files('vhost-vdpa.c'))
> diff --git a/hw/virtio/vhost-user-spi-pci.c b/hw/virtio/vhost-user-spi-pci.c
> new file mode 100644
> index 0000000000..3565d526af
> --- /dev/null
> +++ b/hw/virtio/vhost-user-spi-pci.c
> @@ -0,0 +1,69 @@
> +/*
> + * Vhost-user spi virtio device PCI glue
> + *
> + * Copyright(c) 2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/virtio/vhost-user-spi.h"
> +#include "hw/virtio/virtio-pci.h"
> +
> +struct VHostUserSPIPCI {
> + VirtIOPCIProxy parent_obj;
> + VHostUserSPI vdev;
> +};
> +
> +typedef struct VHostUserSPIPCI VHostUserSPIPCI;
> +
> +#define TYPE_VHOST_USER_SPI_PCI "vhost-user-spi-pci-base"
> +
> +DECLARE_INSTANCE_CHECKER(VHostUserSPIPCI, VHOST_USER_SPI_PCI,
> + TYPE_VHOST_USER_SPI_PCI)
> +
> +static void vhost_user_spi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
> +{
> + VHostUserSPIPCI *dev = VHOST_USER_SPI_PCI(vpci_dev);
> + DeviceState *vdev = DEVICE(&dev->vdev);
> +
> + vpci_dev->nvectors = 1;
> + qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
> +}
> +
> +static void vhost_user_spi_pci_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
> + PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
> + k->realize = vhost_user_spi_pci_realize;
> + set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
> + pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
> + pcidev_k->device_id = 0; /* Set by virtio-pci based on virtio id */
> + pcidev_k->revision = 0x00;
> + pcidev_k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
> +}
> +
> +static void vhost_user_spi_pci_instance_init(Object *obj)
> +{
> + VHostUserSPIPCI *dev = VHOST_USER_SPI_PCI(obj);
> +
> + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
> + TYPE_VHOST_USER_SPI);
> +}
> +
> +static const VirtioPCIDeviceTypeInfo vhost_user_spi_pci_info = {
> + .base_name = TYPE_VHOST_USER_SPI_PCI,
> + .non_transitional_name = "vhost-user-spi-pci",
> + .instance_size = sizeof(VHostUserSPIPCI),
> + .instance_init = vhost_user_spi_pci_instance_init,
> + .class_init = vhost_user_spi_pci_class_init,
> +};
> +
> +static void vhost_user_spi_pci_register(void)
> +{
> + virtio_pci_types_register(&vhost_user_spi_pci_info);
> +}
> +
> +type_init(vhost_user_spi_pci_register);
> diff --git a/hw/virtio/vhost-user-spi.c b/hw/virtio/vhost-user-spi.c
> new file mode 100644
> index 0000000000..e138b8b53b
> --- /dev/null
> +++ b/hw/virtio/vhost-user-spi.c
> @@ -0,0 +1,66 @@
> +/*
> + * Vhost-user spi virtio device
> + *
> + * Copyright(c) 2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/virtio/virtio-bus.h"
> +#include "hw/virtio/vhost-user-spi.h"
> +#include "qemu/error-report.h"
> +#include "standard-headers/linux/virtio_ids.h"
> +#include "standard-headers/linux/virtio_spi.h"
> +
> +static Property vspi_properties[] = {
> + DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
> + DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void vspi_realize(DeviceState *dev, Error **errp)
> +{
> + VHostUserBase *vub = VHOST_USER_BASE(dev);
> + VHostUserBaseClass *vubc = VHOST_USER_BASE_GET_CLASS(dev);
> +
> + /* Fixed for SPI */
> + vub->virtio_id = VIRTIO_ID_SPI;
> + vub->num_vqs = 1;
> + vub->vq_size = 4;
> + vub->config_size = sizeof(struct virtio_spi_config);
> +
> + vubc->parent_realize(dev, errp);
> +}
> +
> +static const VMStateDescription vu_spi_vmstate = {
> + .name = "vhost-user-spi",
> + .unmigratable = 1,
> +};
> +
> +static void vu_spi_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass);
> +
> + dc->vmsd = &vu_spi_vmstate;
> + device_class_set_props(dc, vspi_properties);
> + device_class_set_parent_realize(dc, vspi_realize,
> + &vubc->parent_realize);
> + set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
> +}
> +
> +static const TypeInfo vu_spi_info = {
> + .name = TYPE_VHOST_USER_SPI,
> + .parent = TYPE_VHOST_USER_BASE,
> + .instance_size = sizeof(VHostUserSPI),
> + .class_init = vu_spi_class_init,
> +};
> +
> +static void vu_spi_register_types(void)
> +{
> + type_register_static(&vu_spi_info);
> +}
> +
> +type_init(vu_spi_register_types)
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 583a224163..689e2e21e7 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -46,6 +46,7 @@
> #include "standard-headers/linux/virtio_iommu.h"
> #include "standard-headers/linux/virtio_mem.h"
> #include "standard-headers/linux/virtio_vsock.h"
> +#include "standard-headers/linux/virtio_spi.h"
>
> /*
> * Maximum size of virtio device config space
> @@ -194,7 +195,8 @@ const char *virtio_device_names[] = {
> [VIRTIO_ID_PARAM_SERV] = "virtio-param-serv",
> [VIRTIO_ID_AUDIO_POLICY] = "virtio-audio-pol",
> [VIRTIO_ID_BT] = "virtio-bluetooth",
> - [VIRTIO_ID_GPIO] = "virtio-gpio"
> + [VIRTIO_ID_GPIO] = "virtio-gpio",
> + [VIRTIO_ID_SPI] = "virtio-spi"
> };
For the vhost-user-stub bits when split from the headers:
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Add vhost-user-spi and vhost-user-spi-pci devices
2024-08-27 17:14 ` Alex Bennée
@ 2024-09-02 8:57 ` Haixu Cui
2024-09-02 10:15 ` Alex Bennée
0 siblings, 1 reply; 7+ messages in thread
From: Haixu Cui @ 2024-09-02 8:57 UTC (permalink / raw)
To: Alex Bennée; +Cc: qemu-devel, viresh.kumar, quic_ztu, quic_tsoni
Hi Alex,
Thanks a lot for your comments, please refer to my response below.
On 8/28/2024 1:14 AM, Alex Bennée wrote:
> Haixu Cui <quic_haixcui@quicinc.com> writes:
>
>
> Apologies for the delay in getting to this.
>
>> This work is based on the virtio-spi spec, virtio-spi driver introduced by
>> the following patch series:
>> - https://github.com/oasis-tcs/virtio-spec/tree/virtio-1.4/device-types/spi
>> - https://lwn.net/Articles/966715/
>>
>> To test with rust-vmm vhost-user-spi daemon, start the vhost-daemon firstly:
>> vhost-device-spi --socket-path=vspi.sock --socket-count=1 --device "/dev/spidev0.0"
>
> I'm struggling to test this on my main dev box. Are there any dummy SPI
> modules for the kernel for testing? Otherwise we could consider
> implementing something similar to "mock_gpio" for the rust-vmm
> vhost-user-spi backend?
I verified this on my board with physical SPI interface, and I don't
know if these is dummy SPI module available in kernel. I'll look into this.
>
>
>> Then invoke qemu with the following parameters:
>> qemu-system-aarch64 -m 1G \
>> -chardev socket,path=/home/root/vspi.sock0,id=vspi \
>> -device vhost-user-spi-pci,chardev=vspi,id=spi \
>> -object memory-backend-file,id=mem,size=1G,mem-path=/dev/shm,share=on \
>> -numa node,memdev=mem
>> ...
>
>>
>> Signed-off-by: Haixu Cui <quic_haixcui@quicinc.com>
>> ---
>> hw/virtio/Kconfig | 5 +
>> hw/virtio/meson.build | 3 +
>> hw/virtio/vhost-user-spi-pci.c | 69 ++++++++
>> hw/virtio/vhost-user-spi.c | 66 +++++++
>> hw/virtio/virtio.c | 4 +-
>> include/hw/virtio/vhost-user-spi.h | 25 +++
>> include/standard-headers/linux/virtio_ids.h | 1 +
>> include/standard-headers/linux/virtio_spi.h | 186 ++++++++++++++++++++
>> 8 files changed, 358 insertions(+), 1 deletion(-)
>> create mode 100644 hw/virtio/vhost-user-spi-pci.c
>> create mode 100644 hw/virtio/vhost-user-spi.c
>> create mode 100644 include/hw/virtio/vhost-user-spi.h
>> create mode 100644 include/standard-headers/linux/virtio_spi.h
>
> Generally we want separate headers patches for the importing of headers.
> Doubly so in this case because I can't see the SPI definitions in the
> current Linux master. So:
>
> - 1/2 - Import headers for SPI (!merge until upstream)
> - 2/2 - Implement vhost-user stub for virtio-spi
>
Should I move only virtio_spi.h to the first patch, or all of the header
files? I don't quite understand here.
Best Regards
Thanks
>
>
>>
>> diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
>> index aa63ff7fd4..d5857651e5 100644
>> --- a/hw/virtio/Kconfig
>> +++ b/hw/virtio/Kconfig
>> @@ -110,3 +110,8 @@ config VHOST_USER_SCMI
>> bool
>> default y
>> depends on VIRTIO && VHOST_USER
>> +
>> +config VHOST_USER_SPI
>> + bool
>> + default y
>> + depends on VIRTIO && VHOST_USER
>> diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
>> index 621fc65454..42296219e5 100644
>> --- a/hw/virtio/meson.build
>> +++ b/hw/virtio/meson.build
>> @@ -26,6 +26,7 @@ if have_vhost
>> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: files('vhost-user-rng.c'))
>> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_SND', if_true: files('vhost-user-snd.c'))
>> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_INPUT', if_true: files('vhost-user-input.c'))
>> + system_virtio_ss.add(when: 'CONFIG_VHOST_USER_SPI', if_true: files('vhost-user-spi.c'))
>>
>> # PCI Stubs
>> system_virtio_ss.add(when: 'CONFIG_VIRTIO_PCI', if_true: files('vhost-user-device-pci.c'))
>> @@ -39,6 +40,8 @@ if have_vhost
>> if_true: files('vhost-user-snd-pci.c'))
>> system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_INPUT'],
>> if_true: files('vhost-user-input-pci.c'))
>> + system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_SPI'],
>> + if_true: files('vhost-user-spi-pci.c'))
>> endif
>> if have_vhost_vdpa
>> system_virtio_ss.add(files('vhost-vdpa.c'))
>> diff --git a/hw/virtio/vhost-user-spi-pci.c b/hw/virtio/vhost-user-spi-pci.c
>> new file mode 100644
>> index 0000000000..3565d526af
>> --- /dev/null
>> +++ b/hw/virtio/vhost-user-spi-pci.c
>> @@ -0,0 +1,69 @@
>> +/*
>> + * Vhost-user spi virtio device PCI glue
>> + *
>> + * Copyright(c) 2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
>> + *
>> + * SPDX-License-Identifier: GPL-2.0-or-later
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "hw/qdev-properties.h"
>> +#include "hw/virtio/vhost-user-spi.h"
>> +#include "hw/virtio/virtio-pci.h"
>> +
>> +struct VHostUserSPIPCI {
>> + VirtIOPCIProxy parent_obj;
>> + VHostUserSPI vdev;
>> +};
>> +
>> +typedef struct VHostUserSPIPCI VHostUserSPIPCI;
>> +
>> +#define TYPE_VHOST_USER_SPI_PCI "vhost-user-spi-pci-base"
>> +
>> +DECLARE_INSTANCE_CHECKER(VHostUserSPIPCI, VHOST_USER_SPI_PCI,
>> + TYPE_VHOST_USER_SPI_PCI)
>> +
>> +static void vhost_user_spi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
>> +{
>> + VHostUserSPIPCI *dev = VHOST_USER_SPI_PCI(vpci_dev);
>> + DeviceState *vdev = DEVICE(&dev->vdev);
>> +
>> + vpci_dev->nvectors = 1;
>> + qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
>> +}
>> +
>> +static void vhost_user_spi_pci_class_init(ObjectClass *klass, void *data)
>> +{
>> + DeviceClass *dc = DEVICE_CLASS(klass);
>> + VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
>> + PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
>> + k->realize = vhost_user_spi_pci_realize;
>> + set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
>> + pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
>> + pcidev_k->device_id = 0; /* Set by virtio-pci based on virtio id */
>> + pcidev_k->revision = 0x00;
>> + pcidev_k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
>> +}
>> +
>> +static void vhost_user_spi_pci_instance_init(Object *obj)
>> +{
>> + VHostUserSPIPCI *dev = VHOST_USER_SPI_PCI(obj);
>> +
>> + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
>> + TYPE_VHOST_USER_SPI);
>> +}
>> +
>> +static const VirtioPCIDeviceTypeInfo vhost_user_spi_pci_info = {
>> + .base_name = TYPE_VHOST_USER_SPI_PCI,
>> + .non_transitional_name = "vhost-user-spi-pci",
>> + .instance_size = sizeof(VHostUserSPIPCI),
>> + .instance_init = vhost_user_spi_pci_instance_init,
>> + .class_init = vhost_user_spi_pci_class_init,
>> +};
>> +
>> +static void vhost_user_spi_pci_register(void)
>> +{
>> + virtio_pci_types_register(&vhost_user_spi_pci_info);
>> +}
>> +
>> +type_init(vhost_user_spi_pci_register);
>> diff --git a/hw/virtio/vhost-user-spi.c b/hw/virtio/vhost-user-spi.c
>> new file mode 100644
>> index 0000000000..e138b8b53b
>> --- /dev/null
>> +++ b/hw/virtio/vhost-user-spi.c
>> @@ -0,0 +1,66 @@
>> +/*
>> + * Vhost-user spi virtio device
>> + *
>> + * Copyright(c) 2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
>> + *
>> + * SPDX-License-Identifier: GPL-2.0-or-later
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "qapi/error.h"
>> +#include "hw/qdev-properties.h"
>> +#include "hw/virtio/virtio-bus.h"
>> +#include "hw/virtio/vhost-user-spi.h"
>> +#include "qemu/error-report.h"
>> +#include "standard-headers/linux/virtio_ids.h"
>> +#include "standard-headers/linux/virtio_spi.h"
>> +
>> +static Property vspi_properties[] = {
>> + DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
>> + DEFINE_PROP_END_OF_LIST(),
>> +};
>> +
>> +static void vspi_realize(DeviceState *dev, Error **errp)
>> +{
>> + VHostUserBase *vub = VHOST_USER_BASE(dev);
>> + VHostUserBaseClass *vubc = VHOST_USER_BASE_GET_CLASS(dev);
>> +
>> + /* Fixed for SPI */
>> + vub->virtio_id = VIRTIO_ID_SPI;
>> + vub->num_vqs = 1;
>> + vub->vq_size = 4;
>> + vub->config_size = sizeof(struct virtio_spi_config);
>> +
>> + vubc->parent_realize(dev, errp);
>> +}
>> +
>> +static const VMStateDescription vu_spi_vmstate = {
>> + .name = "vhost-user-spi",
>> + .unmigratable = 1,
>> +};
>> +
>> +static void vu_spi_class_init(ObjectClass *klass, void *data)
>> +{
>> + DeviceClass *dc = DEVICE_CLASS(klass);
>> + VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass);
>> +
>> + dc->vmsd = &vu_spi_vmstate;
>> + device_class_set_props(dc, vspi_properties);
>> + device_class_set_parent_realize(dc, vspi_realize,
>> + &vubc->parent_realize);
>> + set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
>> +}
>> +
>> +static const TypeInfo vu_spi_info = {
>> + .name = TYPE_VHOST_USER_SPI,
>> + .parent = TYPE_VHOST_USER_BASE,
>> + .instance_size = sizeof(VHostUserSPI),
>> + .class_init = vu_spi_class_init,
>> +};
>> +
>> +static void vu_spi_register_types(void)
>> +{
>> + type_register_static(&vu_spi_info);
>> +}
>> +
>> +type_init(vu_spi_register_types)
>> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
>> index 583a224163..689e2e21e7 100644
>> --- a/hw/virtio/virtio.c
>> +++ b/hw/virtio/virtio.c
>> @@ -46,6 +46,7 @@
>> #include "standard-headers/linux/virtio_iommu.h"
>> #include "standard-headers/linux/virtio_mem.h"
>> #include "standard-headers/linux/virtio_vsock.h"
>> +#include "standard-headers/linux/virtio_spi.h"
>>
>> /*
>> * Maximum size of virtio device config space
>> @@ -194,7 +195,8 @@ const char *virtio_device_names[] = {
>> [VIRTIO_ID_PARAM_SERV] = "virtio-param-serv",
>> [VIRTIO_ID_AUDIO_POLICY] = "virtio-audio-pol",
>> [VIRTIO_ID_BT] = "virtio-bluetooth",
>> - [VIRTIO_ID_GPIO] = "virtio-gpio"
>> + [VIRTIO_ID_GPIO] = "virtio-gpio",
>> + [VIRTIO_ID_SPI] = "virtio-spi"
>> };
>
>
> For the vhost-user-stub bits when split from the headers:
>
> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Add vhost-user-spi and vhost-user-spi-pci devices
2024-09-02 8:57 ` Haixu Cui
@ 2024-09-02 10:15 ` Alex Bennée
2024-09-10 8:39 ` Haixu Cui
0 siblings, 1 reply; 7+ messages in thread
From: Alex Bennée @ 2024-09-02 10:15 UTC (permalink / raw)
To: Haixu Cui; +Cc: qemu-devel, viresh.kumar, quic_ztu, quic_tsoni
Haixu Cui <quic_haixcui@quicinc.com> writes:
> Hi Alex,
> Thanks a lot for your comments, please refer to my response below.
>
> On 8/28/2024 1:14 AM, Alex Bennée wrote:
>> Haixu Cui <quic_haixcui@quicinc.com> writes:
>> Apologies for the delay in getting to this.
>>
>>> This work is based on the virtio-spi spec, virtio-spi driver introduced by
>>> the following patch series:
>>> - https://github.com/oasis-tcs/virtio-spec/tree/virtio-1.4/device-types/spi
>>> - https://lwn.net/Articles/966715/
>>>
>>> To test with rust-vmm vhost-user-spi daemon, start the vhost-daemon firstly:
>>> vhost-device-spi --socket-path=vspi.sock --socket-count=1 --device "/dev/spidev0.0"
>> I'm struggling to test this on my main dev box. Are there any dummy
>> SPI
>> modules for the kernel for testing? Otherwise we could consider
>> implementing something similar to "mock_gpio" for the rust-vmm
>> vhost-user-spi backend?
>
> I verified this on my board with physical SPI interface, and I don't
> know if these is dummy SPI module available in kernel. I'll look into
> this.
I'll see if I can boot full Linux into a QEMU machine with SPI devices
which would be another approach.
>>
>>> Then invoke qemu with the following parameters:
>>> qemu-system-aarch64 -m 1G \
>>> -chardev socket,path=/home/root/vspi.sock0,id=vspi \
>>> -device vhost-user-spi-pci,chardev=vspi,id=spi \
>>> -object memory-backend-file,id=mem,size=1G,mem-path=/dev/shm,share=on \
>>> -numa node,memdev=mem
>>> ...
>>
>>>
>>> Signed-off-by: Haixu Cui <quic_haixcui@quicinc.com>
>>> ---
>>> hw/virtio/Kconfig | 5 +
>>> hw/virtio/meson.build | 3 +
>>> hw/virtio/vhost-user-spi-pci.c | 69 ++++++++
>>> hw/virtio/vhost-user-spi.c | 66 +++++++
>>> hw/virtio/virtio.c | 4 +-
>>> include/hw/virtio/vhost-user-spi.h | 25 +++
>>> include/standard-headers/linux/virtio_ids.h | 1 +
>>> include/standard-headers/linux/virtio_spi.h | 186 ++++++++++++++++++++
>>> 8 files changed, 358 insertions(+), 1 deletion(-)
>>> create mode 100644 hw/virtio/vhost-user-spi-pci.c
>>> create mode 100644 hw/virtio/vhost-user-spi.c
>>> create mode 100644 include/hw/virtio/vhost-user-spi.h
>>> create mode 100644 include/standard-headers/linux/virtio_spi.h
>> Generally we want separate headers patches for the importing of
>> headers.
>> Doubly so in this case because I can't see the SPI definitions in the
>> current Linux master. So:
>> - 1/2 - Import headers for SPI (!merge until upstream)
>> - 2/2 - Implement vhost-user stub for virtio-spi
>>
>
> Should I move only virtio_spi.h to the first patch, or all of the
> header files? I don't quite understand here.
Just the kernel headers (include/standard-headers). You should import
the kernel headers from a checked out kernel tree using:
./scripts/update-linux-headers.sh <path/to/linux.git>
and save them as a single commit for the 1st patch. As the SPI code is
not yet upstream just make it clear in the commit to avoid merging. e.g.
linux-headers: update to 6.10-rc5 + SPI patches (!merge)
This imports the headers from the current Linux HEAD + the VirtIO SPI
patches which are not yet upstream. Once the SPI work is up-streamed in
the kernel they will be imported from there.
Just make sure you kernel base is newer than the last import otherwise
you will get a lot of additional noise.
>
> Best Regards
> Thanks
>>
>>>
>>> diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
>>> index aa63ff7fd4..d5857651e5 100644
>>> --- a/hw/virtio/Kconfig
>>> +++ b/hw/virtio/Kconfig
>>> @@ -110,3 +110,8 @@ config VHOST_USER_SCMI
>>> bool
>>> default y
>>> depends on VIRTIO && VHOST_USER
>>> +
>>> +config VHOST_USER_SPI
>>> + bool
>>> + default y
>>> + depends on VIRTIO && VHOST_USER
>>> diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
>>> index 621fc65454..42296219e5 100644
>>> --- a/hw/virtio/meson.build
>>> +++ b/hw/virtio/meson.build
>>> @@ -26,6 +26,7 @@ if have_vhost
>>> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: files('vhost-user-rng.c'))
>>> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_SND', if_true: files('vhost-user-snd.c'))
>>> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_INPUT', if_true: files('vhost-user-input.c'))
>>> + system_virtio_ss.add(when: 'CONFIG_VHOST_USER_SPI', if_true: files('vhost-user-spi.c'))
>>> # PCI Stubs
>>> system_virtio_ss.add(when: 'CONFIG_VIRTIO_PCI', if_true: files('vhost-user-device-pci.c'))
>>> @@ -39,6 +40,8 @@ if have_vhost
>>> if_true: files('vhost-user-snd-pci.c'))
>>> system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_INPUT'],
>>> if_true: files('vhost-user-input-pci.c'))
>>> + system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_SPI'],
>>> + if_true: files('vhost-user-spi-pci.c'))
>>> endif
>>> if have_vhost_vdpa
>>> system_virtio_ss.add(files('vhost-vdpa.c'))
>>> diff --git a/hw/virtio/vhost-user-spi-pci.c b/hw/virtio/vhost-user-spi-pci.c
>>> new file mode 100644
>>> index 0000000000..3565d526af
>>> --- /dev/null
>>> +++ b/hw/virtio/vhost-user-spi-pci.c
>>> @@ -0,0 +1,69 @@
>>> +/*
>>> + * Vhost-user spi virtio device PCI glue
>>> + *
>>> + * Copyright(c) 2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
>>> + *
>>> + * SPDX-License-Identifier: GPL-2.0-or-later
>>> + */
>>> +
>>> +#include "qemu/osdep.h"
>>> +#include "hw/qdev-properties.h"
>>> +#include "hw/virtio/vhost-user-spi.h"
>>> +#include "hw/virtio/virtio-pci.h"
>>> +
>>> +struct VHostUserSPIPCI {
>>> + VirtIOPCIProxy parent_obj;
>>> + VHostUserSPI vdev;
>>> +};
>>> +
>>> +typedef struct VHostUserSPIPCI VHostUserSPIPCI;
>>> +
>>> +#define TYPE_VHOST_USER_SPI_PCI "vhost-user-spi-pci-base"
>>> +
>>> +DECLARE_INSTANCE_CHECKER(VHostUserSPIPCI, VHOST_USER_SPI_PCI,
>>> + TYPE_VHOST_USER_SPI_PCI)
>>> +
>>> +static void vhost_user_spi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
>>> +{
>>> + VHostUserSPIPCI *dev = VHOST_USER_SPI_PCI(vpci_dev);
>>> + DeviceState *vdev = DEVICE(&dev->vdev);
>>> +
>>> + vpci_dev->nvectors = 1;
>>> + qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
>>> +}
>>> +
>>> +static void vhost_user_spi_pci_class_init(ObjectClass *klass, void *data)
>>> +{
>>> + DeviceClass *dc = DEVICE_CLASS(klass);
>>> + VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
>>> + PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
>>> + k->realize = vhost_user_spi_pci_realize;
>>> + set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
>>> + pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
>>> + pcidev_k->device_id = 0; /* Set by virtio-pci based on virtio id */
>>> + pcidev_k->revision = 0x00;
>>> + pcidev_k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
>>> +}
>>> +
>>> +static void vhost_user_spi_pci_instance_init(Object *obj)
>>> +{
>>> + VHostUserSPIPCI *dev = VHOST_USER_SPI_PCI(obj);
>>> +
>>> + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
>>> + TYPE_VHOST_USER_SPI);
>>> +}
>>> +
>>> +static const VirtioPCIDeviceTypeInfo vhost_user_spi_pci_info = {
>>> + .base_name = TYPE_VHOST_USER_SPI_PCI,
>>> + .non_transitional_name = "vhost-user-spi-pci",
>>> + .instance_size = sizeof(VHostUserSPIPCI),
>>> + .instance_init = vhost_user_spi_pci_instance_init,
>>> + .class_init = vhost_user_spi_pci_class_init,
>>> +};
>>> +
>>> +static void vhost_user_spi_pci_register(void)
>>> +{
>>> + virtio_pci_types_register(&vhost_user_spi_pci_info);
>>> +}
>>> +
>>> +type_init(vhost_user_spi_pci_register);
>>> diff --git a/hw/virtio/vhost-user-spi.c b/hw/virtio/vhost-user-spi.c
>>> new file mode 100644
>>> index 0000000000..e138b8b53b
>>> --- /dev/null
>>> +++ b/hw/virtio/vhost-user-spi.c
>>> @@ -0,0 +1,66 @@
>>> +/*
>>> + * Vhost-user spi virtio device
>>> + *
>>> + * Copyright(c) 2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
>>> + *
>>> + * SPDX-License-Identifier: GPL-2.0-or-later
>>> + */
>>> +
>>> +#include "qemu/osdep.h"
>>> +#include "qapi/error.h"
>>> +#include "hw/qdev-properties.h"
>>> +#include "hw/virtio/virtio-bus.h"
>>> +#include "hw/virtio/vhost-user-spi.h"
>>> +#include "qemu/error-report.h"
>>> +#include "standard-headers/linux/virtio_ids.h"
>>> +#include "standard-headers/linux/virtio_spi.h"
>>> +
>>> +static Property vspi_properties[] = {
>>> + DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
>>> + DEFINE_PROP_END_OF_LIST(),
>>> +};
>>> +
>>> +static void vspi_realize(DeviceState *dev, Error **errp)
>>> +{
>>> + VHostUserBase *vub = VHOST_USER_BASE(dev);
>>> + VHostUserBaseClass *vubc = VHOST_USER_BASE_GET_CLASS(dev);
>>> +
>>> + /* Fixed for SPI */
>>> + vub->virtio_id = VIRTIO_ID_SPI;
>>> + vub->num_vqs = 1;
>>> + vub->vq_size = 4;
>>> + vub->config_size = sizeof(struct virtio_spi_config);
>>> +
>>> + vubc->parent_realize(dev, errp);
>>> +}
>>> +
>>> +static const VMStateDescription vu_spi_vmstate = {
>>> + .name = "vhost-user-spi",
>>> + .unmigratable = 1,
>>> +};
>>> +
>>> +static void vu_spi_class_init(ObjectClass *klass, void *data)
>>> +{
>>> + DeviceClass *dc = DEVICE_CLASS(klass);
>>> + VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass);
>>> +
>>> + dc->vmsd = &vu_spi_vmstate;
>>> + device_class_set_props(dc, vspi_properties);
>>> + device_class_set_parent_realize(dc, vspi_realize,
>>> + &vubc->parent_realize);
>>> + set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
>>> +}
>>> +
>>> +static const TypeInfo vu_spi_info = {
>>> + .name = TYPE_VHOST_USER_SPI,
>>> + .parent = TYPE_VHOST_USER_BASE,
>>> + .instance_size = sizeof(VHostUserSPI),
>>> + .class_init = vu_spi_class_init,
>>> +};
>>> +
>>> +static void vu_spi_register_types(void)
>>> +{
>>> + type_register_static(&vu_spi_info);
>>> +}
>>> +
>>> +type_init(vu_spi_register_types)
>>> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
>>> index 583a224163..689e2e21e7 100644
>>> --- a/hw/virtio/virtio.c
>>> +++ b/hw/virtio/virtio.c
>>> @@ -46,6 +46,7 @@
>>> #include "standard-headers/linux/virtio_iommu.h"
>>> #include "standard-headers/linux/virtio_mem.h"
>>> #include "standard-headers/linux/virtio_vsock.h"
>>> +#include "standard-headers/linux/virtio_spi.h"
>>> /*
>>> * Maximum size of virtio device config space
>>> @@ -194,7 +195,8 @@ const char *virtio_device_names[] = {
>>> [VIRTIO_ID_PARAM_SERV] = "virtio-param-serv",
>>> [VIRTIO_ID_AUDIO_POLICY] = "virtio-audio-pol",
>>> [VIRTIO_ID_BT] = "virtio-bluetooth",
>>> - [VIRTIO_ID_GPIO] = "virtio-gpio"
>>> + [VIRTIO_ID_GPIO] = "virtio-gpio",
>>> + [VIRTIO_ID_SPI] = "virtio-spi"
>>> };
>> For the vhost-user-stub bits when split from the headers:
>> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
>>
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Add vhost-user-spi and vhost-user-spi-pci devices
2024-09-02 10:15 ` Alex Bennée
@ 2024-09-10 8:39 ` Haixu Cui
0 siblings, 0 replies; 7+ messages in thread
From: Haixu Cui @ 2024-09-10 8:39 UTC (permalink / raw)
To: Alex Bennée; +Cc: qemu-devel, viresh.kumar, quic_ztu, quic_tsoni
On 9/2/2024 6:15 PM, Alex Bennée wrote:
> Haixu Cui <quic_haixcui@quicinc.com> writes:
>
>> Hi Alex,
>> Thanks a lot for your comments, please refer to my response below.
>>
>> On 8/28/2024 1:14 AM, Alex Bennée wrote:
>>> Haixu Cui <quic_haixcui@quicinc.com> writes:
>>> Apologies for the delay in getting to this.
>>>
>>>> This work is based on the virtio-spi spec, virtio-spi driver introduced by
>>>> the following patch series:
>>>> - https://github.com/oasis-tcs/virtio-spec/tree/virtio-1.4/device-types/spi
>>>> - https://lwn.net/Articles/966715/
>>>>
>>>> To test with rust-vmm vhost-user-spi daemon, start the vhost-daemon firstly:
>>>> vhost-device-spi --socket-path=vspi.sock --socket-count=1 --device "/dev/spidev0.0"
>>> I'm struggling to test this on my main dev box. Are there any dummy
>>> SPI
>>> modules for the kernel for testing? Otherwise we could consider
>>> implementing something similar to "mock_gpio" for the rust-vmm
>>> vhost-user-spi backend?
>>
>> I verified this on my board with physical SPI interface, and I don't
>> know if these is dummy SPI module available in kernel. I'll look into
>> this.
>
> I'll see if I can boot full Linux into a QEMU machine with SPI devices
> which would be another approach.
>
Great idea.
>>>
>>>> Then invoke qemu with the following parameters:
>>>> qemu-system-aarch64 -m 1G \
>>>> -chardev socket,path=/home/root/vspi.sock0,id=vspi \
>>>> -device vhost-user-spi-pci,chardev=vspi,id=spi \
>>>> -object memory-backend-file,id=mem,size=1G,mem-path=/dev/shm,share=on \
>>>> -numa node,memdev=mem
>>>> ...
>>>
>>>>
>>>> Signed-off-by: Haixu Cui <quic_haixcui@quicinc.com>
>>>> ---
>>>> hw/virtio/Kconfig | 5 +
>>>> hw/virtio/meson.build | 3 +
>>>> hw/virtio/vhost-user-spi-pci.c | 69 ++++++++
>>>> hw/virtio/vhost-user-spi.c | 66 +++++++
>>>> hw/virtio/virtio.c | 4 +-
>>>> include/hw/virtio/vhost-user-spi.h | 25 +++
>>>> include/standard-headers/linux/virtio_ids.h | 1 +
>>>> include/standard-headers/linux/virtio_spi.h | 186 ++++++++++++++++++++
>>>> 8 files changed, 358 insertions(+), 1 deletion(-)
>>>> create mode 100644 hw/virtio/vhost-user-spi-pci.c
>>>> create mode 100644 hw/virtio/vhost-user-spi.c
>>>> create mode 100644 include/hw/virtio/vhost-user-spi.h
>>>> create mode 100644 include/standard-headers/linux/virtio_spi.h
>>> Generally we want separate headers patches for the importing of
>>> headers.
>>> Doubly so in this case because I can't see the SPI definitions in the
>>> current Linux master. So:
>>> - 1/2 - Import headers for SPI (!merge until upstream)
>>> - 2/2 - Implement vhost-user stub for virtio-spi
>>>
>>
>> Should I move only virtio_spi.h to the first patch, or all of the
>> header files? I don't quite understand here.
>
> Just the kernel headers (include/standard-headers). You should import
> the kernel headers from a checked out kernel tree using:
>
> ./scripts/update-linux-headers.sh <path/to/linux.git>
>
> and save them as a single commit for the 1st patch. As the SPI code is
> not yet upstream just make it clear in the commit to avoid merging. e.g.
>
> linux-headers: update to 6.10-rc5 + SPI patches (!merge)
>
> This imports the headers from the current Linux HEAD + the VirtIO SPI
> patches which are not yet upstream. Once the SPI work is up-streamed in
> the kernel they will be imported from there.
>
> Just make sure you kernel base is newer than the last import otherwise
> you will get a lot of additional noise.
>
Thank you so much for your guidance, I'll generate header file based on
6.11-rc7, the latest version.
BR & Thanks
>>
>> Best Regards
>> Thanks
>>>
>>>>
>>>> diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
>>>> index aa63ff7fd4..d5857651e5 100644
>>>> --- a/hw/virtio/Kconfig
>>>> +++ b/hw/virtio/Kconfig
>>>> @@ -110,3 +110,8 @@ config VHOST_USER_SCMI
>>>> bool
>>>> default y
>>>> depends on VIRTIO && VHOST_USER
>>>> +
>>>> +config VHOST_USER_SPI
>>>> + bool
>>>> + default y
>>>> + depends on VIRTIO && VHOST_USER
>>>> diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
>>>> index 621fc65454..42296219e5 100644
>>>> --- a/hw/virtio/meson.build
>>>> +++ b/hw/virtio/meson.build
>>>> @@ -26,6 +26,7 @@ if have_vhost
>>>> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: files('vhost-user-rng.c'))
>>>> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_SND', if_true: files('vhost-user-snd.c'))
>>>> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_INPUT', if_true: files('vhost-user-input.c'))
>>>> + system_virtio_ss.add(when: 'CONFIG_VHOST_USER_SPI', if_true: files('vhost-user-spi.c'))
>>>> # PCI Stubs
>>>> system_virtio_ss.add(when: 'CONFIG_VIRTIO_PCI', if_true: files('vhost-user-device-pci.c'))
>>>> @@ -39,6 +40,8 @@ if have_vhost
>>>> if_true: files('vhost-user-snd-pci.c'))
>>>> system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_INPUT'],
>>>> if_true: files('vhost-user-input-pci.c'))
>>>> + system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_SPI'],
>>>> + if_true: files('vhost-user-spi-pci.c'))
>>>> endif
>>>> if have_vhost_vdpa
>>>> system_virtio_ss.add(files('vhost-vdpa.c'))
>>>> diff --git a/hw/virtio/vhost-user-spi-pci.c b/hw/virtio/vhost-user-spi-pci.c
>>>> new file mode 100644
>>>> index 0000000000..3565d526af
>>>> --- /dev/null
>>>> +++ b/hw/virtio/vhost-user-spi-pci.c
>>>> @@ -0,0 +1,69 @@
>>>> +/*
>>>> + * Vhost-user spi virtio device PCI glue
>>>> + *
>>>> + * Copyright(c) 2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
>>>> + *
>>>> + * SPDX-License-Identifier: GPL-2.0-or-later
>>>> + */
>>>> +
>>>> +#include "qemu/osdep.h"
>>>> +#include "hw/qdev-properties.h"
>>>> +#include "hw/virtio/vhost-user-spi.h"
>>>> +#include "hw/virtio/virtio-pci.h"
>>>> +
>>>> +struct VHostUserSPIPCI {
>>>> + VirtIOPCIProxy parent_obj;
>>>> + VHostUserSPI vdev;
>>>> +};
>>>> +
>>>> +typedef struct VHostUserSPIPCI VHostUserSPIPCI;
>>>> +
>>>> +#define TYPE_VHOST_USER_SPI_PCI "vhost-user-spi-pci-base"
>>>> +
>>>> +DECLARE_INSTANCE_CHECKER(VHostUserSPIPCI, VHOST_USER_SPI_PCI,
>>>> + TYPE_VHOST_USER_SPI_PCI)
>>>> +
>>>> +static void vhost_user_spi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
>>>> +{
>>>> + VHostUserSPIPCI *dev = VHOST_USER_SPI_PCI(vpci_dev);
>>>> + DeviceState *vdev = DEVICE(&dev->vdev);
>>>> +
>>>> + vpci_dev->nvectors = 1;
>>>> + qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
>>>> +}
>>>> +
>>>> +static void vhost_user_spi_pci_class_init(ObjectClass *klass, void *data)
>>>> +{
>>>> + DeviceClass *dc = DEVICE_CLASS(klass);
>>>> + VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
>>>> + PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
>>>> + k->realize = vhost_user_spi_pci_realize;
>>>> + set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
>>>> + pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
>>>> + pcidev_k->device_id = 0; /* Set by virtio-pci based on virtio id */
>>>> + pcidev_k->revision = 0x00;
>>>> + pcidev_k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
>>>> +}
>>>> +
>>>> +static void vhost_user_spi_pci_instance_init(Object *obj)
>>>> +{
>>>> + VHostUserSPIPCI *dev = VHOST_USER_SPI_PCI(obj);
>>>> +
>>>> + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
>>>> + TYPE_VHOST_USER_SPI);
>>>> +}
>>>> +
>>>> +static const VirtioPCIDeviceTypeInfo vhost_user_spi_pci_info = {
>>>> + .base_name = TYPE_VHOST_USER_SPI_PCI,
>>>> + .non_transitional_name = "vhost-user-spi-pci",
>>>> + .instance_size = sizeof(VHostUserSPIPCI),
>>>> + .instance_init = vhost_user_spi_pci_instance_init,
>>>> + .class_init = vhost_user_spi_pci_class_init,
>>>> +};
>>>> +
>>>> +static void vhost_user_spi_pci_register(void)
>>>> +{
>>>> + virtio_pci_types_register(&vhost_user_spi_pci_info);
>>>> +}
>>>> +
>>>> +type_init(vhost_user_spi_pci_register);
>>>> diff --git a/hw/virtio/vhost-user-spi.c b/hw/virtio/vhost-user-spi.c
>>>> new file mode 100644
>>>> index 0000000000..e138b8b53b
>>>> --- /dev/null
>>>> +++ b/hw/virtio/vhost-user-spi.c
>>>> @@ -0,0 +1,66 @@
>>>> +/*
>>>> + * Vhost-user spi virtio device
>>>> + *
>>>> + * Copyright(c) 2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
>>>> + *
>>>> + * SPDX-License-Identifier: GPL-2.0-or-later
>>>> + */
>>>> +
>>>> +#include "qemu/osdep.h"
>>>> +#include "qapi/error.h"
>>>> +#include "hw/qdev-properties.h"
>>>> +#include "hw/virtio/virtio-bus.h"
>>>> +#include "hw/virtio/vhost-user-spi.h"
>>>> +#include "qemu/error-report.h"
>>>> +#include "standard-headers/linux/virtio_ids.h"
>>>> +#include "standard-headers/linux/virtio_spi.h"
>>>> +
>>>> +static Property vspi_properties[] = {
>>>> + DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
>>>> + DEFINE_PROP_END_OF_LIST(),
>>>> +};
>>>> +
>>>> +static void vspi_realize(DeviceState *dev, Error **errp)
>>>> +{
>>>> + VHostUserBase *vub = VHOST_USER_BASE(dev);
>>>> + VHostUserBaseClass *vubc = VHOST_USER_BASE_GET_CLASS(dev);
>>>> +
>>>> + /* Fixed for SPI */
>>>> + vub->virtio_id = VIRTIO_ID_SPI;
>>>> + vub->num_vqs = 1;
>>>> + vub->vq_size = 4;
>>>> + vub->config_size = sizeof(struct virtio_spi_config);
>>>> +
>>>> + vubc->parent_realize(dev, errp);
>>>> +}
>>>> +
>>>> +static const VMStateDescription vu_spi_vmstate = {
>>>> + .name = "vhost-user-spi",
>>>> + .unmigratable = 1,
>>>> +};
>>>> +
>>>> +static void vu_spi_class_init(ObjectClass *klass, void *data)
>>>> +{
>>>> + DeviceClass *dc = DEVICE_CLASS(klass);
>>>> + VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass);
>>>> +
>>>> + dc->vmsd = &vu_spi_vmstate;
>>>> + device_class_set_props(dc, vspi_properties);
>>>> + device_class_set_parent_realize(dc, vspi_realize,
>>>> + &vubc->parent_realize);
>>>> + set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
>>>> +}
>>>> +
>>>> +static const TypeInfo vu_spi_info = {
>>>> + .name = TYPE_VHOST_USER_SPI,
>>>> + .parent = TYPE_VHOST_USER_BASE,
>>>> + .instance_size = sizeof(VHostUserSPI),
>>>> + .class_init = vu_spi_class_init,
>>>> +};
>>>> +
>>>> +static void vu_spi_register_types(void)
>>>> +{
>>>> + type_register_static(&vu_spi_info);
>>>> +}
>>>> +
>>>> +type_init(vu_spi_register_types)
>>>> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
>>>> index 583a224163..689e2e21e7 100644
>>>> --- a/hw/virtio/virtio.c
>>>> +++ b/hw/virtio/virtio.c
>>>> @@ -46,6 +46,7 @@
>>>> #include "standard-headers/linux/virtio_iommu.h"
>>>> #include "standard-headers/linux/virtio_mem.h"
>>>> #include "standard-headers/linux/virtio_vsock.h"
>>>> +#include "standard-headers/linux/virtio_spi.h"
>>>> /*
>>>> * Maximum size of virtio device config space
>>>> @@ -194,7 +195,8 @@ const char *virtio_device_names[] = {
>>>> [VIRTIO_ID_PARAM_SERV] = "virtio-param-serv",
>>>> [VIRTIO_ID_AUDIO_POLICY] = "virtio-audio-pol",
>>>> [VIRTIO_ID_BT] = "virtio-bluetooth",
>>>> - [VIRTIO_ID_GPIO] = "virtio-gpio"
>>>> + [VIRTIO_ID_GPIO] = "virtio-gpio",
>>>> + [VIRTIO_ID_SPI] = "virtio-spi"
>>>> };
>>> For the vhost-user-stub bits when split from the headers:
>>> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
>>>
>
^ permalink raw reply [flat|nested] 7+ messages in thread