Thread (122 messages) 122 messages, 8 authors, 2016-02-03

Re: [PATCH v2 7/7] virtio: add 1.0 support

From: Xie, Huawei <hidden>
Date: 2016-01-14 07:50:09

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]
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help