[dpdk-dev] [PATCH v2 7/7] virtio: add 1.0 support
Xie, Huawei
huawei.xie at intel.com
Thu Jan 14 08:50:00 CET 2016
On 1/12/2016 2:58 PM, Yuanhan Liu wrote:
> Modern (v1.0) virtio pci device defines several pci capabilities.
> Each cap has a configure structure corresponding to it, and the
> cap.bar and cap.offset fields tell us where to find it.
>
> Firstly, we map the pci resources by rte_eal_pci_map_device().
> We then could easily locate to a cfg structure by:
s/Locate/Locate to/
>
> cfg_addr = dev->mem_resources[cap.bar].addr + cap.offset;
>
> Therefore, the entrance of enabling modern (v1.0) pci device support
> is to iterate the pci capability lists, and to locate some configs
> we care; and they are:
>
> - common cfg
>
> For generic virtio and virtuqueu configuration, such as setting/getting
typo for virtqueue
> features, enabling a specific queue, and so on.
>
> - nofity cfg
>
> Combining with `queue_notify_off' from common cfg, we could use it to
> notify a specific virt queue.
>
> - device cfg
>
> Where virtio_net_config structure locates.
is located
> If any of above cap is not found, we fallback to the legacy virtio
>
[SNIP]
>
>
>
> +#define MODERN_READ_DEF(nr_bits, type) \
> +static inline type \
> +modern_read##nr_bits(type *addr) \
> +{ \
> + return *(volatile type *)addr; \
> +}
> +
> +#define MODERN_WRITE_DEF(nr_bits, type) \
> +static inline void \
> +modern_write##nr_bits(type val, type *addr) \
> +{ \
> + *(volatile type *)addr = val; \
> +}
> +
> +MODERN_READ_DEF (8, uint8_t)
> +MODERN_WRITE_DEF(8, uint8_t)
> +
> +MODERN_READ_DEF (16, uint16_t)
> +MODERN_WRITE_DEF(16, uint16_t)
> +
> +MODERN_READ_DEF (32, uint32_t)
> +MODERN_WRITE_DEF(32, uint32_t)
> +
> +static inline void
> +modern_write64_twopart(uint64_t val, uint32_t *lo, uint32_t *hi)
> +{
> + modern_write32((uint32_t)val, lo);
> + modern_write32(val >> 32, hi);
> +}
> +
This is normal mmio read/write operation. ioread8/16/32/64 or just
readxx is more meaningful name here.
> +static void
[SNIP]
> +
> +static void
> +modern_write_dev_config(struct virtio_hw *hw, uint64_t offset,
> + void *src, int length)
define src as const
[snip]
>
> +static inline void *
> +get_cfg_addr(struct rte_pci_device *dev, struct virtio_pci_cap *cap)
No explicit inline for non performance critical functions.
> +{
> + uint8_t bar = cap->bar;
> + uint32_t length = cap->length;
> + uint32_t offset = cap->offset;
> + uint8_t *base;
> +
> + if (unlikely(bar > 5)) {
Don't use constant value number whenever possible
No likely/unlikely for non performance critical functions
> + PMD_INIT_LOG(ERR, "invalid bar: %u", bar);
> + return NULL;
> + }
> +
> + if (unlikely(offset + length > dev->mem_resource[bar].len)) {
> + PMD_INIT_LOG(ERR,
> + "invalid cap: overflows bar space: %u > %"PRIu64,
> + offset + length, dev->mem_resource[bar].len);
> + return NULL;
> + }
> +
> + base = dev->mem_resource[bar].addr;
> + if (unlikely(base == NULL)) {
> + PMD_INIT_LOG(ERR, "bar %u base addr is NULL", bar);
> + return NULL;
> + }
> +
> + return base + offset;
> +}
> +
> +static int
> +virtio_read_caps(struct rte_pci_device *dev, struct virtio_hw *hw)
> +{
> + uint8_t pos;
> + struct virtio_pci_cap cap;
> + int ret;
> +
> + if (rte_eal_pci_map_device(dev) < 0) {
> + PMD_INIT_LOG(DEBUG, "failed to map pci device!");
s /DEBUG/ERR/
> + return -1;
> + }
> +
> + ret = rte_eal_pci_read_config(dev, &pos, 1, PCI_CAPABILITY_LIST);
> +
[snip]
More information about the dev
mailing list