From 924311eeb428b6d23a94360d04b1c18b49fb1623 Mon Sep 17 00:00:00 2001 From: Arnaud Pouliquen Date: Mon, 9 Oct 2023 17:36:04 +0200 Subject: [PATCH 1/2] virtio: Complete virtio and virtqueue structures Doxygen description Add descriptions for following structures: - virtio_device_id - virtio_feature_desc - virtio_dispatch - virtqueue_buf - virtqueue - vring_alloc_info Move some comments related to the vring structure in its description. Signed-off-by: Arnaud Pouliquen --- lib/include/openamp/virtio.h | 51 ++++++++++++++++++---- lib/include/openamp/virtio_ring.h | 34 ++++++++------- lib/include/openamp/virtqueue.h | 70 ++++++++++++++++++++++--------- 3 files changed, 112 insertions(+), 43 deletions(-) diff --git a/lib/include/openamp/virtio.h b/lib/include/openamp/virtio.h index 0df3067eb..6d4442ef3 100644 --- a/lib/include/openamp/virtio.h +++ b/lib/include/openamp/virtio.h @@ -95,9 +95,15 @@ __deprecated static inline int deprecated_virtio_dev_slave(void) #warning "VIRTIO_SLAVE_ONLY is deprecated, please use VIRTIO_DEVICE_ONLY" #endif +/** @brief Virtio device identifier. */ struct virtio_device_id { + /** Virtio subsystem device ID. */ uint32_t device; + + /** Virtio subsystem vendor ID. */ uint32_t vendor; + + /** Virtio subsystem device version. */ uint32_t version; }; @@ -142,8 +148,12 @@ typedef void (*virtio_dev_reset_cb)(struct virtio_device *vdev); struct virtio_dispatch; +/** @brief Device features. */ struct virtio_feature_desc { + /** Unique feature ID, defined in the virtio specification. */ uint32_t vfd_val; + + /** Name of the feature (for debug). */ const char *vfd_str; }; @@ -200,36 +210,61 @@ void virtio_describe(struct virtio_device *dev, const char *msg, uint32_t features, struct virtio_feature_desc *feature_desc); -/* - * Functions for virtio device configuration as defined in Rusty Russell's - * paper. - * Drivers are expected to implement these functions in their respective codes. +/** + * @brief Virtio device dispatcher functions. + * + * Functions for virtio device configuration as defined in Rusty Russell's paper. + * The virtio transport layers are expected to implement these functions in their respective codes. */ struct virtio_dispatch { + /** Create virtio queue instances. */ int (*create_virtqueues)(struct virtio_device *vdev, unsigned int flags, unsigned int nvqs, const char *names[], vq_callback callbacks[], void *callback_args[]); + + /** Delete virtio queue instances. */ void (*delete_virtqueues)(struct virtio_device *vdev); + + /** Get the status of the virtio device. */ uint8_t (*get_status)(struct virtio_device *dev); + + /** Set the status of the virtio device. */ void (*set_status)(struct virtio_device *dev, uint8_t status); + + /** Get the feature exposed by the virtio device. */ uint32_t (*get_features)(struct virtio_device *dev); + + /** Set the supported feature (virtio driver only). */ void (*set_features)(struct virtio_device *dev, uint32_t feature); + + /** + * Set the supported feature negotiate between the \ref features parameter and features + * supported by the device (virtio driver only). + */ uint32_t (*negotiate_features)(struct virtio_device *dev, uint32_t features); - /* - * Read/write a variable amount from the device specific (ie, network) - * configuration region. This region is encoded in the same endian as - * the guest. + /** + * Read a variable amount from the device specific (ie, network) + * configuration region. */ void (*read_config)(struct virtio_device *dev, uint32_t offset, void *dst, int length); + + /** + * Write a variable amount from the device specific (ie, network) + * configuration region. + */ void (*write_config)(struct virtio_device *dev, uint32_t offset, void *src, int length); + + /** Request a reset of the virtio device. */ void (*reset_device)(struct virtio_device *dev); + + /** Notify the other side that a virtio vring as been updated. */ void (*notify)(struct virtqueue *vq); }; diff --git a/lib/include/openamp/virtio_ring.h b/lib/include/openamp/virtio_ring.h index e3e93ae23..60a9710dc 100644 --- a/lib/include/openamp/virtio_ring.h +++ b/lib/include/openamp/virtio_ring.h @@ -122,22 +122,8 @@ struct vring_used { * index into the available ring. It then notifies the device. When the device * has finished a buffer, it writes the descriptor index into the used ring, * and sends an interrupt. - */ -struct vring { - /** The number of descriptors in the virtqueue */ - unsigned int num; - - /** The actual descriptors, 16 bytes each */ - struct vring_desc *desc; - - /** A ring of available descriptor heads with free-running index */ - struct vring_avail *avail; - - /** A ring of used descriptor heads with free-running index */ - struct vring_used *used; -}; - -/* The standard layout for the ring is a continuous chunk of memory which + * + * The standard layout for the ring is a continuous chunk of memory which * looks like this. We assume num is a power of 2. * * struct vring { @@ -162,6 +148,22 @@ struct vring { * * NOTE: for VirtIO PCI, align is 4096. */ +struct vring { + /** + * The maximum number of buffer descriptors in the virtqueue. + * The value is always a power of 2. + */ + unsigned int num; + + /** The actual buffer descriptors, 16 bytes each */ + struct vring_desc *desc; + + /** A ring of available descriptor heads with free-running index */ + struct vring_avail *avail; + + /** A ring of used descriptor heads with free-running index */ + struct vring_used *used; +}; /* * We publish the used event index at the end of the available ring, and vice diff --git a/lib/include/openamp/virtqueue.h b/lib/include/openamp/virtqueue.h index 1b44e5417..1a9d2e8fe 100644 --- a/lib/include/openamp/virtqueue.h +++ b/lib/include/openamp/virtqueue.h @@ -63,66 +63,98 @@ extern "C" { #define VRING_INVALIDATE(x, s) do { } while (0) #endif /* VIRTIO_CACHED_VRINGS || VIRTIO_USE_DCACHE */ +/** @brief Buffer descriptor. */ struct virtqueue_buf { + /** Address of the buffer. */ void *buf; + + /** Size of the buffer. */ int len; }; +/** @brief Vring descriptor extra information for buffer list management. */ struct vq_desc_extra { + /** Pointer to first descriptor. */ void *cookie; + + /** Number of chained descriptors. */ uint16_t ndescs; }; +/** @brief Local virtio queue to manage a virtio ring for sending or receiving. */ struct virtqueue { + /** Associated virtio device. */ struct virtio_device *vq_dev; + + /** Name of the virtio queue. */ const char *vq_name; + + /** Index of the virtio queue. */ uint16_t vq_queue_index; + + /** Max number of buffers in the virtio queue. */ uint16_t vq_nentries; + + /** Function to invoke, when message is available on the virtio queue. */ void (*callback)(struct virtqueue *vq); + + /** Private data associated to the virtio queue. */ void *priv; + + /** Function to invoke, to inform the other side about an update in the virtio queue. */ void (*notify)(struct virtqueue *vq); + + /** Associated virtio ring. */ struct vring vq_ring; + + /** Number of free descriptor in the virtio ring. */ uint16_t vq_free_cnt; + + /** Number of queued buffer in the virtio ring. */ uint16_t vq_queued_cnt; - void *shm_io; /* opaque pointer to data needed to allow v2p & p2v */ - /* - * Head of the free chain in the descriptor table. If - * there are no free descriptors, this will be set to - * VQ_RING_DESC_CHAIN_END. + /** + * Metal I/O region of the vrings and buffers. + * This structure is used for conversion between virtual and physical addresses. */ - uint16_t vq_desc_head_idx; + void *shm_io; - /* - * Last consumed descriptor in the used table, - * trails vq_ring.used->idx. + /** + * Head of the free chain in the descriptor table. If there are no free descriptors, + * this will be set to VQ_RING_DESC_CHAIN_END. */ + uint16_t vq_desc_head_idx; + + /** Last consumed descriptor in the used table, trails vq_ring.used->idx. */ uint16_t vq_used_cons_idx; - /* - * Last consumed descriptor in the available table - - * used by the consumer side. - */ + /** Last consumed descriptor in the available table, used by the consumer side. */ uint16_t vq_available_idx; #ifdef VQUEUE_DEBUG + /** Debug counter for virtqueue reentrance check. */ bool vq_inuse; #endif - /* - * Used by the host side during callback. Cookie - * holds the address of buffer received from other side. - * Other fields in this structure are not used currently. + /** + * Used by the host side during callback. Cookie holds the address of buffer received from + * other side. Other fields in this structure are not used currently. */ - struct vq_desc_extra vq_descx[0]; }; -/* struct to hold vring specific information */ +/** @brief Virtio ring specific information. */ struct vring_alloc_info { + /** Vring address. */ void *vaddr; + + /** Vring alignment. */ uint32_t align; + + /** Number of descriptors in the vring. */ uint16_t num_descs; + + /** Padding */ uint16_t pad; }; From 7a41371d97d11e2c2a0375dd1205178c93618850 Mon Sep 17 00:00:00 2001 From: Arnaud Pouliquen Date: Mon, 9 Oct 2023 17:37:09 +0200 Subject: [PATCH 2/2] virtio: Add virtio_dev_name function description Add function description in Doxygen format for documentation. Signed-off-by: Arnaud Pouliquen --- lib/include/openamp/virtio.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/include/openamp/virtio.h b/lib/include/openamp/virtio.h index 6d4442ef3..f677feff9 100644 --- a/lib/include/openamp/virtio.h +++ b/lib/include/openamp/virtio.h @@ -205,6 +205,14 @@ struct virtio_device { /* * Helper functions. */ + +/** + * @brief Get the name of a virtio device. + * + * @param devid Id of the device. + * + * @return pointer to the device name string if found, otherwise null. + */ const char *virtio_dev_name(uint16_t devid); void virtio_describe(struct virtio_device *dev, const char *msg, uint32_t features,