So far virtio handle rw access for uio / ioport interface, This patch to extend the support for vfio interface.
Applicable for virtio 0.95 spec. Signed-off-by: Santosh Shukla <sshukla at mvista.com> --- v4--> v5: - Replaced virtio_rd/wr_1/2/4() macro implementation with inline function, per Yuan review commment. drivers/net/virtio/virtio_pci.c | 110 ++++++++++++++++++++++++++++++++++----- 1 file changed, 97 insertions(+), 13 deletions(-) diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c index a9f179f..0c29f1d 100644 --- a/drivers/net/virtio/virtio_pci.c +++ b/drivers/net/virtio/virtio_pci.c @@ -40,6 +40,7 @@ #include "virtio_pci.h" #include "virtio_logs.h" #include "virtqueue.h" +#include "virtio_vfio_rw.h" /* * Following macros are derieved from linux/pci_regs.h, however, @@ -49,24 +50,107 @@ #define PCI_CAPABILITY_LIST 0x34 #define PCI_CAP_ID_VNDR 0x09 - #define VIRTIO_PCI_REG_ADDR(hw, reg) \ (unsigned short)((hw)->io_base + (reg)) -#define VIRTIO_READ_REG_1(hw, reg) \ - inb((VIRTIO_PCI_REG_ADDR((hw), (reg)))) -#define VIRTIO_WRITE_REG_1(hw, reg, value) \ - outb_p((unsigned char)(value), (VIRTIO_PCI_REG_ADDR((hw), (reg)))) +static inline uint8_t +virtio_read_reg_1(struct virtio_hw *hw, uint64_t reg_offset) +{ + uint8_t ret; + struct rte_pci_device *dev; + + dev = hw->dev; + if (dev->kdrv == RTE_KDRV_VFIO) + ioport_inb(dev, reg_offset, &ret); + else + ret = inb(VIRTIO_PCI_REG_ADDR(hw, reg_offset)); + + return ret; +} + +static inline uint16_t +virtio_read_reg_2(struct virtio_hw *hw, uint64_t reg_offset) +{ + uint16_t ret; + struct rte_pci_device *dev; + + dev = hw->dev; + if (dev->kdrv == RTE_KDRV_VFIO) + ioport_inw(dev, reg_offset, &ret); + else + ret = inw(VIRTIO_PCI_REG_ADDR(hw, reg_offset)); + + return ret; +} + +static inline uint32_t +virtio_read_reg_4(struct virtio_hw *hw, uint64_t reg_offset) +{ + uint32_t ret; + struct rte_pci_device *dev; + + dev = hw->dev; + if (dev->kdrv == RTE_KDRV_VFIO) + ioport_inl(dev, reg_offset, &ret); + else + ret = inl(VIRTIO_PCI_REG_ADDR(hw, reg_offset)); + + return ret; +} + +static inline void +virtio_write_reg_1(struct virtio_hw *hw, uint64_t reg_offset, uint8_t value) +{ + struct rte_pci_device *dev; + + dev = hw->dev; + if (dev->kdrv == RTE_KDRV_VFIO) + ioport_outb_p(dev, reg_offset, value); + else + outb_p((unsigned char)value, + VIRTIO_PCI_REG_ADDR(hw, reg_offset)); +} + +static inline void +virtio_write_reg_2(struct virtio_hw *hw, uint64_t reg_offset, uint16_t value) +{ + struct rte_pci_device *dev; + + dev = hw->dev; + if (dev->kdrv == RTE_KDRV_VFIO) + ioport_outw_p(dev, reg_offset, value); + else + outw_p((unsigned short)value, + VIRTIO_PCI_REG_ADDR(hw, reg_offset)); +} + +static inline void +virtio_write_reg_4(struct virtio_hw *hw, uint64_t reg_offset, uint32_t value) +{ + struct rte_pci_device *dev; + + dev = hw->dev; + if (dev->kdrv == RTE_KDRV_VFIO) + ioport_outl_p(dev, reg_offset, value); + else + outl_p((unsigned int)value, + VIRTIO_PCI_REG_ADDR(hw, reg_offset)); +} + +#define VIRTIO_READ_REG_1(hw, reg) \ + virtio_read_reg_1((hw), (reg)) +#define VIRTIO_WRITE_REG_1(hw, reg, value) \ + virtio_write_reg_1((hw), (reg), (value)) -#define VIRTIO_READ_REG_2(hw, reg) \ - inw((VIRTIO_PCI_REG_ADDR((hw), (reg)))) -#define VIRTIO_WRITE_REG_2(hw, reg, value) \ - outw_p((unsigned short)(value), (VIRTIO_PCI_REG_ADDR((hw), (reg)))) +#define VIRTIO_READ_REG_2(hw, reg) \ + virtio_read_reg_2((hw), (reg)) +#define VIRTIO_WRITE_REG_2(hw, reg, value) \ + virtio_write_reg_2((hw), (reg), (value)) -#define VIRTIO_READ_REG_4(hw, reg) \ - inl((VIRTIO_PCI_REG_ADDR((hw), (reg)))) -#define VIRTIO_WRITE_REG_4(hw, reg, value) \ - outl_p((unsigned int)(value), (VIRTIO_PCI_REG_ADDR((hw), (reg)))) +#define VIRTIO_READ_REG_4(hw, reg) \ + virtio_read_reg_4((hw), (reg)) +#define VIRTIO_WRITE_REG_4(hw, reg, value) \ + virtio_write_reg_4((hw), (reg), (value)) static void legacy_read_dev_config(struct virtio_hw *hw, uint64_t offset, -- 1.7.9.5