[v2,1/7] bus/pci: add new memory resource access APIs

Message ID 20210918022443.12719-2-chenbo.xia@intel.com (mailing list archive)
State Superseded, archived
Delegated to: David Marchand
Headers
Series Removal of PCI bus ABIs |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Chenbo Xia Sept. 18, 2021, 2:24 a.m. UTC
  Some applications wants to access PCI memory resource. Currently
applications use struct rte_pci_device to access it. Since the
structure will be made internal later, this patch adds two APIs
for memory resource access.

Signed-off-by: Chenbo Xia <chenbo.xia@intel.com>
Acked-by: Ray Kinsella <mdr@ashroe.eu>
---
 doc/guides/rel_notes/release_21_11.rst |  6 ++
 drivers/bus/pci/pci_common.c           | 78 ++++++++++++++++++++++++++
 drivers/bus/pci/rte_bus_pci.h          | 36 ++++++++++++
 drivers/bus/pci/version.map            |  4 ++
 4 files changed, 124 insertions(+)
  

Patch

diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 1d56fa9bf2..ce3f554e10 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -55,6 +55,12 @@  New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Added new memory resource read/write APIs in PCI bus.**
+
+  Added new memory resource read/write APIs ``rte_pci_mem_rd32`` and
+  ``rte_pci_mem_wr32`` for applications to read/write PCI memory
+  resource.
+
 * **Enabled new devargs parser.**
 
   * Enabled devargs syntax
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index 3406e03b29..5bc7c8e2c7 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -25,6 +25,7 @@ 
 #include <rte_common.h>
 #include <rte_devargs.h>
 #include <rte_vfio.h>
+#include <rte_io.h>
 
 #include "private.h"
 
@@ -777,6 +778,83 @@  rte_pci_set_bus_master(struct rte_pci_device *dev, bool enable)
 	return 0;
 }
 
+static void *
+get_pci_mem_addr(const char *name, uint16_t idx, uint64_t offset)
+{
+	struct rte_pci_device *dev = NULL;
+	struct rte_pci_addr addr = {0};
+	struct rte_mem_resource *res = NULL;
+	bool found = false;
+
+	if (rte_pci_addr_parse(name, &addr)) {
+		RTE_LOG(ERR, EAL, "Wrong name format of PCI device (%s)", name);
+		return NULL;
+	}
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (rte_pci_addr_cmp(&dev->addr, &addr)) {
+			continue;
+		} else {
+			found = true;
+			break;
+		}
+	}
+
+	if (!found) {
+		RTE_LOG(ERR, EAL, "Can not find the device (%s)", name);
+		return NULL;
+	}
+
+	res = &dev->mem_resource[idx];
+	if (idx >= PCI_MAX_RESOURCE || res->len == 0 || res->addr == NULL) {
+		RTE_LOG(ERR, EAL, "Invalid index of a mapped memory resourse");
+		return NULL;
+	}
+
+	if (offset + 4 > res->len) {
+		RTE_LOG(ERR, EAL, "Invalid offset of a memory resourse");
+		return NULL;
+	}
+
+	return (void *)((char *)res->addr + offset);
+}
+
+int
+rte_pci_mem_rd32(const char *name, uint16_t idx, uint32_t *data, uint64_t offset)
+{
+	void *reg_addr = NULL;
+
+	if (data == NULL) {
+		RTE_LOG(ERR, EAL, "NULL data buffer for PCI memory access");
+		return -EINVAL;
+	}
+
+	reg_addr = get_pci_mem_addr(name, idx, offset);
+	if (reg_addr == NULL)
+		return -EINVAL;
+
+	*data = rte_read32(reg_addr);
+	return 0;
+}
+
+int
+rte_pci_mem_wr32(const char *name, uint16_t idx, const uint32_t *data, uint64_t offset)
+{
+	void *reg_addr = NULL;
+
+	if (data == NULL) {
+		RTE_LOG(ERR, EAL, "NULL data buffer for PCI memory access");
+		return -EINVAL;
+	}
+
+	reg_addr = get_pci_mem_addr(name, idx, offset);
+	if (reg_addr == NULL)
+		return -EINVAL;
+
+	rte_write32(*data, reg_addr);
+	return 0;
+}
+
 struct rte_pci_bus rte_pci_bus = {
 	.bus = {
 		.scan = rte_pci_scan,
diff --git a/drivers/bus/pci/rte_bus_pci.h b/drivers/bus/pci/rte_bus_pci.h
index 583470e831..21d9dd4289 100644
--- a/drivers/bus/pci/rte_bus_pci.h
+++ b/drivers/bus/pci/rte_bus_pci.h
@@ -392,6 +392,42 @@  void rte_pci_ioport_read(struct rte_pci_ioport *p,
 void rte_pci_ioport_write(struct rte_pci_ioport *p,
 		const void *data, size_t len, off_t offset);
 
+/**
+ * Read 4 bytes from PCI memory resource.
+ *
+ * @param name
+ *   PCI device name (e.g., 0000:18:00.0).
+ * @param idx
+ *   Memory resource index.
+ * @param data
+ *   Data buffer where the bytes should be read into.
+ * @param offset
+ *   The offset into the PCI memory resource.
+ * @return
+ *  0 on success, negative value on error.
+ */
+__rte_experimental
+int
+rte_pci_mem_rd32(const char *name, uint16_t idx, uint32_t *data, uint64_t offset);
+
+/**
+ * Write 4 bytes to PCI memory resource.
+ *
+ * @param name
+ *   PCI device name (e.g., 0000:18:00.0).
+ * @param idx
+ *   Memory resource index.
+ * @param data
+ *   Buffer of data that should be written to PCI memory.
+ * @param offset
+ *   The offset into the PCI memory resource.
+ * @return
+ *  0 on success, negative value on error.
+ */
+__rte_experimental
+int
+rte_pci_mem_wr32(const char *name, uint16_t idx, const uint32_t *data, uint64_t offset);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/drivers/bus/pci/version.map b/drivers/bus/pci/version.map
index aa56439c2b..01ec836559 100644
--- a/drivers/bus/pci/version.map
+++ b/drivers/bus/pci/version.map
@@ -24,4 +24,8 @@  EXPERIMENTAL {
 
 	# added in 21.08
 	rte_pci_set_bus_master;
+
+	# added in 21.11
+	rte_pci_mem_rd32;
+	rte_pci_mem_wr32;
 };