DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH] pci: support both io and mmio bar for legacy virtio on x86
@ 2020-09-14  3:19 谢华伟(此时此刻)
  2020-09-14  3:42 ` 谢华伟(此时此刻)
  0 siblings, 1 reply; 4+ messages in thread
From: 谢华伟(此时此刻) @ 2020-09-14  3:19 UTC (permalink / raw)
  To: ferruh.yigit, Wang, Zhihong, Xia, Chenbo; +Cc: dev

Signed-off-by: huawei.xhw <huawei.xhw@alibaba-inc.com>
---

 drivers/bus/pci/linux/pci.c     |  71 ------------------

 drivers/bus/pci/linux/pci_uio.c | 154 +++++++++++++++++++++++++++-------------

 2 files changed, 106 insertions(+), 119 deletions(-)



diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c

index a2198ab..619dfec 100644

--- a/drivers/bus/pci/linux/pci.c

+++ b/drivers/bus/pci/linux/pci.c

@@ -687,71 +687,6 @@ int rte_pci_write_config(const struct rte_pci_device *device,

        }

 }



-#if defined(RTE_ARCH_X86)

-static int

-pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,

-               struct rte_pci_ioport *p)

-{

-       uint16_t start, end;

-       FILE *fp;

-       char *line = NULL;

-       char pci_id[16];

-       int found = 0;

-       size_t linesz;

-

-       if (rte_eal_iopl_init() != 0) {

-               RTE_LOG(ERR, EAL, "%s(): insufficient ioport permissions for PCI device %s\n",

-                       __func__, dev->name);

-               return -1;

-       }

-

-       snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,

-                dev->addr.domain, dev->addr.bus,

-                dev->addr.devid, dev->addr.function);

-

-       fp = fopen("/proc/ioports", "r");

-       if (fp == NULL) {

-               RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__);

-               return -1;

-       }

-

-       while (getdelim(&line, &linesz, '\n', fp) > 0) {

-               char *ptr = line;

-               char *left;

-               int n;

-

-               n = strcspn(ptr, ":");

-               ptr[n] = 0;

-               left = &ptr[n + 1];

-

-               while (*left && isspace(*left))

-                       left++;

-

-               if (!strncmp(left, pci_id, strlen(pci_id))) {

-                       found = 1;

-

-                       while (*ptr && isspace(*ptr))

-                               ptr++;

-

-                       sscanf(ptr, "%04hx-%04hx", &start, &end);

-

-                       break;

-               }

-       }

-

-       free(line);

-       fclose(fp);

-

-       if (!found)

-               return -1;

-

-       p->base = start;

-       RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start);

-

-       return 0;

-}

-#endif

-

 int

 rte_pci_ioport_map(struct rte_pci_device *dev, int bar,

                struct rte_pci_ioport *p)

@@ -766,14 +701,8 @@ int rte_pci_write_config(const struct rte_pci_device *device,

                break;

 #endif

        case RTE_KDRV_IGB_UIO:

-               ret = pci_uio_ioport_map(dev, bar, p);

-               break;

        case RTE_KDRV_UIO_GENERIC:

-#if defined(RTE_ARCH_X86)

-               ret = pci_ioport_map(dev, bar, p);

-#else

                ret = pci_uio_ioport_map(dev, bar, p);

-#endif

                break;

        default:

                break;

diff --git a/drivers/bus/pci/linux/pci_uio.c b/drivers/bus/pci/linux/pci_uio.c

index 097dc19..67ddbc0 100644

--- a/drivers/bus/pci/linux/pci_uio.c

+++ b/drivers/bus/pci/linux/pci_uio.c

@@ -372,12 +372,50 @@

 pci_uio_ioport_map(struct rte_pci_device *dev, int bar,

                   struct rte_pci_ioport *p)

 {

+       FILE *f;

        char dirname[PATH_MAX];

        char filename[PATH_MAX];

+       char buf[BUFSIZ];

+       uint64_t phys_addr, end_addr, flags;

        int uio_num;

-       unsigned long start;

+       unsigned long base;

+       bool iobar;

+       int i;



-       if (rte_eal_iopl_init() != 0) {

+       /* open and read addresses of the corresponding resource in sysfs */

+       snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource",

+               rte_pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,

+               dev->addr.devid, dev->addr.function);

+       f = fopen(filename, "r");

+       if (f == NULL) {

+               RTE_LOG(ERR, EAL, "Cannot open sysfs resource: %s\n",

+                       strerror(errno));

+               return -1;

+       }

+       for (i = 0; i < bar + 1; i++) {

+               if (fgets(buf, sizeof(buf), f) == NULL) {

+                       RTE_LOG(ERR, EAL, "Cannot read sysfs resource\n");

+                       goto error;

+               }

+       }

+       if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,

+                       &end_addr, &flags) < 0)

+               goto error;

+

+       if (flags & IORESOURCE_IO) {

+               iobar = 1;

+               base = (unsigned long)phys_addr;

+               RTE_LOG(INFO, EAL, "%s(): iobar %08lx detected\n", __func__, base);

+       } else if (flags & IORESOURCE_MEM) {

+               iobar = 0;

+               base = (unsigned long)dev->mem_resource[bar].addr;

+               RTE_LOG(INFO, EAL, "%s():membar %08lx detected\n", __func__, base);

+       } else {

+               RTE_LOG(ERR, EAL, "%s(): unknow bar type\n", __func__);

+               goto error;

+       }

+

+       if (iobar && rte_eal_iopl_init() != 0) {

                RTE_LOG(ERR, EAL, "%s(): insufficient ioport permissions for PCI device %s\n",

                        __func__, dev->name);

                return -1;

@@ -387,22 +425,8 @@

        if (uio_num < 0)

                return -1;



-       /* get portio start */

-       snprintf(filename, sizeof(filename),

-                "%s/portio/port%d/start", dirname, bar);

-       if (eal_parse_sysfs_value(filename, &start) < 0) {

-               RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",

-                       __func__);

-               return -1;

-       }

-       /* ensure we don't get anything funny here, read/write will cast to

-        * uin16_t */

-       if (start > UINT16_MAX)

-               return -1;

-

        /* FIXME only for primary process ? */

        if (dev->intr_handle.type == RTE_INTR_HANDLE_UNKNOWN) {

-

                snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);

                dev->intr_handle.fd = open(filename, O_RDWR);

                if (dev->intr_handle.fd < 0) {

@@ -413,11 +437,14 @@

                dev->intr_handle.type = RTE_INTR_HANDLE_UIO;

        }



-       RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", start);

+       RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", base);



-       p->base = start;

+       p->base = base;

        p->len = 0;

        return 0;

+error:

+       fclose(f);

+       return -1;

 }

 #else

 int

@@ -488,6 +515,61 @@

 }

 #endif



+#define PIO_MAX 0x10000

+static inline uint8_t ioread8(void *addr)

+{

+       uint8_t val;

+

+       val = (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint8_t *)addr :

+               inb((unsigned long)addr);

+

+       return val;

+}

+

+static inline uint16_t ioread16(void *addr)

+{

+       uint16_t val;

+

+       val = (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint16_t *)addr :

+               inw((unsigned long)addr);

+

+       return val;

+}

+

+static inline uint32_t ioread32(void *addr)

+{

+       uint32_t val;

+

+       val = (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint32_t *)addr :

+               inl((unsigned long)addr);

+

+       return val;

+}

+

+static inline void iowrite8(uint8_t val, void *addr)

+{

+       (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint8_t *)addr = val :

+               outb(val, (unsigned long)addr);

+}

+

+static inline void iowrite16(uint16_t val, void *addr)

+{

+       (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint16_t *)addr = val :

+               outw(val, (unsigned long)addr);

+}

+

+static inline void iowrite32(uint32_t val, void *addr)

+{

+       (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint32_t *)addr = val :

+               outl(val, (unsigned long)addr);

+}

+

 void

 pci_uio_ioport_read(struct rte_pci_ioport *p,

                    void *data, size_t len, off_t offset)

@@ -499,25 +581,13 @@

        for (d = data; len > 0; d += size, reg += size, len -= size) {

                if (len >= 4) {

                        size = 4;

-#if defined(RTE_ARCH_X86)

-                       *(uint32_t *)d = inl(reg);

-#else

-                       *(uint32_t *)d = *(volatile uint32_t *)reg;

-#endif

+                       *(uint32_t *)d = ioread32((void *)reg);

                } else if (len >= 2) {

                        size = 2;

-#if defined(RTE_ARCH_X86)

-                       *(uint16_t *)d = inw(reg);

-#else

-                       *(uint16_t *)d = *(volatile uint16_t *)reg;

-#endif

+                       *(uint16_t *)d = ioread16((void *)reg);

                } else {

                        size = 1;

-#if defined(RTE_ARCH_X86)

-                       *d = inb(reg);

-#else

-                       *d = *(volatile uint8_t *)reg;

-#endif

+                       *d = ioread8((void *)reg);

                }

        }

 }

@@ -533,25 +603,13 @@

        for (s = data; len > 0; s += size, reg += size, len -= size) {

                if (len >= 4) {

                        size = 4;

-#if defined(RTE_ARCH_X86)

-                       outl_p(*(const uint32_t *)s, reg);

-#else

-                       *(volatile uint32_t *)reg = *(const uint32_t *)s;

-#endif

+                       iowrite32(*(const uint32_t *)s, (void *)reg);

                } else if (len >= 2) {

                        size = 2;

-#if defined(RTE_ARCH_X86)

-                       outw_p(*(const uint16_t *)s, reg);

-#else

-                       *(volatile uint16_t *)reg = *(const uint16_t *)s;

-#endif

+                       iowrite16(*(const uint16_t *)s, (void *)reg);

                } else {

                        size = 1;

-#if defined(RTE_ARCH_X86)

-                       outb_p(*s, reg);

-#else

-                       *(volatile uint8_t *)reg = *s;

-#endif

+                       iowrite8(*s, (void *)reg);

                }

        }

 }

--

1.8.3.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [dpdk-dev] [PATCH] pci: support both io and mmio bar for legacy virtio on x86
  2020-09-14  3:19 [dpdk-dev] [PATCH] pci: support both io and mmio bar for legacy virtio on x86 谢华伟(此时此刻)
@ 2020-09-14  3:42 ` 谢华伟(此时此刻)
  0 siblings, 0 replies; 4+ messages in thread
From: 谢华伟(此时此刻) @ 2020-09-14  3:42 UTC (permalink / raw)
  To: Chris, ferruh.yigit, Wang, Zhihong, Xia, Chenbo, thomas; +Cc: dev, HANG



Hi Ferruy:
Resent the patch.
This patch is to support both MMIO and PIO bar for legacy virtio. We use MMIO bar for legacy virtio on x86 because we create lots of virtio devices as PIO resource is very limited.
virtio is the only PMD which might use PIO. kernel virtio-pci driver supports both PIO bar and MMIO bar. This patch handles MMIO and PIO in the same way.

------------------------------------------------------------------
From:Chris <huawei.xhw@alibaba-inc.com>
Sent At:2020 Sep. 14 (Mon.) 11:19
To:ferruh.yigit <ferruh.yigit@intel.com>; "Wang, Zhihong" <zhihong.wang@intel.com>; "Xia, Chenbo" <chenbo.xia@intel.com>
Cc:dev <dev@dpdk.org>
Subject:[PATCH] pci: support both io and mmio bar for legacy virtio on x86


Signed-off-by: huawei.xhw <huawei.xhw@alibaba-inc.com>
---

 drivers/bus/pci/linux/pci.c     |  71 ------------------

 drivers/bus/pci/linux/pci_uio.c | 154 +++++++++++++++++++++++++++-------------

 2 files changed, 106 insertions(+), 119 deletions(-)



diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c

index a2198ab..619dfec 100644

--- a/drivers/bus/pci/linux/pci.c

+++ b/drivers/bus/pci/linux/pci.c

@@ -687,71 +687,6 @@ int rte_pci_write_config(const struct rte_pci_device *device,

        }

 }



-#if defined(RTE_ARCH_X86)

-static int

-pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,

-               struct rte_pci_ioport *p)

-{

-       uint16_t start, end;

-       FILE *fp;

-       char *line = NULL;

-       char pci_id[16];

-       int found = 0;

-       size_t linesz;

-

-       if (rte_eal_iopl_init() != 0) {

-               RTE_LOG(ERR, EAL, "%s(): insufficient ioport permissions for PCI device %s\n",

-                       __func__, dev->name);

-               return -1;

-       }

-

-       snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,

-                dev->addr.domain, dev->addr.bus,

-                dev->addr.devid, dev->addr.function);

-

-       fp = fopen("/proc/ioports", "r");

-       if (fp == NULL) {

-               RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__);

-               return -1;

-       }

-

-       while (getdelim(&line, &linesz, '\n', fp) > 0) {

-               char *ptr = line;

-               char *left;

-               int n;

-

-               n = strcspn(ptr, ":");

-               ptr[n] = 0;

-               left = &ptr[n + 1];

-

-               while (*left && isspace(*left))

-                       left++;

-

-               if (!strncmp(left, pci_id, strlen(pci_id))) {

-                       found = 1;

-

-                       while (*ptr && isspace(*ptr))

-                               ptr++;

-

-                       sscanf(ptr, "%04hx-%04hx", &start, &end);

-

-                       break;

-               }

-       }

-

-       free(line);

-       fclose(fp);

-

-       if (!found)

-               return -1;

-

-       p->base = start;

-       RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start);

-

-       return 0;

-}

-#endif

-

 int

 rte_pci_ioport_map(struct rte_pci_device *dev, int bar,

                struct rte_pci_ioport *p)

@@ -766,14 +701,8 @@ int rte_pci_write_config(const struct rte_pci_device *device,

                break;

 #endif

        case RTE_KDRV_IGB_UIO:

-               ret = pci_uio_ioport_map(dev, bar, p);

-               break;

        case RTE_KDRV_UIO_GENERIC:

-#if defined(RTE_ARCH_X86)

-               ret = pci_ioport_map(dev, bar, p);

-#else

                ret = pci_uio_ioport_map(dev, bar, p);

-#endif

                break;

        default:

                break;

diff --git a/drivers/bus/pci/linux/pci_uio.c b/drivers/bus/pci/linux/pci_uio.c

index 097dc19..67ddbc0 100644

--- a/drivers/bus/pci/linux/pci_uio.c

+++ b/drivers/bus/pci/linux/pci_uio.c

@@ -372,12 +372,50 @@

 pci_uio_ioport_map(struct rte_pci_device *dev, int bar,

                   struct rte_pci_ioport *p)

 {

+       FILE *f;

        char dirname[PATH_MAX];

        char filename[PATH_MAX];

+       char buf[BUFSIZ];

+       uint64_t phys_addr, end_addr, flags;

        int uio_num;

-       unsigned long start;

+       unsigned long base;

+       bool iobar;

+       int i;



-       if (rte_eal_iopl_init() != 0) {

+       /* open and read addresses of the corresponding resource in sysfs */

+       snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource",

+               rte_pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,

+               dev->addr.devid, dev->addr.function);

+       f = fopen(filename, "r");

+       if (f == NULL) {

+               RTE_LOG(ERR, EAL, "Cannot open sysfs resource: %s\n",

+                       strerror(errno));

+               return -1;

+       }

+       for (i = 0; i < bar + 1; i++) {

+               if (fgets(buf, sizeof(buf), f) == NULL) {

+                       RTE_LOG(ERR, EAL, "Cannot read sysfs resource\n");

+                       goto error;

+               }

+       }

+       if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,

+                       &end_addr, &flags) < 0)

+               goto error;

+

+       if (flags & IORESOURCE_IO) {

+               iobar = 1;

+               base = (unsigned long)phys_addr;

+               RTE_LOG(INFO, EAL, "%s(): iobar %08lx detected\n", __func__, base);

+       } else if (flags & IORESOURCE_MEM) {

+               iobar = 0;

+               base = (unsigned long)dev->mem_resource[bar].addr;

+               RTE_LOG(INFO, EAL, "%s():membar %08lx detected\n", __func__, base);

+       } else {

+               RTE_LOG(ERR, EAL, "%s(): unknow bar type\n", __func__);

+               goto error;

+       }

+

+       if (iobar && rte_eal_iopl_init() != 0) {

                RTE_LOG(ERR, EAL, "%s(): insufficient ioport permissions for PCI device %s\n",

                        __func__, dev->name);

                return -1;

@@ -387,22 +425,8 @@

        if (uio_num < 0)

                return -1;



-       /* get portio start */

-       snprintf(filename, sizeof(filename),

-                "%s/portio/port%d/start", dirname, bar);

-       if (eal_parse_sysfs_value(filename, &start) < 0) {

-               RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",

-                       __func__);

-               return -1;

-       }

-       /* ensure we don't get anything funny here, read/write will cast to

-        * uin16_t */

-       if (start > UINT16_MAX)

-               return -1;

-

        /* FIXME only for primary process ? */

        if (dev->intr_handle.type == RTE_INTR_HANDLE_UNKNOWN) {

-

                snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);

                dev->intr_handle.fd = open(filename, O_RDWR);

                if (dev->intr_handle.fd < 0) {

@@ -413,11 +437,14 @@

                dev->intr_handle.type = RTE_INTR_HANDLE_UIO;

        }



-       RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", start);

+       RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", base);



-       p->base = start;

+       p->base = base;

        p->len = 0;

        return 0;

+error:

+       fclose(f);

+       return -1;

 }

 #else

 int

@@ -488,6 +515,61 @@

 }

 #endif



+#define PIO_MAX 0x10000

+static inline uint8_t ioread8(void *addr)

+{

+       uint8_t val;

+

+       val = (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint8_t *)addr :

+               inb((unsigned long)addr);

+

+       return val;

+}

+

+static inline uint16_t ioread16(void *addr)

+{

+       uint16_t val;

+

+       val = (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint16_t *)addr :

+               inw((unsigned long)addr);

+

+       return val;

+}

+

+static inline uint32_t ioread32(void *addr)

+{

+       uint32_t val;

+

+       val = (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint32_t *)addr :

+               inl((unsigned long)addr);

+

+       return val;

+}

+

+static inline void iowrite8(uint8_t val, void *addr)

+{

+       (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint8_t *)addr = val :

+               outb(val, (unsigned long)addr);

+}

+

+static inline void iowrite16(uint16_t val, void *addr)

+{

+       (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint16_t *)addr = val :

+               outw(val, (unsigned long)addr);

+}

+

+static inline void iowrite32(uint32_t val, void *addr)

+{

+       (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint32_t *)addr = val :

+               outl(val, (unsigned long)addr);

+}

+

 void

 pci_uio_ioport_read(struct rte_pci_ioport *p,

                    void *data, size_t len, off_t offset)

@@ -499,25 +581,13 @@

        for (d = data; len > 0; d += size, reg += size, len -= size) {

                if (len >= 4) {

                        size = 4;

-#if defined(RTE_ARCH_X86)

-                       *(uint32_t *)d = inl(reg);

-#else

-                       *(uint32_t *)d = *(volatile uint32_t *)reg;

-#endif

+                       *(uint32_t *)d = ioread32((void *)reg);

                } else if (len >= 2) {

                        size = 2;

-#if defined(RTE_ARCH_X86)

-                       *(uint16_t *)d = inw(reg);

-#else

-                       *(uint16_t *)d = *(volatile uint16_t *)reg;

-#endif

+                       *(uint16_t *)d = ioread16((void *)reg);

                } else {

                        size = 1;

-#if defined(RTE_ARCH_X86)

-                       *d = inb(reg);

-#else

-                       *d = *(volatile uint8_t *)reg;

-#endif

+                       *d = ioread8((void *)reg);

                }

        }

 }

@@ -533,25 +603,13 @@

        for (s = data; len > 0; s += size, reg += size, len -= size) {

                if (len >= 4) {

                        size = 4;

-#if defined(RTE_ARCH_X86)

-                       outl_p(*(const uint32_t *)s, reg);

-#else

-                       *(volatile uint32_t *)reg = *(const uint32_t *)s;

-#endif

+                       iowrite32(*(const uint32_t *)s, (void *)reg);

                } else if (len >= 2) {

                        size = 2;

-#if defined(RTE_ARCH_X86)

-                       outw_p(*(const uint16_t *)s, reg);

-#else

-                       *(volatile uint16_t *)reg = *(const uint16_t *)s;

-#endif

+                       iowrite16(*(const uint16_t *)s, (void *)reg);

                } else {

                        size = 1;

-#if defined(RTE_ARCH_X86)

-                       outb_p(*s, reg);

-#else

-                       *(volatile uint8_t *)reg = *s;

-#endif

+                       iowrite8(*s, (void *)reg);

                }

        }

 }

--

1.8.3.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [dpdk-dev] [PATCH] pci: support both io and mmio bar for legacy virtio on x86
       [not found] ` <19b35451-45bb-4090-a3cf-31954d7c9c44.>
@ 2020-09-11 14:56   ` 谢华伟(此时此刻)
  0 siblings, 0 replies; 4+ messages in thread
From: 谢华伟(此时此刻) @ 2020-09-11 14:56 UTC (permalink / raw)
  To: Chris, ferruh.yigit; +Cc: dev, Wang, Zhihong, Xia, Chenbo


Hi Ferruh:
This patch is to support both MMIO and PIO bar for legacy virtio. We use MM bar for legacy virtio on x86 because we create lots of virtio devices as PIO resource is very limited.
virtio on x86 is the only PMD which might use PIO. kernel virtio-pci driver supports both PIO bar and MMIO bar. This patch handles MMIO and PIO in the same way.



------------------------------------------------------------------
From:Chris <huawei.xhw@alibaba-inc.com>
Sent At:2020 Sep. 11 (Fri.) 20:57
To:ferruh.yigit <ferruh.yigit@intel.com>
Cc:dev <dev@dpdk.org>; "Wang, Zhihong" <zhihong.wang@intel.com>; "Xia, Chenbo" <chenbo.xia@intel.com>
Subject:[PATCH] pci: support both io and mmio bar for legacy virtio on x86

Signed-off-by: huawei.xhw <huawei.xhw@alibaba-inc.com>

---

 drivers/bus/pci/linux/pci.c     |  71 ------------------

 drivers/bus/pci/linux/pci_uio.c | 154 +++++++++++++++++++++++++++-------------

 2 files changed, 106 insertions(+), 119 deletions(-)



diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c

index a2198ab..619dfec 100644

--- a/drivers/bus/pci/linux/pci.c

+++ b/drivers/bus/pci/linux/pci.c

@@ -687,71 +687,6 @@ int rte_pci_write_config(const struct rte_pci_device *device,

        }

 }



-#if defined(RTE_ARCH_X86)

-static int

-pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,

-               struct rte_pci_ioport *p)

-{

-       uint16_t start, end;

-       FILE *fp;

-       char *line = NULL;

-       char pci_id[16];

-       int found = 0;

-       size_t linesz;

-

-       if (rte_eal_iopl_init() != 0) {

-               RTE_LOG(ERR, EAL, "%s(): insufficient ioport permissions for PCI device %s\n",

-                       __func__, dev->name);

-               return -1;

-       }

-

-       snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,

-                dev->addr.domain, dev->addr.bus,

-                dev->addr.devid, dev->addr.function);

-

-       fp = fopen("/proc/ioports", "r");

-       if (fp == NULL) {

-               RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__);

-               return -1;

-       }

-

-       while (getdelim(&line, &linesz, '\n', fp) > 0) {

-               char *ptr = line;

-               char *left;

-               int n;

-

-               n = strcspn(ptr, ":");

-               ptr[n] = 0;

-               left = &ptr[n + 1];

-

-               while (*left && isspace(*left))

-                       left++;

-

-               if (!strncmp(left, pci_id, strlen(pci_id))) {

-                       found = 1;

-

-                       while (*ptr && isspace(*ptr))

-                               ptr++;

-

-                       sscanf(ptr, "%04hx-%04hx", &start, &end);

-

-                       break;

-               }

-       }

-

-       free(line);

-       fclose(fp);

-

-       if (!found)

-               return -1;

-

-       p->base = start;

-       RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start);

-

-       return 0;

-}

-#endif

-

 int

 rte_pci_ioport_map(struct rte_pci_device *dev, int bar,

                struct rte_pci_ioport *p)

@@ -766,14 +701,8 @@ int rte_pci_write_config(const struct rte_pci_device *device,

                break;

 #endif

        case RTE_KDRV_IGB_UIO:

-               ret = pci_uio_ioport_map(dev, bar, p);

-               break;

        case RTE_KDRV_UIO_GENERIC:

-#if defined(RTE_ARCH_X86)

-               ret = pci_ioport_map(dev, bar, p);

-#else

                ret = pci_uio_ioport_map(dev, bar, p);

-#endif

                break;

        default:

                break;

diff --git a/drivers/bus/pci/linux/pci_uio.c b/drivers/bus/pci/linux/pci_uio.c

index 097dc19..67ddbc0 100644

--- a/drivers/bus/pci/linux/pci_uio.c

+++ b/drivers/bus/pci/linux/pci_uio.c

@@ -372,12 +372,50 @@

 pci_uio_ioport_map(struct rte_pci_device *dev, int bar,

                   struct rte_pci_ioport *p)

 {

+       FILE *f;

        char dirname[PATH_MAX];

        char filename[PATH_MAX];

+       char buf[BUFSIZ];

+       uint64_t phys_addr, end_addr, flags;

        int uio_num;

-       unsigned long start;

+       unsigned long base;

+       bool iobar;

+       int i;



-       if (rte_eal_iopl_init() != 0) {

+       /* open and read addresses of the corresponding resource in sysfs */

+       snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource",

+               rte_pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,

+               dev->addr.devid, dev->addr.function);

+       f = fopen(filename, "r");

+       if (f == NULL) {

+               RTE_LOG(ERR, EAL, "Cannot open sysfs resource: %s\n",

+                       strerror(errno));

+               return -1;

+       }

+       for (i = 0; i < bar + 1; i++) {

+               if (fgets(buf, sizeof(buf), f) == NULL) {

+                       RTE_LOG(ERR, EAL, "Cannot read sysfs resource\n");

+                       goto error;

+               }

+       }

+       if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,

+                       &end_addr, &flags) < 0)

+               goto error;

+

+       if (flags & IORESOURCE_IO) {

+               iobar = 1;

+               base = (unsigned long)phys_addr;

+               RTE_LOG(INFO, EAL, "%s(): iobar %08lx detected\n", __func__, base);

+       } else if (flags & IORESOURCE_MEM) {

+               iobar = 0;

+               base = (unsigned long)dev->mem_resource[bar].addr;

+               RTE_LOG(INFO, EAL, "%s():membar %08lx detected\n", __func__, base);

+       } else {

+               RTE_LOG(ERR, EAL, "%s(): unknow bar type\n", __func__);

+               goto error;

+       }

+

+       if (iobar && rte_eal_iopl_init() != 0) {

                RTE_LOG(ERR, EAL, "%s(): insufficient ioport permissions for PCI device %s\n",

                        __func__, dev->name);

                return -1;

@@ -387,22 +425,8 @@

        if (uio_num < 0)

                return -1;



-       /* get portio start */

-       snprintf(filename, sizeof(filename),

-                "%s/portio/port%d/start", dirname, bar);

-       if (eal_parse_sysfs_value(filename, &start) < 0) {

-               RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",

-                       __func__);

-               return -1;

-       }

-       /* ensure we don't get anything funny here, read/write will cast to

-        * uin16_t */

-       if (start > UINT16_MAX)

-               return -1;

-

        /* FIXME only for primary process ? */

        if (dev->intr_handle.type == RTE_INTR_HANDLE_UNKNOWN) {

-

                snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);

                dev->intr_handle.fd = open(filename, O_RDWR);

                if (dev->intr_handle.fd < 0) {

@@ -413,11 +437,14 @@

                dev->intr_handle.type = RTE_INTR_HANDLE_UIO;

        }



-       RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", start);

+       RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", base);



-       p->base = start;

+       p->base = base;

        p->len = 0;

        return 0;

+error:

+       fclose(f);

+       return -1;

 }

 #else

 int

@@ -488,6 +515,61 @@

 }

 #endif



+#define PIO_MAX 0x10000

+static inline uint8_t ioread8(void *addr)

+{

+       uint8_t val;

+

+       val = (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint8_t *)addr :

+               inb((unsigned long)addr);

+

+       return val;

+}

+

+static inline uint16_t ioread16(void *addr)

+{

+       uint16_t val;

+

+       val = (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint16_t *)addr :

+               inw((unsigned long)addr);

+

+       return val;

+}

+

+static inline uint32_t ioread32(void *addr)

+{

+       uint32_t val;

+

+       val = (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint32_t *)addr :

+               inl((unsigned long)addr);

+

+       return val;

+}

+

+static inline void iowrite8(uint8_t val, void *addr)

+{

+       (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint8_t *)addr = val :

+               outb(val, (unsigned long)addr);

+}

+

+static inline void iowrite16(uint16_t val, void *addr)

+{

+       (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint16_t *)addr = val :

+               outw(val, (unsigned long)addr);

+}

+

+static inline void iowrite32(uint32_t val, void *addr)

+{

+       (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint32_t *)addr = val :

+               outl(val, (unsigned long)addr);

+}

+

 void

 pci_uio_ioport_read(struct rte_pci_ioport *p,

                    void *data, size_t len, off_t offset)

@@ -499,25 +581,13 @@

        for (d = data; len > 0; d += size, reg += size, len -= size) {

                if (len >= 4) {

                        size = 4;

-#if defined(RTE_ARCH_X86)

-                       *(uint32_t *)d = inl(reg);

-#else

-                       *(uint32_t *)d = *(volatile uint32_t *)reg;

-#endif

+                       *(uint32_t *)d = ioread32((void *)reg);

                } else if (len >= 2) {

                        size = 2;

-#if defined(RTE_ARCH_X86)

-                       *(uint16_t *)d = inw(reg);

-#else

-                       *(uint16_t *)d = *(volatile uint16_t *)reg;

-#endif

+                       *(uint16_t *)d = ioread16((void *)reg);

                } else {

                        size = 1;

-#if defined(RTE_ARCH_X86)

-                       *d = inb(reg);

-#else

-                       *d = *(volatile uint8_t *)reg;

-#endif

+                       *d = ioread8((void *)reg);

                }

        }

 }

@@ -533,25 +603,13 @@

        for (s = data; len > 0; s += size, reg += size, len -= size) {

                if (len >= 4) {

                        size = 4;

-#if defined(RTE_ARCH_X86)

-                       outl_p(*(const uint32_t *)s, reg);

-#else

-                       *(volatile uint32_t *)reg = *(const uint32_t *)s;

-#endif

+                       iowrite32(*(const uint32_t *)s, (void *)reg);

                } else if (len >= 2) {

                        size = 2;

-#if defined(RTE_ARCH_X86)

-                       outw_p(*(const uint16_t *)s, reg);

-#else

-                       *(volatile uint16_t *)reg = *(const uint16_t *)s;

-#endif

+                       iowrite16(*(const uint16_t *)s, (void *)reg);

                } else {

                        size = 1;

-#if defined(RTE_ARCH_X86)

-                       outb_p(*s, reg);

-#else

-                       *(volatile uint8_t *)reg = *s;

-#endif

+                       iowrite8(*s, (void *)reg);

                }

        }

 }

--

1.8.3.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [dpdk-dev] [PATCH] pci: support both io and mmio bar for legacy virtio on x86
@ 2020-09-11 12:57 谢华伟(此时此刻)
       [not found] ` <19b35451-45bb-4090-a3cf-31954d7c9c44.>
  0 siblings, 1 reply; 4+ messages in thread
From: 谢华伟(此时此刻) @ 2020-09-11 12:57 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: dev, Wang, Zhihong, Xia, Chenbo

Signed-off-by: huawei.xhw <huawei.xhw@alibaba-inc.com>

---

 drivers/bus/pci/linux/pci.c     |  71 ------------------

 drivers/bus/pci/linux/pci_uio.c | 154 +++++++++++++++++++++++++++-------------

 2 files changed, 106 insertions(+), 119 deletions(-)



diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c

index a2198ab..619dfec 100644

--- a/drivers/bus/pci/linux/pci.c

+++ b/drivers/bus/pci/linux/pci.c

@@ -687,71 +687,6 @@ int rte_pci_write_config(const struct rte_pci_device *device,

        }

 }



-#if defined(RTE_ARCH_X86)

-static int

-pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,

-               struct rte_pci_ioport *p)

-{

-       uint16_t start, end;

-       FILE *fp;

-       char *line = NULL;

-       char pci_id[16];

-       int found = 0;

-       size_t linesz;

-

-       if (rte_eal_iopl_init() != 0) {

-               RTE_LOG(ERR, EAL, "%s(): insufficient ioport permissions for PCI device %s\n",

-                       __func__, dev->name);

-               return -1;

-       }

-

-       snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,

-                dev->addr.domain, dev->addr.bus,

-                dev->addr.devid, dev->addr.function);

-

-       fp = fopen("/proc/ioports", "r");

-       if (fp == NULL) {

-               RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__);

-               return -1;

-       }

-

-       while (getdelim(&line, &linesz, '\n', fp) > 0) {

-               char *ptr = line;

-               char *left;

-               int n;

-

-               n = strcspn(ptr, ":");

-               ptr[n] = 0;

-               left = &ptr[n + 1];

-

-               while (*left && isspace(*left))

-                       left++;

-

-               if (!strncmp(left, pci_id, strlen(pci_id))) {

-                       found = 1;

-

-                       while (*ptr && isspace(*ptr))

-                               ptr++;

-

-                       sscanf(ptr, "%04hx-%04hx", &start, &end);

-

-                       break;

-               }

-       }

-

-       free(line);

-       fclose(fp);

-

-       if (!found)

-               return -1;

-

-       p->base = start;

-       RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start);

-

-       return 0;

-}

-#endif

-

 int

 rte_pci_ioport_map(struct rte_pci_device *dev, int bar,

                struct rte_pci_ioport *p)

@@ -766,14 +701,8 @@ int rte_pci_write_config(const struct rte_pci_device *device,

                break;

 #endif

        case RTE_KDRV_IGB_UIO:

-               ret = pci_uio_ioport_map(dev, bar, p);

-               break;

        case RTE_KDRV_UIO_GENERIC:

-#if defined(RTE_ARCH_X86)

-               ret = pci_ioport_map(dev, bar, p);

-#else

                ret = pci_uio_ioport_map(dev, bar, p);

-#endif

                break;

        default:

                break;

diff --git a/drivers/bus/pci/linux/pci_uio.c b/drivers/bus/pci/linux/pci_uio.c

index 097dc19..67ddbc0 100644

--- a/drivers/bus/pci/linux/pci_uio.c

+++ b/drivers/bus/pci/linux/pci_uio.c

@@ -372,12 +372,50 @@

 pci_uio_ioport_map(struct rte_pci_device *dev, int bar,

                   struct rte_pci_ioport *p)

 {

+       FILE *f;

        char dirname[PATH_MAX];

        char filename[PATH_MAX];

+       char buf[BUFSIZ];

+       uint64_t phys_addr, end_addr, flags;

        int uio_num;

-       unsigned long start;

+       unsigned long base;

+       bool iobar;

+       int i;



-       if (rte_eal_iopl_init() != 0) {

+       /* open and read addresses of the corresponding resource in sysfs */

+       snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource",

+               rte_pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,

+               dev->addr.devid, dev->addr.function);

+       f = fopen(filename, "r");

+       if (f == NULL) {

+               RTE_LOG(ERR, EAL, "Cannot open sysfs resource: %s\n",

+                       strerror(errno));

+               return -1;

+       }

+       for (i = 0; i < bar + 1; i++) {

+               if (fgets(buf, sizeof(buf), f) == NULL) {

+                       RTE_LOG(ERR, EAL, "Cannot read sysfs resource\n");

+                       goto error;

+               }

+       }

+       if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,

+                       &end_addr, &flags) < 0)

+               goto error;

+

+       if (flags & IORESOURCE_IO) {

+               iobar = 1;

+               base = (unsigned long)phys_addr;

+               RTE_LOG(INFO, EAL, "%s(): iobar %08lx detected\n", __func__, base);

+       } else if (flags & IORESOURCE_MEM) {

+               iobar = 0;

+               base = (unsigned long)dev->mem_resource[bar].addr;

+               RTE_LOG(INFO, EAL, "%s():membar %08lx detected\n", __func__, base);

+       } else {

+               RTE_LOG(ERR, EAL, "%s(): unknow bar type\n", __func__);

+               goto error;

+       }

+

+       if (iobar && rte_eal_iopl_init() != 0) {

                RTE_LOG(ERR, EAL, "%s(): insufficient ioport permissions for PCI device %s\n",

                        __func__, dev->name);

                return -1;

@@ -387,22 +425,8 @@

        if (uio_num < 0)

                return -1;



-       /* get portio start */

-       snprintf(filename, sizeof(filename),

-                "%s/portio/port%d/start", dirname, bar);

-       if (eal_parse_sysfs_value(filename, &start) < 0) {

-               RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",

-                       __func__);

-               return -1;

-       }

-       /* ensure we don't get anything funny here, read/write will cast to

-        * uin16_t */

-       if (start > UINT16_MAX)

-               return -1;

-

        /* FIXME only for primary process ? */

        if (dev->intr_handle.type == RTE_INTR_HANDLE_UNKNOWN) {

-

                snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);

                dev->intr_handle.fd = open(filename, O_RDWR);

                if (dev->intr_handle.fd < 0) {

@@ -413,11 +437,14 @@

                dev->intr_handle.type = RTE_INTR_HANDLE_UIO;

        }



-       RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", start);

+       RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", base);



-       p->base = start;

+       p->base = base;

        p->len = 0;

        return 0;

+error:

+       fclose(f);

+       return -1;

 }

 #else

 int

@@ -488,6 +515,61 @@

 }

 #endif



+#define PIO_MAX 0x10000

+static inline uint8_t ioread8(void *addr)

+{

+       uint8_t val;

+

+       val = (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint8_t *)addr :

+               inb((unsigned long)addr);

+

+       return val;

+}

+

+static inline uint16_t ioread16(void *addr)

+{

+       uint16_t val;

+

+       val = (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint16_t *)addr :

+               inw((unsigned long)addr);

+

+       return val;

+}

+

+static inline uint32_t ioread32(void *addr)

+{

+       uint32_t val;

+

+       val = (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint32_t *)addr :

+               inl((unsigned long)addr);

+

+       return val;

+}

+

+static inline void iowrite8(uint8_t val, void *addr)

+{

+       (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint8_t *)addr = val :

+               outb(val, (unsigned long)addr);

+}

+

+static inline void iowrite16(uint16_t val, void *addr)

+{

+       (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint16_t *)addr = val :

+               outw(val, (unsigned long)addr);

+}

+

+static inline void iowrite32(uint32_t val, void *addr)

+{

+       (uint64_t)(uintptr_t)addr >= PIO_MAX ?

+               *(volatile uint32_t *)addr = val :

+               outl(val, (unsigned long)addr);

+}

+

 void

 pci_uio_ioport_read(struct rte_pci_ioport *p,

                    void *data, size_t len, off_t offset)

@@ -499,25 +581,13 @@

        for (d = data; len > 0; d += size, reg += size, len -= size) {

                if (len >= 4) {

                        size = 4;

-#if defined(RTE_ARCH_X86)

-                       *(uint32_t *)d = inl(reg);

-#else

-                       *(uint32_t *)d = *(volatile uint32_t *)reg;

-#endif

+                       *(uint32_t *)d = ioread32((void *)reg);

                } else if (len >= 2) {

                        size = 2;

-#if defined(RTE_ARCH_X86)

-                       *(uint16_t *)d = inw(reg);

-#else

-                       *(uint16_t *)d = *(volatile uint16_t *)reg;

-#endif

+                       *(uint16_t *)d = ioread16((void *)reg);

                } else {

                        size = 1;

-#if defined(RTE_ARCH_X86)

-                       *d = inb(reg);

-#else

-                       *d = *(volatile uint8_t *)reg;

-#endif

+                       *d = ioread8((void *)reg);

                }

        }

 }

@@ -533,25 +603,13 @@

        for (s = data; len > 0; s += size, reg += size, len -= size) {

                if (len >= 4) {

                        size = 4;

-#if defined(RTE_ARCH_X86)

-                       outl_p(*(const uint32_t *)s, reg);

-#else

-                       *(volatile uint32_t *)reg = *(const uint32_t *)s;

-#endif

+                       iowrite32(*(const uint32_t *)s, (void *)reg);

                } else if (len >= 2) {

                        size = 2;

-#if defined(RTE_ARCH_X86)

-                       outw_p(*(const uint16_t *)s, reg);

-#else

-                       *(volatile uint16_t *)reg = *(const uint16_t *)s;

-#endif

+                       iowrite16(*(const uint16_t *)s, (void *)reg);

                } else {

                        size = 1;

-#if defined(RTE_ARCH_X86)

-                       outb_p(*s, reg);

-#else

-                       *(volatile uint8_t *)reg = *s;

-#endif

+                       iowrite8(*s, (void *)reg);

                }

        }

 }

--

1.8.3.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-09-14  3:43 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-14  3:19 [dpdk-dev] [PATCH] pci: support both io and mmio bar for legacy virtio on x86 谢华伟(此时此刻)
2020-09-14  3:42 ` 谢华伟(此时此刻)
  -- strict thread matches above, loose matches on Subject: below --
2020-09-11 12:57 谢华伟(此时此刻)
     [not found] ` <19b35451-45bb-4090-a3cf-31954d7c9c44.>
2020-09-11 14:56   ` 谢华伟(此时此刻)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).