All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 0/7] Support non-PCI devices
@ 2016-01-01 21:05 Jan Viktorin
  2016-01-01 21:05 ` [RFC 1/7] eal/common: define rte_soc_* related common interface Jan Viktorin
                   ` (37 more replies)
  0 siblings, 38 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-01-01 21:05 UTC (permalink / raw)
  To: dev; +Cc: Jan Viktorin

Hello DPDK community,

I am proposing an RFC patch series that tries to add support for non-PCI
devices into DPDK. At the moment, the only way how to support such devices is
to utilize the virtual devices. As there are SoCs with integrated Ethernet MACs
(and other devices) that can be controled by DPDK, such infrastructure can be
helpful to write PMD for them. This is mostly the case of ARM SoCs. The ARMv7
SoCs have always an integrated EMAC (if any), the ARM+FPGA provides ways how
to put a custom EMACs into the SoC, and for ARM 64 there is the X-Gene board
with integrated 10G EMACs.

The patch set contains a simple self-test showing that this approach works. It
is possible to test it on any platform as it provides a fake sysfs and device
tree hierarchy.

I am introducing the pair rte_soc_device + rte_soc_driver and the probing code
for Linux. It is based on searching the /sys/bus/platform/devices and the
device-tree (for PMDs). No testing PMD is provided, just a simple test case
in app/test/test_soc.c.

I am unsure about the naming - rte_soc_*, however, it's the best one I've
devised so far.

I am aware of several code-issues and missing comments and moreover, there is
some infrastructure copied from the PCI code base. I will fix those in future
versions of the patch set if it is approved to the upstream. I'd be happy to
get some suggestions how to refactor the common code out from the PCI infra.

I am unaware of any other attempt to extend DPDK in this way so if there is
some work similar to this, I'd like to have a look at it.

Please, consider one important thing. There is no Linux Kernel driver that is
suitable for this kind of devices. Such driver must be PCI-independent, must
(should?) support no-IOMMU access to the device, must provide access to the
device memory specified in the device-tree's reg property, must give a way how
to perform DMA transfers, should be able to deliver interrupts, etc.

See the commits for more details...

Happy New Year!

Regards
Jan Viktorin

Jan Viktorin (7):
  eal/common: define rte_soc_* related common interface
  eal: introduce --no-soc option
  eal: add common part of the SoC infra
  eal/linuxapp: support SoC infra in linuxapp
  eal: init SoC infra on rte_eal_init
  eal/soc: make SoC infra testable on any platform
  app/test: add SoC infra probe/detach test

 app/test/Makefile                           |   3 +
 app/test/soc_test_init.sh                   |  61 +++++
 app/test/test_soc.c                         | 249 +++++++++++++++++
 lib/librte_eal/common/Makefile              |   2 +-
 lib/librte_eal/common/eal_common_devargs.c  |   6 +
 lib/librte_eal/common/eal_common_options.c  |   5 +
 lib/librte_eal/common/eal_common_soc.c      | 367 +++++++++++++++++++++++++
 lib/librte_eal/common/eal_internal_cfg.h    |   1 +
 lib/librte_eal/common/eal_options.h         |   2 +
 lib/librte_eal/common/eal_private.h         |  12 +
 lib/librte_eal/common/include/rte_devargs.h |   7 +
 lib/librte_eal/common/include/rte_soc.h     | 212 ++++++++++++++
 lib/librte_eal/linuxapp/eal/Makefile        |   3 +
 lib/librte_eal/linuxapp/eal/eal.c           |   4 +
 lib/librte_eal/linuxapp/eal/eal_soc.c       | 409 ++++++++++++++++++++++++++++
 15 files changed, 1342 insertions(+), 1 deletion(-)
 create mode 100755 app/test/soc_test_init.sh
 create mode 100644 app/test/test_soc.c
 create mode 100644 lib/librte_eal/common/eal_common_soc.c
 create mode 100644 lib/librte_eal/common/include/rte_soc.h
 create mode 100644 lib/librte_eal/linuxapp/eal/eal_soc.c

-- 
2.6.3

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

* [RFC 1/7] eal/common: define rte_soc_* related common interface
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
@ 2016-01-01 21:05 ` Jan Viktorin
  2016-01-02 18:01   ` Stephen Hemminger
  2016-01-01 21:05 ` [RFC 2/7] eal: introduce --no-soc option Jan Viktorin
                   ` (36 subsequent siblings)
  37 siblings, 1 reply; 231+ messages in thread
From: Jan Viktorin @ 2016-01-01 21:05 UTC (permalink / raw)
  To: dev; +Cc: Jan Viktorin

Introduce the interface to SoC device infrastructure. A SoC device
here means a device integrated on the chip via a (simple) bus
that lacks of auto-discovery and other properties which are common
for PCI. A counterpart in the Linux Kernel would be a platform_device
(but this is not necessarily 1:1 mapping).

Systems without auto-discovery properties are described by a (Flat)
Device Tree. Device Tree is usually available on embedded systems
in /proc/device-tree. Every device has a unique path in the Device
Tree and so it identifies every such device. This path is used
to identify a device in rte_soc_addr.

Binding of drivers to devices in the Linux Kernel is often done
by matching the compatible entry in the Device Tree. As there is
no standard/generic way to read information like vendor, model, etc.
from each SoC device, we match devices by the compatible entry too.
The rte_soc_id contains an array of compatible strings telling what
each device is compatible with.

There are no DPDK-specific OS drivers for SoC devices at the moment
and unfortunately we cannot use the PCI-related ones as they contain
too much PCI-specific logic.

Whitelisting and blacklisting of devices is based on the Device Tree
identifier (rte_soc_addr) to mimic the PCI behaviour.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/common/Makefile              |   2 +-
 lib/librte_eal/common/eal_common_devargs.c  |   6 +
 lib/librte_eal/common/include/rte_devargs.h |   7 +
 lib/librte_eal/common/include/rte_soc.h     | 210 ++++++++++++++++++++++++++++
 4 files changed, 224 insertions(+), 1 deletion(-)
 create mode 100644 lib/librte_eal/common/include/rte_soc.h

diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index f5ea0ee..21326d7 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 INC := rte_branch_prediction.h rte_common.h
 INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
-INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
+INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h rte_soc.h
 INC += rte_pci_dev_ids.h rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index 5d075d0..201f298 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -105,6 +105,12 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
 			goto fail;
 
 		break;
+	case RTE_DEVTYPE_WHITELISTED_SOC:
+	case RTE_DEVTYPE_BLACKLISTED_SOC:
+		strncpy(devargs->soc.addr.devtree_path,
+				buf, PATH_MAX);
+		/* TODO: test file exists? */
+		break;
 	case RTE_DEVTYPE_VIRTUAL:
 		/* save driver name */
 		ret = snprintf(devargs->virt.drv_name,
diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h
index 53c59f5..f69a553 100644
--- a/lib/librte_eal/common/include/rte_devargs.h
+++ b/lib/librte_eal/common/include/rte_devargs.h
@@ -51,6 +51,7 @@ extern "C" {
 #include <stdio.h>
 #include <sys/queue.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 
 /**
  * Type of generic device
@@ -58,6 +59,8 @@ extern "C" {
 enum rte_devtype {
 	RTE_DEVTYPE_WHITELISTED_PCI,
 	RTE_DEVTYPE_BLACKLISTED_PCI,
+	RTE_DEVTYPE_WHITELISTED_SOC,
+	RTE_DEVTYPE_BLACKLISTED_SOC,
 	RTE_DEVTYPE_VIRTUAL,
 };
 
@@ -82,6 +85,10 @@ struct rte_devargs {
 			/** PCI location. */
 			struct rte_pci_addr addr;
 		} pci;
+		struct {
+			/** SoC location. */
+			struct rte_soc_addr addr;
+		} soc;
 		/** Used if type is RTE_DEVTYPE_VIRTUAL. */
 		struct {
 			/** Driver name. */
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
new file mode 100644
index 0000000..7c279b1
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -0,0 +1,210 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_SOC_H_
+#define _RTE_SOC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/errno.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_interrupts.h>
+
+TAILQ_HEAD(soc_device_list, rte_soc_device);
+TAILQ_HEAD(soc_driver_list, rte_soc_driver);
+
+extern struct soc_device_list soc_device_list;
+extern struct soc_driver_list soc_driver_list;
+
+/* Path to detect platform devices (in architecture-specific bus systems). */
+#define SYSFS_SOC_DEVICES "/sys/bus/platform/devices"
+/* Flat Device Tree location in the system. */
+#define FDT_ROOT "/proc/device-tree"
+
+struct rte_soc_resource {
+	uint64_t phys_addr; /**< Physical address, 0 if no resource. */
+	uint64_t len;       /**< Length of the resource. */
+	void *addr;         /**< Virtual address, NULL when not mapped. */
+};
+
+/** Maximum number of SoC resources. */
+#define SOC_MAX_RESOURCE 6
+
+struct rte_soc_id {
+	char **compatible; /**< List of compatible strings. */
+};
+
+struct rte_soc_addr {
+	char devtree_path[PATH_MAX]; /** Path to identify the device in FDT. */
+};
+
+enum rte_soc_kernel_driver {
+	RTE_SOC_KDRV_UNKNOWN = 0,
+	RTE_SOC_KDRV_NONE
+};
+
+/**
+ * A structure describing a SoC device. A SoC device is connected via some
+ * architecture-specific bus without auto-discovery features. Currently, this
+ * covers devices detected by reading the device-tree provided by the OS.
+ */
+struct rte_soc_device {
+	TAILQ_ENTRY(rte_soc_device) next;   /**< Next probed SoC device. */
+	struct rte_soc_addr addr;           /**< Device-tree location. */
+	struct rte_soc_id id;               /**< Device identification. */
+	struct rte_soc_resource mem_resource[SOC_MAX_RESOURCE]; /**< SoC memory resource. */
+	struct rte_intr_handle intr_handle; /**< Interrupt handle. */
+	struct rte_soc_driver *driver;      /**< Associated driver. */
+	int numa_node;                      /**< NUMA node connection. */
+	struct rte_devargs *devargs;        /**< Device user arguments. */
+	enum rte_soc_kernel_driver kdrv;    /**< Kernel driver passthrough. */
+};
+
+struct rte_soc_driver;
+
+/**
+ * Initialization function for the driver called during SoC probing.
+ */
+typedef int (soc_devinit_t)(struct rte_soc_driver *, struct rte_soc_device *);
+
+/**
+ * Uninitialization function for the driver called during SoC hotplugging.
+ */
+typedef int (soc_devuninit_t)(struct rte_soc_device *);
+
+struct rte_soc_driver {
+	TAILQ_ENTRY(rte_soc_driver) next;  /**< Next in list. */
+	const char *name;                  /**< Driver name. */
+	soc_devinit_t *devinit;            /**< Device init. function. */
+	soc_devuninit_t *devuninit;        /**< Device uninit. function. */
+	const struct rte_soc_id *id_table; /**< ID table, NULL terminated. */
+	uint32_t drv_flags;                /**< Flags for handling of device. */
+};
+
+struct soc_map {
+	void *addr;
+	char *path;
+	uint64_t offset;
+	uint64_t size;
+	uint64_t phaddr;
+};
+
+struct mapped_soc_resource {
+	TAILQ_ENTRY(mapped_soc_resource) next;
+	struct rte_soc_addr soc_addr;
+	char path[PATH_MAX];
+	int nb_maps;
+	struct soc_map maps[SOC_MAX_RESOURCE];
+};
+
+TAILQ_HEAD(mapped_soc_res_list, mapped_soc_resource);
+
+/**
+ * Compare two SoC device address.
+ * @return
+ *	0 on addr == addr2
+ *	Positive on addr > addr2
+ *	Negative on addr < addr2
+ */
+static inline int
+rte_eal_compare_soc_addr(const struct rte_soc_addr *addr,
+			 const struct rte_soc_addr *addr2)
+{
+	if ((addr == NULL) || (addr2 == NULL))
+		return -1;
+
+	return strcmp(addr->devtree_path, addr2->devtree_path);
+}
+
+/**
+ * Scan the architecture-specific buses for the SoC devices, and the devices
+ * in the devices list.
+ *
+ * @return
+ * 	0 on success
+ */
+int rte_eal_soc_scan(void);
+
+/**
+ * Probe SoC devices for registered drivers.
+ *
+ * Call probe() function for all registered drivers that have a matching entry
+ * in its id_table for discovered devices.
+ *
+ * @return
+ *	0 on success
+ */
+int rte_eal_soc_probe(void);
+
+void *soc_map_resource(void *requested_addr, int fd, off_t offset,
+		size_t size, int additional_flags);
+void soc_unmap_resource(void *requested_addr, size_t size);
+
+/**
+ * Probe the single SoC device.
+ *
+ * Find the SoC device specified by the SoC address, then call the probe()
+ * function for the registered driver that has a matching entry in its id_table.
+ *
+ * @return
+ *	0 on success
+ */
+int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
+
+/**
+ * Close the single SoC device.
+ *
+ * Find the SoC device specified by the SoC address, then call devuninit()
+ * function for the registered driver.
+ */
+int rte_eal_soc_detach(const struct rte_soc_addr *addr);
+
+void rte_eal_soc_dump(FILE *f);
+
+void rte_eal_soc_register(struct rte_soc_driver *driver);
+void rte_eal_soc_unregister(struct rte_soc_driver *driver);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
-- 
2.6.3

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

* [RFC 2/7] eal: introduce --no-soc option
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
  2016-01-01 21:05 ` [RFC 1/7] eal/common: define rte_soc_* related common interface Jan Viktorin
@ 2016-01-01 21:05 ` Jan Viktorin
  2016-01-01 21:05 ` [RFC 3/7] eal: add common part of the SoC infra Jan Viktorin
                   ` (35 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-01-01 21:05 UTC (permalink / raw)
  To: dev; +Cc: Jan Viktorin

This option has the same meaning for the SoC infra as the --no-pci
for the PCI infra.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/common/eal_common_options.c | 5 +++++
 lib/librte_eal/common/eal_internal_cfg.h   | 1 +
 lib/librte_eal/common/eal_options.h        | 2 ++
 3 files changed, 8 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 29942ea..c9e294c 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -85,6 +85,7 @@ eal_long_options[] = {
 	{OPT_NO_HPET,           0, NULL, OPT_NO_HPET_NUM          },
 	{OPT_NO_HUGE,           0, NULL, OPT_NO_HUGE_NUM          },
 	{OPT_NO_PCI,            0, NULL, OPT_NO_PCI_NUM           },
+	{OPT_NO_SOC,            0, NULL, OPT_NO_SOC_NUM           },
 	{OPT_NO_SHCONF,         0, NULL, OPT_NO_SHCONF_NUM        },
 	{OPT_PCI_BLACKLIST,     1, NULL, OPT_PCI_BLACKLIST_NUM    },
 	{OPT_PCI_WHITELIST,     1, NULL, OPT_PCI_WHITELIST_NUM    },
@@ -838,6 +839,10 @@ eal_parse_common_option(int opt, const char *optarg,
 		conf->no_pci = 1;
 		break;
 
+	case OPT_NO_SOC_NUM:
+		conf->no_soc = 1;
+		break;
+
 	case OPT_NO_HPET_NUM:
 		conf->no_hpet = 1;
 		break;
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 5f1367e..3a98e94 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -67,6 +67,7 @@ struct internal_config {
 	unsigned hugepage_unlink;         /**< true to unlink backing files */
 	volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
 	volatile unsigned no_pci;         /**< true to disable PCI */
+	volatile unsigned no_soc;         /**< true to disable SoC */
 	volatile unsigned no_hpet;        /**< true to disable HPET */
 	volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
 										* instead of native TSC */
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index a881c62..ba1e704 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -69,6 +69,8 @@ enum {
 	OPT_NO_HUGE_NUM,
 #define OPT_NO_PCI            "no-pci"
 	OPT_NO_PCI_NUM,
+#define OPT_NO_SOC            "no-soc"
+	OPT_NO_SOC_NUM,
 #define OPT_NO_SHCONF         "no-shconf"
 	OPT_NO_SHCONF_NUM,
 #define OPT_SOCKET_MEM        "socket-mem"
-- 
2.6.3

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

* [RFC 3/7] eal: add common part of the SoC infra
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
  2016-01-01 21:05 ` [RFC 1/7] eal/common: define rte_soc_* related common interface Jan Viktorin
  2016-01-01 21:05 ` [RFC 2/7] eal: introduce --no-soc option Jan Viktorin
@ 2016-01-01 21:05 ` Jan Viktorin
  2016-01-01 21:05 ` [RFC 4/7] eal/linuxapp: support SoC infra in linuxapp Jan Viktorin
                   ` (34 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-01-01 21:05 UTC (permalink / raw)
  To: dev; +Cc: Jan Viktorin

Probing and detaching of devices. The code is heavily based on the PCI infra.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/common/eal_common_soc.c | 367 +++++++++++++++++++++++++++++++++
 lib/librte_eal/common/eal_private.h    |  12 ++
 lib/librte_eal/linuxapp/eal/Makefile   |   1 +
 3 files changed, 380 insertions(+)
 create mode 100644 lib/librte_eal/common/eal_common_soc.c

diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
new file mode 100644
index 0000000..8a0edf3
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -0,0 +1,367 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_soc.h>
+#include <rte_per_lcore.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_string_fns.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+
+#include "eal_private.h"
+
+struct soc_driver_list soc_driver_list;
+struct soc_device_list soc_device_list;
+
+static struct rte_devargs *soc_devargs_lookup(struct rte_soc_device *dev)
+{
+	struct rte_devargs *devargs;
+
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->type != RTE_DEVTYPE_BLACKLISTED_SOC
+			&& devargs->type != RTE_DEVTYPE_WHITELISTED_SOC)
+			continue;
+
+		if (!rte_eal_compare_soc_addr(&dev->addr, &devargs->soc.addr))
+			return devargs;
+	}
+
+	return NULL;
+}
+
+/* TODO: generalize and merge with PCI version */
+void *
+soc_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
+		int additional_flags)
+{
+	void *mapaddr;
+
+	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
+			MAP_SHARED | additional_flags, fd, offset);
+	if (mapaddr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
+			__func__, fd, requested_addr,
+			(unsigned long)size, (unsigned long)offset,
+			strerror(errno), mapaddr);
+	} else
+		RTE_LOG(DEBUG, EAL, "  SoC memory mapped at %p\n", mapaddr);
+
+	return mapaddr;
+}
+
+/* TODO: generalize and merge with PCI version */
+void
+soc_unmap_resource(void *requested_addr, size_t size)
+{
+	if (requested_addr == NULL)
+		return;
+
+	if (munmap(requested_addr, size)) {
+		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
+			__func__, requested_addr, (unsigned long)size,
+			strerror(errno));
+	} else
+		RTE_LOG(DEBUG, EAL, "  SoC memory unmapped at %p\n",
+				requested_addr);
+}
+
+static int
+rte_eal_soc_id_match(const struct rte_soc_id *dr, const struct rte_soc_id *dev)
+{
+	int i;
+
+	if (dr == NULL || dev == NULL)
+		return 0;
+
+	if (dr->compatible == NULL || dev->compatible == NULL)
+		return 0;
+
+	for (i = 0; dr->compatible[i]; ++i) {
+		int j;
+
+		for (j = 0; dev->compatible[j]; ++j) {
+			if (!strcmp(dr->compatible[i], dev->compatible[j]))
+				return 1;
+		}
+	}
+
+	return 0;
+}
+
+static int
+rte_eal_soc_probe_one_driver(struct rte_soc_driver *dr, struct rte_soc_device *dev)
+{
+	int ret;
+	const struct rte_soc_id *id_table;
+
+	if (dr == NULL || dev == NULL)
+		return -EINVAL;
+
+	for (id_table = dr->id_table; id_table->compatible; ++id_table) {
+		if (!rte_eal_soc_id_match(id_table, &dev->id))
+			continue;
+
+		RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %i\n",
+				dev->addr.devtree_path, dev->numa_node);
+		RTE_LOG(DEBUG, EAL, "  probe driver: %s\n", dr->name);
+
+		if (dev->devargs != NULL
+			&& dev->devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC) {
+			RTE_LOG(DEBUG, EAL, "  Device is blacklisted, skipping\n");
+			return 1;
+		}
+
+		ret = soc_map_device(dev);
+		if (ret != 0)
+			return ret;
+
+		dev->driver = dr;
+		return dr->devinit(dr, dev);
+	}
+
+	return 1;
+}
+
+static int
+rte_eal_soc_detach_dev(struct rte_soc_driver *dr, struct rte_soc_device *dev)
+{
+	const struct rte_soc_id *id_table;
+
+	if (dr == NULL || dev == NULL)
+		return -EINVAL;
+
+	for (id_table = dr->id_table; id_table->compatible; ++id_table) {
+		if (!rte_eal_soc_id_match(id_table, &dev->id))
+			continue;
+
+		RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %i\n",
+				dev->addr.devtree_path, dev->numa_node);
+
+		RTE_LOG(DEBUG, EAL, "  remove driver: %s %s\n",
+				dev->addr.devtree_path, dr->name);
+
+		if (dr->devuninit && (dr->devuninit(dev) < 0))
+			return -1; /* error */
+
+		dev->driver = NULL;
+		soc_unmap_device(dev);
+
+		return 0;
+	}
+
+	return 1;
+}
+
+static int
+soc_probe_all_drivers(struct rte_soc_device *dev)
+{
+	struct rte_soc_driver *dr = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dr, &soc_driver_list, next) {
+		rc = rte_eal_soc_probe_one_driver(dr, dev);
+		if (rc < 0)
+			return -1; /* error */
+		if (rc > 0)
+			continue; /* no driver match */
+
+		return 0;
+	}
+
+	return 1;
+}
+
+static int
+soc_detach_all_drivers(struct rte_soc_device *dev)
+{
+	struct rte_soc_driver *dr = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dr, &soc_driver_list, next) {
+		rc = rte_eal_soc_detach_dev(dr, dev);
+		if (rc < 0)
+			return -1; /* error */
+		if (rc > 0)
+			continue; /* not driver match */
+		return 0;
+	}
+
+	return 1;
+}
+
+int
+rte_eal_soc_probe_one(const struct rte_soc_addr *addr)
+{
+	struct rte_soc_device *dev = NULL;
+	int rc = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		if (rte_eal_compare_soc_addr(&dev->addr, addr))
+			continue;
+
+		rc = soc_probe_all_drivers(dev);
+		if (rc < 0)
+			goto err_return;
+
+		return 0;
+	}
+
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL, "Failed to probe device %s\n",
+			dev->addr.devtree_path);
+	return -1;
+}
+
+int
+rte_eal_soc_detach(const struct rte_soc_addr *addr)
+{
+	struct rte_soc_device *dev = NULL;
+	int rc = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		if (rte_eal_compare_soc_addr(&dev->addr, addr))
+			continue;
+
+		rc = soc_detach_all_drivers(dev);
+		if (rc < 0)
+			goto err_return;
+
+		TAILQ_REMOVE(&soc_device_list, dev, next);
+		return 0;
+	}
+
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL, "Failed to detach device %s\n",
+			dev->addr.devtree_path);
+	return -1;
+}
+
+int
+rte_eal_soc_probe(void)
+{
+	struct rte_soc_device *dev = NULL;
+	struct rte_devargs *devargs;
+	int probe_all = 0;
+	int rc = 0;
+
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_SOC) == 0)
+		probe_all = 1;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		devargs = soc_devargs_lookup(dev);
+		if (devargs != NULL)
+			dev->devargs = devargs;
+
+		/* probe _all_ or _only whitelisted_ devices */
+		if (probe_all)
+			rc = soc_probe_all_drivers(dev);
+		else if (devargs != NULL
+			&& devargs->type == RTE_DEVTYPE_WHITELISTED_SOC)
+			rc = soc_probe_all_drivers(dev);
+		if (rc < 0)
+			rte_exit(EXIT_FAILURE,
+				"Requested device %s cannot be used",
+				dev->addr.devtree_path);
+	}
+
+	return 0;
+}
+
+#define SIZEOF_MEM_RESOURCE_ARRAY(r) (sizeof(r) / sizeof(r[0]))
+
+static int
+soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
+{
+	int i;
+
+	fprintf(f, "%s\n", dev->addr.devtree_path);
+
+	for (i = 0; dev->id.compatible && dev->id.compatible[i]; ++i)
+		fprintf(f, "   %s\n", dev->id.compatible[i]);
+	for (i = 0; i != SIZEOF_MEM_RESOURCE_ARRAY(dev->mem_resource); ++i) {
+		fprintf(f, "   %16.16"PRIx64" %16.16"PRIx64"\n",
+			dev->mem_resource[i].phys_addr,
+			dev->mem_resource[i].len);
+	}
+
+	return 0;
+}
+
+void
+rte_eal_soc_dump(FILE *f)
+{
+	struct rte_soc_device *dev = NULL;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next)
+		soc_dump_one_device(f, dev);
+}
+
+void
+rte_eal_soc_register(struct rte_soc_driver *dr)
+{
+	TAILQ_INSERT_TAIL(&soc_driver_list, dr, next);
+}
+
+void
+rte_eal_soc_unregister(struct rte_soc_driver *dr)
+{
+	TAILQ_REMOVE(&soc_driver_list, dr, next);
+}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 072e672..33e2029 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -36,6 +36,7 @@
 
 #include <stdio.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 
 /**
  * Initialize the memzone subsystem (private to eal).
@@ -129,6 +130,13 @@ int rte_eal_log_init(const char *id, int facility);
  */
 int rte_eal_pci_init(void);
 
+/**
+ * This function is private to EAL.
+ * @return
+ *   0 on success
+ */
+int rte_eal_soc_init(void);
+
 #ifdef RTE_LIBRTE_IVSHMEM
 /**
  * Init the memory from IVSHMEM devices
@@ -175,6 +183,8 @@ int pci_unbind_kernel_driver(struct rte_pci_device *dev);
  */
 int pci_map_device(struct rte_pci_device *dev);
 
+int soc_map_device(struct rte_soc_device *dev);
+
 /**
  * Unmap this device
  *
@@ -182,6 +192,8 @@ int pci_map_device(struct rte_pci_device *dev);
  */
 void pci_unmap_device(struct rte_pci_device *dev);
 
+void soc_unmap_device(struct rte_soc_device *dev);
+
 /**
  * Map the PCI resource of a PCI device in virtual memory
  *
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 26eced5..f2ed696 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -77,6 +77,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_launch.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_pci_uio.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_soc.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_errno.c
-- 
2.6.3

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

* [RFC 4/7] eal/linuxapp: support SoC infra in linuxapp
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (2 preceding siblings ...)
  2016-01-01 21:05 ` [RFC 3/7] eal: add common part of the SoC infra Jan Viktorin
@ 2016-01-01 21:05 ` Jan Viktorin
  2016-01-01 21:05 ` [RFC 5/7] eal: init SoC infra on rte_eal_init Jan Viktorin
                   ` (33 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-01-01 21:05 UTC (permalink / raw)
  To: dev; +Cc: Jan Viktorin

Provide Linux-specific discovery routines. The discovery reads the
/sys/bus/platform/devices/*/uevent file for each device. If the uevent
file contains OF_FULLNAME entry (path in the Device Tree) and a list of
OF_COMPATIBLE_# entries, it is considered as a SoC device and inserted
into the soc_device_list.

We do not care about the mem_resources at the moment. We need a proper
Linux Kernel driver to support this. Gathering of the resource information
could be done by parsing reg properties in the Device Tree.

There is a possible pitfall here, if there is a device depending on another
device (eg. an EMAC with a separate DMA engine), we cannot treat it as a
single device as the relation between whose might not be described in a
standardized way. So the drivers of the particular devices must take care of
this themselfs.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/linuxapp/eal/Makefile  |   2 +
 lib/librte_eal/linuxapp/eal/eal_soc.c | 394 ++++++++++++++++++++++++++++++++++
 2 files changed, 396 insertions(+)
 create mode 100644 lib/librte_eal/linuxapp/eal/eal_soc.c

diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index f2ed696..11e2dc8 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -60,6 +60,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_pci.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_pci_uio.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_pci_vfio.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_pci_vfio_mp_sync.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_soc.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_timer.c
@@ -105,6 +106,7 @@ CFLAGS_eal_hugepage_info.o := -D_GNU_SOURCE
 CFLAGS_eal_pci.o := -D_GNU_SOURCE
 CFLAGS_eal_pci_uio.o := -D_GNU_SOURCE
 CFLAGS_eal_pci_vfio.o := -D_GNU_SOURCE
+CFLAGS_eal_soc.o := -D_GNU_SOURCE
 CFLAGS_eal_common_whitelist.o := -D_GNU_SOURCE
 CFLAGS_eal_common_options.o := -D_GNU_SOURCE
 CFLAGS_eal_common_thread.o := -D_GNU_SOURCE
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
new file mode 100644
index 0000000..be0e44d
--- /dev/null
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -0,0 +1,394 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <dirent.h>
+#include <sys/stat.h>
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+#include <rte_devargs.h>
+#include <rte_memcpy.h>
+
+#include "eal_filesystem.h"
+#include "eal_private.h"
+#include "eal_pci_init.h"
+
+int
+soc_map_device(struct rte_soc_device *dev)
+{
+	int rc = -1;
+
+	switch (dev->kdrv) {
+	case RTE_SOC_KDRV_NONE:
+		rc = 0;
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		rc = 1;
+		break;
+	}
+
+	return rc;
+}
+
+void
+soc_unmap_device(struct rte_soc_device *dev)
+{
+	switch (dev->kdrv) {
+	case RTE_SOC_KDRV_NONE:
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		break;
+	}
+}
+
+static char *
+linecpy(char *dst, const char *line, size_t max)
+{
+	size_t len = 0;
+
+	while (line[len] && line[len] != '\n')
+		len += 1;
+
+	return (char *) memcpy(dst, line, len > max? max : len);
+}
+
+static char *
+linedup(const char *line)
+{
+	size_t len = 0;
+	char *s;
+
+	while (line[len] && line[len] != '\n')
+		len += 1;
+
+	s = malloc(len + 1);
+	if (s == NULL)
+		return NULL;
+
+	memcpy(s, line, len);
+	s[len] = '\0';
+	return s;
+}
+
+static const char *
+uevent_find_entry(const char *start, const char *end,
+		const char *prefix, const char *context)
+{
+	const size_t len = strlen(prefix);
+	const char *p = start;
+
+	while (strncmp(prefix, p, len)) {
+		while (p < end && *p != '\n') {
+			p += 1;
+		}
+
+		if (p >= end) {
+			RTE_LOG(WARNING, EAL,
+				"%s(): missing uevent entry %s (%s)\n",
+				__func__, prefix, context);
+			return NULL;
+		}
+		else {
+			p += 1; /* skip end-of-line */
+		}
+	}
+
+	if (p + len < end)
+		return p + len;
+	else {
+		RTE_LOG(WARNING, EAL,
+			"%s(): missing value for uevent entry %s (%s)\n",
+			__func__, prefix, context);
+		return NULL;
+	}
+}
+
+static int
+soc_device_from_uevent(struct rte_soc_device *dev, const char *uevent)
+{
+	FILE *f;
+	struct stat st;
+	char *buf;
+	char *end;
+	char *err;
+	const char *entry;
+	unsigned long i;
+	unsigned long count;
+
+	if ((f = fopen(uevent, "r")) == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): cannot open sysfs file uevent\n",
+			__func__);
+		return -1;
+	}
+
+	if (fstat(fileno(f), &st) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): cannot stat sysfs file uevent (%s)\n",
+			__func__, strerror(errno));
+		goto fail_fclose;
+	}
+
+	if (st.st_size <= 0) {
+		RTE_LOG(ERR, EAL, "%s(): sysfs file uevent seems to be empty\n",
+			__func__);
+		goto fail_fclose_skip;
+	}
+
+	buf = malloc(st.st_size + 1);
+	if (buf == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): failed to alloc memory\n", __func__);
+		goto fail_fclose;
+	}
+
+	if (fread(buf, 1, st.st_size, f) == 0) {
+		RTE_LOG(ERR, EAL, "%s(): cannot read sysfs file uevent\n",
+			__func__);
+		goto fail_free_buf;
+	}
+	buf[st.st_size] = '\0';
+	end = buf + st.st_size;
+
+	entry = uevent_find_entry(buf, end, "OF_FULLNAME=", uevent);
+	if (entry == NULL)
+		goto fail_free_buf_skip;
+
+	linecpy((char *) dev->addr.devtree_path, entry,
+		sizeof(dev->addr.devtree_path));
+
+	RTE_LOG(DEBUG, EAL, "%s(): OF_FULLNAME=%s\n", __func__,
+			dev->addr.devtree_path);
+
+	entry = uevent_find_entry(buf, end, "OF_COMPATIBLE_N=", uevent);
+	if (entry == NULL)
+		goto fail_free_buf_skip; /* reported from uevent_find_entry */
+
+	count = strtoul(entry, &err, 0);
+	if (err == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): failed to parse OF_COMPATIBLE_N\n",
+			__func__);
+		goto fail_free_buf;
+	}
+
+	RTE_LOG(DEBUG, EAL, "%s(): OF_COMPATIBLE_N=%lu\n", __func__, count);
+
+	dev->id.compatible = calloc(count + 1, sizeof(*dev->id.compatible));
+	if (dev->id.compatible == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): failed to alloc memory\n",
+			__func__);
+		goto fail_free_buf;
+	}
+
+	if (count > 9999) /* FIXME: better way? */
+		rte_exit(EXIT_FAILURE, "Strange count of OF_COMPATIBLE entries"
+				"in sysfs uevent\n");
+
+	for (i = 0; i < count; ++i) {
+		char prefix[strlen("OF_COMPATIBLE_NNNN=")];
+		snprintf(prefix, sizeof(prefix), "OF_COMPATIBLE_%lu=", i);
+
+		entry = uevent_find_entry(buf, end, prefix, uevent);
+		if (entry == NULL) {
+			while (i-- > 0)
+				free(dev->id.compatible[i]);
+			goto fail_id_compatible;
+		}
+
+		dev->id.compatible[i] = linedup(entry);
+		RTE_LOG(DEBUG, EAL, "%s(): %s%s\n", __func__, prefix,
+				dev->id.compatible[i]);
+		if (dev->id.compatible[i] == NULL) {
+			RTE_LOG(ERR, EAL, "%s(): failed to alloc memory\n",
+				__func__);
+
+			while (i-- > 0)
+				free(dev->id.compatible[i]);
+			goto fail_id_compatible;
+		}
+	}
+
+	dev->id.compatible[count] = NULL;
+	return 0;
+
+fail_id_compatible:
+	free(dev->id.compatible);
+fail_free_buf:
+	free(buf);
+fail_fclose:
+	fclose(f);
+	return -1;
+fail_free_buf_skip:
+	free(buf);
+fail_fclose_skip:
+	fclose(f);
+	return 1;
+}
+
+static void
+soc_device_uevent_free(struct rte_soc_device *dev)
+{
+	if (!dev)
+		return;
+
+	if (dev->id.compatible) {
+		int i;
+
+		for (i = 0; dev->id.compatible[i]; ++i)
+			free(dev->id.compatible[i]);
+
+		free(dev->id.compatible);
+	}
+}
+
+static void
+soc_device_free(struct rte_soc_device *dev)
+{
+	soc_device_uevent_free(dev);
+	free(dev);
+}
+
+static int
+soc_scan_one(const char *dirname)
+{
+	char filename[PATH_MAX];
+	struct rte_soc_device *dev;
+	unsigned long tmp;
+	int rc;
+
+	dev = calloc(1, sizeof(*dev));
+	if (dev == NULL)
+		return -1;
+
+	snprintf(filename, sizeof(filename), "%s/numa_node", dirname);
+	if (access(filename, R_OK) != 0) {
+		/* no NUMA support */
+		dev->numa_node = 0;
+	} else {
+		if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+			free(dev);
+			return -1;
+		}
+		dev->numa_node = tmp;
+	}
+
+	snprintf(filename, sizeof(filename), "%s/uevent", dirname);
+	rc = soc_device_from_uevent(dev, filename);
+	if (rc) {
+		free(dev);
+		return rc;
+	}
+
+	dev->driver = NULL;
+	dev->kdrv = RTE_SOC_KDRV_NONE;
+
+	if (TAILQ_EMPTY(&soc_device_list)) {
+		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+	} else {
+		struct rte_soc_device *dev2;
+		int rc;
+
+		TAILQ_FOREACH(dev2, &soc_device_list, next) {
+			rc = rte_eal_compare_soc_addr(&dev->addr, &dev2->addr);
+			if (rc > 0)
+				continue;
+
+			if (rc < 0) {
+				TAILQ_INSERT_BEFORE(dev2, dev, next);
+			} else { /* already exists */
+				dev2->kdrv = dev->kdrv;
+				memmove(dev2->mem_resource, dev->mem_resource,
+						sizeof(dev->mem_resource));
+				soc_device_free(dev);
+			}
+			return 0;
+		}
+		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+	}
+
+	return 0;
+}
+
+int
+rte_eal_soc_scan(void)
+{
+	struct dirent *e;
+	DIR *dir;
+	char dirname[PATH_MAX];
+
+	dir = opendir(SYSFS_SOC_DEVICES);
+	if (dir == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
+			__func__, strerror(errno));
+		return -1;
+	}
+
+	while ((e = readdir(dir)) != NULL) {
+		if (e->d_name[0] == '.')
+			continue;
+
+		snprintf(dirname, sizeof(dirname), "%s/%s", SYSFS_SOC_DEVICES,
+				e->d_name);
+		if (soc_scan_one(dirname) < 0)
+			goto error;
+	}
+
+	closedir(dir);
+	return 0;
+
+error:
+	closedir(dir);
+	return -1;
+}
+
+int
+rte_eal_soc_init(void)
+{
+	TAILQ_INIT(&soc_driver_list);
+	TAILQ_INIT(&soc_device_list);
+
+	if (internal_config.no_soc)
+		return 0;
+
+	if (rte_eal_soc_scan() < 0) {
+		RTE_LOG(ERR, EAL, "%s(): Failed to scan for SoC devices\n",
+			__func__);
+		return -1;
+	}
+
+	return 0;
+}
-- 
2.6.3

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

* [RFC 5/7] eal: init SoC infra on rte_eal_init
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (3 preceding siblings ...)
  2016-01-01 21:05 ` [RFC 4/7] eal/linuxapp: support SoC infra in linuxapp Jan Viktorin
@ 2016-01-01 21:05 ` Jan Viktorin
  2016-01-01 21:05 ` [RFC 6/7] eal/soc: make SoC infra testable on any platform Jan Viktorin
                   ` (32 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-01-01 21:05 UTC (permalink / raw)
  To: dev; +Cc: Jan Viktorin

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/linuxapp/eal/eal.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 635ec36..8a6691d 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -69,6 +69,7 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_devargs.h>
 #include <rte_common.h>
 #include <rte_version.h>
@@ -785,6 +786,9 @@ rte_eal_init(int argc, char **argv)
 	if (rte_eal_pci_init() < 0)
 		rte_panic("Cannot init PCI\n");
 
+	if (rte_eal_soc_init() < 0)
+		rte_panic("Cannot init SoC\n");
+
 #ifdef RTE_LIBRTE_IVSHMEM
 	if (rte_eal_ivshmem_init() < 0)
 		rte_panic("Cannot init IVSHMEM\n");
-- 
2.6.3

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

* [RFC 6/7] eal/soc: make SoC infra testable on any platform
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (4 preceding siblings ...)
  2016-01-01 21:05 ` [RFC 5/7] eal: init SoC infra on rte_eal_init Jan Viktorin
@ 2016-01-01 21:05 ` Jan Viktorin
  2016-01-01 21:05 ` [RFC 7/7] app/test: add SoC infra probe/detach test Jan Viktorin
                   ` (31 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-01-01 21:05 UTC (permalink / raw)
  To: dev; +Cc: Jan Viktorin

The hardcoded constant paths to sysfs and device-tree locations
makes the SoC infra difficult to test. With this code, it is
possible to override the default path by setting the appropriate
environment variables.

A test can provide a fake sysfs and device-tree hierarchy of devices.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/common/include/rte_soc.h |  6 ++++--
 lib/librte_eal/linuxapp/eal/eal_soc.c   | 15 +++++++++++++++
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 7c279b1..d7d6827 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -56,9 +56,11 @@ extern struct soc_device_list soc_device_list;
 extern struct soc_driver_list soc_driver_list;
 
 /* Path to detect platform devices (in architecture-specific bus systems). */
-#define SYSFS_SOC_DEVICES "/sys/bus/platform/devices"
+#define SYSFS_SOC_DEVICES __sysfs_soc_devices
+extern const char *__sysfs_soc_devices;
 /* Flat Device Tree location in the system. */
-#define FDT_ROOT "/proc/device-tree"
+#define FDT_ROOT __fdt_root
+extern const char *__fdt_root;
 
 struct rte_soc_resource {
 	uint64_t phys_addr; /**< Physical address, 0 if no resource. */
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index be0e44d..aafb9c3 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -46,6 +46,9 @@
 #include "eal_private.h"
 #include "eal_pci_init.h"
 
+const char *__sysfs_soc_devices = "/sys/bus/platform/devices";
+const char *__fdt_root = "/proc/device-tree";
+
 int
 soc_map_device(struct rte_soc_device *dev)
 {
@@ -378,12 +381,24 @@ error:
 int
 rte_eal_soc_init(void)
 {
+	char *tmp;
+
 	TAILQ_INIT(&soc_driver_list);
 	TAILQ_INIT(&soc_device_list);
 
 	if (internal_config.no_soc)
 		return 0;
 
+	if ((tmp = getenv("SYSFS_SOC_DEVICES")))
+		__sysfs_soc_devices = tmp;
+	else
+		__sysfs_soc_devices = "/sys/bus/platform/devices";
+
+	if ((tmp = getenv("FDT_ROOT")))
+		__fdt_root = tmp;
+	else
+		__fdt_root = "/proc/device-tree";
+
 	if (rte_eal_soc_scan() < 0) {
 		RTE_LOG(ERR, EAL, "%s(): Failed to scan for SoC devices\n",
 			__func__);
-- 
2.6.3

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

* [RFC 7/7] app/test: add SoC infra probe/detach test
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (5 preceding siblings ...)
  2016-01-01 21:05 ` [RFC 6/7] eal/soc: make SoC infra testable on any platform Jan Viktorin
@ 2016-01-01 21:05 ` Jan Viktorin
  2016-05-06 13:47 ` [PATCH v1 00/28] Support non-PCI devices Jan Viktorin
                   ` (30 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-01-01 21:05 UTC (permalink / raw)
  To: dev; +Cc: Jan Viktorin

The test probes for devices and tries to match with the test_driver0. The
test_driver0 assumes a fake device. The fake device is created by the provided
script soc_test_init.sh which creates a fake sysfs and fdt in the current
directory. Execute the test by:

  $ ./soc_test_init.sh setup
  $ export SYSFS_SOC_DEVICES=`pwd`/sys/bus/platform/devices
  $ expott FDT_ROOT=`pwd`/device-tree
  $ build/app/test --no-pci --no-huge --no-hpet -c 0x1 -n 1
  $ ./soc_test_init.sh clean

I did not find a proper way how to set the compatible property (a const char *)
list for the driver as DPDK has very strict compilation settings. I have no
idea how to setup the compatible with the const string unless the following
option is set:

 -Wno-error=incompatible-pointer-types

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 app/test/Makefile         |   3 +
 app/test/soc_test_init.sh |  61 ++++++++++++
 app/test/test_soc.c       | 249 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 313 insertions(+)
 create mode 100755 app/test/soc_test_init.sh
 create mode 100644 app/test/test_soc.c

diff --git a/app/test/Makefile b/app/test/Makefile
index ec33e1a..5bd2f16 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -44,6 +44,7 @@ APP = test
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) := commands.c
 SRCS-y += test.c
 SRCS-y += test_pci.c
+SRCS-y += test_soc.c
 SRCS-y += test_prefetch.c
 SRCS-y += test_byteorder.c
 SRCS-y += test_per_lcore.c
@@ -160,6 +161,8 @@ CFLAGS += $(WERROR_FLAGS)
 
 CFLAGS += -D_GNU_SOURCE
 
+CFLAGS_test_soc.o += -Wno-error=incompatible-pointer-types
+
 # Disable VTA for memcpy test
 ifeq ($(CC), gcc)
 ifeq ($(shell test $(GCC_VERSION) -ge 44 && echo 1), 1)
diff --git a/app/test/soc_test_init.sh b/app/test/soc_test_init.sh
new file mode 100755
index 0000000..1d808ee
--- /dev/null
+++ b/app/test/soc_test_init.sh
@@ -0,0 +1,61 @@
+#! /bin/sh
+
+uevent_create()
+{
+	echo "OF_FULLNAME=/rootbus/testdevice"
+	echo "OF_COMPATIBLE_N=1"
+	echo "OF_COMPATIBLE_0=dpdk,test-device"
+}
+
+setup_sys()
+{
+	cd ${1}
+
+	mkdir -p bus/platform/devices
+	cd bus/platform/devices
+
+	mkdir dpdk@testdevice
+	uevent_create > dpdk@testdevice/uevent
+
+	cd ${2}
+}
+
+setup_fdt()
+{
+	cd ${1}
+
+	mkdir rootbus
+	mkdir rootbus/testdevice
+	echo -e 'dpdk,test-device\0' > rootbus/testdevice/compatible
+	echo -e 'test-device\0' > rootbus/testdevice/name
+
+	cd ${2}
+}
+
+setup()
+{
+	mkdir sys
+	mkdir device-tree
+
+	cur=`pwd`
+	sys=$cur/sys
+	fdt=$cur/device-tree
+
+	setup_sys "$sys" "$cur"
+	setup_fdt "$fdt" "$cur"
+}
+
+clean()
+{
+	rm -rf device-tree
+	rm -rf sys
+}
+
+if [ "${1}" = "setup" ]; then
+	setup
+elif [ "${1}" = "clean" ]; then
+	clean
+else
+	echo "Specify either 'setup' or 'clean' command" >&2
+	exit -1
+fi
diff --git a/app/test/test_soc.c b/app/test/test_soc.c
new file mode 100644
index 0000000..6042626
--- /dev/null
+++ b/app/test/test_soc.c
@@ -0,0 +1,249 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <sys/queue.h>
+
+#include <rte_interrupts.h>
+#include <rte_soc.h>
+#include <rte_ethdev.h>
+#include <rte_devargs.h>
+
+#include "test.h"
+
+#define NUM_MAX_DRIVERS 256
+
+static unsigned int soc_dev_init_count;
+static unsigned int soc_dev_uninit_count;
+
+static int test_driver0_init(struct rte_soc_driver *dr,
+		struct rte_soc_device *dev)
+{
+	printf("Initialize %s\n", dr->name);
+	printf("Device: %s\n", dev->addr.devtree_path);
+
+	soc_dev_init_count += 1;
+	return 0;
+}
+
+static int test_driver0_uninit(struct rte_soc_device *dev)
+{
+	if (dev->driver == NULL) {
+		printf("Uninitialize device %s without any driver\n",
+			dev->addr.devtree_path);
+	} else {
+		printf("Uninitialize device %s bound to %s\n",
+			dev->addr.devtree_path, dev->driver->name);
+	}
+
+	soc_dev_uninit_count += 1;
+	return 0;
+}
+
+static const char *test_driver0_compatible[] = {
+	"dpdk,test-device",
+	NULL
+};
+
+static const struct rte_soc_id test_driver0_id_table[] = {
+	{
+		.compatible = test_driver0_compatible
+	},
+	{
+		.compatible = NULL
+	}
+};
+
+static struct rte_soc_driver test_driver0 = {
+	.name = "test_driver0",
+	.devinit = test_driver0_init,
+	.devuninit = test_driver0_uninit,
+	.id_table = test_driver0_id_table,
+	.drv_flags = 0
+};
+
+static void
+rte_eal_soc_detach_all(void)
+{
+	struct rte_soc_device *dev = NULL;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		int rc = rte_eal_soc_detach(&dev->addr);
+		if (rc != 0) {
+			rte_exit(EXIT_FAILURE, "Failed to detach device %s\n",
+				dev->addr.devtree_path);
+		}
+	}
+}
+
+static int
+blacklist_all_devices(void)
+{
+	struct rte_soc_device *dev = NULL;
+	int i = 0;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		int rc = rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_SOC,
+			dev->addr.devtree_path);
+
+		if (rc < 0) {
+			printf("Failed to blacklist device %s\n",
+				dev->addr.devtree_path);
+			return -1;
+		}
+
+		i += 1;
+	}
+
+	printf("%u devices have been blacklisted\n", i);
+	return 0;
+}
+
+static void free_devargs_list(void)
+{
+	struct rte_devargs *devargs;
+
+	while (!TAILQ_EMPTY(&devargs_list)) {
+		devargs = TAILQ_FIRST(&devargs_list);
+		TAILQ_REMOVE(&devargs_list, devargs, next);
+		if (devargs->args)
+			free(devargs->args);
+
+		free(devargs);
+	}
+}
+
+int test_soc_run = 0; /* value checked by the multiprocess test */
+
+static int
+test_soc(void)
+{
+	struct rte_devargs_list save_devargs_list;
+	struct rte_soc_driver *dr = NULL;
+	struct rte_soc_driver *save_soc_driver_list[NUM_MAX_DRIVERS];
+	int num_drivers = 0;
+	int i;
+	int rc = 0;
+
+	if (TAILQ_EMPTY(&soc_device_list)) {
+		printf("There are no SoC devices detected\n");
+		return -1;
+	}
+
+	printf("Dump all devices\n");
+	rte_eal_soc_dump(stdout);
+
+	TAILQ_FOREACH(dr, &soc_driver_list, next) {
+		rte_eal_soc_unregister(dr);
+		save_soc_driver_list[num_drivers++] = dr;
+	}
+
+	rte_eal_soc_register(&test_driver0);
+
+	soc_dev_init_count = 0;
+	soc_dev_uninit_count = 0;
+
+	printf("Probe SoC devices\n");
+	rte_eal_soc_probe();
+
+	if (soc_dev_init_count == 0) {
+		printf("No SoC device detected\n");
+		rc = -1;
+		goto failed;
+	}
+
+	rte_eal_soc_detach_all();
+
+	if (soc_dev_init_count != soc_dev_uninit_count) {
+		printf("Detached %u out of %u devices\n",
+			soc_dev_uninit_count, soc_dev_init_count);
+		rc = -1;
+		goto failed;
+	}
+
+	if (rte_eal_soc_scan()) {
+		printf("Failed to scan for SoC devices\n");
+		rc = -1;
+		goto failed;
+	}
+
+	if (TAILQ_EMPTY(&soc_device_list)) {
+		printf("There are no SoC devices detected\n");
+		rc = -1;
+		goto failed;
+	}
+
+	save_devargs_list = devargs_list;
+	TAILQ_INIT(&devargs_list);
+
+	if (blacklist_all_devices()) {
+		free_devargs_list();
+		devargs_list = save_devargs_list;
+		rc = -1;
+		goto failed_devargs_restore;
+	}
+
+	soc_dev_init_count = 0;
+	soc_dev_uninit_count = 0;
+
+	printf("Probe SoC devices while all are blacklisted\n");
+	rte_eal_soc_probe();
+
+	if (soc_dev_init_count != 0) {
+		printf("%u devices where probed while blacklisted\n",
+			soc_dev_init_count);
+		rc = -1;
+	}
+
+failed_devargs_restore:
+	free_devargs_list();
+	devargs_list = save_devargs_list;
+
+failed:
+	rte_eal_soc_unregister(&test_driver0);
+
+	test_soc_run = 1;
+
+	for (i = 0; i < num_drivers; ++i)
+		rte_eal_soc_register(save_soc_driver_list[i]);
+
+	return rc;
+}
+
+static struct test_command soc_cmd = {
+	.command = "soc_autotest",
+	.callback = test_soc,
+};
+REGISTER_TEST_COMMAND(soc_cmd);
-- 
2.6.3

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

* Re: [RFC 1/7] eal/common: define rte_soc_* related common interface
  2016-01-01 21:05 ` [RFC 1/7] eal/common: define rte_soc_* related common interface Jan Viktorin
@ 2016-01-02 18:01   ` Stephen Hemminger
  2016-01-02 18:35     ` Wiles, Keith
  2016-01-02 18:45     ` Jan Viktorin
  0 siblings, 2 replies; 231+ messages in thread
From: Stephen Hemminger @ 2016-01-02 18:01 UTC (permalink / raw)
  To: Jan Viktorin; +Cc: dev

On Fri,  1 Jan 2016 22:05:20 +0100
Jan Viktorin <viktorin@rehivetech.com> wrote:

> Introduce the interface to SoC device infrastructure. A SoC device
> here means a device integrated on the chip via a (simple) bus
> that lacks of auto-discovery and other properties which are common
> for PCI. A counterpart in the Linux Kernel would be a platform_device
> (but this is not necessarily 1:1 mapping).
> 
> Systems without auto-discovery properties are described by a (Flat)
> Device Tree. Device Tree is usually available on embedded systems
> in /proc/device-tree. Every device has a unique path in the Device
> Tree and so it identifies every such device. This path is used
> to identify a device in rte_soc_addr.
> 
> Binding of drivers to devices in the Linux Kernel is often done
> by matching the compatible entry in the Device Tree. As there is
> no standard/generic way to read information like vendor, model, etc.
> from each SoC device, we match devices by the compatible entry too.
> The rte_soc_id contains an array of compatible strings telling what
> each device is compatible with.
> 
> There are no DPDK-specific OS drivers for SoC devices at the moment
> and unfortunately we cannot use the PCI-related ones as they contain
> too much PCI-specific logic.
> 
> Whitelisting and blacklisting of devices is based on the Device Tree
> identifier (rte_soc_addr) to mimic the PCI behaviour.
> 
> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>

Yes, DPDK needs to work in embedded environments with device tree.
Would it be possible reimplement device tree parsing in user space?
Ideally with a shared code from kernel??

On a pratical level, the new SoC support must be optional
(via DPDK config infrastructure), since most architectures won't be using it.
In most cases, it is better from usability if everything is runtime based,
but with SoC this is a platform/architecture configuration.

Do you consider this will break binary compatibility since
sizeof (rte_soc_addr) is PATH_MAX (1024) and the other elements of the
union inside rte_devargs are much smaller (like 32 bytes).

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

* Re: [RFC 1/7] eal/common: define rte_soc_* related common interface
  2016-01-02 18:01   ` Stephen Hemminger
@ 2016-01-02 18:35     ` Wiles, Keith
  2016-01-02 18:52       ` Jan Viktorin
  2016-01-02 18:45     ` Jan Viktorin
  1 sibling, 1 reply; 231+ messages in thread
From: Wiles, Keith @ 2016-01-02 18:35 UTC (permalink / raw)
  To: Stephen Hemminger, Jan Viktorin; +Cc: dev

On 1/2/16, 12:01 PM, "dev on behalf of Stephen Hemminger" <dev-bounces@dpdk.org on behalf of stephen@networkplumber.org> wrote:

>On Fri,  1 Jan 2016 22:05:20 +0100
>Jan Viktorin <viktorin@rehivetech.com> wrote:
>
>> Introduce the interface to SoC device infrastructure. A SoC device
>> here means a device integrated on the chip via a (simple) bus
>> that lacks of auto-discovery and other properties which are common
>> for PCI. A counterpart in the Linux Kernel would be a platform_device
>> (but this is not necessarily 1:1 mapping).
>> 
>> Systems without auto-discovery properties are described by a (Flat)
>> Device Tree. Device Tree is usually available on embedded systems
>> in /proc/device-tree. Every device has a unique path in the Device
>> Tree and so it identifies every such device. This path is used
>> to identify a device in rte_soc_addr.
>> 
>> Binding of drivers to devices in the Linux Kernel is often done
>> by matching the compatible entry in the Device Tree. As there is
>> no standard/generic way to read information like vendor, model, etc.
>> from each SoC device, we match devices by the compatible entry too.
>> The rte_soc_id contains an array of compatible strings telling what
>> each device is compatible with.
>> 
>> There are no DPDK-specific OS drivers for SoC devices at the moment
>> and unfortunately we cannot use the PCI-related ones as they contain
>> too much PCI-specific logic.
>> 
>> Whitelisting and blacklisting of devices is based on the Device Tree
>> identifier (rte_soc_addr) to mimic the PCI behaviour.
>> 
>> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>

I do like the idea of having a clean way to locate SoC devices and this design looks very clean to me with a brief read. Thanks Jan.
>
>Yes, DPDK needs to work in embedded environments with device tree.
>Would it be possible reimplement device tree parsing in user space?
>Ideally with a shared code from kernel??

Stephen, Do you mean we have to add kernel code to support DPDK on SoC Platforms? If that is the case I would like to not require code be added to the kernel to support DPDK.
>
>On a pratical level, the new SoC support must be optional
>(via DPDK config infrastructure), since most architectures won't be using it.
>In most cases, it is better from usability if everything is runtime based,
>but with SoC this is a platform/architecture configuration.

I am not sure I agree with the optional support, as it could be stated that PCI support is optional on SoC platforms. It would be best to not treat SoC support as special compared to PCI support. Other then extra footprint it does not seem reasonable to require SoC support to be ifdef’ed in the code. Plus adding more ifdefs is not a good testing solution.

Can we detect somehow we are on a system with SoC support or even a system that supports PCI for that matter?
>
>Do you consider this will break binary compatibility since
>sizeof (rte_soc_addr) is PATH_MAX (1024) and the other elements of the
>union inside rte_devargs are much smaller (like 32 bytes).
>
>


Regards,
Keith





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

* Re: [RFC 1/7] eal/common: define rte_soc_* related common interface
  2016-01-02 18:01   ` Stephen Hemminger
  2016-01-02 18:35     ` Wiles, Keith
@ 2016-01-02 18:45     ` Jan Viktorin
  2016-01-03 17:12       ` Jan Viktorin
  1 sibling, 1 reply; 231+ messages in thread
From: Jan Viktorin @ 2016-01-02 18:45 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

On Sat, 2 Jan 2016 10:01:44 -0800
Stephen Hemminger <stephen@networkplumber.org> wrote:

> On Fri,  1 Jan 2016 22:05:20 +0100
> Jan Viktorin <viktorin@rehivetech.com> wrote:
> 
> > Introduce the interface to SoC device infrastructure. A SoC device
> > here means a device integrated on the chip via a (simple) bus
> > that lacks of auto-discovery and other properties which are common
> > for PCI. A counterpart in the Linux Kernel would be a platform_device
> > (but this is not necessarily 1:1 mapping).
> > 
> > Systems without auto-discovery properties are described by a (Flat)
> > Device Tree. Device Tree is usually available on embedded systems
> > in /proc/device-tree. Every device has a unique path in the Device
> > Tree and so it identifies every such device. This path is used
> > to identify a device in rte_soc_addr.
> > 
> > Binding of drivers to devices in the Linux Kernel is often done
> > by matching the compatible entry in the Device Tree. As there is
> > no standard/generic way to read information like vendor, model, etc.
> > from each SoC device, we match devices by the compatible entry too.
> > The rte_soc_id contains an array of compatible strings telling what
> > each device is compatible with.
> > 
> > There are no DPDK-specific OS drivers for SoC devices at the moment
> > and unfortunately we cannot use the PCI-related ones as they contain
> > too much PCI-specific logic.
> > 
> > Whitelisting and blacklisting of devices is based on the Device Tree
> > identifier (rte_soc_addr) to mimic the PCI behaviour.
> > 
> > Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>  
> 
> Yes, DPDK needs to work in embedded environments with device tree.
> Would it be possible reimplement device tree parsing in user space?

This is possible, I've already done a simple library for this few years
ago [1]. However, I don't think it is suitable for DPDK.

> Ideally with a shared code from kernel??

I have no idea what kernel code do you mean to share with... the
drivers/of/*? In userspace, the device-tree is accessible via the
filesystem (/proc/device-tree). So, I cannot see any overlap with
the kernel code.

> 
> On a pratical level, the new SoC support must be optional
> (via DPDK config infrastructure), since most architectures won't be using it.
> In most cases, it is better from usability if everything is runtime based,
> but with SoC this is a platform/architecture configuration.

I agree. In this RFC, it is not optional yet. On the EAL level, it's a
matter of the right ifdefs and Makefile conditionals (I think) - it does
not look to be an issue from my point of view.

The problem will arise with the lib/* stuff as eg. librte_ether depends
on pci-specific data structures very deeply. I've just finished a quick
raw librte_ether extension of the SoC devices support trying to preserve
API/ABI. Although, it is hopefully possible to preserve ABI (with SoC
disabled), the code becomes a little bit spagetti-like...

> 
> Do you consider this will break binary compatibility since
> sizeof (rte_soc_addr) is PATH_MAX (1024) and the other elements of the
> union inside rte_devargs are much smaller (like 32 bytes).
> 

I had a bad feeling about this... Originally, I started with a pointer
'const char *' so it can be done that way... However, this brings
compilator mad as it does not allow to cast char * -> const char *
because of the strict DPDK compilation settings. I didn't find any
workaround yet. I think I can make it just 'char *' for the next version
of the patch set.


[1] https://github.com/jviki/dtree

-- 
  Jan Viktorin                E-mail: Viktorin@RehiveTech.com
  System Architect            Web:    www.RehiveTech.com
  RehiveTech
  Brno, Czech Republic

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

* Re: [RFC 1/7] eal/common: define rte_soc_* related common interface
  2016-01-02 18:35     ` Wiles, Keith
@ 2016-01-02 18:52       ` Jan Viktorin
  2016-01-02 19:13         ` Wiles, Keith
  2016-01-02 19:14         ` Stephen Hemminger
  0 siblings, 2 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-01-02 18:52 UTC (permalink / raw)
  To: Wiles, Keith; +Cc: dev

On Sat, 2 Jan 2016 18:35:08 +0000
"Wiles, Keith" <keith.wiles@intel.com> wrote:

> >Yes, DPDK needs to work in embedded environments with device tree.
> >Would it be possible reimplement device tree parsing in user space?
> >Ideally with a shared code from kernel??  
> 
> Stephen, Do you mean we have to add kernel code to support DPDK on SoC Platforms? If that is the case I would like to not require code be added to the kernel to support DPDK.

We will need a kernel module. But this is not necessarily related to the
device-tree parsing.

> >
> >On a pratical level, the new SoC support must be optional
> >(via DPDK config infrastructure), since most architectures won't be using it.
> >In most cases, it is better from usability if everything is runtime based,
> >but with SoC this is a platform/architecture configuration.  
> 
> I am not sure I agree with the optional support, as it could be stated that PCI support is optional on SoC platforms. It would be best to not treat SoC support as special compared to PCI support. Other then extra footprint it does not seem reasonable to require SoC support to be ifdef’ed in the code. Plus adding more ifdefs is not a good testing solution.

This is a matter of preserving ABI. Turning PCI-support to be optional
seems to be a difficult step at the moment.

> 
> Can we detect somehow we are on a system with SoC support or even a system that supports PCI for that matter?

IMO, we can detect two things: "PCI is present on the system" and
"Device tree is accessible in /proc/device-tree". Is this acceptable?

-- 
  Jan Viktorin                E-mail: Viktorin@RehiveTech.com
  System Architect            Web:    www.RehiveTech.com
  RehiveTech
  Brno, Czech Republic

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

* Re: [RFC 1/7] eal/common: define rte_soc_* related common interface
  2016-01-02 18:52       ` Jan Viktorin
@ 2016-01-02 19:13         ` Wiles, Keith
  2016-01-02 19:14         ` Stephen Hemminger
  1 sibling, 0 replies; 231+ messages in thread
From: Wiles, Keith @ 2016-01-02 19:13 UTC (permalink / raw)
  To: Jan Viktorin; +Cc: dev

On 1/2/16, 12:52 PM, "Jan Viktorin" <viktorin@rehivetech.com> wrote:

>On Sat, 2 Jan 2016 18:35:08 +0000
>"Wiles, Keith" <keith.wiles@intel.com> wrote:
>
>> >Yes, DPDK needs to work in embedded environments with device tree.
>> >Would it be possible reimplement device tree parsing in user space?
>> >Ideally with a shared code from kernel??  
>> 
>> Stephen, Do you mean we have to add kernel code to support DPDK on SoC Platforms? If that is the case I would like to not require code be added to the kernel to support DPDK.
>
>We will need a kernel module. But this is not necessarily related to the
>device-tree parsing.
>
>> >
>> >On a pratical level, the new SoC support must be optional
>> >(via DPDK config infrastructure), since most architectures won't be using it.
>> >In most cases, it is better from usability if everything is runtime based,
>> >but with SoC this is a platform/architecture configuration.  
>> 
>> I am not sure I agree with the optional support, as it could be stated that PCI support is optional on SoC platforms. It would be best to not treat SoC support as special compared to PCI support. Other then extra footprint it does not seem reasonable to require SoC support to be ifdef’ed in the code. Plus adding more ifdefs is not a good testing solution.
>
>This is a matter of preserving ABI. Turning PCI-support to be optional
>seems to be a difficult step at the moment.

Turning off PCI support is bit hard to do as well, I was looking for a way to execute the PCI or SoC code during startup. I think having both compiled into the DPDK , but figure out how to detect if that code needs to be run is the better solution as you have pointed out later.
>
>> 
>> Can we detect somehow we are on a system with SoC support or even a system that supports PCI for that matter?
>
>IMO, we can detect two things: "PCI is present on the system" and
>"Device tree is accessible in /proc/device-tree". Is this acceptable?

I guess this would be fine with me, as I do not like us to add ifdefs.
>
>-- 
>  Jan Viktorin                E-mail: Viktorin@RehiveTech.com
>  System Architect            Web:    www.RehiveTech.com
>  RehiveTech
>  Brno, Czech Republic
>


Regards,
Keith





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

* Re: [RFC 1/7] eal/common: define rte_soc_* related common interface
  2016-01-02 18:52       ` Jan Viktorin
  2016-01-02 19:13         ` Wiles, Keith
@ 2016-01-02 19:14         ` Stephen Hemminger
  2016-01-02 19:22           ` Wiles, Keith
  1 sibling, 1 reply; 231+ messages in thread
From: Stephen Hemminger @ 2016-01-02 19:14 UTC (permalink / raw)
  To: Jan Viktorin; +Cc: dev

On Sat, 2 Jan 2016 19:52:16 +0100
Jan Viktorin <viktorin@rehivetech.com> wrote:

> On Sat, 2 Jan 2016 18:35:08 +0000
> "Wiles, Keith" <keith.wiles@intel.com> wrote:
> 
> > >Yes, DPDK needs to work in embedded environments with device tree.
> > >Would it be possible reimplement device tree parsing in user space?
> > >Ideally with a shared code from kernel??  
> > 
> > Stephen, Do you mean we have to add kernel code to support DPDK on SoC Platforms? If that is the case I would like to not require code be added to the kernel to support DPDK.
> 
> We will need a kernel module. But this is not necessarily related to the
> device-tree parsing.
> 
> > >
> > >On a pratical level, the new SoC support must be optional
> > >(via DPDK config infrastructure), since most architectures won't be using it.
> > >In most cases, it is better from usability if everything is runtime based,
> > >but with SoC this is a platform/architecture configuration.  
> > 
> > I am not sure I agree with the optional support, as it could be stated that PCI support is optional on SoC platforms. It would be best to not treat SoC support as special compared to PCI support. Other then extra footprint it does not seem reasonable to require SoC support to be ifdef’ed in the code. Plus adding more ifdefs is not a good testing solution.
> 
> This is a matter of preserving ABI. Turning PCI-support to be optional
> seems to be a difficult step at the moment.
> 
> > 
> > Can we detect somehow we are on a system with SoC support or even a system that supports PCI for that matter?
> 
> IMO, we can detect two things: "PCI is present on the system" and
> "Device tree is accessible in /proc/device-tree". Is this acceptable?
> 

I am just as concerned with building and having useless code.
For now most environments can just use PCI, and having to carry around
dead code seems wasteful and potential for some security abuse as well.

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

* Re: [RFC 1/7] eal/common: define rte_soc_* related common interface
  2016-01-02 19:14         ` Stephen Hemminger
@ 2016-01-02 19:22           ` Wiles, Keith
  0 siblings, 0 replies; 231+ messages in thread
From: Wiles, Keith @ 2016-01-02 19:22 UTC (permalink / raw)
  To: Stephen Hemminger, Jan Viktorin; +Cc: dev

On 1/2/16, 1:14 PM, "Stephen Hemminger" <stephen@networkplumber.org> wrote:

>On Sat, 2 Jan 2016 19:52:16 +0100
>Jan Viktorin <viktorin@rehivetech.com> wrote:
>
>> On Sat, 2 Jan 2016 18:35:08 +0000
>> "Wiles, Keith" <keith.wiles@intel.com> wrote:
>> 
>> > >Yes, DPDK needs to work in embedded environments with device tree.
>> > >Would it be possible reimplement device tree parsing in user space?
>> > >Ideally with a shared code from kernel??  
>> > 
>> > Stephen, Do you mean we have to add kernel code to support DPDK on SoC Platforms? If that is the case I would like to not require code be added to the kernel to support DPDK.
>> 
>> We will need a kernel module. But this is not necessarily related to the
>> device-tree parsing.
>> 
>> > >
>> > >On a pratical level, the new SoC support must be optional
>> > >(via DPDK config infrastructure), since most architectures won't be using it.
>> > >In most cases, it is better from usability if everything is runtime based,
>> > >but with SoC this is a platform/architecture configuration.  
>> > 
>> > I am not sure I agree with the optional support, as it could be stated that PCI support is optional on SoC platforms. It would be best to not treat SoC support as special compared to PCI support. Other then extra footprint it does not seem reasonable to require SoC support to be ifdef’ed in the code. Plus adding more ifdefs is not a good testing solution.
>> 
>> This is a matter of preserving ABI. Turning PCI-support to be optional
>> seems to be a difficult step at the moment.
>> 
>> > 
>> > Can we detect somehow we are on a system with SoC support or even a system that supports PCI for that matter?
>> 
>> IMO, we can detect two things: "PCI is present on the system" and
>> "Device tree is accessible in /proc/device-tree". Is this acceptable?
>> 
>
>I am just as concerned with building and having useless code.
>For now most environments can just use PCI, and having to carry around
>dead code seems wasteful and potential for some security abuse as well.

Hi Stephen,

With including every archive with the include whole archive option means we already have a huge amount of dead code in a DPDK image :-( Adding a bit more is not going to make a difference IMO. Also a system without PCI could be a security abuse too.

I think we just figure out how not to call the PCI or SoC code at runtime if not supported and compile it in always.
>


Regards,
Keith





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

* Re: [RFC 1/7] eal/common: define rte_soc_* related common interface
  2016-01-02 18:45     ` Jan Viktorin
@ 2016-01-03 17:12       ` Jan Viktorin
  2016-01-04 15:21         ` Wiles, Keith
  0 siblings, 1 reply; 231+ messages in thread
From: Jan Viktorin @ 2016-01-03 17:12 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

On Sat, 2 Jan 2016 19:45:40 +0100
Jan Viktorin <viktorin@rehivetech.com> wrote:

> > 
> > Do you consider this will break binary compatibility since
> > sizeof (rte_soc_addr) is PATH_MAX (1024) and the other elements of the
> > union inside rte_devargs are much smaller (like 32 bytes).
> >   
> 
> I had a bad feeling about this... Originally, I started with a pointer
> 'const char *' so it can be done that way... However, this brings
> compilator mad as it does not allow to cast char * -> const char *
> because of the strict DPDK compilation settings. I didn't find any
> workaround yet. I think I can make it just 'char *' for the next version
> of the patch set.

Having rte_devargs to contain only char * instead of char[PATH_MAX]
brings an issue. There is no common devargs_free function. Inside the
function rte_eal_devargs_add, I must malloc memory here to fill the
devtree_path. But there is no general way to free it. At least, I
didn't find such code... I need to do this:

108         case RTE_DEVTYPE_WHITELISTED_SOC:
109         case RTE_DEVTYPE_BLACKLISTED_SOC:
110                 devargs->soc.addr.devtree_path = strdup(buf);

because the buf variable is deallocated at the end of the function.

In fact, I do not clearly understand the rte_eal_devargs_add function.
What is the expected input? The call to rte_eal_parse_devargs_str
separates the string into drvname and drvargs. What are the drvargs
supposted to be? I'd expect the user types -w <deviceid> or -b <deviceid>
(for PCI <deviceid> is the quaternion, for SoC it's the device-tree
path).

Regards
Jan

-- 
  Jan Viktorin                E-mail: Viktorin@RehiveTech.com
  System Architect            Web:    www.RehiveTech.com
  RehiveTech
  Brno, Czech Republic

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

* Re: [RFC 1/7] eal/common: define rte_soc_* related common interface
  2016-01-03 17:12       ` Jan Viktorin
@ 2016-01-04 15:21         ` Wiles, Keith
  0 siblings, 0 replies; 231+ messages in thread
From: Wiles, Keith @ 2016-01-04 15:21 UTC (permalink / raw)
  To: Jan Viktorin, Stephen Hemminger; +Cc: dev

On 1/3/16, 11:12 AM, "dev on behalf of Jan Viktorin" <dev-bounces@dpdk.org on behalf of viktorin@rehivetech.com> wrote:

>On Sat, 2 Jan 2016 19:45:40 +0100
>Jan Viktorin <viktorin@rehivetech.com> wrote:
>
>> > 
>> > Do you consider this will break binary compatibility since
>> > sizeof (rte_soc_addr) is PATH_MAX (1024) and the other elements of the
>> > union inside rte_devargs are much smaller (like 32 bytes).
>> >   
>> 
>> I had a bad feeling about this... Originally, I started with a pointer
>> 'const char *' so it can be done that way... However, this brings
>> compilator mad as it does not allow to cast char * -> const char *
>> because of the strict DPDK compilation settings. I didn't find any
>> workaround yet. I think I can make it just 'char *' for the next version
>> of the patch set.
>
>Having rte_devargs to contain only char * instead of char[PATH_MAX]
>brings an issue. There is no common devargs_free function. Inside the
>function rte_eal_devargs_add, I must malloc memory here to fill the
>devtree_path. But there is no general way to free it. At least, I
>didn't find such code... I need to do this:
>
>108         case RTE_DEVTYPE_WHITELISTED_SOC:
>109         case RTE_DEVTYPE_BLACKLISTED_SOC:
>110                 devargs->soc.addr.devtree_path = strdup(buf);
>
>because the buf variable is deallocated at the end of the function.
>
>In fact, I do not clearly understand the rte_eal_devargs_add function.
>What is the expected input? The call to rte_eal_parse_devargs_str
>separates the string into drvname and drvargs. What are the drvargs
>supposted to be? I'd expect the user types -w <deviceid> or -b <deviceid>
>(for PCI <deviceid> is the quaternion, for SoC it's the device-tree
>path).
>
>Regards
>Jan
>
>-- 
>  Jan Viktorin                E-mail: Viktorin@RehiveTech.com
>  System Architect            Web:    www.RehiveTech.com
>  RehiveTech
>  Brno, Czech Republic
>


Regards,
Keith





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

* [PATCH v1 00/28] Support non-PCI devices
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (6 preceding siblings ...)
  2016-01-01 21:05 ` [RFC 7/7] app/test: add SoC infra probe/detach test Jan Viktorin
@ 2016-05-06 13:47 ` Jan Viktorin
  2016-05-06 13:47 ` [PATCH v1 01/28] eal: make enum rte_kernel_driver non-PCI specific Jan Viktorin
                   ` (29 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:47 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

Hello,

as a part of reworking the rte_(pci_)device/driver core of DPDK, I am
developing support for devices connected anotherway then by the PCI bus. I call
those devices _SoC devices_ and they are similar to the kernel's
platform_device. The goal is to have access to the on-chip MACs integrated
into many SoCs.

This patch set depends on

* [PATCH v2 00/17] prepare for rte_device / rte_driver
  http://thread.gmane.org/gmane.comp.networking.dpdk.devel/32387

Patches have been generated and tested on top of 84c9b5a (& 32387)
	
There are some BSD stubs (but I didn't test whether this is enough to not break
the BSD builds).

I've generalized certain internal (PCI-specific) functions of EAL to reuse them
by the SoC infrastructure (patches 1-5).

Then the SoC infra is introduced in quite small steps (6-22). For some of those
steps I've got an auto test (however not included to avoid introducing
dependencies on other series - (3)). Note:

* rte_soc_device/driver has a lot of common contents with rte_pci_* ones. This
  is a subject of future changes - introduction of rte_driver/device. The
  common members of device are:
  - next,
  - intr_handle,
  - numa_node,
  - devargs,
  - kdrv.

  The some for driver:
  - next
  - name
  - drv_flags
  
  Moreover, the addr, id and driver (from device), and devinit, devuninit
  and id_tables can be generalized to some degree as well.

* Do we want a list of PCI devices/drivers, a list of SoC devices/drivers
  (separated) or integrated into a single list and check for some type member?
  When iterating over a generic rte_driver/device, it introduces a lot of bloat
  code:

    struct rte_driver *drv;
    struct rte_pci_driver *pci_drv;
    TAILQ_FOREACH(drv, drivers_list, next) {
	    if (!is_pci(drv))
		    continue;
	    pci_drv = to_pci_driver(drv);
	    ...
    }

  I didn't find a way how to wrap this into something like PCI_DRV_FOREACH(...)
  (sys/queue.h is not suitable for this).

* rte_soc_resource and rte_pci_resource can be generalized to rte_resource.
  The similar might be possible for pci_map and mapped_pci_resource.

* RTE_*_DRV_* flags should be generalized.

* rte_soc_id has problem with the compatible property that must be const
  but we need to see it as non-const (GCC doesn't like it). Thus, I've used
  a workaround (union).

* rte_soc_addr contains fdt_path string - this can be connected with the FDT
  API (1) if possible later.

* I parse devargs by testing presence of a prefix "soc:" (not tested).

Finally (23-28), I created the necessary glue code to connect with
librte_ether. You can see that this is not a problem anymore, however, it
duplicates code. So, at this stage, the generic rte_driver/device is not
necessary but would be helpful.

I've also investigated how the VFIO and UIO work. After refactoring of the VFIO
as done in (2), it is possible to add a SoC-VFIO layer. Similar for UIO. It is
possible to utilize uio_pdev_genirq or (patched) uio_dmem_genirq. The
uio_dmem_genirq is better (after few small changes) as it provides access to
the DMA coherent memory. The VFIO should be used on platforms with I/O MMU
and with hugepages. I think, those extensions are for 16.11 as it's another
quite long amount of code. However, it it is not necessary to break APIs.

I've already posted 3 related patch sets:

(1) [RFC 0/6] Flattened Device Tree access from DPDK
    http://thread.gmane.org/gmane.comp.networking.dpdk.devel/36545

(2) [PATCH 00/15] Make VFIO support independent on PCI
    http://article.gmane.org/gmane.comp.networking.dpdk.devel/38154

(3) [PATCH v1 00/10] Include resources in tests
    http://thread.gmane.org/gmane.comp.networking.dpdk.devel/38459

I do my best to leave those patch sets independent on each other but they all
should finally work together.

The end :-). The patch set is designed to be merged partially, if needed
(due to its size) and at this stage it should help to solve the rte_driver /
rte_device task.

Regards
Jan

Jan Viktorin (28):
  eal: make enum rte_kernel_driver non-PCI specific
  eal: extract function eal_parse_sysfs_valuef
  eal/linux: extract function rte_eal_unbind_kernel_driver
  eal/linux: extract function rte_eal_get_kernel_driver_by_path
  eal: remove pci_ prefix from pci_(un)map_resource
  eal/soc: introduce very essential SoC infra definitions
  eal/soc: add rte_eal_soc_register/unregister logic
  eal/soc: implement SoC device discovery
  eal: introduce --no-soc option
  eal/soc: init SoC infra from EAL
  eal/soc: implement probing of drivers
  eal/soc: extend and utilize devargs
  eal/soc: update device on probe when already exists
  eal/soc: detect assigned kernel driver
  eal/soc: map/unmap resources
  eal/soc: add intr_handle
  eal/soc: hack (const char *) compatible setting
  eal/soc: detect numa_node of the rte_soc_device
  eal/soc: add drv_flags
  eal/soc: map resources conditionally
  eal/soc: unbind kernel driver on probe
  eal/soc: detect DMA non-coherent devices
  eal: define macro container_of
  ether: utilize container_of for pci_drv
  ether: verify we copy info from a PCI device
  ether: extract function eth_dev_get_intr_handle
  ether: extract function eth_dev_get_driver_name
  ether: support SoC device/driver

 app/test/Makefile                               |   1 +
 app/test/test_soc.c                             | 199 ++++++++++
 lib/librte_eal/bsdapp/eal/Makefile              |   2 +
 lib/librte_eal/bsdapp/eal/eal.c                 |   4 +
 lib/librte_eal/bsdapp/eal/eal_pci.c             |   2 +-
 lib/librte_eal/bsdapp/eal/eal_soc.c             |  52 +++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  11 +
 lib/librte_eal/common/Makefile                  |   2 +-
 lib/librte_eal/common/eal_common_dev.c          |  70 +++-
 lib/librte_eal/common/eal_common_devargs.c      |   7 +
 lib/librte_eal/common/eal_common_options.c      |   5 +
 lib/librte_eal/common/eal_common_pci.c          |  39 --
 lib/librte_eal/common/eal_common_pci_uio.c      |   6 +-
 lib/librte_eal/common/eal_common_soc.c          | 373 ++++++++++++++++++
 lib/librte_eal/common/eal_filesystem.h          |   5 +
 lib/librte_eal/common/eal_internal_cfg.h        |   1 +
 lib/librte_eal/common/eal_options.h             |   2 +
 lib/librte_eal/common/eal_private.h             |  96 +++++
 lib/librte_eal/common/include/rte_common.h      |  16 +
 lib/librte_eal/common/include/rte_dev.h         |   8 +
 lib/librte_eal/common/include/rte_devargs.h     |   8 +
 lib/librte_eal/common/include/rte_pci.h         |  42 +-
 lib/librte_eal/common/include/rte_soc.h         | 296 ++++++++++++++
 lib/librte_eal/linuxapp/eal/Makefile            |   2 +
 lib/librte_eal/linuxapp/eal/eal.c               |  98 ++++-
 lib/librte_eal/linuxapp/eal/eal_pci.c           |  62 +--
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c       |   3 +-
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c      |   4 +-
 lib/librte_eal/linuxapp/eal/eal_soc.c           | 492 ++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  13 +
 lib/librte_ether/rte_ethdev.c                   | 163 +++++++-
 lib/librte_ether/rte_ethdev.h                   |  33 +-
 32 files changed, 1952 insertions(+), 165 deletions(-)
 create mode 100644 app/test/test_soc.c
 create mode 100644 lib/librte_eal/bsdapp/eal/eal_soc.c
 create mode 100644 lib/librte_eal/common/eal_common_soc.c
 create mode 100644 lib/librte_eal/common/include/rte_soc.h
 create mode 100644 lib/librte_eal/linuxapp/eal/eal_soc.c

-- 
2.8.0

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

* [PATCH v1 01/28] eal: make enum rte_kernel_driver non-PCI specific
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (7 preceding siblings ...)
  2016-05-06 13:47 ` [PATCH v1 00/28] Support non-PCI devices Jan Viktorin
@ 2016-05-06 13:47 ` Jan Viktorin
  2016-05-06 13:47 ` [PATCH v1 02/28] eal: extract function eal_parse_sysfs_valuef Jan Viktorin
                   ` (28 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:47 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/common/include/rte_dev.h |  8 ++++++++
 lib/librte_eal/common/include/rte_pci.h | 10 +---------
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index b1c0520..ad4bfeb 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -100,6 +100,14 @@ rte_pmd_debug_trace(const char *func_name, const char *fmt, ...)
 	} \
 } while (0)
 
+enum rte_kernel_driver {
+	RTE_KDRV_UNKNOWN = 0,
+	RTE_KDRV_IGB_UIO,
+	RTE_KDRV_VFIO,
+	RTE_KDRV_UIO_GENERIC,
+	RTE_KDRV_NIC_UIO,
+	RTE_KDRV_NONE,
+};
 
 /** Double linked list of device drivers. */
 TAILQ_HEAD(rte_driver_list, rte_driver);
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 169b746..dab150e 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -83,6 +83,7 @@ extern "C" {
 #include <inttypes.h>
 
 #include <rte_debug.h>
+#include <rte_dev.h>
 #include <rte_interrupts.h>
 
 TAILQ_HEAD(pci_device_list, rte_pci_device); /**< PCI devices in D-linked Q. */
@@ -145,15 +146,6 @@ struct rte_pci_addr {
 
 struct rte_devargs;
 
-enum rte_kernel_driver {
-	RTE_KDRV_UNKNOWN = 0,
-	RTE_KDRV_IGB_UIO,
-	RTE_KDRV_VFIO,
-	RTE_KDRV_UIO_GENERIC,
-	RTE_KDRV_NIC_UIO,
-	RTE_KDRV_NONE,
-};
-
 /**
  * A structure describing a PCI device.
  */
-- 
2.8.0

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

* [PATCH v1 02/28] eal: extract function eal_parse_sysfs_valuef
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (8 preceding siblings ...)
  2016-05-06 13:47 ` [PATCH v1 01/28] eal: make enum rte_kernel_driver non-PCI specific Jan Viktorin
@ 2016-05-06 13:47 ` Jan Viktorin
  2016-05-06 13:47 ` [PATCH v1 03/28] eal/linux: extract function rte_eal_unbind_kernel_driver Jan Viktorin
                   ` (27 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:47 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

The eal_parse_sysfs_value function accepts a filename however, such interface
introduces race-conditions to the code. Introduce the variant of this function
that accepts an already opened file instead of a filename.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/common/eal_filesystem.h |  5 +++++
 lib/librte_eal/linuxapp/eal/eal.c      | 36 +++++++++++++++++++++++-----------
 2 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/lib/librte_eal/common/eal_filesystem.h b/lib/librte_eal/common/eal_filesystem.h
index fdb4a70..7875454 100644
--- a/lib/librte_eal/common/eal_filesystem.h
+++ b/lib/librte_eal/common/eal_filesystem.h
@@ -43,6 +43,7 @@
 /** Path of rte config file. */
 #define RUNTIME_CONFIG_FMT "%s/.%s_config"
 
+#include <stdio.h>
 #include <stdint.h>
 #include <limits.h>
 #include <unistd.h>
@@ -115,4 +116,8 @@ eal_get_hugefile_temp_path(char *buffer, size_t buflen, const char *hugedir, int
  * Used to read information from files on /sys */
 int eal_parse_sysfs_value(const char *filename, unsigned long *val);
 
+/** Function to read a single numeric value from a file on the filesystem.
+ * Used to read information from files on /sys */
+int eal_parse_sysfs_valuef(FILE *f, unsigned long *val);
+
 #endif /* EAL_FILESYSTEM_H */
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 4b28197..e8fce6b 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -126,13 +126,30 @@ rte_eal_get_configuration(void)
 	return &rte_config;
 }
 
+int
+eal_parse_sysfs_valuef(FILE *f, unsigned long *val)
+{
+	char buf[BUFSIZ];
+	char *end = NULL;
+
+	RTE_VERIFY(f != NULL);
+
+	if (fgets(buf, sizeof(buf), f) == NULL)
+		return -1;
+
+	*val = strtoul(buf, &end, 0);
+	if ((buf[0] == '\0') || (end == NULL) || (*end != '\n'))
+		return -2;
+
+	return 0;
+}
+
 /* parse a sysfs (or other) file containing one integer value */
 int
 eal_parse_sysfs_value(const char *filename, unsigned long *val)
 {
+	int ret;
 	FILE *f;
-	char buf[BUFSIZ];
-	char *end = NULL;
 
 	if ((f = fopen(filename, "r")) == NULL) {
 		RTE_LOG(ERR, EAL, "%s(): cannot open sysfs value %s\n",
@@ -140,21 +157,18 @@ eal_parse_sysfs_value(const char *filename, unsigned long *val)
 		return -1;
 	}
 
-	if (fgets(buf, sizeof(buf), f) == NULL) {
+	ret = eal_parse_sysfs_valuef(f, val);
+	if (ret == -1) {
 		RTE_LOG(ERR, EAL, "%s(): cannot read sysfs value %s\n",
-			__func__, filename);
-		fclose(f);
-		return -1;
+				__func__, filename);
 	}
-	*val = strtoul(buf, &end, 0);
-	if ((buf[0] == '\0') || (end == NULL) || (*end != '\n')) {
+	else if (ret < 0) {
 		RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs value %s\n",
 				__func__, filename);
-		fclose(f);
-		return -1;
 	}
+
 	fclose(f);
-	return 0;
+	return ret;
 }
 
 
-- 
2.8.0

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

* [PATCH v1 03/28] eal/linux: extract function rte_eal_unbind_kernel_driver
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (9 preceding siblings ...)
  2016-05-06 13:47 ` [PATCH v1 02/28] eal: extract function eal_parse_sysfs_valuef Jan Viktorin
@ 2016-05-06 13:47 ` Jan Viktorin
  2016-05-13  1:22   ` Jianbo Liu
  2016-05-06 13:47 ` [PATCH v1 04/28] eal/linux: extract function rte_eal_get_kernel_driver_by_path Jan Viktorin
                   ` (26 subsequent siblings)
  37 siblings, 1 reply; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:47 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

Generalize the PCI-specific pci_unbind_kernel_driver. It is now divided into
two parts. First, determination of the path and string identification of the
device to be unbound. Second, the actual unbind operation which is generic.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/common/eal_private.h   | 13 +++++++++++++
 lib/librte_eal/linuxapp/eal/eal.c     | 26 ++++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/eal_pci.c | 33 +++++++++------------------------
 3 files changed, 48 insertions(+), 24 deletions(-)

diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 81816a6..3fb8353 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -289,6 +289,19 @@ int rte_eal_alarm_init(void);
 int rte_eal_check_module(const char *module_name);
 
 /**
+ * Unbind kernel driver bound to the device specified by the given devpath,
+ * and its string identification.
+ *
+ * @param devpath  path to the device directory ("/sys/.../devices/<name>")
+ * @param devid    identification of the device (<name>)
+ *
+ * @return
+ *      -1  unbind has failed
+ *       0  module has been unbound
+ */
+int rte_eal_unbind_kernel_driver(const char *devpath, const char *devid);
+
+/**
  * Get cpu core_id.
  *
  * This function is private to the EAL.
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index e8fce6b..844f958 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -949,3 +949,29 @@ rte_eal_check_module(const char *module_name)
 	/* Module has been found */
 	return 1;
 }
+
+int
+rte_eal_unbind_kernel_driver(const char *devpath, const char *devid)
+{
+	char filename[PATH_MAX];
+	FILE *f;
+
+	snprintf(filename, sizeof(filename),
+	         "%s/driver/unbind", devpath);
+
+	f = fopen(filename, "w");
+	if (f == NULL) /* device was not bound */
+		return 0;
+
+	if (fwrite(devid, strlen(devid), 1, f) == 0) {
+		RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
+				filename);
+		goto error;
+	}
+
+	fclose(f);
+	return 0;
+error:
+	fclose(f);
+	return -1;
+}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index fd7e34f..312cb14 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -59,38 +59,23 @@ int
 pci_unbind_kernel_driver(struct rte_pci_device *dev)
 {
 	int n;
-	FILE *f;
-	char filename[PATH_MAX];
-	char buf[BUFSIZ];
+	char devpath[PATH_MAX];
+	char devid[BUFSIZ];
 	struct rte_pci_addr *loc = &dev->addr;
 
-	/* open /sys/bus/pci/devices/AAAA:BB:CC.D/driver */
-	snprintf(filename, sizeof(filename),
-	         SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/driver/unbind",
+	/* devpath /sys/bus/pci/devices/AAAA:BB:CC.D */
+	snprintf(devpath, sizeof(devpath),
+	         SYSFS_PCI_DEVICES "/" PCI_PRI_FMT,
 	         loc->domain, loc->bus, loc->devid, loc->function);
 
-	f = fopen(filename, "w");
-	if (f == NULL) /* device was not bound */
-		return 0;
-
-	n = snprintf(buf, sizeof(buf), PCI_PRI_FMT "\n",
+	n = snprintf(devid, sizeof(devid), PCI_PRI_FMT "\n",
 	             loc->domain, loc->bus, loc->devid, loc->function);
-	if ((n < 0) || (n >= (int)sizeof(buf))) {
+	if ((n < 0) || (n >= (int)sizeof(devid))) {
 		RTE_LOG(ERR, EAL, "%s(): snprintf failed\n", __func__);
-		goto error;
-	}
-	if (fwrite(buf, n, 1, f) == 0) {
-		RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
-				filename);
-		goto error;
+		return -1;
 	}
 
-	fclose(f);
-	return 0;
-
-error:
-	fclose(f);
-	return -1;
+	return rte_eal_unbind_kernel_driver(devpath, devid);
 }
 
 static int
-- 
2.8.0

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

* [PATCH v1 04/28] eal/linux: extract function rte_eal_get_kernel_driver_by_path
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (10 preceding siblings ...)
  2016-05-06 13:47 ` [PATCH v1 03/28] eal/linux: extract function rte_eal_unbind_kernel_driver Jan Viktorin
@ 2016-05-06 13:47 ` Jan Viktorin
  2016-05-06 13:47 ` [PATCH v1 05/28] eal: remove pci_ prefix from pci_(un)map_resource Jan Viktorin
                   ` (25 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:47 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

Generalize the PCI-specific pci_get_kernel_driver_by_path. The function is
general enough, we have just moved it to eal.c, changed the prefix to rte_eal
and provided it privately to other parts of EAL.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/common/eal_private.h   | 14 ++++++++++++++
 lib/librte_eal/linuxapp/eal/eal.c     | 29 +++++++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/eal_pci.c | 31 +------------------------------
 3 files changed, 44 insertions(+), 30 deletions(-)

diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 3fb8353..9a81fdd 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -302,6 +302,20 @@ int rte_eal_check_module(const char *module_name);
 int rte_eal_unbind_kernel_driver(const char *devpath, const char *devid);
 
 /**
+ * Extrat the kernel driver name from the absolute path to the driver.
+ *
+ * @param filename  path to the driver ("<path-to-device>/driver")
+ * @path  dri_name  target buffer where to place the driver name
+ *                  (should be at least PATH_MAX long)
+ *
+ * @return
+ *      -1   on failure
+ *       0   when successful
+ *       1   when there is no such driver
+ */
+int rte_eal_get_kernel_driver_by_path(const char *filename, char *dri_name);
+
+/**
  * Get cpu core_id.
  *
  * This function is private to the EAL.
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 844f958..a9f3ae2 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -975,3 +975,32 @@ error:
 	fclose(f);
 	return -1;
 }
+
+int
+rte_eal_get_kernel_driver_by_path(const char *filename, char *dri_name)
+{
+	int count;
+	char path[PATH_MAX];
+	char *name;
+
+	if (!filename || !dri_name)
+		return -1;
+
+	count = readlink(filename, path, PATH_MAX);
+	if (count >= PATH_MAX)
+		return -1;
+
+	/* For device does not have a driver */
+	if (count < 0)
+		return 1;
+
+	path[count] = '\0';
+
+	name = strrchr(path, '/');
+	if (name) {
+		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
+		return 0;
+	}
+
+	return -1;
+}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index 312cb14..162d46e 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -78,35 +78,6 @@ pci_unbind_kernel_driver(struct rte_pci_device *dev)
 	return rte_eal_unbind_kernel_driver(devpath, devid);
 }
 
-static int
-pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
-{
-	int count;
-	char path[PATH_MAX];
-	char *name;
-
-	if (!filename || !dri_name)
-		return -1;
-
-	count = readlink(filename, path, PATH_MAX);
-	if (count >= PATH_MAX)
-		return -1;
-
-	/* For device does not have a driver */
-	if (count < 0)
-		return 1;
-
-	path[count] = '\0';
-
-	name = strrchr(path, '/');
-	if (name) {
-		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
-		return 0;
-	}
-
-	return -1;
-}
-
 /* Map pci device */
 int
 rte_eal_pci_map_device(struct rte_pci_device *dev)
@@ -330,7 +301,7 @@ pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus,
 
 	/* parse driver */
 	snprintf(filename, sizeof(filename), "%s/driver", dirname);
-	ret = pci_get_kernel_driver_by_path(filename, driver);
+	ret = rte_eal_get_kernel_driver_by_path(filename, driver);
 	if (ret < 0) {
 		RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
 		free(dev);
-- 
2.8.0

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

* [PATCH v1 05/28] eal: remove pci_ prefix from pci_(un)map_resource
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (11 preceding siblings ...)
  2016-05-06 13:47 ` [PATCH v1 04/28] eal/linux: extract function rte_eal_get_kernel_driver_by_path Jan Viktorin
@ 2016-05-06 13:47 ` Jan Viktorin
  2016-05-06 13:47 ` [PATCH v1 06/28] eal/soc: introduce very essential SoC infra definitions Jan Viktorin
                   ` (24 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:47 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

The functions pci_map_resource, pci_unmap_resource are generic so the pci_
prefix can be omitted. The functions are moved to the eal_common_dev.c so
they can be reused by other infrastructure.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/bsdapp/eal/eal_pci.c        |  2 +-
 lib/librte_eal/common/eal_common_dev.c     | 39 ++++++++++++++++++++++++++++++
 lib/librte_eal/common/eal_common_pci.c     | 39 ------------------------------
 lib/librte_eal/common/eal_common_pci_uio.c |  6 ++---
 lib/librte_eal/common/eal_private.h        | 32 ++++++++++++++++++++++++
 lib/librte_eal/common/include/rte_pci.h    | 32 ------------------------
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c  |  3 ++-
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c |  4 +--
 8 files changed, 79 insertions(+), 78 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 85e49f6..b5a20fa 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -228,7 +228,7 @@ pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
 
 	/* if matching map is found, then use it */
 	offset = res_idx * pagesz;
-	mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
+	mapaddr = map_resource(NULL, fd, (off_t)offset,
 			(size_t)dev->mem_resource[res_idx].len, 0);
 	close(fd);
 	if (mapaddr == MAP_FAILED)
diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 59ed3a0..d2763b0 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -36,6 +36,7 @@
 #include <string.h>
 #include <inttypes.h>
 #include <sys/queue.h>
+#include <sys/mman.h>
 
 #include <rte_dev.h>
 #include <rte_devargs.h>
@@ -189,3 +190,41 @@ err:
 	RTE_LOG(ERR, EAL, "Driver, cannot detach the device\n");
 	return -1;
 }
+
+/* map a particular resource from a file */
+void *
+map_resource(void *requested_addr, int fd, off_t offset, size_t size,
+		 int additional_flags)
+{
+	void *mapaddr;
+
+	/* Map the PCI memory resource of device */
+	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
+			MAP_SHARED | additional_flags, fd, offset);
+	if (mapaddr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
+			__func__, fd, requested_addr,
+			(unsigned long)size, (unsigned long)offset,
+			strerror(errno), mapaddr);
+	} else
+		RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
+
+	return mapaddr;
+}
+
+/* unmap a particular resource */
+void
+unmap_resource(void *requested_addr, size_t size)
+{
+	if (requested_addr == NULL)
+		return;
+
+	/* Unmap the PCI memory resource of device */
+	if (munmap(requested_addr, size)) {
+		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
+			__func__, requested_addr, (unsigned long)size,
+			strerror(errno));
+	} else
+		RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
+				requested_addr);
+}
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index f24dc4d..f85106d 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -67,7 +67,6 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/queue.h>
-#include <sys/mman.h>
 
 #include <rte_interrupts.h>
 #include <rte_log.h>
@@ -101,44 +100,6 @@ static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
 	return NULL;
 }
 
-/* map a particular resource from a file */
-void *
-pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
-		 int additional_flags)
-{
-	void *mapaddr;
-
-	/* Map the PCI memory resource of device */
-	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
-			MAP_SHARED | additional_flags, fd, offset);
-	if (mapaddr == MAP_FAILED) {
-		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
-			__func__, fd, requested_addr,
-			(unsigned long)size, (unsigned long)offset,
-			strerror(errno), mapaddr);
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
-
-	return mapaddr;
-}
-
-/* unmap a particular resource */
-void
-pci_unmap_resource(void *requested_addr, size_t size)
-{
-	if (requested_addr == NULL)
-		return;
-
-	/* Unmap the PCI memory resource of device */
-	if (munmap(requested_addr, size)) {
-		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
-			__func__, requested_addr, (unsigned long)size,
-			strerror(errno));
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
-				requested_addr);
-}
-
 /*
  * If vendor/device ID match, call the devinit() function of the
  * driver.
diff --git a/lib/librte_eal/common/eal_common_pci_uio.c b/lib/librte_eal/common/eal_common_pci_uio.c
index f062e81..40b161d 100644
--- a/lib/librte_eal/common/eal_common_pci_uio.c
+++ b/lib/librte_eal/common/eal_common_pci_uio.c
@@ -75,7 +75,7 @@ pci_uio_map_secondary(struct rte_pci_device *dev)
 				return -1;
 			}
 
-			void *mapaddr = pci_map_resource(uio_res->maps[i].addr,
+			void *mapaddr = map_resource(uio_res->maps[i].addr,
 					fd, (off_t)uio_res->maps[i].offset,
 					(size_t)uio_res->maps[i].size, 0);
 			/* fd is not needed in slave process, close it */
@@ -140,7 +140,7 @@ pci_uio_map_resource(struct rte_pci_device *dev)
 	return 0;
 error:
 	for (i = 0; i < map_idx; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
+		unmap_resource(uio_res->maps[i].addr,
 				(size_t)uio_res->maps[i].size);
 		rte_free(uio_res->maps[i].path);
 	}
@@ -157,7 +157,7 @@ pci_uio_unmap(struct mapped_pci_resource *uio_res)
 		return;
 
 	for (i = 0; i != uio_res->nb_maps; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
+		unmap_resource(uio_res->maps[i].addr,
 				(size_t)uio_res->maps[i].size);
 		rte_free(uio_res->maps[i].path);
 	}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 9a81fdd..b8ce5b9 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -120,6 +120,38 @@ int rte_eal_log_early_init(void);
 int rte_eal_log_init(const char *id, int facility);
 
 /**
+ * @internal
+ * Map a particular resource from a file.
+ *
+ * @param requested_addr
+ *      The starting address for the new mapping range.
+ * @param fd
+ *      The file descriptor.
+ * @param offset
+ *      The offset for the mapping range.
+ * @param size
+ *      The size for the mapping range.
+ * @param additional_flags
+ *      The additional flags for the mapping range.
+ * @return
+ *   - On success, the function returns a pointer to the mapped area.
+ *   - On error, the value MAP_FAILED is returned.
+ */
+void *map_resource(void *requested_addr, int fd, off_t offset,
+		size_t size, int additional_flags);
+
+/**
+ * @internal
+ * Unmap a particular resource.
+ *
+ * @param requested_addr
+ *      The address for the unmapping range.
+ * @param size
+ *      The size for the unmapping range.
+ */
+void unmap_resource(void *requested_addr, size_t size);
+
+/**
  * Init the default log stream
  *
  * This function is private to EAL.
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index dab150e..d1d4202 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -408,38 +408,6 @@ int rte_eal_pci_map_device(struct rte_pci_device *dev);
 void rte_eal_pci_unmap_device(struct rte_pci_device *dev);
 
 /**
- * @internal
- * Map a particular resource from a file.
- *
- * @param requested_addr
- *      The starting address for the new mapping range.
- * @param fd
- *      The file descriptor.
- * @param offset
- *      The offset for the mapping range.
- * @param size
- *      The size for the mapping range.
- * @param additional_flags
- *      The additional flags for the mapping range.
- * @return
- *   - On success, the function returns a pointer to the mapped area.
- *   - On error, the value MAP_FAILED is returned.
- */
-void *pci_map_resource(void *requested_addr, int fd, off_t offset,
-		size_t size, int additional_flags);
-
-/**
- * @internal
- * Unmap a particular resource.
- *
- * @param requested_addr
- *      The address for the unmapping range.
- * @param size
- *      The size for the unmapping range.
- */
-void pci_unmap_resource(void *requested_addr, size_t size);
-
-/**
  * Probe the single PCI device.
  *
  * Scan the content of the PCI bus, and find the pci device specified by pci
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
index 068694d..d543f89 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
@@ -51,6 +51,7 @@
 
 #include "eal_filesystem.h"
 #include "eal_pci_init.h"
+#include "eal_private.h"
 
 void *pci_map_addr = NULL;
 
@@ -345,7 +346,7 @@ pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
 	if (pci_map_addr == NULL)
 		pci_map_addr = pci_find_max_end_va();
 
-	mapaddr = pci_map_resource(pci_map_addr, fd, 0,
+	mapaddr = map_resource(pci_map_addr, fd, 0,
 			(size_t)dev->mem_resource[res_idx].len, 0);
 	close(fd);
 	if (mapaddr == MAP_FAILED)
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
index 10266f8..a50639d 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
@@ -930,7 +930,7 @@ pci_vfio_map_resource(struct rte_pci_device *dev)
 			void *map_addr = NULL;
 			if (memreg[0].size) {
 				/* actual map of first part */
-				map_addr = pci_map_resource(bar_addr, vfio_dev_fd,
+				map_addr = map_resource(bar_addr, vfio_dev_fd,
 							    memreg[0].offset,
 							    memreg[0].size,
 							    MAP_FIXED);
@@ -940,7 +940,7 @@ pci_vfio_map_resource(struct rte_pci_device *dev)
 			if (map_addr != MAP_FAILED
 			    && memreg[1].offset && memreg[1].size) {
 				void *second_addr = RTE_PTR_ADD(bar_addr, memreg[1].offset);
-				map_addr = pci_map_resource(second_addr,
+				map_addr = map_resource(second_addr,
 							    vfio_dev_fd, memreg[1].offset,
 							    memreg[1].size,
 							    MAP_FIXED);
-- 
2.8.0

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

* [PATCH v1 06/28] eal/soc: introduce very essential SoC infra definitions
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (12 preceding siblings ...)
  2016-05-06 13:47 ` [PATCH v1 05/28] eal: remove pci_ prefix from pci_(un)map_resource Jan Viktorin
@ 2016-05-06 13:47 ` Jan Viktorin
  2016-05-06 13:47 ` [PATCH v1 07/28] eal/soc: add rte_eal_soc_register/unregister logic Jan Viktorin
                   ` (23 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:47 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

Define initial structures and functions for the SoC infrastructure. We support
only a very minimal functions now. More features will be added in the following
commits. It is to be refactored when a generic rte_device/driver pair is added
to DPDK.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 app/test/Makefile                       |   1 +
 app/test/test_soc.c                     |  93 ++++++++++++++++++++++
 lib/librte_eal/common/Makefile          |   2 +-
 lib/librte_eal/common/eal_private.h     |   4 +
 lib/librte_eal/common/include/rte_soc.h | 134 ++++++++++++++++++++++++++++++++
 5 files changed, 233 insertions(+), 1 deletion(-)
 create mode 100644 app/test/test_soc.c
 create mode 100644 lib/librte_eal/common/include/rte_soc.h

diff --git a/app/test/Makefile b/app/test/Makefile
index a4907d5..33c44c2 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -43,6 +43,7 @@ APP = test
 #
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) := commands.c
 SRCS-y += test.c
+SRCS-y += test_soc.c
 SRCS-y += test_pci.c
 SRCS-y += test_prefetch.c
 SRCS-y += test_byteorder.c
diff --git a/app/test/test_soc.c b/app/test/test_soc.c
new file mode 100644
index 0000000..a49fc9b
--- /dev/null
+++ b/app/test/test_soc.c
@@ -0,0 +1,93 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <sys/queue.h>
+
+#include <rte_soc.h>
+#include <rte_devargs.h>
+#include <rte_debug.h>
+
+#include "test.h"
+
+static char *safe_strdup(const char *s)
+{
+	char *c = strdup(s);
+	if (c == NULL)
+		rte_panic("failed to strdup '%s'\n", s);
+
+	return c;
+}
+
+static int test_compare_addr(void)
+{
+	struct rte_soc_addr a0;
+	struct rte_soc_addr a1;
+	struct rte_soc_addr a2;
+
+	a0.name = safe_strdup("ethernet0");
+	a0.fdt_path = NULL;
+
+	a1.name = safe_strdup("ethernet0");
+	a1.fdt_path = NULL;
+
+	a2.name = safe_strdup("ethernet1");
+	a2.fdt_path = NULL;
+
+	TEST_ASSERT(!rte_eal_compare_soc_addr(&a0, &a1),
+		"Failed to compare two soc addresses that equal");
+	TEST_ASSERT(rte_eal_compare_soc_addr(&a0, &a2),
+		"Failed to compare two soc addresses that differs");
+
+	free(a2.name);
+	free(a1.name);
+	free(a0.name);
+	return 0;
+}
+
+static int
+test_soc(void)
+{
+	if (test_compare_addr())
+		return -1;
+
+	return 0;
+}
+
+static struct test_command soc_cmd = {
+	.command = "soc_autotest",
+	.callback = test_soc,
+};
+REGISTER_TEST_COMMAND(soc_cmd);
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index f5ea0ee..a409c22 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 INC := rte_branch_prediction.h rte_common.h
 INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
-INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
+INC += rte_log.h rte_memory.h rte_memzone.h rte_soc.h rte_pci.h
 INC += rte_pci_dev_ids.h rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index b8ce5b9..5145215 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -36,6 +36,7 @@
 
 #include <stdio.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 
 /**
  * Initialize the memzone subsystem (private to eal).
@@ -183,6 +184,9 @@ int rte_eal_ivshmem_init(void);
 int rte_eal_ivshmem_obj_init(void);
 #endif
 
+struct rte_soc_driver;
+struct rte_soc_device;
+
 struct rte_pci_driver;
 struct rte_pci_device;
 
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
new file mode 100644
index 0000000..cde588a
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -0,0 +1,134 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_SOC_H_
+#define _RTE_SOC_H_
+
+/**
+ * @file
+ *
+ * RTE SoC Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include <rte_debug.h>
+
+struct rte_soc_id {
+	const char *compatible; /**< OF compatible specification */
+};
+
+struct rte_soc_addr {
+	char *name;     /**< name used in sysfs */
+	char *fdt_path; /**< path to the associated node in FDT */
+};
+
+/**
+ * A structure describing a SoC device.
+ */
+struct rte_soc_device {
+	TAILQ_ENTRY(rte_soc_device) next;   /**< Next probed SoC device */
+	struct rte_soc_addr addr;           /**< SoC device Location */
+	struct rte_soc_id *id;              /**< SoC device ID list */
+	struct rte_soc_driver *driver;      /**< Associated driver */
+};
+
+struct rte_soc_driver;
+
+/**
+ * Initialization function for the driver called during SoC probing.
+ */
+typedef int (soc_devinit_t)(struct rte_soc_driver *, struct rte_soc_device *);
+
+/**
+ * Uninitialization function for the driver called during hotplugging.
+ */
+typedef int (soc_devuninit_t)(struct rte_soc_device *);
+
+/**
+ * A structure describing a SoC driver.
+ */
+struct rte_soc_driver {
+	TAILQ_ENTRY(rte_soc_driver) next;  /**< Next in list */
+	const char *name;                  /**< Driver name */
+	soc_devinit_t *devinit;            /**< Device initialization */
+	soc_devuninit_t *devuninit;        /**< Device uninitialization */
+	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
+};
+
+/**
+ * Utility function to write a SoC device name, this device name can later be
+ * used to retrieve the corresponding rte_soc_addr using above functions.
+ *
+ * @param addr
+ *	The SoC address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ * @return
+ *  0 on success, negative on error.
+ */
+static inline void
+rte_eal_soc_device_name(const struct rte_soc_addr *addr,
+		    char *output, size_t size)
+{
+	int ret;
+	RTE_VERIFY(addr != NULL);
+	RTE_VERIFY(size >= strlen(addr->name));
+	ret = snprintf(output, size, "%s", addr->name);
+	RTE_VERIFY(ret >= 0);
+}
+
+static inline int
+rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
+                         const struct rte_soc_addr *a1)
+{
+	if (a0 == NULL || a1 == NULL)
+		return -1;
+
+	RTE_VERIFY(a0->name != NULL);
+	RTE_VERIFY(a1->name != NULL);
+
+	return strcmp(a0->name, a1->name);
+}
+
+#endif
-- 
2.8.0

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

* [PATCH v1 07/28] eal/soc: add rte_eal_soc_register/unregister logic
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (13 preceding siblings ...)
  2016-05-06 13:47 ` [PATCH v1 06/28] eal/soc: introduce very essential SoC infra definitions Jan Viktorin
@ 2016-05-06 13:47 ` Jan Viktorin
  2016-06-13 14:19   ` Shreyansh Jain
  2016-05-06 13:47 ` [PATCH v1 08/28] eal/soc: implement SoC device discovery Jan Viktorin
                   ` (22 subsequent siblings)
  37 siblings, 1 reply; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:47 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 app/test/test_soc.c                             | 106 ++++++++++++++++++++++++
 lib/librte_eal/bsdapp/eal/Makefile              |   1 +
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   3 +
 lib/librte_eal/common/eal_common_soc.c          |  55 ++++++++++++
 lib/librte_eal/common/include/rte_soc.h         |  23 +++++
 lib/librte_eal/linuxapp/eal/Makefile            |   1 +
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   4 +
 7 files changed, 193 insertions(+)
 create mode 100644 lib/librte_eal/common/eal_common_soc.c

diff --git a/app/test/test_soc.c b/app/test/test_soc.c
index a49fc9b..f6288dc 100644
--- a/app/test/test_soc.c
+++ b/app/test/test_soc.c
@@ -74,6 +74,103 @@ static int test_compare_addr(void)
 	free(a2.name);
 	free(a1.name);
 	free(a0.name);
+
+	return 0;
+}
+
+/**
+ * Empty PMD driver based on the SoC infra.
+ *
+ * The rte_soc_device is usually wrapped in some higher-level struct
+ * (eth_driver). We simulate such a wrapper with an anonymous struct here.
+ */
+struct test_wrapper {
+	struct rte_soc_driver soc_drv;
+};
+
+struct test_wrapper empty_pmd0 = {
+	.soc_drv = {
+		.name = "empty_pmd0",
+	},
+};
+
+struct test_wrapper empty_pmd1 = {
+	.soc_drv = {
+		.name = "empty_pmd1",
+	},
+};
+
+static int
+count_registered_socdrvs(void)
+{
+	int i;
+	struct rte_soc_driver *drv;
+
+	i = 0;
+	TAILQ_FOREACH(drv, &soc_driver_list, next)
+		i += 1;
+
+	return i;
+}
+
+static int
+test_register_unregister(void)
+{
+	struct rte_soc_driver *drv;
+	int count;
+
+	rte_eal_soc_register(&empty_pmd0.soc_drv);
+
+	TEST_ASSERT(!TAILQ_EMPTY(&soc_driver_list),
+		"No PMD is present but the empty_pmd0 should be there");
+	drv = TAILQ_FIRST(&soc_driver_list);
+	TEST_ASSERT(!strcmp(drv->name, "empty_pmd0"),
+		"The registered PMD is not empty_pmd but '%s'", drv->name);
+
+	rte_eal_soc_register(&empty_pmd1.soc_drv);
+
+	count = count_registered_socdrvs();
+	TEST_ASSERT_EQUAL(count, 2, "Expected 2 PMDs but detected %d", count);
+
+	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
+	count = count_registered_socdrvs();
+	TEST_ASSERT_EQUAL(count, 1, "Expected 1 PMDs but detected %d", count);
+
+	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
+
+	printf("%s has been successful\n", __func__);
+	return 0;
+}
+
+/* save real devices and drivers until the tests finishes */
+struct soc_driver_list real_soc_driver_list =
+	TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
+
+static int test_soc_setup(void)
+{
+	struct rte_soc_driver *drv;
+
+	/* no real drivers for the test */
+	while (!TAILQ_EMPTY(&soc_driver_list)) {
+		drv = TAILQ_FIRST(&soc_driver_list);
+		rte_eal_soc_unregister(drv);
+		TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
+	}
+
+	return 0;
+}
+
+static int test_soc_cleanup(void)
+{
+	struct rte_soc_driver *drv;
+
+	/* bring back real drivers after the test */
+	while (!TAILQ_EMPTY(&real_soc_driver_list)) {
+		drv = TAILQ_FIRST(&real_soc_driver_list);
+		TAILQ_REMOVE(&real_soc_driver_list, drv, next);
+		rte_eal_soc_register(drv);
+	}
+
 	return 0;
 }
 
@@ -83,6 +180,15 @@ test_soc(void)
 	if (test_compare_addr())
 		return -1;
 
+	if (test_soc_setup())
+		return -1;
+
+	if (test_register_unregister())
+		return -1;
+
+	if (test_soc_cleanup())
+		return -1;
+
 	return 0;
 }
 
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 9054ad6..d956808 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -71,6 +71,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 4d075df..c430b4b 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -158,4 +158,7 @@ DPDK_16.07 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 
+	rte_eal_soc_register;
+	rte_eal_soc_unregister;
+
 } DPDK_16.04;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
new file mode 100644
index 0000000..afeed2f
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -0,0 +1,55 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/queue.h>
+
+#include <rte_log.h>
+
+#include "eal_private.h"
+
+struct soc_driver_list soc_driver_list =
+	TAILQ_HEAD_INITIALIZER(soc_driver_list);
+
+/* register a driver */
+void
+rte_eal_soc_register(struct rte_soc_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_eal_soc_unregister(struct rte_soc_driver *driver)
+{
+	TAILQ_REMOVE(&soc_driver_list, driver, next);
+}
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index cde588a..28c1798 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -46,11 +46,17 @@ extern "C" {
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/queue.h>
 #include <stdint.h>
 #include <inttypes.h>
 #include <string.h>
 
 #include <rte_debug.h>
+#include <rte_eal.h>
+
+TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
+
+extern struct soc_driver_list soc_driver_list; /**< Global list of SoC drivers. */
 
 struct rte_soc_id {
 	const char *compatible; /**< OF compatible specification */
@@ -131,4 +137,21 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 	return strcmp(a0->name, a1->name);
 }
 
+/**
+ * Register a SoC driver.
+ */
+void rte_eal_soc_register(struct rte_soc_driver *driver);
+
+#define RTE_EAL_SOC_REGISTER(name) \
+RTE_INIT(socinitfn_ ##name); \
+static void socinitfn_ ##name(void) \
+{ \
+	rte_eal_soc_register(&name.soc_drv); \
+}
+
+/**
+ * Unregister a SoC driver.
+ */
+void rte_eal_soc_unregister(struct rte_soc_driver *driver);
+
 #endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index e109361..37ab8d5 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -82,6 +82,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 0404a52..6ff38b8 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -161,4 +161,8 @@ DPDK_16.07 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 
+	soc_driver_list;
+	rte_eal_soc_register;
+	rte_eal_soc_unregister;
+
 } DPDK_16.04;
-- 
2.8.0

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

* [PATCH v1 08/28] eal/soc: implement SoC device discovery
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (14 preceding siblings ...)
  2016-05-06 13:47 ` [PATCH v1 07/28] eal/soc: add rte_eal_soc_register/unregister logic Jan Viktorin
@ 2016-05-06 13:47 ` Jan Viktorin
  2016-05-06 13:47 ` [PATCH v1 09/28] eal: introduce --no-soc option Jan Viktorin
                   ` (21 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:47 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/bsdapp/eal/Makefile              |   1 +
 lib/librte_eal/bsdapp/eal/eal_soc.c             |  40 ++++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   3 +
 lib/librte_eal/common/eal_common_soc.c          |  45 ++++
 lib/librte_eal/common/include/rte_soc.h         |  14 ++
 lib/librte_eal/linuxapp/eal/Makefile            |   1 +
 lib/librte_eal/linuxapp/eal/eal_soc.c           | 282 ++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   4 +
 8 files changed, 390 insertions(+)
 create mode 100644 lib/librte_eal/bsdapp/eal/eal_soc.c
 create mode 100644 lib/librte_eal/linuxapp/eal/eal_soc.c

diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index d956808..7ac6c94 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -58,6 +58,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_hugepage_info.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_log.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_lcore.c
diff --git a/lib/librte_eal/bsdapp/eal/eal_soc.c b/lib/librte_eal/bsdapp/eal/eal_soc.c
new file mode 100644
index 0000000..f84aae9
--- /dev/null
+++ b/lib/librte_eal/bsdapp/eal/eal_soc.c
@@ -0,0 +1,40 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rte_soc.h>
+
+int
+rte_eal_soc_scan(void)
+{
+	return 0;
+}
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index c430b4b..4a2eeaf 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -158,7 +158,10 @@ DPDK_16.07 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 
+	soc_get_sysfs_path;
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
+	rte_eal_soc_scan;
+	rte_eal_soc_dump;
 
 } DPDK_16.04;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index afeed2f..d8bb6d6 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -31,6 +31,8 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <stddef.h>
+#include <stdio.h>
 #include <sys/queue.h>
 
 #include <rte_log.h>
@@ -39,6 +41,49 @@
 
 struct soc_driver_list soc_driver_list =
 	TAILQ_HEAD_INITIALIZER(soc_driver_list);
+struct soc_device_list soc_device_list =
+	TAILQ_HEAD_INITIALIZER(soc_device_list);
+
+/** Pathname of SoC devices directory. */
+#define SYSFS_SOC_DEVICES "/sys/bus/platform/devices"
+
+const char *soc_get_sysfs_path(void)
+{
+	const char *path = NULL;
+
+	path = getenv("SYSFS_SOC_DEVICES");
+	if (path == NULL)
+		return SYSFS_SOC_DEVICES;
+
+	return path;
+}
+
+/* dump one device */
+static int
+soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
+{
+	int i;
+
+	fprintf(f, "%s", dev->addr.name);
+	fprintf(f, " - fdt_path: %s\n",
+			dev->addr.fdt_path? dev->addr.fdt_path : "(none)");
+
+	for (i = 0; dev->id && dev->id[i].compatible; ++i)
+		fprintf(f, "   %s\n", dev->id[i].compatible);
+
+	return 0;
+}
+
+/* dump devices on the bus */
+void
+rte_eal_soc_dump(FILE *f)
+{
+	struct rte_soc_device *dev = NULL;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		soc_dump_one_device(f, dev);
+	}
+}
 
 /* register a driver */
 void
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 28c1798..6278295 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -55,8 +55,13 @@ extern "C" {
 #include <rte_eal.h>
 
 TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
+TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
 
 extern struct soc_driver_list soc_driver_list; /**< Global list of SoC drivers. */
+extern struct soc_device_list soc_device_list; /**< Global list of SoC devices. */
+
+/** Return SoC scan path of the sysfs root. */
+const char *soc_get_sysfs_path(void);
 
 struct rte_soc_id {
 	const char *compatible; /**< OF compatible specification */
@@ -136,6 +141,15 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 
 	return strcmp(a0->name, a1->name);
 }
+/**
+ * Scan for new SoC devices.
+ */
+int rte_eal_soc_scan(void);
+
+/**
+ * Dump discovered SoC devices.
+ */
+void rte_eal_soc_dump(FILE *f);
 
 /**
  * Register a SoC driver.
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 37ab8d5..85a892a 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -63,6 +63,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_xen_memory.c
 endif
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_log.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_vfio.c
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
new file mode 100644
index 0000000..8dbb367
--- /dev/null
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -0,0 +1,282 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <rte_log.h>
+#include <rte_soc.h>
+
+#include "eal_private.h"
+
+static char *
+dev_read_uevent(const char *dirname)
+{
+	char filename[PATH_MAX];
+	struct stat st;
+	char *buf;
+	ssize_t total = 0;
+	int fd;
+
+	snprintf(filename, sizeof(filename), "%s/uevent", dirname);
+	fd = open(filename, O_RDONLY);
+	if (fd < 0) {
+		RTE_LOG(WARNING, EAL, "Failed to open file %s\n", filename);
+		return strdup("");
+	}
+
+	if (fstat(fd, &st) < 0) {
+		RTE_LOG(ERR, EAL, "Failed to stat file %s\n", filename);
+		close(fd);
+		return NULL;
+	}
+
+	if (st.st_size == 0) {
+		close(fd);
+		return strdup("");
+	}
+
+	buf = malloc(st.st_size + 1);
+	if (buf == NULL) {
+		RTE_LOG(ERR, EAL, "Failed to alloc memory to read %s\n", filename);
+		close(fd);
+		return NULL;
+	}
+
+	while (total < st.st_size) {
+		ssize_t rlen = read(fd, buf + total, st.st_size - total);
+		if (rlen < 0) {
+			if (errno == EINTR)
+				continue;
+
+			RTE_LOG(ERR, EAL, "Failed to read file %s\n", filename);
+
+			free(buf);
+			close(fd);
+			return NULL;
+		}
+		if (rlen == 0) /* EOF */
+			break;
+
+		total += rlen;
+	}
+
+	buf[total] = '\0';
+	close(fd);
+
+	return buf;
+}
+
+static const char *
+dev_uevent_find(const char *uevent, const char *key)
+{
+	const size_t keylen = strlen(key);
+	const size_t total = strlen(uevent);
+	const char *p = uevent;
+
+	/* check whether it is the first key */
+	if (!strncmp(uevent, key, keylen))
+		return uevent + keylen;
+
+	/* check 2nd key or further... */
+	do {
+		p = strstr(p, key);
+		if (p == NULL)
+			break;
+
+		if (p[-1] == '\n') /* check we are at a new line */
+			return p + keylen;
+
+		p += keylen; /* skip this one */
+	} while(p - uevent < (ptrdiff_t) total);
+
+	return NULL;
+}
+
+static char *
+strdup_until_nl(const char *p)
+{
+	const char *nl = strchr(p, '\n');
+	if (nl == NULL)
+		return strdup(p); /* no newline, copy until '\0' */
+
+	return strndup(p, nl - p);
+}
+
+static int
+dev_parse_uevent(struct rte_soc_device *dev, const char *uevent)
+{
+	const char *of;
+
+	of = dev_uevent_find(uevent, "OF_FULLNAME=");
+	if (of == NULL)
+		return 1; /* don't care about this device */
+
+	dev->addr.fdt_path = strdup_until_nl(of);
+	if (dev->addr.fdt_path == NULL) {
+		RTE_LOG(ERR, PMD,
+			"Failed to alloc memory for fdt_path\n");
+		return -1;
+	}
+
+	RTE_LOG(DEBUG, EAL, "Detected device %s (%s)\n",
+			dev->addr.name, dev->addr.fdt_path);
+
+	dev->id = calloc(1, sizeof(*dev->id));
+	if (dev->id == NULL) {
+		free(dev->addr.fdt_path);
+		return -1;
+	}
+
+	return 0;
+}
+
+static void
+dev_content_free(struct rte_soc_device *dev)
+{
+	if (dev->addr.fdt_path)
+		free(dev->addr.fdt_path);
+
+	free(dev->id);
+	dev->id = NULL;
+}
+
+/**
+ * Scan one SoC sysfs entry, and fill the devices list from it.
+ * We require to have the uevent file with records: OF_FULLNAME and
+ * OF_COMPATIBLE array (with at least one entry). Otherwise, such device
+ * is skipped.
+ */
+static int
+soc_scan_one(const char *dirname, const char *name)
+{
+	struct rte_soc_device *dev;
+	char *uevent;
+	int ret;
+
+	uevent = dev_read_uevent(dirname);
+	if (uevent == NULL)
+		return -1;
+
+	if (uevent[0] == '\0') {
+		/* ignore directory without uevent file */
+		free(uevent);
+		return 1;
+	}
+
+	dev = malloc(sizeof(*dev) + strlen(name) + 1);
+	if (dev == NULL) {
+		RTE_LOG(ERR, PMD, "Failed to alloc memory for %s\n", name);
+		free(uevent);
+		return -1;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	dev->addr.name = (char *) (dev + 1);
+	strcpy(dev->addr.name, name);
+
+	if ((ret = dev_parse_uevent(dev, uevent)))
+		goto fail;
+	free(uevent); /* not needed anymore */
+
+	/* device is valid, add in list (sorted) */
+	if (TAILQ_EMPTY(&soc_device_list)) {
+		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+	} else {
+		struct rte_soc_device *dev2;
+
+		TAILQ_FOREACH(dev2, &soc_device_list, next) {
+			ret = rte_eal_compare_soc_addr(&dev->addr, &dev2->addr);
+			if (ret > 0)
+				continue;
+
+			if (ret < 0) {
+				TAILQ_INSERT_BEFORE(dev2, dev, next);
+			} else { /* already registered */
+
+				dev_content_free(dev2);
+				dev2->addr.fdt_path = dev->addr.fdt_path;
+				dev2->id = dev->id;
+				free(dev);
+			}
+			return 0;
+		}
+		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+	}
+
+	return 0;
+
+fail:
+	free(uevent);
+	dev_content_free(dev);
+	free(dev);
+	return ret;
+}
+
+int
+rte_eal_soc_scan(void)
+{
+	struct dirent *e;
+	DIR *dir;
+	char dirname[PATH_MAX];
+
+	dir = opendir(soc_get_sysfs_path());
+	if (dir == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
+			__func__, strerror(errno));
+		return -1;
+	}
+
+	while ((e = readdir(dir)) != NULL) {
+		if (e->d_name[0] == '.')
+			continue;
+
+		snprintf(dirname, sizeof(dirname), "%s/%s",
+				soc_get_sysfs_path(), e->d_name);
+		if (soc_scan_one(dirname, e->d_name) < 0)
+			goto error;
+	}
+	closedir(dir);
+	return 0;
+
+error:
+	closedir(dir);
+	return -1;
+}
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 6ff38b8..280622f 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -162,7 +162,11 @@ DPDK_16.07 {
 	rte_eal_dev_detach;
 
 	soc_driver_list;
+	soc_device_list;
+	soc_get_sysfs_path;
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
+	rte_eal_soc_scan;
+	rte_eal_soc_dump;
 
 } DPDK_16.04;
-- 
2.8.0

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

* [PATCH v1 09/28] eal: introduce --no-soc option
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (15 preceding siblings ...)
  2016-05-06 13:47 ` [PATCH v1 08/28] eal/soc: implement SoC device discovery Jan Viktorin
@ 2016-05-06 13:47 ` Jan Viktorin
  2016-05-13  3:28   ` Jianbo Liu
  2016-05-06 13:47 ` [PATCH v1 10/28] eal/soc: init SoC infra from EAL Jan Viktorin
                   ` (20 subsequent siblings)
  37 siblings, 1 reply; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:47 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

This option has the same meaning for the SoC infra as the --no-pci
for the PCI infra.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/common/eal_common_options.c | 5 +++++
 lib/librte_eal/common/eal_internal_cfg.h   | 1 +
 lib/librte_eal/common/eal_options.h        | 2 ++
 3 files changed, 8 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 3efc90f..09d64f7 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -85,6 +85,7 @@ eal_long_options[] = {
 	{OPT_NO_HPET,           0, NULL, OPT_NO_HPET_NUM          },
 	{OPT_NO_HUGE,           0, NULL, OPT_NO_HUGE_NUM          },
 	{OPT_NO_PCI,            0, NULL, OPT_NO_PCI_NUM           },
+	{OPT_NO_SOC,            0, NULL, OPT_NO_SOC_NUM           },
 	{OPT_NO_SHCONF,         0, NULL, OPT_NO_SHCONF_NUM        },
 	{OPT_PCI_BLACKLIST,     1, NULL, OPT_PCI_BLACKLIST_NUM    },
 	{OPT_PCI_WHITELIST,     1, NULL, OPT_PCI_WHITELIST_NUM    },
@@ -841,6 +842,10 @@ eal_parse_common_option(int opt, const char *optarg,
 		conf->no_pci = 1;
 		break;
 
+	case OPT_NO_SOC_NUM:
+		conf->no_soc = 1;
+		break;
+
 	case OPT_NO_HPET_NUM:
 		conf->no_hpet = 1;
 		break;
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 5f1367e..3a98e94 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -67,6 +67,7 @@ struct internal_config {
 	unsigned hugepage_unlink;         /**< true to unlink backing files */
 	volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
 	volatile unsigned no_pci;         /**< true to disable PCI */
+	volatile unsigned no_soc;         /**< true to disable SoC */
 	volatile unsigned no_hpet;        /**< true to disable HPET */
 	volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
 										* instead of native TSC */
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index a881c62..ba1e704 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -69,6 +69,8 @@ enum {
 	OPT_NO_HUGE_NUM,
 #define OPT_NO_PCI            "no-pci"
 	OPT_NO_PCI_NUM,
+#define OPT_NO_SOC            "no-soc"
+	OPT_NO_SOC_NUM,
 #define OPT_NO_SHCONF         "no-shconf"
 	OPT_NO_SHCONF_NUM,
 #define OPT_SOCKET_MEM        "socket-mem"
-- 
2.8.0

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

* [PATCH v1 10/28] eal/soc: init SoC infra from EAL
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (16 preceding siblings ...)
  2016-05-06 13:47 ` [PATCH v1 09/28] eal: introduce --no-soc option Jan Viktorin
@ 2016-05-06 13:47 ` Jan Viktorin
  2016-05-06 13:47 ` [PATCH v1 11/28] eal/soc: implement probing of drivers Jan Viktorin
                   ` (19 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:47 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/bsdapp/eal/eal.c       |  4 ++++
 lib/librte_eal/common/eal_private.h   | 10 ++++++++++
 lib/librte_eal/linuxapp/eal/eal.c     |  3 +++
 lib/librte_eal/linuxapp/eal/eal_soc.c | 17 +++++++++++++++++
 4 files changed, 34 insertions(+)

diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 06bfd4e..23faebd 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -64,6 +64,7 @@
 #include <rte_string_fns.h>
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
+#include <rte_soc.h>
 #include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
@@ -567,6 +568,9 @@ rte_eal_init(int argc, char **argv)
 	if (rte_eal_pci_init() < 0)
 		rte_panic("Cannot init PCI\n");
 
+	if (rte_eal_soc_init() < 0)
+		rte_panic("Cannot init SoC\n");
+
 	eal_check_mem_on_local_socket();
 
 	if (eal_plugins_init() < 0)
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 5145215..b27ec89 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -187,6 +187,16 @@ int rte_eal_ivshmem_obj_init(void);
 struct rte_soc_driver;
 struct rte_soc_device;
 
+/**
+ * Init the SoC infra.
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int rte_eal_soc_init(void);
+
 struct rte_pci_driver;
 struct rte_pci_device;
 
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index a9f3ae2..5f190ff 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -803,6 +803,9 @@ rte_eal_init(int argc, char **argv)
 	if (rte_eal_pci_init() < 0)
 		rte_panic("Cannot init PCI\n");
 
+	if (rte_eal_soc_init() < 0)
+		rte_panic("Cannot init SoC\n");
+
 #ifdef RTE_LIBRTE_IVSHMEM
 	if (rte_eal_ivshmem_init() < 0)
 		rte_panic("Cannot init IVSHMEM\n");
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index 8dbb367..a3b9935 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -44,6 +44,7 @@
 #include <rte_log.h>
 #include <rte_soc.h>
 
+#include "eal_internal_cfg.h"
 #include "eal_private.h"
 
 static char *
@@ -280,3 +281,19 @@ error:
 	closedir(dir);
 	return -1;
 }
+
+/* Init the SoC EAL subsystem */
+int
+rte_eal_soc_init(void)
+{
+	/* for debug purposes, SoC can be disabled */
+	if (internal_config.no_soc)
+		return 0;
+
+	if (rte_eal_soc_scan() < 0) {
+		RTE_LOG(ERR, EAL, "%s(): Cannot scan SoC devices\n", __func__);
+		return -1;
+	}
+
+	return 0;
+}
-- 
2.8.0

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

* [PATCH v1 11/28] eal/soc: implement probing of drivers
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (17 preceding siblings ...)
  2016-05-06 13:47 ` [PATCH v1 10/28] eal/soc: init SoC infra from EAL Jan Viktorin
@ 2016-05-06 13:47 ` Jan Viktorin
  2016-05-06 13:47 ` [PATCH v1 12/28] eal/soc: extend and utilize devargs Jan Viktorin
                   ` (18 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:47 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   3 +
 lib/librte_eal/common/eal_common_soc.c          | 200 ++++++++++++++++++++++++
 lib/librte_eal/common/include/rte_soc.h         |  25 +++
 lib/librte_eal/linuxapp/eal/eal.c               |   4 +
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   3 +
 5 files changed, 235 insertions(+)

diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 4a2eeaf..bd3dd11 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -163,5 +163,8 @@ DPDK_16.07 {
 	rte_eal_soc_unregister;
 	rte_eal_soc_scan;
 	rte_eal_soc_dump;
+	rte_eal_soc_detach;
+	rte_eal_soc_probe;
+	rte_eal_soc_probe_one;
 
 } DPDK_16.04;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index d8bb6d6..d8f0c00 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -36,6 +36,8 @@
 #include <sys/queue.h>
 
 #include <rte_log.h>
+#include <rte_common.h>
+#include <rte_soc.h>
 
 #include "eal_private.h"
 
@@ -58,6 +60,204 @@ const char *soc_get_sysfs_path(void)
 	return path;
 }
 
+static int soc_id_match(const struct rte_soc_id *drv_id,
+		const struct rte_soc_id *dev_id)
+{
+	int i;
+	int j;
+
+	RTE_VERIFY(drv_id != NULL);
+	RTE_VERIFY(dev_id != NULL);
+
+	for (i = 0; drv_id[i].compatible; ++i) {
+		const char *drv_compat = drv_id[i].compatible;
+
+		for (j = 0; dev_id[j].compatible; ++j) {
+			const char *dev_compat = dev_id[j].compatible;
+
+			if (!strcmp(drv_compat, dev_compat))
+				return 1;
+		}
+	}
+
+	return 0;
+}
+
+static int
+rte_eal_soc_probe_one_driver(struct rte_soc_driver *dr,
+		struct rte_soc_device *dev)
+{
+	int ret;
+
+	if (!soc_id_match(dr->id_table, dev->id))
+		return 1;
+
+	RTE_LOG(DEBUG, EAL, "SoC device %s\n",
+			dev->addr.name);
+	RTE_LOG(DEBUG, EAL, "  probe driver %s\n", dr->name);
+
+	dev->driver = dr;
+	RTE_VERIFY(dr->devinit != NULL);
+	return dr->devinit(dr, dev);
+}
+
+static int
+soc_probe_all_drivers(struct rte_soc_device *dev)
+{
+	struct rte_soc_driver *dr = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dr, &soc_driver_list, next) {
+		rc = rte_eal_soc_probe_one_driver(dr, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+/* If the IDs match, call the devuninit() function of the driver. */
+static int
+rte_eal_soc_detach_dev(struct rte_soc_driver *dr,
+		struct rte_soc_device *dev)
+{
+	if ((dr == NULL) || (dev == NULL))
+		return -EINVAL;
+
+	if (!soc_id_match(dr->id_table, dev->id))
+		return 1;
+
+	RTE_LOG(DEBUG, EAL, "SoC device %s\n",
+			dev->addr.name);
+
+	RTE_LOG(DEBUG, EAL, "  remove driver: %s\n", dr->name);
+
+	if (dr->devuninit && (dr->devuninit(dev) < 0))
+		return -1;	/* negative value is an error */
+
+	/* clear driver structure */
+	dev->driver = NULL;
+
+	return 0;
+}
+
+/*
+ * Call the devuninit() function of all registered drivers for the given
+ * device if their IDs match.
+ *
+ * @return
+ *       0 when successful
+ *      -1 if deinitialization fails
+ *       1 if no driver is found for this device.
+ */
+static int
+soc_detach_all_drivers(struct rte_soc_device *dev)
+{
+	struct rte_soc_driver *dr = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dr, &soc_driver_list, next) {
+		rc = rte_eal_soc_detach_dev(dr, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+/*
+ * Detach device specified by its SoC address.
+ */
+int
+rte_eal_soc_detach(const struct rte_soc_addr *addr)
+{
+	struct rte_soc_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		if (rte_eal_compare_soc_addr(&dev->addr, addr))
+			continue;
+
+		ret = soc_detach_all_drivers(dev);
+		if (ret < 0)
+			goto err_return;
+
+		TAILQ_REMOVE(&soc_device_list, dev, next);
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL, "Requested device %s cannot be used\n",
+			dev->addr.name);
+	return -1;
+}
+
+int
+rte_eal_soc_probe_one(const struct rte_soc_addr *addr)
+{
+	struct rte_soc_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		if (rte_eal_compare_soc_addr(&dev->addr, addr))
+			continue;
+
+		ret = soc_probe_all_drivers(dev);
+		if (ret < 0)
+			goto err_return;
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL,
+		"Requested device %s cannot be used\n", addr->name);
+	return -1;
+}
+
+/*
+ * Scan the SoC devices and call the devinit() function for all registered
+ * drivers that have a matching entry in its id_table for discovered devices.
+ */
+int
+rte_eal_soc_probe(void)
+{
+	struct rte_soc_device *dev = NULL;
+	int probe_all = 0;
+	int ret = 0;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+
+		ret = soc_probe_all_drivers(dev);
+		if (ret < 0)
+			rte_exit(EXIT_FAILURE, "Requested device %s"
+				 " cannot be used\n", dev->addr.name);
+	}
+
+	return 0;
+}
+
 /* dump one device */
 static int
 soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 6278295..4117ffb 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -147,6 +147,31 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 int rte_eal_soc_scan(void);
 
 /**
+ * Probe SoC devices for registered drivers.
+ */
+int rte_eal_soc_probe(void);
+
+/**
+ * Probe the single SoC device.
+ */
+int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
+
+/**
+ * Close the single SoC device.
+ *
+ * Scan the SoC devices and find the SoC device specified by the SoC
+ * address, then call the devuninit() function for registered driver
+ * that has a matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The SoC address to close.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_eal_soc_detach(const struct rte_soc_addr *addr);
+
+/**
  * Dump discovered SoC devices.
  */
 void rte_eal_soc_dump(FILE *f);
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 5f190ff..e697bb0 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -896,6 +896,10 @@ rte_eal_init(int argc, char **argv)
 	if (rte_eal_pci_probe())
 		rte_panic("Cannot probe PCI\n");
 
+	/* Probe & Initialize SoC devices */
+	if (rte_eal_soc_probe())
+		rte_panic("Cannot probe SoC\n");
+
 	rte_eal_mcfg_complete();
 
 	return fctret;
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 280622f..811cbf8 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -168,5 +168,8 @@ DPDK_16.07 {
 	rte_eal_soc_unregister;
 	rte_eal_soc_scan;
 	rte_eal_soc_dump;
+	rte_eal_soc_detach;
+	rte_eal_soc_probe;
+	rte_eal_soc_probe_one;
 
 } DPDK_16.04;
-- 
2.8.0

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

* [PATCH v1 12/28] eal/soc: extend and utilize devargs
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (18 preceding siblings ...)
  2016-05-06 13:47 ` [PATCH v1 11/28] eal/soc: implement probing of drivers Jan Viktorin
@ 2016-05-06 13:47 ` Jan Viktorin
  2016-05-06 13:47 ` [PATCH v1 13/28] eal/soc: update device on probe when already exists Jan Viktorin
                   ` (17 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:47 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

This code is not tested. We assume to white/blacklist SoC devices by giving
the prefix "soc:" on the command line.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/common/eal_common_dev.c      | 31 ++++++++++++++++++-----
 lib/librte_eal/common/eal_common_devargs.c  |  7 ++++++
 lib/librte_eal/common/eal_common_soc.c      | 39 ++++++++++++++++++++++++++++-
 lib/librte_eal/common/include/rte_devargs.h |  8 ++++++
 lib/librte_eal/common/include/rte_soc.h     | 28 +++++++++++++++++++++
 5 files changed, 106 insertions(+), 7 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index d2763b0..4182a55 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -154,11 +154,19 @@ rte_eal_vdev_uninit(const char *name)
 
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
-	struct rte_pci_addr addr;
+	struct rte_soc_addr soc_addr;
+	struct rte_pci_addr pci_addr;
 	int ret = -1;
 
-	if (eal_parse_pci_DomBDF(name, &addr) == 0) {
-		if (rte_eal_pci_probe_one(&addr) < 0)
+	memset(&soc_addr, 0, sizeof(soc_addr));
+	if (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+		if (rte_eal_soc_probe_one(&soc_addr) < 0)
+			goto err_soc;
+
+		free(soc_addr.name);
+
+	} else 	if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+		if (rte_eal_pci_probe_one(&pci_addr) < 0)
 			goto err;
 
 	} else {
@@ -168,6 +176,8 @@ int rte_eal_dev_attach(const char *name, const char *devargs)
 
 	return 0;
 
+err_soc:
+	free(soc_addr.name);
 err:
 	RTE_LOG(ERR, EAL, "Driver, cannot attach the device\n");
 	return ret;
@@ -175,10 +185,17 @@ err:
 
 int rte_eal_dev_detach(const char *name)
 {
-	struct rte_pci_addr addr;
+	struct rte_soc_addr soc_addr;
+	struct rte_pci_addr pci_addr;
+
+	if (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+		if (rte_eal_soc_detach(&soc_addr) < 0)
+			goto soc_err;
+
+		free(soc_addr.name);
 
-	if (eal_parse_pci_DomBDF(name, &addr) == 0) {
-		if (rte_eal_pci_detach(&addr) < 0)
+	} else if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+		if (rte_eal_pci_detach(&pci_addr) < 0)
 			goto err;
 	} else {
 		if (rte_eal_vdev_uninit(name))
@@ -186,6 +203,8 @@ int rte_eal_dev_detach(const char *name)
 	}
 	return 0;
 
+soc_err:
+	free(soc_addr.name);
 err:
 	RTE_LOG(ERR, EAL, "Driver, cannot detach the device\n");
 	return -1;
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index 2bfe54a..5f6bcff 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -105,6 +105,13 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
 			goto fail;
 
 		break;
+
+	case RTE_DEVTYPE_WHITELISTED_SOC:
+	case RTE_DEVTYPE_BLACKLISTED_SOC:
+		/* save target device name */
+		devargs->soc.addr.name = strdup(buf); /* FIXME: memory leak */
+		break;
+
 	case RTE_DEVTYPE_VIRTUAL:
 		/* save driver name */
 		ret = snprintf(devargs->virt.drv_name,
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index d8f0c00..3b885e8 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -37,6 +37,7 @@
 
 #include <rte_log.h>
 #include <rte_common.h>
+#include <rte_devargs.h>
 #include <rte_soc.h>
 
 #include "eal_private.h"
@@ -60,6 +61,21 @@ const char *soc_get_sysfs_path(void)
 	return path;
 }
 
+static struct rte_devargs *soc_devargs_lookup(struct rte_soc_device *dev)
+{
+	struct rte_devargs *devargs;
+
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->type != RTE_DEVTYPE_BLACKLISTED_SOC &&
+			devargs->type != RTE_DEVTYPE_WHITELISTED_SOC)
+			continue;
+		if (!rte_eal_compare_soc_addr(&dev->addr, &devargs->soc.addr))
+			return devargs;
+	}
+
+	return NULL;
+}
+
 static int soc_id_match(const struct rte_soc_id *drv_id,
 		const struct rte_soc_id *dev_id)
 {
@@ -96,6 +112,13 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *dr,
 			dev->addr.name);
 	RTE_LOG(DEBUG, EAL, "  probe driver %s\n", dr->name);
 
+	if (dev->devargs != NULL
+		&& dev->devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC) {
+		RTE_LOG(DEBUG, EAL,
+			"  device is blacklisted, skipping\n");
+		return 1;
+	}
+
 	dev->driver = dr;
 	RTE_VERIFY(dr->devinit != NULL);
 	return dr->devinit(dr, dev);
@@ -244,12 +267,26 @@ int
 rte_eal_soc_probe(void)
 {
 	struct rte_soc_device *dev = NULL;
+	struct rte_devargs *devargs;
 	int probe_all = 0;
 	int ret = 0;
 
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_SOC) == 0)
+		probe_all = 1;
+
 	TAILQ_FOREACH(dev, &soc_device_list, next) {
 
-		ret = soc_probe_all_drivers(dev);
+		/* set devargs in SoC structure */
+		devargs = soc_devargs_lookup(dev);
+		if (devargs != NULL)
+			dev->devargs = devargs;
+
+		/* probe all or only whitelisted devices */
+		if (probe_all)
+			ret = soc_probe_all_drivers(dev);
+		else if (devargs != NULL &&
+			devargs->type == RTE_DEVTYPE_WHITELISTED_SOC)
+			ret = soc_probe_all_drivers(dev);
 		if (ret < 0)
 			rte_exit(EXIT_FAILURE, "Requested device %s"
 				 " cannot be used\n", dev->addr.name);
diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h
index 53c59f5..757320e 100644
--- a/lib/librte_eal/common/include/rte_devargs.h
+++ b/lib/librte_eal/common/include/rte_devargs.h
@@ -51,6 +51,7 @@ extern "C" {
 #include <stdio.h>
 #include <sys/queue.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 
 /**
  * Type of generic device
@@ -58,6 +59,8 @@ extern "C" {
 enum rte_devtype {
 	RTE_DEVTYPE_WHITELISTED_PCI,
 	RTE_DEVTYPE_BLACKLISTED_PCI,
+	RTE_DEVTYPE_WHITELISTED_SOC,
+	RTE_DEVTYPE_BLACKLISTED_SOC,
 	RTE_DEVTYPE_VIRTUAL,
 };
 
@@ -82,6 +85,11 @@ struct rte_devargs {
 			/** PCI location. */
 			struct rte_pci_addr addr;
 		} pci;
+		/** Used if type is RTE_DEVTYPE_*_SOC. */
+		struct {
+			/** SoC location. */
+			struct rte_soc_addr addr;
+		} soc;
 		/** Used if type is RTE_DEVTYPE_VIRTUAL. */
 		struct {
 			/** Driver name. */
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 4117ffb..00fd0a6 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -72,6 +72,8 @@ struct rte_soc_addr {
 	char *fdt_path; /**< path to the associated node in FDT */
 };
 
+struct rte_devargs;
+
 /**
  * A structure describing a SoC device.
  */
@@ -80,6 +82,7 @@ struct rte_soc_device {
 	struct rte_soc_addr addr;           /**< SoC device Location */
 	struct rte_soc_id *id;              /**< SoC device ID list */
 	struct rte_soc_driver *driver;      /**< Associated driver */
+	struct rte_devargs *devargs;        /**< Device user arguments */
 };
 
 struct rte_soc_driver;
@@ -141,6 +144,31 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 
 	return strcmp(a0->name, a1->name);
 }
+
+/**
+ * Parse a specification of a soc device. The specification must differentiate
+ * a SoC device specification from the PCI bus and virtual devices. We assume
+ * a SoC specification starts with "soc:". The function allocates the name
+ * entry of the given addr.
+ *
+ * @return
+ *      -  0 on success
+ *      -  1 when not a SoC spec
+ *      - -1 on failure
+ */
+static inline int
+rte_eal_parse_soc_spec(const char *spec, struct rte_soc_addr *addr)
+{
+	if (strstr(spec, "soc:") == spec) {
+		addr->name = strdup(spec + 4);
+		if (addr->name == NULL)
+			return -1;
+		return 0;
+	}
+
+	return 1;
+}
+
 /**
  * Scan for new SoC devices.
  */
-- 
2.8.0

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

* [PATCH v1 13/28] eal/soc: update device on probe when already exists
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (19 preceding siblings ...)
  2016-05-06 13:47 ` [PATCH v1 12/28] eal/soc: extend and utilize devargs Jan Viktorin
@ 2016-05-06 13:47 ` Jan Viktorin
  2016-05-06 13:47 ` [PATCH v1 14/28] eal/soc: detect assigned kernel driver Jan Viktorin
                   ` (16 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:47 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/common/eal_common_soc.c |  5 +++++
 lib/librte_eal/common/eal_private.h    | 13 +++++++++++++
 lib/librte_eal/linuxapp/eal/eal_soc.c  | 11 +++++++++++
 3 files changed, 29 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 3b885e8..75a7a97 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -242,6 +242,11 @@ rte_eal_soc_probe_one(const struct rte_soc_addr *addr)
 	if (addr == NULL)
 		return -1;
 
+	/* update current SoC device in global list, kernel bindings might have
+	 * changed since last time we looked at it */
+	if (soc_update_device(addr) < 0)
+		goto err_return;
+
 	TAILQ_FOREACH(dev, &soc_device_list, next) {
 		if (rte_eal_compare_soc_addr(&dev->addr, addr))
 			continue;
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index b27ec89..fc1d9c6 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -197,6 +197,19 @@ struct rte_soc_device;
  */
 int rte_eal_soc_init(void);
 
+/**
+ * Update a soc device object by asking the kernel for the latest information.
+ *
+ * This function is private to EAL.
+ *
+ * @param addr
+ *	The SoC address to look for
+ * @return
+ *   - 0 on success.
+ *   - negative on error.
+ */
+int soc_update_device(const struct rte_soc_addr *addr);
+
 struct rte_pci_driver;
 struct rte_pci_device;
 
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index a3b9935..742d80d 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -252,6 +252,17 @@ fail:
 }
 
 int
+soc_update_device(const struct rte_soc_addr *addr)
+{
+	char filename[PATH_MAX];
+
+	snprintf(filename, sizeof(filename), "%s/%s",
+			soc_get_sysfs_path(), addr->name);
+
+	return soc_scan_one(filename, addr->name);
+}
+
+int
 rte_eal_soc_scan(void)
 {
 	struct dirent *e;
-- 
2.8.0

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

* [PATCH v1 14/28] eal/soc: detect assigned kernel driver
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (20 preceding siblings ...)
  2016-05-06 13:47 ` [PATCH v1 13/28] eal/soc: update device on probe when already exists Jan Viktorin
@ 2016-05-06 13:47 ` Jan Viktorin
  2016-05-06 13:47 ` [PATCH v1 15/28] eal/soc: map/unmap resources Jan Viktorin
                   ` (15 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:47 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

We reuse the existing infrastructure (rte_eal_get_kernel_driver_by_path) here
however another possible implementation is by parsing the uevent file.

As there are no well-known driver for SoC infra, we does not detect any. This
will be changed in the future by checking for VFIO and UIO drivers.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/common/include/rte_soc.h |  2 ++
 lib/librte_eal/linuxapp/eal/eal_soc.c   | 28 ++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 00fd0a6..206244a 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -53,6 +53,7 @@ extern "C" {
 
 #include <rte_debug.h>
 #include <rte_eal.h>
+#include <rte_dev.h>
 
 TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
 TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
@@ -83,6 +84,7 @@ struct rte_soc_device {
 	struct rte_soc_id *id;              /**< SoC device ID list */
 	struct rte_soc_driver *driver;      /**< Associated driver */
 	struct rte_devargs *devargs;        /**< Device user arguments */
+	enum rte_kernel_driver kdrv;        /**< Kernel driver */
 };
 
 struct rte_soc_driver;
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index 742d80d..4f9070e 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -179,6 +179,30 @@ dev_content_free(struct rte_soc_device *dev)
 	dev->id = NULL;
 }
 
+static int
+dev_setup_associated_driver(struct rte_soc_device *dev, const char *dirname)
+{
+	char filename[PATH_MAX];
+	char driver[PATH_MAX];
+	int ret;
+
+	/* parse driver */
+	snprintf(filename, sizeof(filename), "%s/driver", dirname);
+	ret = rte_eal_get_kernel_driver_by_path(filename, driver);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "Fail to get kernel driver for %s\n", dirname);
+		return 1;
+	}
+
+	if (!ret) {
+		dev->kdrv = RTE_KDRV_UNKNOWN;
+	} else {
+		dev->kdrv = RTE_KDRV_NONE;
+	}
+
+	return 0;
+}
+
 /**
  * Scan one SoC sysfs entry, and fill the devices list from it.
  * We require to have the uevent file with records: OF_FULLNAME and
@@ -217,6 +241,9 @@ soc_scan_one(const char *dirname, const char *name)
 		goto fail;
 	free(uevent); /* not needed anymore */
 
+	if ((ret = dev_setup_associated_driver(dev, dirname)))
+		goto fail;
+
 	/* device is valid, add in list (sorted) */
 	if (TAILQ_EMPTY(&soc_device_list)) {
 		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
@@ -231,6 +258,7 @@ soc_scan_one(const char *dirname, const char *name)
 			if (ret < 0) {
 				TAILQ_INSERT_BEFORE(dev2, dev, next);
 			} else { /* already registered */
+				dev2->kdrv = dev->kdrv;
 
 				dev_content_free(dev2);
 				dev2->addr.fdt_path = dev->addr.fdt_path;
-- 
2.8.0

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

* [PATCH v1 15/28] eal/soc: map/unmap resources
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (21 preceding siblings ...)
  2016-05-06 13:47 ` [PATCH v1 14/28] eal/soc: detect assigned kernel driver Jan Viktorin
@ 2016-05-06 13:47 ` Jan Viktorin
  2016-05-06 13:47 ` [PATCH v1 16/28] eal/soc: add intr_handle Jan Viktorin
                   ` (14 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:47 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/bsdapp/eal/eal_soc.c             | 12 ++++++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  2 +
 lib/librte_eal/common/eal_common_soc.c          | 13 +++++++
 lib/librte_eal/common/include/rte_soc.h         | 50 +++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/eal_soc.c           | 30 +++++++++++++++
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  2 +
 6 files changed, 109 insertions(+)

diff --git a/lib/librte_eal/bsdapp/eal/eal_soc.c b/lib/librte_eal/bsdapp/eal/eal_soc.c
index f84aae9..687d37b 100644
--- a/lib/librte_eal/bsdapp/eal/eal_soc.c
+++ b/lib/librte_eal/bsdapp/eal/eal_soc.c
@@ -32,9 +32,21 @@
  */
 
 #include <rte_soc.h>
+#include <rte_common.h>
 
 int
 rte_eal_soc_scan(void)
 {
 	return 0;
 }
+
+int
+rte_eal_soc_map_device(struct rte_soc_device *dev __rte_unused)
+{
+	return 0;
+}
+
+void
+rte_eal_soc_unmap_device(struct rte_soc_device *dev __rte_unused)
+{
+}
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index bd3dd11..b33282a 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -166,5 +166,7 @@ DPDK_16.07 {
 	rte_eal_soc_detach;
 	rte_eal_soc_probe;
 	rte_eal_soc_probe_one;
+	rte_eal_soc_map_device;
+	rte_eal_soc_unmap_device;
 
 } DPDK_16.04;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 75a7a97..d0e5351 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -119,6 +119,11 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *dr,
 		return 1;
 	}
 
+	/* map resources */
+	ret = rte_eal_soc_map_device(dev);
+	if (ret)
+		return ret;
+
 	dev->driver = dr;
 	RTE_VERIFY(dr->devinit != NULL);
 	return dr->devinit(dr, dev);
@@ -168,6 +173,8 @@ rte_eal_soc_detach_dev(struct rte_soc_driver *dr,
 	/* clear driver structure */
 	dev->driver = NULL;
 
+	/* unmap resources for devices */
+	rte_eal_soc_unmap_device(dev);
 	return 0;
 }
 
@@ -313,6 +320,12 @@ soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
 	for (i = 0; dev->id && dev->id[i].compatible; ++i)
 		fprintf(f, "   %s\n", dev->id[i].compatible);
 
+	for (i = 0; i < SOC_MAX_RESOURCE; i++) {
+		fprintf(f, "   %16.16"PRIx64" %16.16"PRIx64"\n",
+			dev->mem_resource[i].phys_addr,
+			dev->mem_resource[i].len);
+	}
+
 	return 0;
 }
 
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 206244a..3192121 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -50,6 +50,7 @@ extern "C" {
 #include <stdint.h>
 #include <inttypes.h>
 #include <string.h>
+#include <limits.h>
 
 #include <rte_debug.h>
 #include <rte_eal.h>
@@ -64,6 +65,14 @@ extern struct soc_device_list soc_device_list; /**< Global list of SoC devices.
 /** Return SoC scan path of the sysfs root. */
 const char *soc_get_sysfs_path(void);
 
+#define SOC_MAX_RESOURCE 6
+
+struct rte_soc_resource {
+	uint64_t phys_addr;
+	uint64_t len;
+	void *addr;
+};
+
 struct rte_soc_id {
 	const char *compatible; /**< OF compatible specification */
 };
@@ -82,6 +91,7 @@ struct rte_soc_device {
 	TAILQ_ENTRY(rte_soc_device) next;   /**< Next probed SoC device */
 	struct rte_soc_addr addr;           /**< SoC device Location */
 	struct rte_soc_id *id;              /**< SoC device ID list */
+	struct rte_soc_resource mem_resource[SOC_MAX_RESOURCE];
 	struct rte_soc_driver *driver;      /**< Associated driver */
 	struct rte_devargs *devargs;        /**< Device user arguments */
 	enum rte_kernel_driver kdrv;        /**< Kernel driver */
@@ -111,6 +121,34 @@ struct rte_soc_driver {
 };
 
 /**
+ * A structure describing a SoC mapping.
+ */
+struct soc_map {
+	void *addr;
+	char *path;
+	uint64_t offset;
+	uint64_t size;
+	uint64_t phaddr;
+};
+
+/**
+ * A structure describing a mapped SoC resource.
+ * For multi-process we need to reproduce all SoC mappings in secondary
+ * processes, so save them in a tailq.
+ */
+struct mapped_soc_resource {
+	TAILQ_ENTRY(mapped_soc_resource) next;
+
+	struct rte_soc_addr soc_addr;
+	char path[PATH_MAX];
+	int nb_maps;
+	struct soc_map maps[SOC_MAX_RESOURCE];
+};
+
+/** mapped SoC resource list */
+TAILQ_HEAD(mapped_soc_res_list, mapped_soc_resource);
+
+/**
  * Utility function to write a SoC device name, this device name can later be
  * used to retrieve the corresponding rte_soc_addr using above functions.
  *
@@ -202,6 +240,18 @@ int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
 int rte_eal_soc_detach(const struct rte_soc_addr *addr);
 
 /**
+ * Map SoC device resources into userspace.
+ *
+ * This is called by the EAL if (drv_flags & RTE_SOC_DRV_NEED_MAPPING).
+ */
+int rte_eal_soc_map_device(struct rte_soc_device *dev);
+
+/**
+ * Unmap the device resources.
+ */
+void rte_eal_soc_unmap_device(struct rte_soc_device *dev);
+
+/**
  * Dump discovered SoC devices.
  */
 void rte_eal_soc_dump(FILE *f);
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index 4f9070e..f57486a 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -47,6 +47,34 @@
 #include "eal_internal_cfg.h"
 #include "eal_private.h"
 
+int
+rte_eal_soc_map_device(struct rte_soc_device *dev)
+{
+	int ret = -1;
+
+	/* try mapping the NIC resources using VFIO if it exists */
+	switch (dev->kdrv) {
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		ret = 1;
+		break;
+	}
+
+	return ret;
+}
+
+void
+rte_eal_soc_unmap_device(struct rte_soc_device *dev)
+{
+	switch (dev->kdrv) {
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		break;
+	}
+}
+
 static char *
 dev_read_uevent(const char *dirname)
 {
@@ -259,6 +287,8 @@ soc_scan_one(const char *dirname, const char *name)
 				TAILQ_INSERT_BEFORE(dev2, dev, next);
 			} else { /* already registered */
 				dev2->kdrv = dev->kdrv;
+				memmove(dev2->mem_resource, dev->mem_resource,
+					sizeof(dev->mem_resource));
 
 				dev_content_free(dev2);
 				dev2->addr.fdt_path = dev->addr.fdt_path;
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 811cbf8..8e95a41 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -171,5 +171,7 @@ DPDK_16.07 {
 	rte_eal_soc_detach;
 	rte_eal_soc_probe;
 	rte_eal_soc_probe_one;
+	rte_eal_soc_map_device;
+	rte_eal_soc_unmap_device;
 
 } DPDK_16.04;
-- 
2.8.0

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

* [PATCH v1 16/28] eal/soc: add intr_handle
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (22 preceding siblings ...)
  2016-05-06 13:47 ` [PATCH v1 15/28] eal/soc: map/unmap resources Jan Viktorin
@ 2016-05-06 13:47 ` Jan Viktorin
  2016-05-06 13:47 ` [PATCH v1 17/28] eal/soc: hack (const char *) compatible setting Jan Viktorin
                   ` (13 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:47 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/common/include/rte_soc.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 3192121..4b4789b 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -55,6 +55,7 @@ extern "C" {
 #include <rte_debug.h>
 #include <rte_eal.h>
 #include <rte_dev.h>
+#include <rte_interrupts.h>
 
 TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
 TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
@@ -92,6 +93,7 @@ struct rte_soc_device {
 	struct rte_soc_addr addr;           /**< SoC device Location */
 	struct rte_soc_id *id;              /**< SoC device ID list */
 	struct rte_soc_resource mem_resource[SOC_MAX_RESOURCE];
+	struct rte_intr_handle intr_handle; /**< Interrupt handle */
 	struct rte_soc_driver *driver;      /**< Associated driver */
 	struct rte_devargs *devargs;        /**< Device user arguments */
 	enum rte_kernel_driver kdrv;        /**< Kernel driver */
-- 
2.8.0

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

* [PATCH v1 17/28] eal/soc: hack (const char *) compatible setting
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (23 preceding siblings ...)
  2016-05-06 13:47 ` [PATCH v1 16/28] eal/soc: add intr_handle Jan Viktorin
@ 2016-05-06 13:47 ` Jan Viktorin
  2016-05-06 13:48 ` [PATCH v1 18/28] eal/soc: detect numa_node of the rte_soc_device Jan Viktorin
                   ` (12 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:47 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

The strict GCC rules do not allow to set the rte_soc_addr.compatible as it is
marked 'const'. However, we need it to be const because drivers will set it
statically by const strings. So this hack enables both.

Is there a better way to go?

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/common/include/rte_soc.h |  6 ++-
 lib/librte_eal/linuxapp/eal/eal_soc.c   | 69 +++++++++++++++++++++++++++++++--
 2 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 4b4789b..830fcdc 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -75,7 +75,11 @@ struct rte_soc_resource {
 };
 
 struct rte_soc_id {
-	const char *compatible; /**< OF compatible specification */
+	union {
+		/* workaround -Werror=discarded-qualifiers,cast-equal */
+		char *_compatible;      /**< OF compatible specification */
+		const char *compatible; /**< OF compatible specification */
+	};
 };
 
 struct rte_soc_addr {
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index f57486a..c0e123a 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -173,6 +173,11 @@ static int
 dev_parse_uevent(struct rte_soc_device *dev, const char *uevent)
 {
 	const char *of;
+	const char *compat_n;
+	char *err;
+	long n;
+	char compat[strlen("OF_COMPATIBLE_NNNN=")];
+	long i;
 
 	of = dev_uevent_find(uevent, "OF_FULLNAME=");
 	if (of == NULL)
@@ -188,23 +193,81 @@ dev_parse_uevent(struct rte_soc_device *dev, const char *uevent)
 	RTE_LOG(DEBUG, EAL, "Detected device %s (%s)\n",
 			dev->addr.name, dev->addr.fdt_path);
 
-	dev->id = calloc(1, sizeof(*dev->id));
+	compat_n = dev_uevent_find(uevent, "OF_COMPATIBLE_N=");
+	if (compat_n == NULL) {
+		RTE_LOG(ERR, EAL, "No OF_COMPATIBLE_N found\n");
+		return -1;
+	}
+
+	n = strtoul(compat_n, &err, 0);
+	if (*err != '\n' && err != NULL) {
+		RTE_LOG(ERR, EAL, "Failed to parse OF_COMPATIBLE_N: %.10s\n", err);
+		goto fail_fdt_path;
+	}
+
+	if (n == 0)
+		return 1; /* cannot match anything */
+	if (n > 9999) { /* match NNNN */
+		RTE_LOG(ERR, EAL, "OF_COMPATIBLE_N is invalid: %ld\n", n);
+		goto fail_fdt_path;
+	}
+
+	dev->id = calloc(n + 1, sizeof(*dev->id));
 	if (dev->id == NULL) {
+		RTE_LOG(ERR, PMD, "Failed to alloc memory for ID\n");
 		free(dev->addr.fdt_path);
 		return -1;
 	}
 
+	for (i = 0; i < n; ++i) {
+		snprintf(compat, sizeof(compat), "OF_COMPATIBLE_%lu=", i);
+		const char *val;
+
+		val = dev_uevent_find(uevent, compat);
+		if (val == NULL) {
+			RTE_LOG(ERR, EAL, "%s was not found\n", compat);
+			goto fail_id;
+		}
+
+		dev->id[i]._compatible = strdup_until_nl(val);
+		if (dev->id[i]._compatible == NULL) {
+			RTE_LOG(ERR, PMD,
+				"Failed to alloc memory for compatible\n");
+			goto fail_id;
+		}
+
+		RTE_LOG(DEBUG, EAL, "  compatible: %s\n",
+				dev->id[i].compatible);
+	}
+
+	dev->id[n]._compatible = NULL; /* mark last one */
+
 	return 0;
+
+fail_id:
+	while (i-- >= 0)
+		free(dev->id[i]._compatible);
+	free(dev->id);
+fail_fdt_path:
+	free(dev->addr.fdt_path);
+	return -1;
 }
 
 static void
 dev_content_free(struct rte_soc_device *dev)
 {
+	int i;
+
 	if (dev->addr.fdt_path)
 		free(dev->addr.fdt_path);
 
-	free(dev->id);
-	dev->id = NULL;
+	if (dev->id != NULL) {
+		for (i = 0; dev->id[i]._compatible; ++i)
+			free(dev->id[i]._compatible);
+
+		free(dev->id);
+		dev->id = NULL;
+	}
 }
 
 static int
-- 
2.8.0

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

* [PATCH v1 18/28] eal/soc: detect numa_node of the rte_soc_device
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (24 preceding siblings ...)
  2016-05-06 13:47 ` [PATCH v1 17/28] eal/soc: hack (const char *) compatible setting Jan Viktorin
@ 2016-05-06 13:48 ` Jan Viktorin
  2016-05-06 13:48 ` [PATCH v1 19/28] eal/soc: add drv_flags Jan Viktorin
                   ` (11 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:48 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

No idea whether this is useful. Who creates the numa_node in the sysfs?
This can be probably dropped later.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/common/eal_common_soc.c  |  8 ++++----
 lib/librte_eal/common/include/rte_soc.h |  1 +
 lib/librte_eal/linuxapp/eal/eal_soc.c   | 26 ++++++++++++++++++++++++++
 3 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index d0e5351..af4daa5 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -108,8 +108,8 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *dr,
 	if (!soc_id_match(dr->id_table, dev->id))
 		return 1;
 
-	RTE_LOG(DEBUG, EAL, "SoC device %s\n",
-			dev->addr.name);
+	RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %d\n",
+			dev->addr.name, dev->numa_node);
 	RTE_LOG(DEBUG, EAL, "  probe driver %s\n", dr->name);
 
 	if (dev->devargs != NULL
@@ -162,8 +162,8 @@ rte_eal_soc_detach_dev(struct rte_soc_driver *dr,
 	if (!soc_id_match(dr->id_table, dev->id))
 		return 1;
 
-	RTE_LOG(DEBUG, EAL, "SoC device %s\n",
-			dev->addr.name);
+	RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %i\n",
+			dev->addr.name, dev->numa_node);
 
 	RTE_LOG(DEBUG, EAL, "  remove driver: %s\n", dr->name);
 
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 830fcdc..49cfeb7 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -99,6 +99,7 @@ struct rte_soc_device {
 	struct rte_soc_resource mem_resource[SOC_MAX_RESOURCE];
 	struct rte_intr_handle intr_handle; /**< Interrupt handle */
 	struct rte_soc_driver *driver;      /**< Associated driver */
+	int numa_node;                      /**< NUMA node connection */
 	struct rte_devargs *devargs;        /**< Device user arguments */
 	enum rte_kernel_driver kdrv;        /**< Kernel driver */
 };
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index c0e123a..6ef7d2f 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -45,6 +45,7 @@
 #include <rte_soc.h>
 
 #include "eal_internal_cfg.h"
+#include "eal_filesystem.h"
 #include "eal_private.h"
 
 int
@@ -294,6 +295,28 @@ dev_setup_associated_driver(struct rte_soc_device *dev, const char *dirname)
 	return 0;
 }
 
+static int
+dev_setup_numa_node(struct rte_soc_device *dev, const char *dirname)
+{
+	char filename[PATH_MAX];
+	FILE *f;
+	/* if no NUMA support, set default to 0 */
+	unsigned long tmp = 0;
+	int ret = 0;
+
+	/* get numa node */
+	snprintf(filename, sizeof(filename), "%s/numa_node", dirname);
+	if ((f = fopen(filename, "r")) != NULL) {
+		if (eal_parse_sysfs_valuef(f, &tmp) < 0)
+			ret = 1;
+
+		fclose(f);
+	}
+
+	dev->numa_node = tmp;
+	return ret;
+}
+
 /**
  * Scan one SoC sysfs entry, and fill the devices list from it.
  * We require to have the uevent file with records: OF_FULLNAME and
@@ -335,6 +358,9 @@ soc_scan_one(const char *dirname, const char *name)
 	if ((ret = dev_setup_associated_driver(dev, dirname)))
 		goto fail;
 
+	if ((ret = dev_setup_numa_node(dev, dirname)) < 0)
+		goto fail;
+
 	/* device is valid, add in list (sorted) */
 	if (TAILQ_EMPTY(&soc_device_list)) {
 		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
-- 
2.8.0

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

* [PATCH v1 19/28] eal/soc: add drv_flags
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (25 preceding siblings ...)
  2016-05-06 13:48 ` [PATCH v1 18/28] eal/soc: detect numa_node of the rte_soc_device Jan Viktorin
@ 2016-05-06 13:48 ` Jan Viktorin
  2016-06-13 14:21   ` Shreyansh Jain
  2016-05-06 13:48 ` [PATCH v1 20/28] eal/soc: map resources conditionally Jan Viktorin
                   ` (10 subsequent siblings)
  37 siblings, 1 reply; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:48 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

The flags are copied from the PCI ones. They should be refactorized into a
general set of flags in the future.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/common/include/rte_soc.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 49cfeb7..50a3b35 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -125,8 +125,18 @@ struct rte_soc_driver {
 	soc_devinit_t *devinit;            /**< Device initialization */
 	soc_devuninit_t *devuninit;        /**< Device uninitialization */
 	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
+	uint32_t drv_flags;                /**< Control handling of device */
 };
 
+/** Device needs to map its resources by EAL */
+#define RTE_SOC_DRV_NEED_MAPPING 0x0001
+/** Device needs to be unbound event if no module is provieded */
+#define RTE_SOC_DRV_FORCE_UNBIND 0x0004
+/** Device driver supports link state interrupt */
+#define RTE_SOC_DRV_INTR_LSC	 0x0008
+/** Device driver supports detaching capability */
+#define RTE_SOC_DRV_DETACHABLE	 0x0010
+
 /**
  * A structure describing a SoC mapping.
  */
-- 
2.8.0

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

* [PATCH v1 20/28] eal/soc: map resources conditionally
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (26 preceding siblings ...)
  2016-05-06 13:48 ` [PATCH v1 19/28] eal/soc: add drv_flags Jan Viktorin
@ 2016-05-06 13:48 ` Jan Viktorin
  2016-05-06 13:48 ` [PATCH v1 21/28] eal/soc: unbind kernel driver on probe Jan Viktorin
                   ` (9 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:48 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/common/eal_common_soc.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index af4daa5..d178c48 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -119,10 +119,12 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *dr,
 		return 1;
 	}
 
-	/* map resources */
-	ret = rte_eal_soc_map_device(dev);
-	if (ret)
-		return ret;
+	if (dr->drv_flags & RTE_SOC_DRV_NEED_MAPPING) {
+		/* map resources */
+		ret = rte_eal_soc_map_device(dev);
+		if (ret)
+			return ret;
+	}
 
 	dev->driver = dr;
 	RTE_VERIFY(dr->devinit != NULL);
@@ -173,8 +175,10 @@ rte_eal_soc_detach_dev(struct rte_soc_driver *dr,
 	/* clear driver structure */
 	dev->driver = NULL;
 
-	/* unmap resources for devices */
-	rte_eal_soc_unmap_device(dev);
+	if (dr->drv_flags & RTE_SOC_DRV_NEED_MAPPING)
+		/* unmap resources for devices */
+		rte_eal_soc_unmap_device(dev);
+
 	return 0;
 }
 
-- 
2.8.0

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

* [PATCH v1 21/28] eal/soc: unbind kernel driver on probe
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (27 preceding siblings ...)
  2016-05-06 13:48 ` [PATCH v1 20/28] eal/soc: map resources conditionally Jan Viktorin
@ 2016-05-06 13:48 ` Jan Viktorin
  2016-05-06 13:48 ` [PATCH v1 22/28] eal/soc: detect DMA non-coherent devices Jan Viktorin
                   ` (8 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:48 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/common/eal_common_soc.c |  6 ++++++
 lib/librte_eal/common/eal_private.h    | 10 ++++++++++
 lib/librte_eal/linuxapp/eal/eal_soc.c  | 11 +++++++++++
 3 files changed, 27 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index d178c48..49dbcb8 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -38,6 +38,7 @@
 #include <rte_log.h>
 #include <rte_common.h>
 #include <rte_devargs.h>
+#include <rte_eal.h>
 #include <rte_soc.h>
 
 #include "eal_private.h"
@@ -124,6 +125,11 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *dr,
 		ret = rte_eal_soc_map_device(dev);
 		if (ret)
 			return ret;
+	} else if (dr->drv_flags & RTE_SOC_DRV_FORCE_UNBIND
+		&& rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		/* unbind */
+		if (soc_unbind_kernel_driver(dev) < 0)
+			return -1;
 	}
 
 	dev->driver = dr;
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index fc1d9c6..f1409cf 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -210,6 +210,16 @@ int rte_eal_soc_init(void);
  */
 int soc_update_device(const struct rte_soc_addr *addr);
 
+/**
+ * Unbind kernel driver for this device
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int soc_unbind_kernel_driver(struct rte_soc_device *dev);
+
 struct rte_pci_driver;
 struct rte_pci_device;
 
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index 6ef7d2f..6e9e242 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -49,6 +49,17 @@
 #include "eal_private.h"
 
 int
+soc_unbind_kernel_driver(struct rte_soc_device *dev)
+{
+	char devpath[PATH_MAX];
+
+	snprintf(devpath, sizeof(devpath), "%s/%s",
+	         soc_get_sysfs_path(), dev->addr.name);
+
+	return rte_eal_unbind_kernel_driver(devpath, dev->addr.name);
+}
+
+int
 rte_eal_soc_map_device(struct rte_soc_device *dev)
 {
 	int ret = -1;
-- 
2.8.0

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

* [PATCH v1 22/28] eal/soc: detect DMA non-coherent devices
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (28 preceding siblings ...)
  2016-05-06 13:48 ` [PATCH v1 21/28] eal/soc: unbind kernel driver on probe Jan Viktorin
@ 2016-05-06 13:48 ` Jan Viktorin
  2016-05-06 13:48 ` [PATCH v1 23/28] eal: define macro container_of Jan Viktorin
                   ` (7 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:48 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

The SoC devices can be sometimes DMA non-coherent. This means that we need
to take care of memory allocation for those. Generally, drivers assume that
every device is DMA coherent. If a driver supports a DMA non-coherent device,
it sets the RTE_SOC_DRV_ACCEPT_NONCC flag.

Note that the is_dma_coherent flag have in fact the following semantics:

 * if true the device is DMA coherent
 * otherwise we don't know...

Notes:

The current dma-coherent detection is not perfect as the property may be placed
in parent nodes of FDT as well. It is a question whether this detection is
important here because the kernel drivers might help transparently. However,
at the moment, there is no standard kernel driver that provides the proper
memory (dma_alloc_coherent) to us. So we can either create one or patch the
uio_dmem_genirq to be more generic (this is a way to go). Anyway, a custom
mempool should be used here.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/common/eal_common_soc.c  |  8 ++++++++
 lib/librte_eal/common/include/rte_soc.h |  3 +++
 lib/librte_eal/linuxapp/eal/eal_soc.c   | 24 ++++++++++++++++++++++++
 3 files changed, 35 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 49dbcb8..4d32826 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -120,6 +120,14 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *dr,
 		return 1;
 	}
 
+	if (!dev->is_dma_coherent) {
+		if (!(dr->drv_flags & RTE_SOC_DRV_ACCEPT_NONCC)) {
+			RTE_LOG(DEBUG, EAL,
+				"  device is not DMA coherent, skipping\n");
+			return 1;
+		}
+	}
+
 	if (dr->drv_flags & RTE_SOC_DRV_NEED_MAPPING) {
 		/* map resources */
 		ret = rte_eal_soc_map_device(dev);
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 50a3b35..2225a63 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -100,6 +100,7 @@ struct rte_soc_device {
 	struct rte_intr_handle intr_handle; /**< Interrupt handle */
 	struct rte_soc_driver *driver;      /**< Associated driver */
 	int numa_node;                      /**< NUMA node connection */
+	int is_dma_coherent;                /**< DMA coherent device */
 	struct rte_devargs *devargs;        /**< Device user arguments */
 	enum rte_kernel_driver kdrv;        /**< Kernel driver */
 };
@@ -136,6 +137,8 @@ struct rte_soc_driver {
 #define RTE_SOC_DRV_INTR_LSC	 0x0008
 /** Device driver supports detaching capability */
 #define RTE_SOC_DRV_DETACHABLE	 0x0010
+/** Device driver accepts DMA non-coherent devices */
+#define RTE_SOC_DRV_ACCEPT_NONCC 0x0020
 
 /**
  * A structure describing a SoC mapping.
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index 6e9e242..5277fb7 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -328,6 +328,25 @@ dev_setup_numa_node(struct rte_soc_device *dev, const char *dirname)
 	return ret;
 }
 
+static int
+dev_detect_is_coherent(struct rte_soc_device *dev)
+{
+	char filename[PATH_MAX];
+	FILE *f;
+
+	if (dev->addr.fdt_path == NULL)
+		return 0; /* no way to detect */
+
+	snprintf(filename, sizeof(filename), "%s%s/dma-coherent",
+			"/proc/device-tree", dev->addr.fdt_path);
+	if ((f = fopen(filename, "r")) == NULL) {
+		return 0;
+	}
+
+	fclose(f);
+	return 1;
+}
+
 /**
  * Scan one SoC sysfs entry, and fill the devices list from it.
  * We require to have the uevent file with records: OF_FULLNAME and
@@ -372,6 +391,10 @@ soc_scan_one(const char *dirname, const char *name)
 	if ((ret = dev_setup_numa_node(dev, dirname)) < 0)
 		goto fail;
 
+	dev->is_dma_coherent = dev_detect_is_coherent(dev);
+	RTE_LOG(DEBUG, EAL, "  DMA %s\n",
+			dev->is_dma_coherent? "coherent" : "non-coherent");
+
 	/* device is valid, add in list (sorted) */
 	if (TAILQ_EMPTY(&soc_device_list)) {
 		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
@@ -387,6 +410,7 @@ soc_scan_one(const char *dirname, const char *name)
 				TAILQ_INSERT_BEFORE(dev2, dev, next);
 			} else { /* already registered */
 				dev2->kdrv = dev->kdrv;
+				dev2->is_dma_coherent = dev->is_dma_coherent;
 				memmove(dev2->mem_resource, dev->mem_resource,
 					sizeof(dev->mem_resource));
 
-- 
2.8.0

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

* [PATCH v1 23/28] eal: define macro container_of
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (29 preceding siblings ...)
  2016-05-06 13:48 ` [PATCH v1 22/28] eal/soc: detect DMA non-coherent devices Jan Viktorin
@ 2016-05-06 13:48 ` Jan Viktorin
  2016-05-06 13:48 ` [PATCH v1 24/28] ether: utilize container_of for pci_drv Jan Viktorin
                   ` (6 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:48 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_eal/common/include/rte_common.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h
index 332f2a4..a9b6792 100644
--- a/lib/librte_eal/common/include/rte_common.h
+++ b/lib/librte_eal/common/include/rte_common.h
@@ -322,6 +322,22 @@ rte_bsf32(uint32_t v)
 #define offsetof(TYPE, MEMBER)  __builtin_offsetof (TYPE, MEMBER)
 #endif
 
+/**
+ * Return pointer to the wrapping struct instance.
+ * Example:
+ *
+ *  struct wrapper {
+ *      ...
+ *      struct child c;
+ *      ...
+ *  };
+ *
+ *  struct child *x = obtain(...);
+ *  struct wrapper *w = container_of(x, struct wrapper, c);
+ */
+#define container_of(p, type, member) \
+	((type *) (((char *) (p)) - offsetof(type, member)))
+
 #define _RTE_STR(x) #x
 /** Take a macro value and get a string version of it */
 #define RTE_STR(x) _RTE_STR(x)
-- 
2.8.0

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

* [PATCH v1 24/28] ether: utilize container_of for pci_drv
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (30 preceding siblings ...)
  2016-05-06 13:48 ` [PATCH v1 23/28] eal: define macro container_of Jan Viktorin
@ 2016-05-06 13:48 ` Jan Viktorin
  2016-05-06 13:48 ` [PATCH v1 25/28] ether: verify we copy info from a PCI device Jan Viktorin
                   ` (5 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:48 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

It is not necessary to place the rte_pci_driver at the beginning
of the rte_eth_dev struct anymore as we use the container_of macro
to get the parent pointer.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_ether/rte_ethdev.c | 4 ++--
 lib/librte_ether/rte_ethdev.h | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 55b32da..5474523 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -236,7 +236,7 @@ rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
 
 	int diag;
 
-	eth_drv = (struct eth_driver *)pci_drv;
+	eth_drv = container_of(pci_drv, struct eth_driver, pci_drv);
 
 	rte_eal_pci_device_name(&pci_dev->addr, ethdev_name,
 			sizeof(ethdev_name));
@@ -297,7 +297,7 @@ rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
 	if (eth_dev == NULL)
 		return -ENODEV;
 
-	eth_drv = (const struct eth_driver *)pci_dev->driver;
+	eth_drv = container_of(pci_dev->driver, struct eth_driver, pci_drv);
 
 	/* Invoke PMD device uninit function */
 	if (*eth_drv->eth_dev_uninit) {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index c8cbe17..622c9d8 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1813,7 +1813,7 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *eth_dev);
  * Each Ethernet driver acts as a PCI driver and is represented by a generic
  * *eth_driver* structure that holds:
  *
- * - An *rte_pci_driver* structure (which must be the first field).
+ * - An *rte_pci_driver* structure.
  *
  * - The *eth_dev_init* function invoked for each matching PCI device.
  *
-- 
2.8.0

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

* [PATCH v1 25/28] ether: verify we copy info from a PCI device
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (31 preceding siblings ...)
  2016-05-06 13:48 ` [PATCH v1 24/28] ether: utilize container_of for pci_drv Jan Viktorin
@ 2016-05-06 13:48 ` Jan Viktorin
  2016-05-06 13:48 ` [PATCH v1 26/28] ether: extract function eth_dev_get_intr_handle Jan Viktorin
                   ` (4 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:48 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_ether/rte_ethdev.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 5474523..0b0dcbc 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3077,6 +3077,8 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_de
 		return;
 	}
 
+	RTE_VERIFY(eth_dev->pci_dev != NULL);
+
 	eth_dev->data->dev_flags = 0;
 	if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC)
 		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
-- 
2.8.0

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

* [PATCH v1 26/28] ether: extract function eth_dev_get_intr_handle
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (32 preceding siblings ...)
  2016-05-06 13:48 ` [PATCH v1 25/28] ether: verify we copy info from a PCI device Jan Viktorin
@ 2016-05-06 13:48 ` Jan Viktorin
  2016-05-06 13:48 ` [PATCH v1 27/28] ether: extract function eth_dev_get_driver_name Jan Viktorin
                   ` (3 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:48 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

We abstract access to the intr_handle here as we want to get
it either from the pci_dev or soc_dev.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_ether/rte_ethdev.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 0b0dcbc..9378a4a 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2404,6 +2404,17 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
 	rte_spinlock_unlock(&rte_eth_dev_cb_lock);
 }
 
+static inline
+struct rte_intr_handle *eth_dev_get_intr_handle(struct rte_eth_dev *dev)
+{
+	if (dev->pci_dev) {
+		return &dev->pci_dev->intr_handle;
+	}
+
+	RTE_VERIFY(0);
+	return NULL;
+}
+
 int
 rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 {
@@ -2419,7 +2430,7 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 	}
 
 	dev = &rte_eth_devices[port_id];
-	intr_handle = &dev->pci_dev->intr_handle;
+	intr_handle = eth_dev_get_intr_handle(dev);
 	if (!intr_handle->intr_vec) {
 		RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
 		return -EPERM;
@@ -2482,7 +2493,7 @@ rte_eth_dev_rx_intr_ctl_q(uint8_t port_id, uint16_t queue_id,
 		return -EINVAL;
 	}
 
-	intr_handle = &dev->pci_dev->intr_handle;
+	intr_handle = eth_dev_get_intr_handle(dev);
 	if (!intr_handle->intr_vec) {
 		RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
 		return -EPERM;
-- 
2.8.0

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

* [PATCH v1 27/28] ether: extract function eth_dev_get_driver_name
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (33 preceding siblings ...)
  2016-05-06 13:48 ` [PATCH v1 26/28] ether: extract function eth_dev_get_intr_handle Jan Viktorin
@ 2016-05-06 13:48 ` Jan Viktorin
  2016-05-06 13:48 ` [PATCH v1 28/28] ether: support SoC device/driver Jan Viktorin
                   ` (2 subsequent siblings)
  37 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:48 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_ether/rte_ethdev.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 9378a4a..4af2e5f 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2449,6 +2449,17 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 	return 0;
 }
 
+static inline
+const char *eth_dev_get_driver_name(const struct rte_eth_dev *dev)
+{
+	if (dev->pci_dev) {
+		return dev->driver->pci_drv.name;
+	}
+
+	RTE_VERIFY(0);
+	return NULL;
+}
+
 const struct rte_memzone *
 rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 			 uint16_t queue_id, size_t size, unsigned align,
@@ -2456,9 +2467,11 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 {
 	char z_name[RTE_MEMZONE_NAMESIZE];
 	const struct rte_memzone *mz;
+	const char *drv_name;
 
+	drv_name = eth_dev_get_driver_name(dev);
 	snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
-		 dev->driver->pci_drv.name, ring_name,
+		 drv_name, ring_name,
 		 dev->data->port_id, queue_id);
 
 	mz = rte_memzone_lookup(z_name);
-- 
2.8.0

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

* [PATCH v1 28/28] ether: support SoC device/driver
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (34 preceding siblings ...)
  2016-05-06 13:48 ` [PATCH v1 27/28] ether: extract function eth_dev_get_driver_name Jan Viktorin
@ 2016-05-06 13:48 ` Jan Viktorin
  2016-06-29  9:42   ` Shreyansh jain
  2016-08-31 11:00 ` [PATCH v2 00/14] Introduce SoC device/driver framework for EAL Shreyansh Jain
  2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
  37 siblings, 1 reply; 231+ messages in thread
From: Jan Viktorin @ 2016-05-06 13:48 UTC (permalink / raw)
  To: dev
  Cc: Jan Viktorin, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
---
 lib/librte_ether/rte_ethdev.c | 127 +++++++++++++++++++++++++++++++++++++++++-
 lib/librte_ether/rte_ethdev.h |  31 +++++++++++
 2 files changed, 157 insertions(+), 1 deletion(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 4af2e5f..9259c2c 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -320,6 +320,99 @@ rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
 }
 
 int
+rte_eth_dev_soc_probe(struct rte_soc_driver *soc_drv,
+		      struct rte_soc_device *soc_dev)
+{
+	struct eth_driver    *eth_drv;
+	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
+	int diag;
+
+	eth_drv = container_of(soc_drv, struct eth_driver, soc_drv);
+
+	rte_eal_soc_device_name(&soc_dev->addr, ethdev_name,
+			sizeof(ethdev_name));
+
+	eth_dev = rte_eth_dev_allocate(ethdev_name);
+	if (eth_dev == NULL)
+		return -ENOMEM;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		eth_dev->data->dev_private = rte_zmalloc("ethdev private structure",
+				  eth_drv->dev_private_size,
+				  RTE_CACHE_LINE_SIZE);
+		if (eth_dev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private port data\n");
+	}
+	eth_dev->soc_dev = soc_dev;
+	eth_dev->driver = eth_drv;
+	eth_dev->data->rx_mbuf_alloc_failed = 0;
+
+	/* init user callbacks */
+	TAILQ_INIT(&(eth_dev->link_intr_cbs));
+
+	/*
+	 * Set the default MTU.
+	 */
+	eth_dev->data->mtu = ETHER_MTU;
+
+	/* Invoke PMD device initialization function */
+	diag = (*eth_drv->eth_dev_init)(eth_dev);
+	if (diag == 0)
+		return 0;
+
+	RTE_PMD_DEBUG_TRACE("driver %s: eth_dev_init(%s) failed\n",
+			soc_drv->name,
+			soc_dev->id.name);
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(eth_dev->data->dev_private);
+	rte_eth_dev_release_port(eth_dev);
+	return diag;
+}
+
+int
+rte_eth_dev_soc_remove(struct rte_soc_device *soc_dev)
+{
+	const struct eth_driver *eth_drv;
+	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+	int ret;
+
+	if (soc_dev == NULL)
+		return -EINVAL;
+
+	rte_eal_soc_device_name(&soc_dev->addr, ethdev_name,
+			sizeof(ethdev_name));
+
+	eth_dev = rte_eth_dev_allocated(ethdev_name);
+	if (eth_dev == NULL)
+		return -ENODEV;
+
+	eth_drv = container_of(soc_dev->driver, struct eth_driver, soc_drv);
+
+	/* Invoke PMD device uninit function */
+	if (*eth_drv->eth_dev_uninit) {
+		ret = (*eth_drv->eth_dev_uninit)(eth_dev);
+		if (ret)
+			return ret;
+	}
+
+	/* free ether device */
+	rte_eth_dev_release_port(eth_dev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(eth_dev->data->dev_private);
+
+	eth_dev->soc_dev = NULL;
+	eth_dev->driver = NULL;
+	eth_dev->data = NULL;
+
+	return 0;
+}
+
+
+int
 rte_eth_dev_is_valid_port(uint8_t port_id)
 {
 	if (port_id >= RTE_MAX_ETHPORTS ||
@@ -1431,7 +1524,7 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
 
 	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
-	dev_info->pci_dev = dev->pci_dev;
+	dev_info->soc_dev = dev->soc_dev;
 	dev_info->driver_name = dev->data->drv_name;
 }
 
@@ -2408,8 +2501,13 @@ static inline
 struct rte_intr_handle *eth_dev_get_intr_handle(struct rte_eth_dev *dev)
 {
 	if (dev->pci_dev) {
+		RTE_VERIFY(dev->soc_dev == NULL);
 		return &dev->pci_dev->intr_handle;
 	}
+	if (dev->soc_dev) {
+		RTE_VERIFY(dev->pci_dev == NULL);
+		return &dev->soc_dev->intr_handle;
+	}
 
 	RTE_VERIFY(0);
 	return NULL;
@@ -2453,8 +2551,13 @@ static inline
 const char *eth_dev_get_driver_name(const struct rte_eth_dev *dev)
 {
 	if (dev->pci_dev) {
+		RTE_VERIFY(dev->soc_dev == NULL);
 		return dev->driver->pci_drv.name;
 	}
+	if (dev->soc_dev) {
+		RTE_VERIFY(dev->pci_dev == NULL);
+		return dev->driver->soc_drv.name;
+	}
 
 	RTE_VERIFY(0);
 	return NULL;
@@ -3114,6 +3217,28 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_de
 	eth_dev->data->drv_name = pci_dev->driver->name;
 }
 
+void
+rte_eth_copy_soc_info(struct rte_eth_dev *eth_dev, struct rte_soc_device *soc_dev)
+{
+	if ((eth_dev == NULL) || (soc_dev == NULL)) {
+		RTE_PMD_DEBUG_TRACE("NULL pointer eth_dev=%p soc_dev=%p\n",
+				eth_dev, soc_dev);
+		return;
+	}
+
+	RTE_VERIFY(eth_dev->soc_dev != NULL);
+
+	eth_dev->data->dev_flags = 0;
+	if (soc_dev->driver->drv_flags & RTE_SOC_DRV_INTR_LSC)
+		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
+	if (soc_dev->driver->drv_flags & RTE_SOC_DRV_DETACHABLE)
+		eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
+
+	eth_dev->data->kdrv = soc_dev->kdrv;
+	eth_dev->data->numa_node = soc_dev->numa_node;
+	eth_dev->data->drv_name = soc_dev->driver->name;
+}
+
 int
 rte_eth_dev_l2_tunnel_eth_type_conf(uint8_t port_id,
 				    struct rte_eth_l2_tunnel_conf *l2_tunnel)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 622c9d8..9ecc3b8 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -180,6 +180,7 @@ extern "C" {
 #include <rte_log.h>
 #include <rte_interrupts.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include "rte_ether.h"
@@ -855,6 +856,7 @@ struct rte_eth_conf {
  */
 struct rte_eth_dev_info {
 	struct rte_pci_device *pci_dev; /**< Device PCI information. */
+	struct rte_soc_device *soc_dev; /**< Device SoC information. */
 	const char *driver_name; /**< Device Driver name. */
 	unsigned int if_index; /**< Index to bound host interface, or 0 if none.
 		Use if_indextoname() to translate into an interface name. */
@@ -1590,6 +1592,7 @@ struct rte_eth_dev {
 	const struct eth_driver *driver;/**< Driver for this device */
 	const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
 	struct rte_pci_device *pci_dev; /**< PCI info. supplied by probing */
+	struct rte_soc_device *soc_dev; /**< SoC info. supplied by probing */
 	/** User application callbacks for NIC interrupts */
 	struct rte_eth_dev_cb_list link_intr_cbs;
 	/**
@@ -1823,6 +1826,7 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *eth_dev);
  */
 struct eth_driver {
 	struct rte_pci_driver pci_drv;    /**< The PMD is also a PCI driver. */
+	struct rte_soc_driver soc_drv;    /**< The PMD is also a SoC driver. */
 	eth_dev_init_t eth_dev_init;      /**< Device init function. */
 	eth_dev_uninit_t eth_dev_uninit;  /**< Device uninit function. */
 	unsigned int dev_private_size;    /**< Size of device private data. */
@@ -4158,6 +4162,20 @@ void rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev,
 		struct rte_pci_device *pci_dev);
 
 /**
+ * Copy SoC device info to the Ethernet device data.
+ *
+ * @param eth_dev
+ * The *eth_dev* pointer is the address of the *rte_eth_dev* structure.
+ * @param soc_dev
+ * The *soc_dev* pointer is the address of the *rte_soc_device* structure.
+ *
+ * @return
+ *   - 0 on success, negative on error
+ */
+void rte_eth_copy_soc_info(struct rte_eth_dev *eth_dev,
+		struct rte_soc_device *soc_dev);
+
+/**
  * Create memzone for HW rings.
  * malloc can't be used as the physical address is needed.
  * If the memzone is already created, then this function returns a ptr
@@ -4241,6 +4259,19 @@ int rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
  */
 int rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev);
 
+/**
+ * Wrapper for use by SoC drivers as a .devinit function to attach to a ethdev
+ * interface.
+ */
+int rte_eth_dev_soc_probe(struct rte_soc_driver *soc_drv,
+			  struct rte_soc_device *soc_dev);
+
+/**
+ * Wrapper for use by SoC drivers as a .devuninit function to detach a ethdev
+ * interface.
+ */
+int rte_eth_dev_soc_remove(struct rte_soc_device *soc_dev);
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.8.0

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

* Re: [PATCH v1 03/28] eal/linux: extract function rte_eal_unbind_kernel_driver
  2016-05-06 13:47 ` [PATCH v1 03/28] eal/linux: extract function rte_eal_unbind_kernel_driver Jan Viktorin
@ 2016-05-13  1:22   ` Jianbo Liu
  2016-05-17 18:14     ` Jan Viktorin
  0 siblings, 1 reply; 231+ messages in thread
From: Jianbo Liu @ 2016-05-13  1:22 UTC (permalink / raw)
  To: Jan Viktorin
  Cc: dev, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, Jerin Jacob, Keith Wiles, Stephen Hemminger

On 6 May 2016 at 21:47, Jan Viktorin <viktorin@rehivetech.com> wrote:
> Generalize the PCI-specific pci_unbind_kernel_driver. It is now divided into
> two parts. First, determination of the path and string identification of the
> device to be unbound. Second, the actual unbind operation which is generic.
>
> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> ---
>  lib/librte_eal/common/eal_private.h   | 13 +++++++++++++
>  lib/librte_eal/linuxapp/eal/eal.c     | 26 ++++++++++++++++++++++++++
>  lib/librte_eal/linuxapp/eal/eal_pci.c | 33 +++++++++------------------------
>  3 files changed, 48 insertions(+), 24 deletions(-)
>
> diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
> index 81816a6..3fb8353 100644
> --- a/lib/librte_eal/common/eal_private.h
> +++ b/lib/librte_eal/common/eal_private.h
> @@ -289,6 +289,19 @@ int rte_eal_alarm_init(void);
>  int rte_eal_check_module(const char *module_name);
>
>  /**
> + * Unbind kernel driver bound to the device specified by the given devpath,
> + * and its string identification.
> + *
> + * @param devpath  path to the device directory ("/sys/.../devices/<name>")
> + * @param devid    identification of the device (<name>)
> + *
> + * @return
> + *      -1  unbind has failed
> + *       0  module has been unbound
> + */
> +int rte_eal_unbind_kernel_driver(const char *devpath, const char *devid);
> +
> +/**
>   * Get cpu core_id.
>   *
>   * This function is private to the EAL.
> diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
> index e8fce6b..844f958 100644
> --- a/lib/librte_eal/linuxapp/eal/eal.c
> +++ b/lib/librte_eal/linuxapp/eal/eal.c
> @@ -949,3 +949,29 @@ rte_eal_check_module(const char *module_name)
>         /* Module has been found */
>         return 1;
>  }
> +
> +int
> +rte_eal_unbind_kernel_driver(const char *devpath, const char *devid)
> +{
> +       char filename[PATH_MAX];
> +       FILE *f;
> +
> +       snprintf(filename, sizeof(filename),
> +                "%s/driver/unbind", devpath);
> +
> +       f = fopen(filename, "w");
> +       if (f == NULL) /* device was not bound */
> +               return 0;
> +
> +       if (fwrite(devid, strlen(devid), 1, f) == 0) {
> +               RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
> +                               filename);
> +               goto error;
> +       }
> +
> +       fclose(f);
> +       return 0;
> +error:
> +       fclose(f);
> +       return -1;
> +}
> diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
> index fd7e34f..312cb14 100644
> --- a/lib/librte_eal/linuxapp/eal/eal_pci.c
> +++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
> @@ -59,38 +59,23 @@ int
>  pci_unbind_kernel_driver(struct rte_pci_device *dev)
>  {
>         int n;
> -       FILE *f;
> -       char filename[PATH_MAX];
> -       char buf[BUFSIZ];
> +       char devpath[PATH_MAX];
> +       char devid[BUFSIZ];
>         struct rte_pci_addr *loc = &dev->addr;
>
> -       /* open /sys/bus/pci/devices/AAAA:BB:CC.D/driver */
> -       snprintf(filename, sizeof(filename),
> -                SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/driver/unbind",
> +       /* devpath /sys/bus/pci/devices/AAAA:BB:CC.D */
> +       snprintf(devpath, sizeof(devpath),
> +                SYSFS_PCI_DEVICES "/" PCI_PRI_FMT,
>                  loc->domain, loc->bus, loc->devid, loc->function);
>
> -       f = fopen(filename, "w");
> -       if (f == NULL) /* device was not bound */
> -               return 0;
> -
> -       n = snprintf(buf, sizeof(buf), PCI_PRI_FMT "\n",
> +       n = snprintf(devid, sizeof(devid), PCI_PRI_FMT "\n",
>                      loc->domain, loc->bus, loc->devid, loc->function);
> -       if ((n < 0) || (n >= (int)sizeof(buf))) {
> +       if ((n < 0) || (n >= (int)sizeof(devid))) {

Is it better to move "(n >= (int)sizeof(devid))" before snprintf and
it has different reason from "n < 0"?

>                 RTE_LOG(ERR, EAL, "%s(): snprintf failed\n", __func__);
> -               goto error;
> -       }
> -       if (fwrite(buf, n, 1, f) == 0) {
> -               RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
> -                               filename);
> -               goto error;
> +               return -1;
>         }
>
> -       fclose(f);
> -       return 0;
> -
> -error:
> -       fclose(f);
> -       return -1;
> +       return rte_eal_unbind_kernel_driver(devpath, devid);
>  }
>
>  static int
> --
> 2.8.0
>

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

* Re: [PATCH v1 09/28] eal: introduce --no-soc option
  2016-05-06 13:47 ` [PATCH v1 09/28] eal: introduce --no-soc option Jan Viktorin
@ 2016-05-13  3:28   ` Jianbo Liu
  2016-05-17 18:10     ` Jan Viktorin
  0 siblings, 1 reply; 231+ messages in thread
From: Jianbo Liu @ 2016-05-13  3:28 UTC (permalink / raw)
  To: Jan Viktorin
  Cc: dev, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, Jerin Jacob, Keith Wiles, Stephen Hemminger

On 6 May 2016 at 21:47, Jan Viktorin <viktorin@rehivetech.com> wrote:
> This option has the same meaning for the SoC infra as the --no-pci
> for the PCI infra.
>
> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> ---
>  lib/librte_eal/common/eal_common_options.c | 5 +++++
>  lib/librte_eal/common/eal_internal_cfg.h   | 1 +
>  lib/librte_eal/common/eal_options.h        | 2 ++
>  3 files changed, 8 insertions(+)
>
> diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
> index 3efc90f..09d64f7 100644
> --- a/lib/librte_eal/common/eal_common_options.c
> +++ b/lib/librte_eal/common/eal_common_options.c
> @@ -85,6 +85,7 @@ eal_long_options[] = {
>         {OPT_NO_HPET,           0, NULL, OPT_NO_HPET_NUM          },
>         {OPT_NO_HUGE,           0, NULL, OPT_NO_HUGE_NUM          },
>         {OPT_NO_PCI,            0, NULL, OPT_NO_PCI_NUM           },
> +       {OPT_NO_SOC,            0, NULL, OPT_NO_SOC_NUM           },
>         {OPT_NO_SHCONF,         0, NULL, OPT_NO_SHCONF_NUM        },
>         {OPT_PCI_BLACKLIST,     1, NULL, OPT_PCI_BLACKLIST_NUM    },
>         {OPT_PCI_WHITELIST,     1, NULL, OPT_PCI_WHITELIST_NUM    },
> @@ -841,6 +842,10 @@ eal_parse_common_option(int opt, const char *optarg,
>                 conf->no_pci = 1;
>                 break;
>
> +       case OPT_NO_SOC_NUM:
> +               conf->no_soc = 1;

Could it be better to rename to enable_soc, and disable soc by default?

> +               break;
> +
>         case OPT_NO_HPET_NUM:
>                 conf->no_hpet = 1;
>                 break;
> diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
> index 5f1367e..3a98e94 100644
> --- a/lib/librte_eal/common/eal_internal_cfg.h
> +++ b/lib/librte_eal/common/eal_internal_cfg.h
> @@ -67,6 +67,7 @@ struct internal_config {
>         unsigned hugepage_unlink;         /**< true to unlink backing files */
>         volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
>         volatile unsigned no_pci;         /**< true to disable PCI */
> +       volatile unsigned no_soc;         /**< true to disable SoC */
>         volatile unsigned no_hpet;        /**< true to disable HPET */
>         volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
>                                                                                 * instead of native TSC */
> diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
> index a881c62..ba1e704 100644
> --- a/lib/librte_eal/common/eal_options.h
> +++ b/lib/librte_eal/common/eal_options.h
> @@ -69,6 +69,8 @@ enum {
>         OPT_NO_HUGE_NUM,
>  #define OPT_NO_PCI            "no-pci"
>         OPT_NO_PCI_NUM,
> +#define OPT_NO_SOC            "no-soc"
> +       OPT_NO_SOC_NUM,
>  #define OPT_NO_SHCONF         "no-shconf"
>         OPT_NO_SHCONF_NUM,
>  #define OPT_SOCKET_MEM        "socket-mem"
> --
> 2.8.0
>

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

* Re: [PATCH v1 09/28] eal: introduce --no-soc option
  2016-05-13  3:28   ` Jianbo Liu
@ 2016-05-17 18:10     ` Jan Viktorin
  0 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-05-17 18:10 UTC (permalink / raw)
  To: Jianbo Liu
  Cc: dev, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, Jerin Jacob, Keith Wiles, Stephen Hemminger

On Fri, 13 May 2016 11:28:18 +0800
Jianbo Liu <jianbo.liu@linaro.org> wrote:

> On 6 May 2016 at 21:47, Jan Viktorin <viktorin@rehivetech.com> wrote:
> > This option has the same meaning for the SoC infra as the --no-pci
> > for the PCI infra.
> >
> > Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> > ---
> >  lib/librte_eal/common/eal_common_options.c | 5 +++++
> >  lib/librte_eal/common/eal_internal_cfg.h   | 1 +
> >  lib/librte_eal/common/eal_options.h        | 2 ++
> >  3 files changed, 8 insertions(+)
> >
> > diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
> > index 3efc90f..09d64f7 100644
> > --- a/lib/librte_eal/common/eal_common_options.c
> > +++ b/lib/librte_eal/common/eal_common_options.c
> > @@ -85,6 +85,7 @@ eal_long_options[] = {
> >         {OPT_NO_HPET,           0, NULL, OPT_NO_HPET_NUM          },
> >         {OPT_NO_HUGE,           0, NULL, OPT_NO_HUGE_NUM          },
> >         {OPT_NO_PCI,            0, NULL, OPT_NO_PCI_NUM           },
> > +       {OPT_NO_SOC,            0, NULL, OPT_NO_SOC_NUM           },
> >         {OPT_NO_SHCONF,         0, NULL, OPT_NO_SHCONF_NUM        },
> >         {OPT_PCI_BLACKLIST,     1, NULL, OPT_PCI_BLACKLIST_NUM    },
> >         {OPT_PCI_WHITELIST,     1, NULL, OPT_PCI_WHITELIST_NUM    },
> > @@ -841,6 +842,10 @@ eal_parse_common_option(int opt, const char *optarg,
> >                 conf->no_pci = 1;
> >                 break;
> >
> > +       case OPT_NO_SOC_NUM:
> > +               conf->no_soc = 1;  
> 
> Could it be better to rename to enable_soc, and disable soc by default?

Sure, I tried to be consistent with PCI...

[...]


-- 
   Jan Viktorin                  E-mail: Viktorin@RehiveTech.com
   System Architect              Web:    www.RehiveTech.com
   RehiveTech
   Brno, Czech Republic

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

* Re: [PATCH v1 03/28] eal/linux: extract function rte_eal_unbind_kernel_driver
  2016-05-13  1:22   ` Jianbo Liu
@ 2016-05-17 18:14     ` Jan Viktorin
  2016-05-18 13:45       ` Jianbo Liu
  0 siblings, 1 reply; 231+ messages in thread
From: Jan Viktorin @ 2016-05-17 18:14 UTC (permalink / raw)
  To: Jianbo Liu
  Cc: dev, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, Jerin Jacob, Keith Wiles, Stephen Hemminger

On Fri, 13 May 2016 09:22:23 +0800
Jianbo Liu <jianbo.liu@linaro.org> wrote:

> On 6 May 2016 at 21:47, Jan Viktorin <viktorin@rehivetech.com> wrote:
> > Generalize the PCI-specific pci_unbind_kernel_driver. It is now divided into
> > two parts. First, determination of the path and string identification of the
> > device to be unbound. Second, the actual unbind operation which is generic.
> >
> > Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> > ---
> >  lib/librte_eal/common/eal_private.h   | 13 +++++++++++++
> >  lib/librte_eal/linuxapp/eal/eal.c     | 26 ++++++++++++++++++++++++++
> >  lib/librte_eal/linuxapp/eal/eal_pci.c | 33 +++++++++------------------------
> >  3 files changed, 48 insertions(+), 24 deletions(-)
> >
> > diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
> > index 81816a6..3fb8353 100644
> > --- a/lib/librte_eal/common/eal_private.h
> > +++ b/lib/librte_eal/common/eal_private.h
> > @@ -289,6 +289,19 @@ int rte_eal_alarm_init(void);
> >  int rte_eal_check_module(const char *module_name);
> >
> >  /**
> > + * Unbind kernel driver bound to the device specified by the given devpath,
> > + * and its string identification.
> > + *
> > + * @param devpath  path to the device directory ("/sys/.../devices/<name>")
> > + * @param devid    identification of the device (<name>)
> > + *
> > + * @return
> > + *      -1  unbind has failed
> > + *       0  module has been unbound
> > + */
> > +int rte_eal_unbind_kernel_driver(const char *devpath, const char *devid);
> > +
> > +/**
> >   * Get cpu core_id.
> >   *
> >   * This function is private to the EAL.
> > diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
> > index e8fce6b..844f958 100644
> > --- a/lib/librte_eal/linuxapp/eal/eal.c
> > +++ b/lib/librte_eal/linuxapp/eal/eal.c
> > @@ -949,3 +949,29 @@ rte_eal_check_module(const char *module_name)
> >         /* Module has been found */
> >         return 1;
> >  }
> > +
> > +int
> > +rte_eal_unbind_kernel_driver(const char *devpath, const char *devid)
> > +{
> > +       char filename[PATH_MAX];
> > +       FILE *f;
> > +
> > +       snprintf(filename, sizeof(filename),
> > +                "%s/driver/unbind", devpath);
> > +
> > +       f = fopen(filename, "w");
> > +       if (f == NULL) /* device was not bound */
> > +               return 0;
> > +
> > +       if (fwrite(devid, strlen(devid), 1, f) == 0) {
> > +               RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
> > +                               filename);
> > +               goto error;
> > +       }
> > +
> > +       fclose(f);
> > +       return 0;
> > +error:
> > +       fclose(f);
> > +       return -1;
> > +}
> > diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
> > index fd7e34f..312cb14 100644
> > --- a/lib/librte_eal/linuxapp/eal/eal_pci.c
> > +++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
> > @@ -59,38 +59,23 @@ int
> >  pci_unbind_kernel_driver(struct rte_pci_device *dev)
> >  {
> >         int n;
> > -       FILE *f;
> > -       char filename[PATH_MAX];
> > -       char buf[BUFSIZ];
> > +       char devpath[PATH_MAX];
> > +       char devid[BUFSIZ];
> >         struct rte_pci_addr *loc = &dev->addr;
> >
> > -       /* open /sys/bus/pci/devices/AAAA:BB:CC.D/driver */
> > -       snprintf(filename, sizeof(filename),
> > -                SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/driver/unbind",
> > +       /* devpath /sys/bus/pci/devices/AAAA:BB:CC.D */
> > +       snprintf(devpath, sizeof(devpath),
> > +                SYSFS_PCI_DEVICES "/" PCI_PRI_FMT,
> >                  loc->domain, loc->bus, loc->devid, loc->function);
> >
> > -       f = fopen(filename, "w");
> > -       if (f == NULL) /* device was not bound */
> > -               return 0;
> > -
> > -       n = snprintf(buf, sizeof(buf), PCI_PRI_FMT "\n",
> > +       n = snprintf(devid, sizeof(devid), PCI_PRI_FMT "\n",
> >                      loc->domain, loc->bus, loc->devid, loc->function);
> > -       if ((n < 0) || (n >= (int)sizeof(buf))) {
> > +       if ((n < 0) || (n >= (int)sizeof(devid))) {  
> 
> Is it better to move "(n >= (int)sizeof(devid))" before snprintf and
> it has different reason from "n < 0"?

I don't understant this comment. I cannot move the check for _n_ before
the snprintf as it is its return value... Can you provide an example of
your idea?

Do you mean to split the condition to if (n < 0) and else if (n >= ...)?

> 
> >                 RTE_LOG(ERR, EAL, "%s(): snprintf failed\n", __func__);
> > -               goto error;
> > -       }
> > -       if (fwrite(buf, n, 1, f) == 0) {
> > -               RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
> > -                               filename);
> > -               goto error;
> > +               return -1;
> >         }
> >
> > -       fclose(f);
> > -       return 0;
> > -
> > -error:
> > -       fclose(f);
> > -       return -1;
> > +       return rte_eal_unbind_kernel_driver(devpath, devid);
> >  }
> >
> >  static int
> > --
> > 2.8.0
> >  



-- 
   Jan Viktorin                  E-mail: Viktorin@RehiveTech.com
   System Architect              Web:    www.RehiveTech.com
   RehiveTech
   Brno, Czech Republic

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

* Re: [PATCH v1 03/28] eal/linux: extract function rte_eal_unbind_kernel_driver
  2016-05-17 18:14     ` Jan Viktorin
@ 2016-05-18 13:45       ` Jianbo Liu
  0 siblings, 0 replies; 231+ messages in thread
From: Jianbo Liu @ 2016-05-18 13:45 UTC (permalink / raw)
  To: Jan Viktorin
  Cc: dev, David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, Jerin Jacob, Keith Wiles, Stephen Hemminger

On 18 May 2016 at 02:14, Jan Viktorin <viktorin@rehivetech.com> wrote:
> On Fri, 13 May 2016 09:22:23 +0800
> Jianbo Liu <jianbo.liu@linaro.org> wrote:
>
>> On 6 May 2016 at 21:47, Jan Viktorin <viktorin@rehivetech.com> wrote:
>> > Generalize the PCI-specific pci_unbind_kernel_driver. It is now divided into
>> > two parts. First, determination of the path and string identification of the
>> > device to be unbound. Second, the actual unbind operation which is generic.
>> > -       if ((n < 0) || (n >= (int)sizeof(buf))) {
>> > +       if ((n < 0) || (n >= (int)sizeof(devid))) {
>>
>> Is it better to move "(n >= (int)sizeof(devid))" before snprintf and
>> it has different reason from "n < 0"?
>
> I don't understant this comment. I cannot move the check for _n_ before
> the snprintf as it is its return value... Can you provide an example of
> your idea?
>
> Do you mean to split the condition to if (n < 0) and else if (n >= ...)?
>
No, I thought the correct output of devid is a fixed-size string, and
need to check the buf length before snprintf.
but it seems unnessaray. Sorry :(

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

* Re: [PATCH v1 07/28] eal/soc: add rte_eal_soc_register/unregister logic
  2016-05-06 13:47 ` [PATCH v1 07/28] eal/soc: add rte_eal_soc_register/unregister logic Jan Viktorin
@ 2016-06-13 14:19   ` Shreyansh Jain
  2016-06-13 14:25     ` Jan Viktorin
  2016-06-15  5:57     ` Shreyansh Jain
  0 siblings, 2 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-06-13 14:19 UTC (permalink / raw)
  To: Jan Viktorin
  Cc: David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger, dev

Another trivial comment inlined:

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Jan Viktorin
> Sent: Friday, May 06, 2016 7:18 PM
> To: dev@dpdk.org
> Cc: Jan Viktorin <viktorin@rehivetech.com>; David Marchand
> <david.marchand@6wind.com>; Thomas Monjalon <thomas.monjalon@6wind.com>;
> Bruce Richardson <bruce.richardson@intel.com>; Declan Doherty
> <declan.doherty@intel.com>; jianbo.liu@linaro.org;
> jerin.jacob@caviumnetworks.com; Keith Wiles <keith.wiles@intel.com>; Stephen
> Hemminger <stephen@networkplumber.org>
> Subject: [dpdk-dev] [PATCH v1 07/28] eal/soc: add
> rte_eal_soc_register/unregister logic
> 
> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> ---
>  app/test/test_soc.c                             | 106
> ++++++++++++++++++++++++
>  lib/librte_eal/bsdapp/eal/Makefile              |   1 +
>  lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   3 +
>  lib/librte_eal/common/eal_common_soc.c          |  55 ++++++++++++
>  lib/librte_eal/common/include/rte_soc.h         |  23 +++++
>  lib/librte_eal/linuxapp/eal/Makefile            |   1 +
>  lib/librte_eal/linuxapp/eal/rte_eal_version.map |   4 +
>  7 files changed, 193 insertions(+)
>  create mode 100644 lib/librte_eal/common/eal_common_soc.c
> 
> diff --git a/app/test/test_soc.c b/app/test/test_soc.c
> index a49fc9b..f6288dc 100644
> --- a/app/test/test_soc.c
> +++ b/app/test/test_soc.c
> @@ -74,6 +74,103 @@ static int test_compare_addr(void)
>  	free(a2.name);
>  	free(a1.name);
>  	free(a0.name);
> +
> +	return 0;
> +}
> +
> +/**
> + * Empty PMD driver based on the SoC infra.
> + *
> + * The rte_soc_device is usually wrapped in some higher-level struct
> + * (eth_driver). We simulate such a wrapper with an anonymous struct here.
> + */
> +struct test_wrapper {
> +	struct rte_soc_driver soc_drv;
> +};
> +
> +struct test_wrapper empty_pmd0 = {
> +	.soc_drv = {
> +		.name = "empty_pmd0",
> +	},
> +};
> +
> +struct test_wrapper empty_pmd1 = {
> +	.soc_drv = {
> +		.name = "empty_pmd1",
> +	},
> +};
> +
> +static int
> +count_registered_socdrvs(void)
> +{
> +	int i;
> +	struct rte_soc_driver *drv;
> +
> +	i = 0;
> +	TAILQ_FOREACH(drv, &soc_driver_list, next)
> +		i += 1;
> +
> +	return i;
> +}
> +
> +static int
> +test_register_unregister(void)
> +{
> +	struct rte_soc_driver *drv;
> +	int count;
> +
> +	rte_eal_soc_register(&empty_pmd0.soc_drv);
> +
> +	TEST_ASSERT(!TAILQ_EMPTY(&soc_driver_list),
> +		"No PMD is present but the empty_pmd0 should be there");
> +	drv = TAILQ_FIRST(&soc_driver_list);
> +	TEST_ASSERT(!strcmp(drv->name, "empty_pmd0"),
> +		"The registered PMD is not empty_pmd but '%s'", drv->name);

Trivial: TEST_ASSERT Message should be: "... is not empty_pmd0 but..."

> +
> +	rte_eal_soc_register(&empty_pmd1.soc_drv);
> +
> +	count = count_registered_socdrvs();
> +	TEST_ASSERT_EQUAL(count, 2, "Expected 2 PMDs but detected %d", count);
> +
> +	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
> +	count = count_registered_socdrvs();
> +	TEST_ASSERT_EQUAL(count, 1, "Expected 1 PMDs but detected %d", count);
> +
> +	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
> +
> +	printf("%s has been successful\n", __func__);
> +	return 0;
> +}
> +
> +/* save real devices and drivers until the tests finishes */
> +struct soc_driver_list real_soc_driver_list =
> +	TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
> +
> +static int test_soc_setup(void)
> +{
> +	struct rte_soc_driver *drv;
> +
> +	/* no real drivers for the test */
> +	while (!TAILQ_EMPTY(&soc_driver_list)) {
> +		drv = TAILQ_FIRST(&soc_driver_list);
> +		rte_eal_soc_unregister(drv);
> +		TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
> +	}
> +
> +	return 0;
> +}
> +
> +static int test_soc_cleanup(void)
> +{
> +	struct rte_soc_driver *drv;
> +
> +	/* bring back real drivers after the test */
> +	while (!TAILQ_EMPTY(&real_soc_driver_list)) {
> +		drv = TAILQ_FIRST(&real_soc_driver_list);
> +		TAILQ_REMOVE(&real_soc_driver_list, drv, next);
> +		rte_eal_soc_register(drv);
> +	}
> +
>  	return 0;
>  }
> 
> @@ -83,6 +180,15 @@ test_soc(void)
>  	if (test_compare_addr())
>  		return -1;
> 
> +	if (test_soc_setup())
> +		return -1;
> +
> +	if (test_register_unregister())
> +		return -1;
> +
> +	if (test_soc_cleanup())
> +		return -1;
> +
>  	return 0;
>  }
> 
> diff --git a/lib/librte_eal/bsdapp/eal/Makefile
> b/lib/librte_eal/bsdapp/eal/Makefile
> index 9054ad6..d956808 100644
> --- a/lib/librte_eal/bsdapp/eal/Makefile
> +++ b/lib/librte_eal/bsdapp/eal/Makefile
> @@ -71,6 +71,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_timer.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
> +SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_soc.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
> diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> index 4d075df..c430b4b 100644
> --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> @@ -158,4 +158,7 @@ DPDK_16.07 {
>  	rte_eal_dev_attach;
>  	rte_eal_dev_detach;
> 
> +	rte_eal_soc_register;
> +	rte_eal_soc_unregister;
> +
>  } DPDK_16.04;
> diff --git a/lib/librte_eal/common/eal_common_soc.c
> b/lib/librte_eal/common/eal_common_soc.c
> new file mode 100644
> index 0000000..afeed2f
> --- /dev/null
> +++ b/lib/librte_eal/common/eal_common_soc.c
> @@ -0,0 +1,55 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2016 RehiveTech. All rights reserved.
> + *   All rights reserved.
> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of RehiveTech nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <sys/queue.h>
> +
> +#include <rte_log.h>
> +
> +#include "eal_private.h"
> +
> +struct soc_driver_list soc_driver_list =
> +	TAILQ_HEAD_INITIALIZER(soc_driver_list);
> +
> +/* register a driver */
> +void
> +rte_eal_soc_register(struct rte_soc_driver *driver)
> +{
> +	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
> +}
> +
> +/* unregister a driver */
> +void
> +rte_eal_soc_unregister(struct rte_soc_driver *driver)
> +{
> +	TAILQ_REMOVE(&soc_driver_list, driver, next);
> +}
> diff --git a/lib/librte_eal/common/include/rte_soc.h
> b/lib/librte_eal/common/include/rte_soc.h
> index cde588a..28c1798 100644
> --- a/lib/librte_eal/common/include/rte_soc.h
> +++ b/lib/librte_eal/common/include/rte_soc.h
> @@ -46,11 +46,17 @@ extern "C" {
> 
>  #include <stdio.h>
>  #include <stdlib.h>
> +#include <sys/queue.h>
>  #include <stdint.h>
>  #include <inttypes.h>
>  #include <string.h>
> 
>  #include <rte_debug.h>
> +#include <rte_eal.h>
> +
> +TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q.
> */
> +
> +extern struct soc_driver_list soc_driver_list; /**< Global list of SoC
> drivers. */
> 
>  struct rte_soc_id {
>  	const char *compatible; /**< OF compatible specification */
> @@ -131,4 +137,21 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
>  	return strcmp(a0->name, a1->name);
>  }
> 
> +/**
> + * Register a SoC driver.
> + */
> +void rte_eal_soc_register(struct rte_soc_driver *driver);
> +
> +#define RTE_EAL_SOC_REGISTER(name) \
> +RTE_INIT(socinitfn_ ##name); \
> +static void socinitfn_ ##name(void) \
> +{ \
> +	rte_eal_soc_register(&name.soc_drv); \
> +}
> +
> +/**
> + * Unregister a SoC driver.
> + */
> +void rte_eal_soc_unregister(struct rte_soc_driver *driver);
> +
>  #endif
> diff --git a/lib/librte_eal/linuxapp/eal/Makefile
> b/lib/librte_eal/linuxapp/eal/Makefile
> index e109361..37ab8d5 100644
> --- a/lib/librte_eal/linuxapp/eal/Makefile
> +++ b/lib/librte_eal/linuxapp/eal/Makefile
> @@ -82,6 +82,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
> +SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_soc.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
>  SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
> diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> index 0404a52..6ff38b8 100644
> --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> @@ -161,4 +161,8 @@ DPDK_16.07 {
>  	rte_eal_dev_attach;
>  	rte_eal_dev_detach;
> 
> +	soc_driver_list;
> +	rte_eal_soc_register;
> +	rte_eal_soc_unregister;
> +
>  } DPDK_16.04;
> --
> 2.8.0

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

* Re: [PATCH v1 19/28] eal/soc: add drv_flags
  2016-05-06 13:48 ` [PATCH v1 19/28] eal/soc: add drv_flags Jan Viktorin
@ 2016-06-13 14:21   ` Shreyansh Jain
  2016-06-13 14:26     ` Jan Viktorin
  0 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-06-13 14:21 UTC (permalink / raw)
  To: Jan Viktorin
  Cc: David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger, dev



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Jan Viktorin
> Sent: Friday, May 06, 2016 7:18 PM
> To: dev@dpdk.org
> Cc: Jan Viktorin <viktorin@rehivetech.com>; David Marchand
> <david.marchand@6wind.com>; Thomas Monjalon <thomas.monjalon@6wind.com>;
> Bruce Richardson <bruce.richardson@intel.com>; Declan Doherty
> <declan.doherty@intel.com>; jianbo.liu@linaro.org;
> jerin.jacob@caviumnetworks.com; Keith Wiles <keith.wiles@intel.com>; Stephen
> Hemminger <stephen@networkplumber.org>
> Subject: [dpdk-dev] [PATCH v1 19/28] eal/soc: add drv_flags
> 
> The flags are copied from the PCI ones. They should be refactorized into a
> general set of flags in the future.
> 
> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> ---
>  lib/librte_eal/common/include/rte_soc.h | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/lib/librte_eal/common/include/rte_soc.h
> b/lib/librte_eal/common/include/rte_soc.h
> index 49cfeb7..50a3b35 100644
> --- a/lib/librte_eal/common/include/rte_soc.h
> +++ b/lib/librte_eal/common/include/rte_soc.h
> @@ -125,8 +125,18 @@ struct rte_soc_driver {
>  	soc_devinit_t *devinit;            /**< Device initialization */
>  	soc_devuninit_t *devuninit;        /**< Device uninitialization */
>  	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
> +	uint32_t drv_flags;                /**< Control handling of device */
>  };
> 
> +/** Device needs to map its resources by EAL */
> +#define RTE_SOC_DRV_NEED_MAPPING 0x0001
> +/** Device needs to be unbound event if no module is provieded */

Comment should read "Device needs to be unbound even if no module is provided"

> +#define RTE_SOC_DRV_FORCE_UNBIND 0x0004
> +/** Device driver supports link state interrupt */
> +#define RTE_SOC_DRV_INTR_LSC	 0x0008
> +/** Device driver supports detaching capability */
> +#define RTE_SOC_DRV_DETACHABLE	 0x0010
> +
>  /**
>   * A structure describing a SoC mapping.
>   */
> --
> 2.8.0

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

* Re: [PATCH v1 07/28] eal/soc: add rte_eal_soc_register/unregister logic
  2016-06-13 14:19   ` Shreyansh Jain
@ 2016-06-13 14:25     ` Jan Viktorin
  2016-06-15  5:57     ` Shreyansh Jain
  1 sibling, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-06-13 14:25 UTC (permalink / raw)
  To: Shreyansh Jain
  Cc: David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger, dev

On Mon, 13 Jun 2016 14:19:39 +0000
Shreyansh Jain <shreyansh.jain@nxp.com> wrote:

> Another trivial comment inlined:
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Jan Viktorin
> > Sent: Friday, May 06, 2016 7:18 PM
> > To: dev@dpdk.org
> > Cc: Jan Viktorin <viktorin@rehivetech.com>; David Marchand
> > <david.marchand@6wind.com>; Thomas Monjalon <thomas.monjalon@6wind.com>;
> > Bruce Richardson <bruce.richardson@intel.com>; Declan Doherty
> > <declan.doherty@intel.com>; jianbo.liu@linaro.org;
> > jerin.jacob@caviumnetworks.com; Keith Wiles <keith.wiles@intel.com>; Stephen
> > Hemminger <stephen@networkplumber.org>
> > Subject: [dpdk-dev] [PATCH v1 07/28] eal/soc: add
> > rte_eal_soc_register/unregister logic
> > 
> > Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> > ---
> >  app/test/test_soc.c                             | 106
> > ++++++++++++++++++++++++
> >  lib/librte_eal/bsdapp/eal/Makefile              |   1 +
> >  lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   3 +
> >  lib/librte_eal/common/eal_common_soc.c          |  55 ++++++++++++
> >  lib/librte_eal/common/include/rte_soc.h         |  23 +++++
> >  lib/librte_eal/linuxapp/eal/Makefile            |   1 +
> >  lib/librte_eal/linuxapp/eal/rte_eal_version.map |   4 +
> >  7 files changed, 193 insertions(+)
> >  create mode 100644 lib/librte_eal/common/eal_common_soc.c
> > 
> > diff --git a/app/test/test_soc.c b/app/test/test_soc.c
> > index a49fc9b..f6288dc 100644
> > --- a/app/test/test_soc.c
> > +++ b/app/test/test_soc.c
> > @@ -74,6 +74,103 @@ static int test_compare_addr(void)
> >  	free(a2.name);
> >  	free(a1.name);
> >  	free(a0.name);
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * Empty PMD driver based on the SoC infra.
> > + *
> > + * The rte_soc_device is usually wrapped in some higher-level struct
> > + * (eth_driver). We simulate such a wrapper with an anonymous struct here.
> > + */
> > +struct test_wrapper {
> > +	struct rte_soc_driver soc_drv;
> > +};
> > +
> > +struct test_wrapper empty_pmd0 = {
> > +	.soc_drv = {
> > +		.name = "empty_pmd0",
> > +	},
> > +};
> > +
> > +struct test_wrapper empty_pmd1 = {
> > +	.soc_drv = {
> > +		.name = "empty_pmd1",
> > +	},
> > +};
> > +
> > +static int
> > +count_registered_socdrvs(void)
> > +{
> > +	int i;
> > +	struct rte_soc_driver *drv;
> > +
> > +	i = 0;
> > +	TAILQ_FOREACH(drv, &soc_driver_list, next)
> > +		i += 1;
> > +
> > +	return i;
> > +}
> > +
> > +static int
> > +test_register_unregister(void)
> > +{
> > +	struct rte_soc_driver *drv;
> > +	int count;
> > +
> > +	rte_eal_soc_register(&empty_pmd0.soc_drv);
> > +
> > +	TEST_ASSERT(!TAILQ_EMPTY(&soc_driver_list),
> > +		"No PMD is present but the empty_pmd0 should be there");
> > +	drv = TAILQ_FIRST(&soc_driver_list);
> > +	TEST_ASSERT(!strcmp(drv->name, "empty_pmd0"),
> > +		"The registered PMD is not empty_pmd but '%s'", drv->name);  
> 
> Trivial: TEST_ASSERT Message should be: "... is not empty_pmd0 but..."

OK, thanks.

> 
[...]

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

* Re: [PATCH v1 19/28] eal/soc: add drv_flags
  2016-06-13 14:21   ` Shreyansh Jain
@ 2016-06-13 14:26     ` Jan Viktorin
  0 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-06-13 14:26 UTC (permalink / raw)
  To: Shreyansh Jain
  Cc: David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger, dev

On Mon, 13 Jun 2016 14:21:40 +0000
Shreyansh Jain <shreyansh.jain@nxp.com> wrote:

> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Jan Viktorin
> > Sent: Friday, May 06, 2016 7:18 PM
> > To: dev@dpdk.org
> > Cc: Jan Viktorin <viktorin@rehivetech.com>; David Marchand
> > <david.marchand@6wind.com>; Thomas Monjalon <thomas.monjalon@6wind.com>;
> > Bruce Richardson <bruce.richardson@intel.com>; Declan Doherty
> > <declan.doherty@intel.com>; jianbo.liu@linaro.org;
> > jerin.jacob@caviumnetworks.com; Keith Wiles <keith.wiles@intel.com>; Stephen
> > Hemminger <stephen@networkplumber.org>
> > Subject: [dpdk-dev] [PATCH v1 19/28] eal/soc: add drv_flags
> > 
> > The flags are copied from the PCI ones. They should be refactorized into a
> > general set of flags in the future.
> > 
> > Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> > ---
> >  lib/librte_eal/common/include/rte_soc.h | 10 ++++++++++
> >  1 file changed, 10 insertions(+)
> > 
> > diff --git a/lib/librte_eal/common/include/rte_soc.h
> > b/lib/librte_eal/common/include/rte_soc.h
> > index 49cfeb7..50a3b35 100644
> > --- a/lib/librte_eal/common/include/rte_soc.h
> > +++ b/lib/librte_eal/common/include/rte_soc.h
> > @@ -125,8 +125,18 @@ struct rte_soc_driver {
> >  	soc_devinit_t *devinit;            /**< Device initialization */
> >  	soc_devuninit_t *devuninit;        /**< Device uninitialization */
> >  	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
> > +	uint32_t drv_flags;                /**< Control handling of device */
> >  };
> > 
> > +/** Device needs to map its resources by EAL */
> > +#define RTE_SOC_DRV_NEED_MAPPING 0x0001
> > +/** Device needs to be unbound event if no module is provieded */  
> 
> Comment should read "Device needs to be unbound even if no module is provided"

OK, thanks.

> 
> > +#define RTE_SOC_DRV_FORCE_UNBIND 0x0004
> > +/** Device driver supports link state interrupt */
> > +#define RTE_SOC_DRV_INTR_LSC	 0x0008
> > +/** Device driver supports detaching capability */
> > +#define RTE_SOC_DRV_DETACHABLE	 0x0010
> > +
> >  /**
> >   * A structure describing a SoC mapping.
> >   */
> > --
> > 2.8.0  
> 

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

* Re: [PATCH v1 07/28] eal/soc: add rte_eal_soc_register/unregister logic
  2016-06-13 14:19   ` Shreyansh Jain
  2016-06-13 14:25     ` Jan Viktorin
@ 2016-06-15  5:57     ` Shreyansh Jain
  2016-06-15  9:50       ` Jan Viktorin
  1 sibling, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-06-15  5:57 UTC (permalink / raw)
  To: Jan Viktorin
  Cc: David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger, dev

Hi Jan,

One more comment which I missed in previous reply:

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Shreyansh Jain
> Sent: Monday, June 13, 2016 7:50 PM
> To: Jan Viktorin <viktorin@rehivetech.com>
> Cc: David Marchand <david.marchand@6wind.com>; Thomas Monjalon
> <thomas.monjalon@6wind.com>; Bruce Richardson <bruce.richardson@intel.com>;
> Declan Doherty <declan.doherty@intel.com>; jianbo.liu@linaro.org;
> jerin.jacob@caviumnetworks.com; Keith Wiles <keith.wiles@intel.com>; Stephen
> Hemminger <stephen@networkplumber.org>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v1 07/28] eal/soc: add
> rte_eal_soc_register/unregister logic
> 
> Another trivial comment inlined:
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Jan Viktorin
> > Sent: Friday, May 06, 2016 7:18 PM
> > To: dev@dpdk.org
> > Cc: Jan Viktorin <viktorin@rehivetech.com>; David Marchand
> > <david.marchand@6wind.com>; Thomas Monjalon <thomas.monjalon@6wind.com>;
> > Bruce Richardson <bruce.richardson@intel.com>; Declan Doherty
> > <declan.doherty@intel.com>; jianbo.liu@linaro.org;
> > jerin.jacob@caviumnetworks.com; Keith Wiles <keith.wiles@intel.com>;
> Stephen
> > Hemminger <stephen@networkplumber.org>
> > Subject: [dpdk-dev] [PATCH v1 07/28] eal/soc: add
> > rte_eal_soc_register/unregister logic
> >
> > Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> > ---
> >  app/test/test_soc.c                             | 106
> > ++++++++++++++++++++++++
> >  lib/librte_eal/bsdapp/eal/Makefile              |   1 +
> >  lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   3 +
> >  lib/librte_eal/common/eal_common_soc.c          |  55 ++++++++++++
> >  lib/librte_eal/common/include/rte_soc.h         |  23 +++++
> >  lib/librte_eal/linuxapp/eal/Makefile            |   1 +
> >  lib/librte_eal/linuxapp/eal/rte_eal_version.map |   4 +
> >  7 files changed, 193 insertions(+)
> >  create mode 100644 lib/librte_eal/common/eal_common_soc.c
> >
> > diff --git a/app/test/test_soc.c b/app/test/test_soc.c
> > index a49fc9b..f6288dc 100644
> > --- a/app/test/test_soc.c
> > +++ b/app/test/test_soc.c
> > @@ -74,6 +74,103 @@ static int test_compare_addr(void)
> >  	free(a2.name);
> >  	free(a1.name);
> >  	free(a0.name);
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * Empty PMD driver based on the SoC infra.
> > + *
> > + * The rte_soc_device is usually wrapped in some higher-level struct
> > + * (eth_driver). We simulate such a wrapper with an anonymous struct here.
> > + */
> > +struct test_wrapper {
> > +	struct rte_soc_driver soc_drv;
> > +};
> > +
> > +struct test_wrapper empty_pmd0 = {
> > +	.soc_drv = {
> > +		.name = "empty_pmd0",
> > +	},
> > +};
> > +
> > +struct test_wrapper empty_pmd1 = {
> > +	.soc_drv = {
> > +		.name = "empty_pmd1",
> > +	},
> > +};
> > +
> > +static int
> > +count_registered_socdrvs(void)
> > +{
> > +	int i;
> > +	struct rte_soc_driver *drv;
> > +
> > +	i = 0;
> > +	TAILQ_FOREACH(drv, &soc_driver_list, next)
> > +		i += 1;
> > +
> > +	return i;
> > +}
> > +
> > +static int
> > +test_register_unregister(void)
> > +{
> > +	struct rte_soc_driver *drv;
> > +	int count;
> > +
> > +	rte_eal_soc_register(&empty_pmd0.soc_drv);
> > +
> > +	TEST_ASSERT(!TAILQ_EMPTY(&soc_driver_list),
> > +		"No PMD is present but the empty_pmd0 should be there");
> > +	drv = TAILQ_FIRST(&soc_driver_list);
> > +	TEST_ASSERT(!strcmp(drv->name, "empty_pmd0"),
> > +		"The registered PMD is not empty_pmd but '%s'", drv->name);
> 
> Trivial: TEST_ASSERT Message should be: "... is not empty_pmd0 but..."
> 
> > +
> > +	rte_eal_soc_register(&empty_pmd1.soc_drv);
> > +
> > +	count = count_registered_socdrvs();
> > +	TEST_ASSERT_EQUAL(count, 2, "Expected 2 PMDs but detected %d", count);
> > +
> > +	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
> > +	count = count_registered_socdrvs();
> > +	TEST_ASSERT_EQUAL(count, 1, "Expected 1 PMDs but detected %d", count);
> > +
> > +	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
> > +
> > +	printf("%s has been successful\n", __func__);
> > +	return 0;
> > +}
> > +
> > +/* save real devices and drivers until the tests finishes */
> > +struct soc_driver_list real_soc_driver_list =
> > +	TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
> > +
> > +static int test_soc_setup(void)
> > +{
> > +	struct rte_soc_driver *drv;
> > +
> > +	/* no real drivers for the test */
> > +	while (!TAILQ_EMPTY(&soc_driver_list)) {
> > +		drv = TAILQ_FIRST(&soc_driver_list);
> > +		rte_eal_soc_unregister(drv);
> > +		TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int test_soc_cleanup(void)
> > +{
> > +	struct rte_soc_driver *drv;
> > +
> > +	/* bring back real drivers after the test */
> > +	while (!TAILQ_EMPTY(&real_soc_driver_list)) {
> > +		drv = TAILQ_FIRST(&real_soc_driver_list);
> > +		TAILQ_REMOVE(&real_soc_driver_list, drv, next);
> > +		rte_eal_soc_register(drv);
> > +	}
> > +
> >  	return 0;
> >  }
> >
> > @@ -83,6 +180,15 @@ test_soc(void)
> >  	if (test_compare_addr())
> >  		return -1;
> >
> > +	if (test_soc_setup())
> > +		return -1;
> > +
> > +	if (test_register_unregister())
> > +		return -1;
> > +
> > +	if (test_soc_cleanup())
> > +		return -1;
> > +
> >  	return 0;
> >  }
> >
> > diff --git a/lib/librte_eal/bsdapp/eal/Makefile
> > b/lib/librte_eal/bsdapp/eal/Makefile
> > index 9054ad6..d956808 100644
> > --- a/lib/librte_eal/bsdapp/eal/Makefile
> > +++ b/lib/librte_eal/bsdapp/eal/Makefile
> > @@ -71,6 +71,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_timer.c
> >  SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
> >  SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
> >  SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
> > +SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_soc.c
> >  SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
> >  SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
> >  SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
> > diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> > b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> > index 4d075df..c430b4b 100644
> > --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> > +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> > @@ -158,4 +158,7 @@ DPDK_16.07 {
> >  	rte_eal_dev_attach;
> >  	rte_eal_dev_detach;
> >
> > +	rte_eal_soc_register;
> > +	rte_eal_soc_unregister;
> > +
> >  } DPDK_16.04;
> > diff --git a/lib/librte_eal/common/eal_common_soc.c
> > b/lib/librte_eal/common/eal_common_soc.c
> > new file mode 100644
> > index 0000000..afeed2f
> > --- /dev/null
> > +++ b/lib/librte_eal/common/eal_common_soc.c
> > @@ -0,0 +1,55 @@
> > +/*-
> > + *   BSD LICENSE
> > + *
> > + *   Copyright(c) 2016 RehiveTech. All rights reserved.
> > + *   All rights reserved.
> > + *
> > + *   Redistribution and use in source and binary forms, with or without
> > + *   modification, are permitted provided that the following conditions
> > + *   are met:
> > + *
> > + *     * Redistributions of source code must retain the above copyright
> > + *       notice, this list of conditions and the following disclaimer.
> > + *     * Redistributions in binary form must reproduce the above copyright
> > + *       notice, this list of conditions and the following disclaimer in
> > + *       the documentation and/or other materials provided with the
> > + *       distribution.
> > + *     * Neither the name of RehiveTech nor the names of its
> > + *       contributors may be used to endorse or promote products derived
> > + *       from this software without specific prior written permission.
> > + *
> > + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> > + */
> > +
> > +#include <sys/queue.h>
> > +
> > +#include <rte_log.h>
> > +
> > +#include "eal_private.h"
> > +
> > +struct soc_driver_list soc_driver_list =
> > +	TAILQ_HEAD_INITIALIZER(soc_driver_list);
> > +
> > +/* register a driver */
> > +void
> > +rte_eal_soc_register(struct rte_soc_driver *driver)
> > +{
> > +	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
> > +}
> > +
> > +/* unregister a driver */
> > +void
> > +rte_eal_soc_unregister(struct rte_soc_driver *driver)
> > +{
> > +	TAILQ_REMOVE(&soc_driver_list, driver, next);
> > +}
> > diff --git a/lib/librte_eal/common/include/rte_soc.h
> > b/lib/librte_eal/common/include/rte_soc.h
> > index cde588a..28c1798 100644
> > --- a/lib/librte_eal/common/include/rte_soc.h
> > +++ b/lib/librte_eal/common/include/rte_soc.h
> > @@ -46,11 +46,17 @@ extern "C" {
> >
> >  #include <stdio.h>
> >  #include <stdlib.h>
> > +#include <sys/queue.h>
> >  #include <stdint.h>
> >  #include <inttypes.h>
> >  #include <string.h>
> >
> >  #include <rte_debug.h>
> > +#include <rte_eal.h>
> > +
> > +TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked
> Q.
> > */
> > +
> > +extern struct soc_driver_list soc_driver_list; /**< Global list of SoC
> > drivers. */
> >
> >  struct rte_soc_id {
> >  	const char *compatible; /**< OF compatible specification */
> > @@ -131,4 +137,21 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr
> *a0,
> >  	return strcmp(a0->name, a1->name);
> >  }
> >
> > +/**
> > + * Register a SoC driver.
> > + */
> > +void rte_eal_soc_register(struct rte_soc_driver *driver);
> > +
> > +#define RTE_EAL_SOC_REGISTER(name) \
> > +RTE_INIT(socinitfn_ ##name); \
> > +static void socinitfn_ ##name(void) \
> > +{ \
> > +	rte_eal_soc_register(&name.soc_drv); \

It should be 'rte_eal_soc_register(&name)'.
As a user of 'RTE_EAL_SOC_REGISTER', I would pass reference to 'rte_soc_driver' object. It doesn't have any 'soc_drv' member.

I am guessing that because you have created a wrapper structure 'test_wrapper' in test_soc.c which contains a 'soc_drv', the macro reflects that usage.

> > +}
> > +
> > +/**
> > + * Unregister a SoC driver.
> > + */
> > +void rte_eal_soc_unregister(struct rte_soc_driver *driver);
> > +
> >  #endif
> > diff --git a/lib/librte_eal/linuxapp/eal/Makefile
> > b/lib/librte_eal/linuxapp/eal/Makefile
> > index e109361..37ab8d5 100644
> > --- a/lib/librte_eal/linuxapp/eal/Makefile
> > +++ b/lib/librte_eal/linuxapp/eal/Makefile
> > @@ -82,6 +82,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) +=
> eal_common_timer.c
> >  SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
> >  SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
> >  SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
> > +SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_soc.c
> >  SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
> >  SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
> >  SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
> > diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> > b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> > index 0404a52..6ff38b8 100644
> > --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> > +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> > @@ -161,4 +161,8 @@ DPDK_16.07 {
> >  	rte_eal_dev_attach;
> >  	rte_eal_dev_detach;
> >
> > +	soc_driver_list;
> > +	rte_eal_soc_register;
> > +	rte_eal_soc_unregister;
> > +
> >  } DPDK_16.04;
> > --
> > 2.8.0

-
Shreyansh

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

* Re: [PATCH v1 07/28] eal/soc: add rte_eal_soc_register/unregister logic
  2016-06-15  5:57     ` Shreyansh Jain
@ 2016-06-15  9:50       ` Jan Viktorin
  0 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-06-15  9:50 UTC (permalink / raw)
  To: Shreyansh Jain
  Cc: David Marchand, Thomas Monjalon, Bruce Richardson,
	Declan Doherty, jianbo.liu, jerin.jacob, Keith Wiles,
	Stephen Hemminger, dev

On Wed, 15 Jun 2016 05:57:33 +0000
Shreyansh Jain <shreyansh.jain@nxp.com> wrote:

> Hi Jan,
> 
> One more comment which I missed in previous reply:
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Shreyansh Jain
> > Sent: Monday, June 13, 2016 7:50 PM
> > To: Jan Viktorin <viktorin@rehivetech.com>
> > Cc: David Marchand <david.marchand@6wind.com>; Thomas Monjalon
> > <thomas.monjalon@6wind.com>; Bruce Richardson <bruce.richardson@intel.com>;
> > Declan Doherty <declan.doherty@intel.com>; jianbo.liu@linaro.org;
> > jerin.jacob@caviumnetworks.com; Keith Wiles <keith.wiles@intel.com>; Stephen
> > Hemminger <stephen@networkplumber.org>; dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH v1 07/28] eal/soc: add
> > rte_eal_soc_register/unregister logic
> > 

[...]

> > > +
> > > +/**
> > > + * Empty PMD driver based on the SoC infra.
> > > + *
> > > + * The rte_soc_device is usually wrapped in some higher-level struct
> > > + * (eth_driver). We simulate such a wrapper with an anonymous struct here.
> > > + */
> > > +struct test_wrapper {
> > > +	struct rte_soc_driver soc_drv;
> > > +};
> > > +
> > > +struct test_wrapper empty_pmd0 = {
> > > +	.soc_drv = {
> > > +		.name = "empty_pmd0",
> > > +	},
> > > +};
> > > +
> > > +struct test_wrapper empty_pmd1 = {
> > > +	.soc_drv = {
> > > +		.name = "empty_pmd1",
> > > +	},
> > > +};
> > > +
> > > +static int
> > > +count_registered_socdrvs(void)
> > > +{
> > > +	int i;
> > > +	struct rte_soc_driver *drv;
> > > +
> > > +	i = 0;
> > > +	TAILQ_FOREACH(drv, &soc_driver_list, next)
> > > +		i += 1;
> > > +
> > > +	return i;
> > > +}
> > > +
> > > +static int
> > > +test_register_unregister(void)
> > > +{
> > > +	struct rte_soc_driver *drv;
> > > +	int count;
> > > +
> > > +	rte_eal_soc_register(&empty_pmd0.soc_drv);

[...]

> > > +
> > > +extern struct soc_driver_list soc_driver_list; /**< Global list of SoC
> > > drivers. */
> > >
> > >  struct rte_soc_id {
> > >  	const char *compatible; /**< OF compatible specification */
> > > @@ -131,4 +137,21 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr  
> > *a0,  
> > >  	return strcmp(a0->name, a1->name);
> > >  }
> > >
> > > +/**
> > > + * Register a SoC driver.
> > > + */
> > > +void rte_eal_soc_register(struct rte_soc_driver *driver);
> > > +
> > > +#define RTE_EAL_SOC_REGISTER(name) \
> > > +RTE_INIT(socinitfn_ ##name); \
> > > +static void socinitfn_ ##name(void) \
> > > +{ \
> > > +	rte_eal_soc_register(&name.soc_drv); \  
> 
> It should be 'rte_eal_soc_register(&name)'.
> As a user of 'RTE_EAL_SOC_REGISTER', I would pass reference to 'rte_soc_driver' object. It doesn't have any 'soc_drv' member.

But eth_driver would have it. And other upper-level structs would have it as well.

> 
> I am guessing that because you have created a wrapper structure 'test_wrapper' in test_soc.c which contains a 'soc_drv', the macro reflects that usage.

I don't assume to use rte_soc_driver directly (similarly to rte_pci_driver). However, I agree that
it is strange, we should have RTE_ETHDRV_SOC_REGISTER for such purpose (if needed).

I wanted to avoid redundant arguments to the RTE_EAL_SOC_REGISTER because the name is 
used to create the constructor function. But, it seems that other parts of DPDK does not
care of this so I will probably give up and make it:

RTE_EAL_SOC_REGISTER(my_cool_drv, &my_cool_drv.soc_drv);

Thanks for your opinion. I'll fix it in v2.

Jan

> 
[...]
> 
> -
> Shreyansh
> 



-- 
   Jan Viktorin                  E-mail: Viktorin@RehiveTech.com
   System Architect              Web:    www.RehiveTech.com
   RehiveTech
   Brno, Czech Republic

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

* Re: [PATCH v1 28/28] ether: support SoC device/driver
  2016-05-06 13:48 ` [PATCH v1 28/28] ether: support SoC device/driver Jan Viktorin
@ 2016-06-29  9:42   ` Shreyansh jain
  2016-07-04 13:04     ` Jan Viktorin
  0 siblings, 1 reply; 231+ messages in thread
From: Shreyansh jain @ 2016-06-29  9:42 UTC (permalink / raw)
  To: Jan Viktorin; +Cc: dev

Hi Jan,

On Friday 06 May 2016 07:18 PM, Jan Viktorin wrote:
> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> ---
>  lib/librte_ether/rte_ethdev.c | 127 +++++++++++++++++++++++++++++++++++++++++-
>  lib/librte_ether/rte_ethdev.h |  31 +++++++++++
>  2 files changed, 157 insertions(+), 1 deletion(-)
> 
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index 4af2e5f..9259c2c 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -320,6 +320,99 @@ rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
>  }
>  
[...]
> +int
>  rte_eth_dev_is_valid_port(uint8_t port_id)
>  {
>  	if (port_id >= RTE_MAX_ETHPORTS ||
> @@ -1431,7 +1524,7 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
>  
>  	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
>  	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
> -	dev_info->pci_dev = dev->pci_dev;
> +	dev_info->soc_dev = dev->soc_dev;

I think both the members, pci_dev and soc_dev, should be updated by this call.
Is there some specific reason why soc_dev is the only one which is getting updated?

>  	dev_info->driver_name = dev->data->drv_name;
>  }
>  
[...]

-
Shreyansh

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

* Re: [PATCH v1 28/28] ether: support SoC device/driver
  2016-06-29  9:42   ` Shreyansh jain
@ 2016-07-04 13:04     ` Jan Viktorin
  2016-07-04 14:27       ` Shreyansh jain
  0 siblings, 1 reply; 231+ messages in thread
From: Jan Viktorin @ 2016-07-04 13:04 UTC (permalink / raw)
  To: Shreyansh jain; +Cc: dev

On Wed, 29 Jun 2016 15:12:07 +0530
Shreyansh jain <shreyansh.jain@nxp.com> wrote:

> Hi Jan,
> 
> On Friday 06 May 2016 07:18 PM, Jan Viktorin wrote:
> > Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> > ---
> >  lib/librte_ether/rte_ethdev.c | 127 +++++++++++++++++++++++++++++++++++++++++-
> >  lib/librte_ether/rte_ethdev.h |  31 +++++++++++
> >  2 files changed, 157 insertions(+), 1 deletion(-)
> > 
> > diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> > index 4af2e5f..9259c2c 100644
> > --- a/lib/librte_ether/rte_ethdev.c
> > +++ b/lib/librte_ether/rte_ethdev.c
> > @@ -320,6 +320,99 @@ rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
> >  }
> >    
> [...]
> > +int
> >  rte_eth_dev_is_valid_port(uint8_t port_id)
> >  {
> >  	if (port_id >= RTE_MAX_ETHPORTS ||
> > @@ -1431,7 +1524,7 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
> >  
> >  	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
> >  	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
> > -	dev_info->pci_dev = dev->pci_dev;
> > +	dev_info->soc_dev = dev->soc_dev;  
> 
> I think both the members, pci_dev and soc_dev, should be updated by this call.
> Is there some specific reason why soc_dev is the only one which is getting updated?

Yes, looks like a mistake. Thanks! And sorry for delayed reply.

Jan

> 
> >  	dev_info->driver_name = dev->data->drv_name;
> >  }
> >    
> [...]
> 
> -
> Shreyansh
> 



-- 
   Jan Viktorin                  E-mail: Viktorin@RehiveTech.com
   System Architect              Web:    www.RehiveTech.com
   RehiveTech
   Brno, Czech Republic

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

* Re: [PATCH v1 28/28] ether: support SoC device/driver
  2016-07-04 13:04     ` Jan Viktorin
@ 2016-07-04 14:27       ` Shreyansh jain
  2016-07-04 14:36         ` Jan Viktorin
  0 siblings, 1 reply; 231+ messages in thread
From: Shreyansh jain @ 2016-07-04 14:27 UTC (permalink / raw)
  To: Jan Viktorin; +Cc: dev

On Monday 04 July 2016 06:34 PM, Jan Viktorin wrote:
> On Wed, 29 Jun 2016 15:12:07 +0530
> Shreyansh jain <shreyansh.jain@nxp.com> wrote:
> 
>> Hi Jan,
>>
>> On Friday 06 May 2016 07:18 PM, Jan Viktorin wrote:
>>> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
>>> ---
>>>  lib/librte_ether/rte_ethdev.c | 127 +++++++++++++++++++++++++++++++++++++++++-
>>>  lib/librte_ether/rte_ethdev.h |  31 +++++++++++
>>>  2 files changed, 157 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
>>> index 4af2e5f..9259c2c 100644
>>> --- a/lib/librte_ether/rte_ethdev.c
>>> +++ b/lib/librte_ether/rte_ethdev.c
>>> @@ -320,6 +320,99 @@ rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
>>>  }
>>>    
>> [...]
>>> +int
>>>  rte_eth_dev_is_valid_port(uint8_t port_id)
>>>  {
>>>  	if (port_id >= RTE_MAX_ETHPORTS ||
>>> @@ -1431,7 +1524,7 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
>>>  
>>>  	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
>>>  	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
>>> -	dev_info->pci_dev = dev->pci_dev;
>>> +	dev_info->soc_dev = dev->soc_dev;  
>>
>> I think both the members, pci_dev and soc_dev, should be updated by this call.
>> Is there some specific reason why soc_dev is the only one which is getting updated?
> 
> Yes, looks like a mistake. Thanks! And sorry for delayed reply.

No problems - thanks for confirmation.
I have gone through almost complete series and as and when you rebase it, it would have my ACK.
rte_driver patchset which I sent last are broken - I will publish an updated version very soon.

> 
> Jan
> 
>>
>>>  	dev_info->driver_name = dev->data->drv_name;
>>>  }
>>>    
>> [...]
>>
>> -
>> Shreyansh
>>
> 
> 
> 

-
Shreyansh

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

* Re: [PATCH v1 28/28] ether: support SoC device/driver
  2016-07-04 14:27       ` Shreyansh jain
@ 2016-07-04 14:36         ` Jan Viktorin
  2016-07-05  4:42           ` Shreyansh jain
  2016-07-12  8:45           ` Shreyansh jain
  0 siblings, 2 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-07-04 14:36 UTC (permalink / raw)
  To: Shreyansh jain; +Cc: dev

On Mon, 4 Jul 2016 19:57:18 +0530
Shreyansh jain <shreyansh.jain@nxp.com> wrote:

[...]

> >>> @@ -1431,7 +1524,7 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
> >>>  
> >>>  	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
> >>>  	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
> >>> -	dev_info->pci_dev = dev->pci_dev;
> >>> +	dev_info->soc_dev = dev->soc_dev;    
> >>
> >> I think both the members, pci_dev and soc_dev, should be updated by this call.
> >> Is there some specific reason why soc_dev is the only one which is getting updated?  
> > 
> > Yes, looks like a mistake. Thanks! And sorry for delayed reply.  
> 
> No problems - thanks for confirmation.
> I have gone through almost complete series and as and when you rebase it, it would have my ACK.

OK, thanks. That's what I am playing with right now. I've rebased on v3 of this patch. There will
be some more tests in my v2.

> rte_driver patchset which I sent last are broken - I will publish an updated version very soon.

I am surprised that you've changed the args to RTE_EAL_PCI_REGISTER... Are you sure about this step?
I wrote that I'll change it myself for v2 for SoC to accept name and pointer as it was originally for PCI...

Jan

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

* Re: [PATCH v1 28/28] ether: support SoC device/driver
  2016-07-04 14:36         ` Jan Viktorin
@ 2016-07-05  4:42           ` Shreyansh jain
  2016-07-05  5:16             ` Jan Viktorin
  2016-07-12  8:45           ` Shreyansh jain
  1 sibling, 1 reply; 231+ messages in thread
From: Shreyansh jain @ 2016-07-05  4:42 UTC (permalink / raw)
  To: Jan Viktorin; +Cc: dev

On Monday 04 July 2016 08:06 PM, Jan Viktorin wrote:
> On Mon, 4 Jul 2016 19:57:18 +0530
> Shreyansh jain <shreyansh.jain@nxp.com> wrote:
> 
> [...]
> 
>>>>> @@ -1431,7 +1524,7 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
>>>>>  
>>>>>  	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
>>>>>  	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
>>>>> -	dev_info->pci_dev = dev->pci_dev;
>>>>> +	dev_info->soc_dev = dev->soc_dev;    
>>>>
>>>> I think both the members, pci_dev and soc_dev, should be updated by this call.
>>>> Is there some specific reason why soc_dev is the only one which is getting updated?  
>>>
>>> Yes, looks like a mistake. Thanks! And sorry for delayed reply.  
>>
>> No problems - thanks for confirmation.
>> I have gone through almost complete series and as and when you rebase it, it would have my ACK.
> 
> OK, thanks. That's what I am playing with right now. I've rebased on v3 of this patch. There will
> be some more tests in my v2.
> 
>> rte_driver patchset which I sent last are broken - I will publish an updated version very soon.
> 
> I am surprised that you've changed the args to RTE_EAL_PCI_REGISTER... Are you sure about this step?
> I wrote that I'll change it myself for v2 for SoC to accept name and pointer as it was originally for PCI...

Really? Then probably I understood it wrong. I don't have any issues with the first one as well but just for slightly cleaner approach I thought of going with your suggest (or, suggestion as understood by me).

Anyways the patch is broken and doesn't apply on master. I will push a new version (with revert EAL_PCI_REGISTER arguments) within today.

> 
> Jan
> 

-
Shreyansh

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

* Re: [PATCH v1 28/28] ether: support SoC device/driver
  2016-07-05  4:42           ` Shreyansh jain
@ 2016-07-05  5:16             ` Jan Viktorin
  2016-07-07 10:29               ` Shreyansh jain
  0 siblings, 1 reply; 231+ messages in thread
From: Jan Viktorin @ 2016-07-05  5:16 UTC (permalink / raw)
  To: Shreyansh jain; +Cc: dev, Thomas Monjalon

Hello Shreyansh,
‎
> On Monday 04 July 2016 08:06 PM, Jan Viktorin wrote:
>> On Mon, 4 Jul 2016 19:57:18 +0530
>> Shreyansh jain <shreyansh.jain@nxp.com> wrote:
>> 
>> [...]
>> 
>>>>>> @@ -1431,7 +1524,7 @@ >rte_eth_dev_info_get(uint8_t port_id, struct >rte_eth_dev_info *dev_info)
>>>>>> 
>>>>>> RTE_FUNC_PTR_OR_RET(*dev->dev_ops->>dev_infos_get);
>>>>>> (*dev->dev_ops->dev_infos_get)(dev, dev_info);
>>>>>> -	dev_info->pci_dev = dev->pci_dev;
>>>>>> +	dev_info->soc_dev = dev->soc_dev; 
>>>>>
>>>>> I think both the members, pci_dev and soc_dev, should be updated by this call.
>>>>> Is there some specific reason why soc_dev is the only one which is getting updated? 
>>>>
>>>> Yes, looks like a mistake. Thanks! And sorry for delayed reply. 
>>>
>>> No problems - thanks for confirmation.
>>> I have gone through almost complete series and as and when you rebase it, it would have my ACK.
>> 
>> OK, thanks. That's what I am playing with right now. I've rebased on v3 of this patch. There will
>> be some more tests in my v2.
>> 
>>> rte_driver patchset which I sent last are broken - I will publish an updated version very soon.
>> 
>> I am surprised that you've changed the args to RTE_EAL_PCI_REGISTER... Are you sure about this step?
>> I wrote that I'll change it myself for v2 for SoC to accept name and pointer as it was originally for PCI...
>
> Really? Then probably I understood it wrong. I don't have any issues with the first one as well but just for slightly cleaner approach I thought of going with your suggest (or, suggestion as understood by me).
‎>
> Anyways the patch is broken and doesn't apply on master. I will push a new version (with revert EAL_PCI_REGISTER arguments) within today.

Ok. I am away for few days this week but I will continue as soon as possible on the soc patchset and also on the rte_device/driver issue. We have to cut this as soon as possible. I think the best would be to post a small patchset on top of this one introducing the change.

I think, there should be a single list of rte_device and a list for rte_driver while preserving lists for each infra, so also rte_pci_device would have a separate list. Then, it's possible to iterate over all PCI devices easily and iterate over all devices generically at the same time.

What I am not sure about are addr and id things. It's quite difficult to generalize them. The addr needs a conpare function but how to compare pci addr to another type of addr? Do we need this? If so, I'll work on this.

Another thing - resources. Do we want to have a kind of a generic rte_resource instead of rte_pci_resource? I think this is clearly possible. I am about to do this.

I am afraid we are unable to change devargs significantly in this release :/ (due to time and lack of a discussion here).‎ What I really like to see is the virtual device conversion and pmd_type removal. Are you able to look at this?

Any other objections?

Jan Viktorin
RehiveTech
Sent from a mobile device‎

>> 
>> Jan
>> 
>
>-
>Shreyansh

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

* Re: [PATCH v1 28/28] ether: support SoC device/driver
  2016-07-05  5:16             ` Jan Viktorin
@ 2016-07-07 10:29               ` Shreyansh jain
  0 siblings, 0 replies; 231+ messages in thread
From: Shreyansh jain @ 2016-07-07 10:29 UTC (permalink / raw)
  To: Jan Viktorin; +Cc: dev, Thomas Monjalon

Hi Jan,

Apologies for delay in my response.

On Tuesday 05 July 2016 10:46 AM, Jan Viktorin wrote:
> Hello Shreyansh,
> ‎
>> On Monday 04 July 2016 08:06 PM, Jan Viktorin wrote:
>>> On Mon, 4 Jul 2016 19:57:18 +0530
>>> Shreyansh jain <shreyansh.jain@nxp.com> wrote:
>>>
>>> [...]
>>>
>>>>>>> @@ -1431,7 +1524,7 @@ >rte_eth_dev_info_get(uint8_t port_id, struct >rte_eth_dev_info *dev_info)
>>>>>>>
>>>>>>> RTE_FUNC_PTR_OR_RET(*dev->dev_ops->>dev_infos_get);
>>>>>>> (*dev->dev_ops->dev_infos_get)(dev, dev_info);
>>>>>>> -	dev_info->pci_dev = dev->pci_dev;
>>>>>>> +	dev_info->soc_dev = dev->soc_dev; 
>>>>>>
>>>>>> I think both the members, pci_dev and soc_dev, should be updated by this call.
>>>>>> Is there some specific reason why soc_dev is the only one which is getting updated? 
>>>>>
>>>>> Yes, looks like a mistake. Thanks! And sorry for delayed reply. 
>>>>
>>>> No problems - thanks for confirmation.
>>>> I have gone through almost complete series and as and when you rebase it, it would have my ACK.
>>>
>>> OK, thanks. That's what I am playing with right now. I've rebased on v3 of this patch. There will
>>> be some more tests in my v2.
>>>
>>>> rte_driver patchset which I sent last are broken - I will publish an updated version very soon.
>>>
>>> I am surprised that you've changed the args to RTE_EAL_PCI_REGISTER... Are you sure about this step?
>>> I wrote that I'll change it myself for v2 for SoC to accept name and pointer as it was originally for PCI...
>>
>> Really? Then probably I understood it wrong. I don't have any issues with the first one as well but just for slightly cleaner approach I thought of going with your suggest (or, suggestion as understood by me).
> ‎>
>> Anyways the patch is broken and doesn't apply on master. I will push a new version (with revert EAL_PCI_REGISTER arguments) within today.
> 
> Ok. I am away for few days this week but I will continue as soon as possible on the soc patchset and also on the rte_device/driver issue. We have to cut this as soon as possible. I think the best would be to post a small patchset on top of this one introducing the change.

I am anyway working on a driver for NXP's SoC platform which I am basing over rte_device + SoC patchset.
I plan to release a draft of this driver soon. It might help validate both the patchsets in a limited manner.

> 
> I think, there should be a single list of rte_device and a list for rte_driver while preserving lists for each infra, so also rte_pci_device would have a separate list. Then, it's possible to iterate over all PCI devices easily and iterate over all devices generically at the same time.

I have similar understanding. Separate pci/soc lists, and unified rte_driver and rte_device lists. This, in my opinion, would help keep the interfaces clean (free of unnecessary checks).

> 
> What I am not sure about are addr and id things. It's quite difficult to generalize them. The addr needs a conpare function but how to compare pci addr to another type of addr? Do we need this? If so, I'll work on this.

I am not sure why we need to compare the PCI addresses with non-PCI (or any other, SoC) address set? Can you elaborate?

> 
> Another thing - resources. Do we want to have a kind of a generic rte_resource instead of rte_pci_resource? I think this is clearly possible. I am about to do this.

The idea sounds good but I don't know whether it would be feasible or not. My understanding is that resources have special characteristics. Generalizing them would involve creating opaque objects in rte_resource{..} which in turn beats the purpose of generalization.

Probably, I will wait for your next patchset version to understand your approach.

> 
> I am afraid we are unable to change devargs significantly in this release :/ (due to time and lack of a discussion here).‎ What I really like to see is the virtual device conversion and pmd_type removal. Are you able to look at this?

pmd_type removal is my todo as well. This would anyway impact the vdevs.
I haven't given devargs much thought, yet.

> 
> Any other objections?

I was looking at various discussions [1],[2] that have happened in past. >From that, the summary I have is:
 1) Generalize devices to rte_device/rte_driver
  `-- Cleaner interfaces/difference for 'bus', 'driver' and 'device'
  `-- Moving the init/deinit functions into rte_device/rte_driver layer
  `-- hierarchical device structure (as explained by David in [1]) 
 2) Do away with device type specific initializations (registrations)
  `-- No more pdev/vdev distinction
  `-- standardizing devargs for accepting device specific strings.
 3) Hotplug support

Most of work of (1) David has already done. What remains is completing (2) and probably (3) which I haven't verified yet.

[1] http://dpdk.org/ml/archives/dev/2016-January/031390.html
[2] http://dpdk.org/ml/archives/dev/2016-January/030975.html

> 
> Jan Viktorin
> RehiveTech
> Sent from a mobile device‎
> 
>>>
>>> Jan
>>>  
>>
>> -
>> Shreyansh
> 

-
Shreyansh
 

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

* Re: [PATCH v1 28/28] ether: support SoC device/driver
  2016-07-04 14:36         ` Jan Viktorin
  2016-07-05  4:42           ` Shreyansh jain
@ 2016-07-12  8:45           ` Shreyansh jain
  2016-07-12 10:41             ` Jan Viktorin
  1 sibling, 1 reply; 231+ messages in thread
From: Shreyansh jain @ 2016-07-12  8:45 UTC (permalink / raw)
  To: Jan Viktorin; +Cc: dev

Hi Jan,

On Monday 04 July 2016 08:06 PM, Jan Viktorin wrote:
> On Mon, 4 Jul 2016 19:57:18 +0530
> Shreyansh jain <shreyansh.jain@nxp.com> wrote:
> 
> [...]
> 
>>>>> @@ -1431,7 +1524,7 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
>>>>>  
>>>>>  	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
>>>>>  	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
>>>>> -	dev_info->pci_dev = dev->pci_dev;
>>>>> +	dev_info->soc_dev = dev->soc_dev;    
>>>>
>>>> I think both the members, pci_dev and soc_dev, should be updated by this call.
>>>> Is there some specific reason why soc_dev is the only one which is getting updated?  
>>>
>>> Yes, looks like a mistake. Thanks! And sorry for delayed reply.  
>>
>> No problems - thanks for confirmation.
>> I have gone through almost complete series and as and when you rebase it, it would have my ACK.
> 
> OK, thanks. That's what I am playing with right now. I've rebased on v3 of this patch. There will
> be some more tests in my v2.
> 
>> rte_driver patchset which I sent last are broken - I will publish an updated version very soon.
> 
> I am surprised that you've changed the args to RTE_EAL_PCI_REGISTER... Are you sure about this step?
> I wrote that I'll change it myself for v2 for SoC to accept name and pointer as it was originally for PCI...

I have sent across a v6 of the rte_device/driver change set.
Can you see if that is in-line with your expectations as well as the series [1] posted by you recently?
I was making changes for vdev but for now I have ignored them as your series already includes those changes.

I used your patches and based them over the v6 rte_device patchset - besides some minor conflicts, its seems to merge fine.

[1] http://dpdk.org/ml/archives/dev/2016-July/043645.html

> 
> Jan
> 

-
Shreyansh

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

* Re: [PATCH v1 28/28] ether: support SoC device/driver
  2016-07-12  8:45           ` Shreyansh jain
@ 2016-07-12 10:41             ` Jan Viktorin
  0 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-07-12 10:41 UTC (permalink / raw)
  To: Shreyansh jain; +Cc: dev

On Tue, 12 Jul 2016 14:15:17 +0530
Shreyansh jain <shreyansh.jain@nxp.com> wrote:

> Hi Jan,
> 
> On Monday 04 July 2016 08:06 PM, Jan Viktorin wrote:
> > On Mon, 4 Jul 2016 19:57:18 +0530
> > Shreyansh jain <shreyansh.jain@nxp.com> wrote:
> > 
> > [...]
> >   
> >>>>> @@ -1431,7 +1524,7 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
> >>>>>  
> >>>>>  	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
> >>>>>  	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
> >>>>> -	dev_info->pci_dev = dev->pci_dev;
> >>>>> +	dev_info->soc_dev = dev->soc_dev;      
> >>>>
> >>>> I think both the members, pci_dev and soc_dev, should be updated by this call.
> >>>> Is there some specific reason why soc_dev is the only one which is getting updated?    
> >>>
> >>> Yes, looks like a mistake. Thanks! And sorry for delayed reply.    
> >>
> >> No problems - thanks for confirmation.
> >> I have gone through almost complete series and as and when you rebase it, it would have my ACK.  
> > 
> > OK, thanks. That's what I am playing with right now. I've rebased on v3 of this patch. There will
> > be some more tests in my v2.
> >   
> >> rte_driver patchset which I sent last are broken - I will publish an updated version very soon.  
> > 
> > I am surprised that you've changed the args to RTE_EAL_PCI_REGISTER... Are you sure about this step?
> > I wrote that I'll change it myself for v2 for SoC to accept name and pointer as it was originally for PCI...  
> 
> I have sent across a v6 of the rte_device/driver change set.
> Can you see if that is in-line with your expectations as well as the series [1] posted by you recently?
> I was making changes for vdev but for now I have ignored them as your series already includes those changes.
> 
> I used your patches and based them over the v6 rte_device patchset - besides some minor conflicts, its seems to merge fine.
> 
> [1] http://dpdk.org/ml/archives/dev/2016-July/043645.html

I will check it as soon as possible. Thanks.

Jan

> 
> > 
> > Jan
> >   
> 
> -
> Shreyansh
> 



-- 
   Jan Viktorin                  E-mail: Viktorin@RehiveTech.com
   System Architect              Web:    www.RehiveTech.com
   RehiveTech
   Brno, Czech Republic

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

* [PATCH v2 00/14] Introduce SoC device/driver framework for EAL
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (35 preceding siblings ...)
  2016-05-06 13:48 ` [PATCH v1 28/28] ether: support SoC device/driver Jan Viktorin
@ 2016-08-31 11:00 ` Shreyansh Jain
  2016-08-31 11:00   ` [PATCH v2 01/14] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
                     ` (13 more replies)
  2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
  37 siblings, 14 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-08-31 11:00 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain

Introduction:
=============

This patch set is direct derivative of Jan's original series [1],[2].
(Confirmed offline with Jan before posting.)

 - As this deviates substantially from original series, if need be I can 
   post it as a separate patch rather than v2. Please suggest.
 - Also, there are comments on original v1 ([4]) which are _not_
   incorporated in this series as they refer to section no more in new
   version.
 - Initial set also contains certain patches to generalize some PCI specific
   structures and function to common EAL ([6,7,8,9]. Those patches I'll post
   separately as they are good changes (in my opinion) and not related to
   SoC framework.

It is built over the series [3] which introduces device structures for
rte_driver/rte_device for generalizing devices into PCI, VDEV, XXX. For
the purpose of this patchset, XXX=>SOC.

Aim:
====

As of now EAL is primarly focused on PCI initialization/probing.
 
 rte_eal_init()
  |- rte_eal_pci_init(): Find PCI devices from sysfs
  |- ...
  |- rte_eal_memzone_init()
  |- ...
  `- rte_eal_pci_probe(): Driver<=>Device initialization

This patchset introduces SoC framework which would enable SoC drivers and
drivers to be plugged into EAL, very similar to how PCI drivers/devices are
done today.

This is a stripped down version of PCI framework which allows the SoC PMDs
to implement their own routines for detecting devices and linking devices to
drivers.

1) Changes to EAL 
 rte_eal_init()
  |- rte_eal_pci_init(): Find PCI devices from sysfs
  |- rte_eal_soc_init(): Calls PMDs->scan_fn
  |- ...
  |- rte_eal_memzone_init()
  |- ...
  |- rte_eal_pci_probe(): Driver<=>Device initialization, PMD->devinit()
  `- rte_eal_soc_probe(): Calls PMDs->match_fn and PMDs->devinit();

2) New device/driver structures:
  - rte_soc_driver (inheriting rte_driver)
  - rte_soc_device (inheriting rte_device)
  - rte_eth_dev and eth_driver embedded rte_soc_device and rte_soc_driver,
    respectively.

3) The SoC PMDs need to:
 - define rte_soc_driver with necessary scan and match callbacks
 - Register themselves using DRIVER_REGISTER_SOC()
 - Implement respective bus scanning in the scan callbacks to add necessary
   devices to SoC device list
 - Implement necessary eth_dev_init/uninint for ethernet instances

4) Design considerations that are same as PCI:
 - SoC initialization is being done through rte_eal_init(), just after PCI 
   initialization is done.
 - As in case of PCI, probe is done after rte_eal_pci_probe() to link the 
   devices detected with the drivers registered.
 - Device attach/detach functions are available and have been designed on 
   the lines of PCI framework.
 - PMDs register using DRIVER_REGISTER_SOC, very similar to 
   DRIVER_REGISTER_PCI for PCI devices.
 - Linked list of SoC driver and devices exists independent of the other 
   driver/device list, but inheriting rte_driver/rte_driver, these are also 
   part of a global list.

5) Design considerations that are different from PCI:
 - Each driver implements its own scan and match function. PCI uses the BDF 
   format to read the device from sysfs, but this _may_not_ be a case for a 
   SoC ethernet device.
   = This is an important change from initial proposal by Jan in [2]. Unlike 
   his attempt to use /sys/bus/platform, this patch relies on the PMD to
   detect the devices. This is because SoC may require specific or
   additional info for device detection. Further, SoC may have embedded
   devices/MACs which require initialization which cannot be covered through
   sysfs parsing.
   = PCI based PMDs rely on EAL's capability to detect devices. This 
   proposal puts the onus on PMD to detect devices, add to soc_device_list 
   and wait for Probe. Matching, of device<=>driver is again PMD's callback.

Patchset Overview:
==================
 - Patches 0001~0003 introduce the base infrastructure and test case
 - Patch 0004 is for command line support for no-soc, on lines of no-pci
 - Patch 0005 enables EAL to handle SoC type devices
 - Patch 0006 adds support for scan and probe callbacks and updates the test
   framework with relevant test case.
 - Patch 0007~0009 enable device argument, driver specific flags and
   interrupt handling related basic infra. Subsequent patches build up on
   them.
 - Patch 0010~0013 makes changes to PCI as well as ethdev code to remove 
   assumption that eth_driver is a PCI driver.
 - Patch 0014 adds necessary ethdev probe/remove functions for PMDs to use

Future/Pending Changes:
=======================
- Device whitelisting/blacklist still relies on command line '-b' and '-c'
  which are internally implemented using OPT_PCI_BLACKLIST/OPT_PCI_WHITELIST.
  This needs to be changed to a generic form - OPT_DEV_*LIST - probably.

 [1] http://dpdk.org/ml/archives/dev/2016-January/030915.html
 [2] http://www.dpdk.org/ml/archives/dev/2016-May/038486.html
 [3] http://dpdk.org/ml/archives/dev/2016-August/045707.html
 [4] http://dpdk.org/ml/archives/dev/2016-May/038948.html
 [5] http://dpdk.org/ml/archives/dev/2016-May/038953.html
 [6] http://dpdk.org/ml/archives/dev/2016-May/038487.html
 [7] http://dpdk.org/ml/archives/dev/2016-May/038488.html
 [8] http://dpdk.org/ml/archives/dev/2016-May/038489.html
 [9] http://dpdk.org/ml/archives/dev/2016-May/038491.html

Change since v1: [2]
 - Removed patch 1-5 which were for generalizing some PCI specific routines
   into EAL. These patches are good-to-have but not directly linked to SoC
   and hence would be proposed separately.
 - Removed support for sysfs parsing (patches 6~9)
 - Rebasing over the recent (v8) version of rte_driver/device patchset
 - Rebasing over master (16.07)
 - Changes to various map file to change API intro to 16.11 from 16.07

Shreyansh Jain (14):
  eal/soc: introduce very essential SoC infra definitions
  eal/soc: add rte_eal_soc_register/unregister logic
  eal/soc: Implement SoC device list and dump
  eal: introduce --no-soc option
  eal/soc: init SoC infra from EAL
  eal/soc: implement probing of drivers
  eal/soc: extend and utilize devargs
  eal/soc: add drv_flags
  eal/soc: add intr_handle
  ether: utilize container_of for pci_drv
  ether: verify we copy info from a PCI device
  ether: extract function eth_dev_get_intr_handle
  ether: extract function eth_dev_get_driver_name
  ether: Support rte_soc_driver/device for etherdev

 app/test/Makefile                               |   1 +
 app/test/test_soc.c                             | 337 ++++++++++++++++++++++++
 lib/librte_eal/bsdapp/eal/Makefile              |   1 +
 lib/librte_eal/bsdapp/eal/eal.c                 |   4 +
 lib/librte_eal/bsdapp/eal/eal_soc.c             |  46 ++++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   9 +
 lib/librte_eal/common/Makefile                  |   2 +-
 lib/librte_eal/common/eal_common_dev.c          |  27 +-
 lib/librte_eal/common/eal_common_devargs.c      |  17 ++
 lib/librte_eal/common/eal_common_options.c      |   5 +
 lib/librte_eal/common/eal_common_soc.c          | 326 +++++++++++++++++++++++
 lib/librte_eal/common/eal_internal_cfg.h        |   1 +
 lib/librte_eal/common/eal_options.h             |   2 +
 lib/librte_eal/common/eal_private.h             |  14 +
 lib/librte_eal/common/include/rte_devargs.h     |   8 +
 lib/librte_eal/common/include/rte_soc.h         | 246 +++++++++++++++++
 lib/librte_eal/linuxapp/eal/Makefile            |   2 +
 lib/librte_eal/linuxapp/eal/eal.c               |   8 +
 lib/librte_eal/linuxapp/eal/eal_soc.c           |  72 +++++
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   8 +
 lib/librte_ether/rte_ethdev.c                   | 165 +++++++++++-
 lib/librte_ether/rte_ethdev.h                   |  33 ++-
 22 files changed, 1320 insertions(+), 14 deletions(-)
 create mode 100644 app/test/test_soc.c
 create mode 100644 lib/librte_eal/bsdapp/eal/eal_soc.c
 create mode 100644 lib/librte_eal/common/eal_common_soc.c
 create mode 100644 lib/librte_eal/common/include/rte_soc.h
 create mode 100644 lib/librte_eal/linuxapp/eal/eal_soc.c

-- 
2.7.4

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

* [PATCH v2 01/14] eal/soc: introduce very essential SoC infra definitions
  2016-08-31 11:00 ` [PATCH v2 00/14] Introduce SoC device/driver framework for EAL Shreyansh Jain
@ 2016-08-31 11:00   ` Shreyansh Jain
  2016-08-31 11:00   ` [PATCH v2 02/14] eal/soc: add rte_eal_soc_register/unregister logic Shreyansh Jain
                     ` (12 subsequent siblings)
  13 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-08-31 11:00 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, Jan Viktorin, Hemant Agrawal

Define initial structures and functions for the SoC infrastructure.
This patch supports only a very minimal functions for now.
More features will be added in the following commits.

Includes rte_device/rte_driver inheritance of
rte_soc_device/rte_soc_driver.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 app/test/Makefile                       |   1 +
 app/test/test_soc.c                     |  90 +++++++++++++++++++++
 lib/librte_eal/common/Makefile          |   2 +-
 lib/librte_eal/common/eal_private.h     |   4 +
 lib/librte_eal/common/include/rte_soc.h | 138 ++++++++++++++++++++++++++++++++
 5 files changed, 234 insertions(+), 1 deletion(-)
 create mode 100644 app/test/test_soc.c
 create mode 100644 lib/librte_eal/common/include/rte_soc.h

diff --git a/app/test/Makefile b/app/test/Makefile
index 611d77a..64b261d 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -77,6 +77,7 @@ APP = test
 #
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) := commands.c
 SRCS-y += test.c
+SRCS-y += test_soc.c
 SRCS-y += resource.c
 SRCS-y += test_resource.c
 test_resource.res: test_resource.c
diff --git a/app/test/test_soc.c b/app/test/test_soc.c
new file mode 100644
index 0000000..916a863
--- /dev/null
+++ b/app/test/test_soc.c
@@ -0,0 +1,90 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <sys/queue.h>
+
+#include <rte_soc.h>
+#include <rte_devargs.h>
+#include <rte_debug.h>
+
+#include "test.h"
+
+static char *safe_strdup(const char *s)
+{
+	char *c = strdup(s);
+
+	if (c == NULL)
+		rte_panic("failed to strdup '%s'\n", s);
+
+	return c;
+}
+
+static int test_compare_addr(void)
+{
+	struct rte_soc_addr a0;
+	struct rte_soc_addr a1;
+	struct rte_soc_addr a2;
+
+	a0.name = safe_strdup("ethernet0");
+	a0.fdt_path = NULL;
+
+	a1.name = safe_strdup("ethernet0");
+	a1.fdt_path = NULL;
+
+	a2.name = safe_strdup("ethernet1");
+	a2.fdt_path = NULL;
+
+	TEST_ASSERT(!rte_eal_compare_soc_addr(&a0, &a1),
+		    "Failed to compare two soc addresses that equal");
+	TEST_ASSERT(rte_eal_compare_soc_addr(&a0, &a2),
+		    "Failed to compare two soc addresses that differs");
+
+	free(a2.name);
+	free(a1.name);
+	free(a0.name);
+	return 0;
+}
+
+static int
+test_soc(void)
+{
+	if (test_compare_addr())
+		return -1;
+
+	return 0;
+}
+
+REGISTER_TEST_COMMAND(soc_autotest, test_soc);
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index dfd64aa..b414008 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 INC := rte_branch_prediction.h rte_common.h
 INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
-INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
+INC += rte_log.h rte_memory.h rte_memzone.h rte_soc.h rte_pci.h
 INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 431d6c2..df6582d 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -36,6 +36,7 @@
 
 #include <stdio.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 
 /**
  * Initialize the memzone subsystem (private to eal).
@@ -126,6 +127,9 @@ int rte_eal_log_init(const char *id, int facility);
  */
 int rte_eal_pci_init(void);
 
+struct rte_soc_driver;
+struct rte_soc_device;
+
 struct rte_pci_driver;
 struct rte_pci_device;
 
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
new file mode 100644
index 0000000..bc0a43b
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -0,0 +1,138 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_SOC_H_
+#define _RTE_SOC_H_
+
+/**
+ * @file
+ *
+ * RTE SoC Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include <rte_dev.h>
+#include <rte_debug.h>
+
+struct rte_soc_id {
+	const char *compatible; /**< OF compatible specification */
+	uint64_t priv_data;     /**< SoC Driver specific data */
+};
+
+struct rte_soc_addr {
+	char *name;     /**< name used in sysfs */
+	char *fdt_path; /**< path to the associated node in FDT */
+};
+
+/**
+ * A structure describing a SoC device.
+ */
+struct rte_soc_device {
+	TAILQ_ENTRY(rte_soc_device) next;   /**< Next probed SoC device */
+	struct rte_device device;           /**< Inherit code device */
+	struct rte_soc_addr addr;           /**< SoC device Location */
+	struct rte_soc_id *id;              /**< SoC device ID list */
+	struct rte_soc_driver *driver;      /**< Associated driver */
+};
+
+struct rte_soc_driver;
+
+/**
+ * Initialization function for the driver called during SoC probing.
+ */
+typedef int (soc_devinit_t)(struct rte_soc_driver *, struct rte_soc_device *);
+
+/**
+ * Uninitialization function for the driver called during hotplugging.
+ */
+typedef int (soc_devuninit_t)(struct rte_soc_device *);
+
+/**
+ * A structure describing a SoC driver.
+ */
+struct rte_soc_driver {
+	TAILQ_ENTRY(rte_soc_driver) next;  /**< Next in list */
+	struct rte_driver driver;          /**< Inherit core driver. */
+	soc_devinit_t *devinit;            /**< Device initialization */
+	soc_devuninit_t *devuninit;        /**< Device uninitialization */
+	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
+};
+
+/**
+ * Utility function to write a SoC device name, this device name can later be
+ * used to retrieve the corresponding rte_soc_addr using above functions.
+ *
+ * @param addr
+ *	The SoC address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ * @return
+ *  0 on success, negative on error.
+ */
+static inline void
+rte_eal_soc_device_name(const struct rte_soc_addr *addr,
+			char *output, size_t size)
+{
+	int ret;
+
+	RTE_VERIFY(addr != NULL);
+	RTE_VERIFY(size >= strlen(addr->name));
+	ret = snprintf(output, size, "%s", addr->name);
+	RTE_VERIFY(ret >= 0);
+}
+
+static inline int
+rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
+			 const struct rte_soc_addr *a1)
+{
+	if (a0 == NULL || a1 == NULL)
+		return -1;
+
+	RTE_VERIFY(a0->name != NULL);
+	RTE_VERIFY(a1->name != NULL);
+
+	return strcmp(a0->name, a1->name);
+}
+
+#endif
-- 
2.7.4

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

* [PATCH v2 02/14] eal/soc: add rte_eal_soc_register/unregister logic
  2016-08-31 11:00 ` [PATCH v2 00/14] Introduce SoC device/driver framework for EAL Shreyansh Jain
  2016-08-31 11:00   ` [PATCH v2 01/14] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
@ 2016-08-31 11:00   ` Shreyansh Jain
  2016-08-31 11:00   ` [PATCH v2 03/14] eal/soc: Implement SoC device list and dump Shreyansh Jain
                     ` (11 subsequent siblings)
  13 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-08-31 11:00 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, Jan Viktorin, Hemant Agrawal

Registeration of a SoC driver through a helper DRIVER_REGISTER_SOC
(on the lines of DRIVER_REGISTER_PCI). soc_driver_list stores all the
registered drivers.

Test case has been introduced to verify the registration and
deregistration.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 app/test/test_soc.c                             | 111 ++++++++++++++++++++++++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   4 +
 lib/librte_eal/common/eal_common_soc.c          |  56 ++++++++++++
 lib/librte_eal/common/include/rte_soc.h         |  26 ++++++
 lib/librte_eal/linuxapp/eal/Makefile            |   1 +
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   3 +
 6 files changed, 201 insertions(+)
 create mode 100644 lib/librte_eal/common/eal_common_soc.c

diff --git a/app/test/test_soc.c b/app/test/test_soc.c
index 916a863..ac03e64 100644
--- a/app/test/test_soc.c
+++ b/app/test/test_soc.c
@@ -75,6 +75,108 @@ static int test_compare_addr(void)
 	free(a2.name);
 	free(a1.name);
 	free(a0.name);
+
+	return 0;
+}
+
+/**
+ * Empty PMD driver based on the SoC infra.
+ *
+ * The rte_soc_device is usually wrapped in some higher-level struct
+ * (eth_driver). We simulate such a wrapper with an anonymous struct here.
+ */
+struct test_wrapper {
+	struct rte_soc_driver soc_drv;
+};
+
+struct test_wrapper empty_pmd0 = {
+	.soc_drv = {
+		.driver = {
+			.name = "empty_pmd0"
+		},
+	},
+};
+
+struct test_wrapper empty_pmd1 = {
+	.soc_drv = {
+		.driver = {
+			.name = "empty_pmd1"
+		},
+	},
+};
+
+static int
+count_registered_socdrvs(void)
+{
+	int i;
+	struct rte_soc_driver *drv;
+
+	i = 0;
+	TAILQ_FOREACH(drv, &soc_driver_list, next)
+		i += 1;
+
+	return i;
+}
+
+static int
+test_register_unregister(void)
+{
+	struct rte_soc_driver *drv;
+	int count;
+
+	rte_eal_soc_register(&empty_pmd0.soc_drv);
+
+	TEST_ASSERT(!TAILQ_EMPTY(&soc_driver_list),
+		    "No PMD is present but the empty_pmd0 should be there");
+	drv = TAILQ_FIRST(&soc_driver_list);
+	TEST_ASSERT(!strcmp(drv->driver.name, "empty_pmd0"),
+		    "The registered PMD is not empty_pmd0 but '%s'",
+		drv->driver.name);
+
+	rte_eal_soc_register(&empty_pmd1.soc_drv);
+
+	count = count_registered_socdrvs();
+	TEST_ASSERT_EQUAL(count, 2, "Expected 2 PMDs but detected %d", count);
+
+	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
+	count = count_registered_socdrvs();
+	TEST_ASSERT_EQUAL(count, 1, "Expected 1 PMDs but detected %d", count);
+
+	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
+
+	printf("%s has been successful\n", __func__);
+	return 0;
+}
+
+/* save real devices and drivers until the tests finishes */
+struct soc_driver_list real_soc_driver_list =
+	TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
+
+static int test_soc_setup(void)
+{
+	struct rte_soc_driver *drv;
+
+	/* no real drivers for the test */
+	while (!TAILQ_EMPTY(&soc_driver_list)) {
+		drv = TAILQ_FIRST(&soc_driver_list);
+		rte_eal_soc_unregister(drv);
+		TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
+	}
+
+	return 0;
+}
+
+static int test_soc_cleanup(void)
+{
+	struct rte_soc_driver *drv;
+
+	/* bring back real drivers after the test */
+	while (!TAILQ_EMPTY(&real_soc_driver_list)) {
+		drv = TAILQ_FIRST(&real_soc_driver_list);
+		TAILQ_REMOVE(&real_soc_driver_list, drv, next);
+		rte_eal_soc_register(drv);
+	}
+
 	return 0;
 }
 
@@ -84,6 +186,15 @@ test_soc(void)
 	if (test_compare_addr())
 		return -1;
 
+	if (test_soc_setup())
+		return -1;
+
+	if (test_register_unregister())
+		return -1;
+
+	if (test_soc_cleanup())
+		return -1;
+
 	return 0;
 }
 
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 7b3d409..cda8009 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -168,4 +168,8 @@ DPDK_16.11 {
 
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
+	soc_driver_list;
+	rte_eal_soc_register;
+	rte_eal_soc_unregister;
+
 } DPDK_16.07;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
new file mode 100644
index 0000000..56135ed
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -0,0 +1,56 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/queue.h>
+
+#include <rte_log.h>
+
+#include "eal_private.h"
+
+/* Global SoC driver list */
+struct soc_driver_list soc_driver_list =
+	TAILQ_HEAD_INITIALIZER(soc_driver_list);
+
+/* register a driver */
+void
+rte_eal_soc_register(struct rte_soc_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_eal_soc_unregister(struct rte_soc_driver *driver)
+{
+	TAILQ_REMOVE(&soc_driver_list, driver, next);
+}
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index bc0a43b..16c5a1b 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -51,8 +51,14 @@ extern "C" {
 #include <string.h>
 
 #include <rte_dev.h>
+#include <rte_eal.h>
 #include <rte_debug.h>
 
+extern struct soc_driver_list soc_driver_list;
+/**< Global list of SoC Drivers */
+
+TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
+
 struct rte_soc_id {
 	const char *compatible; /**< OF compatible specification */
 	uint64_t priv_data;     /**< SoC Driver specific data */
@@ -135,4 +141,24 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 	return strcmp(a0->name, a1->name);
 }
 
+/**
+ * Register a SoC driver.
+ */
+void rte_eal_soc_register(struct rte_soc_driver *driver);
+
+/** Helper for SoC device registeration from PMD Drivers */
+#define DRIVER_REGISTER_SOC(nm, soc_drv) \
+RTE_INIT(socinitfn_ ##name); \
+static void socinitfn_ ##name(void) \
+{\
+	(soc_drv).driver.name = RTE_STR(nm);\
+	rte_eal_soc_register(&soc_drv); \
+} \
+DRIVER_EXPORT_NAME(nm, __COUNTER__)
+
+/**
+ * Unregister a SoC driver.
+ */
+void rte_eal_soc_unregister(struct rte_soc_driver *driver);
+
 #endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 4e206f0..a520477 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -77,6 +77,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index b8bfd4b..66c1258 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -174,5 +174,8 @@ DPDK_16.11 {
 	rte_eal_dev_detach;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
+	soc_driver_list;
+	rte_eal_soc_register;
+	rte_eal_soc_unregister;
 
 } DPDK_16.07;
-- 
2.7.4

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

* [PATCH v2 03/14] eal/soc: Implement SoC device list and dump
  2016-08-31 11:00 ` [PATCH v2 00/14] Introduce SoC device/driver framework for EAL Shreyansh Jain
  2016-08-31 11:00   ` [PATCH v2 01/14] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
  2016-08-31 11:00   ` [PATCH v2 02/14] eal/soc: add rte_eal_soc_register/unregister logic Shreyansh Jain
@ 2016-08-31 11:00   ` Shreyansh Jain
  2016-08-31 11:00   ` [PATCH v2 04/14] eal: introduce --no-soc option Shreyansh Jain
                     ` (10 subsequent siblings)
  13 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-08-31 11:00 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, Jan Viktorin, Hemant Agrawal

SoC devices would be linked in a separate list (from PCI). This is used for
probe function.
A helper for dumping the device list is added.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  2 ++
 lib/librte_eal/common/eal_common_soc.c          | 34 +++++++++++++++++++++++++
 lib/librte_eal/common/include/rte_soc.h         |  9 +++++++
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  2 ++
 4 files changed, 47 insertions(+)

diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index cda8009..de38848 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -169,7 +169,9 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	soc_driver_list;
+	soc_device_list
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
+	rte_eal_soc_dump;
 
 } DPDK_16.07;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 56135ed..5dcddc5 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -31,6 +31,8 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <stddef.h>
+#include <stdio.h>
 #include <sys/queue.h>
 
 #include <rte_log.h>
@@ -40,6 +42,38 @@
 /* Global SoC driver list */
 struct soc_driver_list soc_driver_list =
 	TAILQ_HEAD_INITIALIZER(soc_driver_list);
+struct soc_device_list soc_device_list =
+	TAILQ_HEAD_INITIALIZER(soc_device_list);
+
+/* dump one device */
+static int
+soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
+{
+	int i;
+
+	fprintf(f, "%s", dev->addr.name);
+	fprintf(f, " - fdt_path: %s\n",
+			dev->addr.fdt_path ? dev->addr.fdt_path : "(none)");
+
+	for (i = 0; dev->id && dev->id[i].compatible; ++i)
+		fprintf(f, "   %s\n", dev->id[i].compatible);
+
+	return 0;
+}
+
+/* dump devices on the bus to an output stream */
+void
+rte_eal_soc_dump(FILE *f)
+{
+	struct rte_soc_device *dev = NULL;
+
+	if (!f)
+		return;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		soc_dump_one_device(f, dev);
+	}
+}
 
 /* register a driver */
 void
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 16c5a1b..c6f98eb 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -56,8 +56,12 @@ extern "C" {
 
 extern struct soc_driver_list soc_driver_list;
 /**< Global list of SoC Drivers */
+extern struct soc_device_list soc_device_list;
+/**< Global list of SoC Devices */
 
 TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
+TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
+
 
 struct rte_soc_id {
 	const char *compatible; /**< OF compatible specification */
@@ -142,6 +146,11 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 }
 
 /**
+ * Dump discovered SoC devices.
+ */
+void rte_eal_soc_dump(FILE *f);
+
+/**
  * Register a SoC driver.
  */
 void rte_eal_soc_register(struct rte_soc_driver *driver);
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 66c1258..b9d1932 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -175,7 +175,9 @@ DPDK_16.11 {
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
 	soc_driver_list;
+	soc_device_list;
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
+	rte_eal_soc_dump;
 
 } DPDK_16.07;
-- 
2.7.4

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

* [PATCH v2 04/14] eal: introduce --no-soc option
  2016-08-31 11:00 ` [PATCH v2 00/14] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (2 preceding siblings ...)
  2016-08-31 11:00   ` [PATCH v2 03/14] eal/soc: Implement SoC device list and dump Shreyansh Jain
@ 2016-08-31 11:00   ` Shreyansh Jain
  2016-08-31 11:00   ` [PATCH v2 05/14] eal/soc: init SoC infra from EAL Shreyansh Jain
                     ` (9 subsequent siblings)
  13 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-08-31 11:00 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, Jan Viktorin, Hemant Agrawal

This option has the same meaning for the SoC infra as the --no-pci
for the PCI infra.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/common/eal_common_options.c | 5 +++++
 lib/librte_eal/common/eal_internal_cfg.h   | 1 +
 lib/librte_eal/common/eal_options.h        | 2 ++
 3 files changed, 8 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 1a1bab3..d97cf0a 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -85,6 +85,7 @@ eal_long_options[] = {
 	{OPT_NO_HPET,           0, NULL, OPT_NO_HPET_NUM          },
 	{OPT_NO_HUGE,           0, NULL, OPT_NO_HUGE_NUM          },
 	{OPT_NO_PCI,            0, NULL, OPT_NO_PCI_NUM           },
+	{OPT_NO_SOC,            0, NULL, OPT_NO_SOC_NUM           },
 	{OPT_NO_SHCONF,         0, NULL, OPT_NO_SHCONF_NUM        },
 	{OPT_PCI_BLACKLIST,     1, NULL, OPT_PCI_BLACKLIST_NUM    },
 	{OPT_PCI_WHITELIST,     1, NULL, OPT_PCI_WHITELIST_NUM    },
@@ -855,6 +856,10 @@ eal_parse_common_option(int opt, const char *optarg,
 		conf->no_pci = 1;
 		break;
 
+	case OPT_NO_SOC_NUM:
+		conf->no_soc = 1;
+		break;
+
 	case OPT_NO_HPET_NUM:
 		conf->no_hpet = 1;
 		break;
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 5f1367e..3a98e94 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -67,6 +67,7 @@ struct internal_config {
 	unsigned hugepage_unlink;         /**< true to unlink backing files */
 	volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
 	volatile unsigned no_pci;         /**< true to disable PCI */
+	volatile unsigned no_soc;         /**< true to disable SoC */
 	volatile unsigned no_hpet;        /**< true to disable HPET */
 	volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
 										* instead of native TSC */
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index a881c62..ba1e704 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -69,6 +69,8 @@ enum {
 	OPT_NO_HUGE_NUM,
 #define OPT_NO_PCI            "no-pci"
 	OPT_NO_PCI_NUM,
+#define OPT_NO_SOC            "no-soc"
+	OPT_NO_SOC_NUM,
 #define OPT_NO_SHCONF         "no-shconf"
 	OPT_NO_SHCONF_NUM,
 #define OPT_SOCKET_MEM        "socket-mem"
-- 
2.7.4

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

* [PATCH v2 05/14] eal/soc: init SoC infra from EAL
  2016-08-31 11:00 ` [PATCH v2 00/14] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (3 preceding siblings ...)
  2016-08-31 11:00   ` [PATCH v2 04/14] eal: introduce --no-soc option Shreyansh Jain
@ 2016-08-31 11:00   ` Shreyansh Jain
  2016-08-31 11:00   ` [PATCH v2 06/14] eal/soc: implement probing of drivers Shreyansh Jain
                     ` (8 subsequent siblings)
  13 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-08-31 11:00 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, Jan Viktorin, Hemant Agrawal

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/bsdapp/eal/Makefile    |  1 +
 lib/librte_eal/bsdapp/eal/eal.c       |  4 +++
 lib/librte_eal/bsdapp/eal/eal_soc.c   | 46 ++++++++++++++++++++++++++++
 lib/librte_eal/common/eal_private.h   | 10 +++++++
 lib/librte_eal/linuxapp/eal/Makefile  |  1 +
 lib/librte_eal/linuxapp/eal/eal.c     |  3 ++
 lib/librte_eal/linuxapp/eal/eal_soc.c | 56 +++++++++++++++++++++++++++++++++++
 7 files changed, 121 insertions(+)
 create mode 100644 lib/librte_eal/bsdapp/eal/eal_soc.c
 create mode 100644 lib/librte_eal/linuxapp/eal/eal_soc.c

diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 5a3fc1d..cf4bf78 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -57,6 +57,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_hugepage_info.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_pci.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_timer.c
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index a0c8f8c..7d8c3e8 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -64,6 +64,7 @@
 #include <rte_string_fns.h>
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
+#include <rte_soc.h>
 #include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
@@ -567,6 +568,9 @@ rte_eal_init(int argc, char **argv)
 	if (rte_eal_pci_init() < 0)
 		rte_panic("Cannot init PCI\n");
 
+	if (rte_eal_soc_init() < 0)
+		rte_panic("Cannot init SoC\n");
+
 	eal_check_mem_on_local_socket();
 
 	if (eal_plugins_init() < 0)
diff --git a/lib/librte_eal/bsdapp/eal/eal_soc.c b/lib/librte_eal/bsdapp/eal/eal_soc.c
new file mode 100644
index 0000000..cb297ff
--- /dev/null
+++ b/lib/librte_eal/bsdapp/eal/eal_soc.c
@@ -0,0 +1,46 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <rte_common.h>
+#include <rte_log.h>
+
+#include <eal_private.h>
+
+/* Init the SoC EAL subsystem */
+int
+rte_eal_soc_init(void)
+{
+	return 0;
+}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index df6582d..ba8407d 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -130,6 +130,16 @@ int rte_eal_pci_init(void);
 struct rte_soc_driver;
 struct rte_soc_device;
 
+/**
+ * Init the SoC infra.
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int rte_eal_soc_init(void);
+
 struct rte_pci_driver;
 struct rte_pci_device;
 
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index a520477..59e30fa 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -65,6 +65,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio_mp_sync.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_vfio.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 9412983..15c8c3d 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -798,6 +798,9 @@ rte_eal_init(int argc, char **argv)
 		rte_panic("Cannot init VFIO\n");
 #endif
 
+	if (rte_eal_soc_init() < 0)
+		rte_panic("Cannot init SoC\n");
+
 	if (rte_eal_memory_init() < 0)
 		rte_panic("Cannot init memory\n");
 
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
new file mode 100644
index 0000000..04848b9
--- /dev/null
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -0,0 +1,56 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <rte_log.h>
+#include <rte_soc.h>
+
+#include "eal_internal_cfg.h"
+#include "eal_filesystem.h"
+#include "eal_private.h"
+
+/* Init the SoC EAL subsystem */
+int
+rte_eal_soc_init(void)
+{
+	return 0;
+}
-- 
2.7.4

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

* [PATCH v2 06/14] eal/soc: implement probing of drivers
  2016-08-31 11:00 ` [PATCH v2 00/14] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (4 preceding siblings ...)
  2016-08-31 11:00   ` [PATCH v2 05/14] eal/soc: init SoC infra from EAL Shreyansh Jain
@ 2016-08-31 11:00   ` Shreyansh Jain
  2016-08-31 11:00   ` [PATCH v2 07/14] eal/soc: extend and utilize devargs Shreyansh Jain
                     ` (7 subsequent siblings)
  13 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-08-31 11:00 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, Jan Viktorin, Hemant Agrawal

Each SoC PMD registers a set of callback for scanning its own bus/infra and
matching devices to drivers when probe is called.
This patch introduces the infra for calls to SoC scan on rte_eal_soc_init()
and match on rte_eal_soc_probe().

Patch also adds test case for scan and probe.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 app/test/test_soc.c                             | 138 ++++++++++++++++-
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   3 +
 lib/librte_eal/common/eal_common_soc.c          | 191 ++++++++++++++++++++++++
 lib/librte_eal/common/include/rte_soc.h         |  37 +++++
 lib/librte_eal/linuxapp/eal/eal.c               |   5 +
 lib/librte_eal/linuxapp/eal/eal_soc.c           |  16 ++
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   3 +
 7 files changed, 392 insertions(+), 1 deletion(-)

diff --git a/app/test/test_soc.c b/app/test/test_soc.c
index ac03e64..4eb8146 100644
--- a/app/test/test_soc.c
+++ b/app/test/test_soc.c
@@ -87,14 +87,45 @@ static int test_compare_addr(void)
  */
 struct test_wrapper {
 	struct rte_soc_driver soc_drv;
+	struct rte_soc_device soc_dev;
 };
 
+static int empty_pmd0_devinit(struct rte_soc_driver *drv,
+			      struct rte_soc_device *dev);
+static int empty_pmd0_devuninit(struct rte_soc_device *dev);
+static void test_soc_scan_dev0_cb(void);
+static int test_soc_match_dev0_cb(struct rte_soc_driver *drv,
+				  struct rte_soc_device *dev);
+static void test_soc_scan_dev1_cb(void);
+static int test_soc_match_dev1_cb(struct rte_soc_driver *drv,
+				  struct rte_soc_device *dev);
+
+static int
+empty_pmd0_devinit(struct rte_soc_driver *drv __rte_unused,
+		   struct rte_soc_device *dev __rte_unused)
+{
+	return 0;
+}
+
+static int
+empty_pmd0_devuninit(struct rte_soc_device *dev)
+{
+	/* Release the memory associated with dev->addr.name */
+	free(dev->addr.name);
+
+	return 0;
+}
+
 struct test_wrapper empty_pmd0 = {
 	.soc_drv = {
 		.driver = {
 			.name = "empty_pmd0"
 		},
-	},
+		.devinit = empty_pmd0_devinit,
+		.devuninit = empty_pmd0_devuninit,
+		.scan_fn = test_soc_scan_dev0_cb,
+		.match_fn = test_soc_match_dev0_cb,
+	}
 };
 
 struct test_wrapper empty_pmd1 = {
@@ -102,9 +133,54 @@ struct test_wrapper empty_pmd1 = {
 		.driver = {
 			.name = "empty_pmd1"
 		},
+		.scan_fn = test_soc_scan_dev1_cb,
+		.match_fn = test_soc_match_dev1_cb,
 	},
 };
 
+static void
+test_soc_scan_dev0_cb(void)
+{
+	/* SoC's scan would scan devices on its bus and add to
+	 * soc_device_list
+	 */
+	empty_pmd0.soc_dev.addr.name = strdup("empty_pmd0_dev");
+
+	TAILQ_INSERT_TAIL(&soc_device_list, &empty_pmd0.soc_dev, next);
+}
+
+static int
+test_soc_match_dev0_cb(struct rte_soc_driver *drv __rte_unused,
+		       struct rte_soc_device *dev)
+{
+	if (!dev->addr.name || strcmp(dev->addr.name, "empty_pmd0_dev"))
+		return 0;
+
+	return 1;
+}
+
+
+static void
+test_soc_scan_dev1_cb(void)
+{
+	/* SoC's scan would scan devices on its bus and add to
+	 * soc_device_list
+	 */
+	empty_pmd0.soc_dev.addr.name = strdup("empty_pmd1_dev");
+
+	TAILQ_INSERT_TAIL(&soc_device_list, &empty_pmd1.soc_dev, next);
+}
+
+static int
+test_soc_match_dev1_cb(struct rte_soc_driver *drv __rte_unused,
+		       struct rte_soc_device *dev)
+{
+	if (!dev->addr.name || strcmp(dev->addr.name, "empty_pmd1_dev"))
+		return 0;
+
+	return 1;
+}
+
 static int
 count_registered_socdrvs(void)
 {
@@ -148,13 +224,54 @@ test_register_unregister(void)
 	return 0;
 }
 
+/* Test Probe (scan and match) functionality */
+static int
+test_soc_init_and_probe(void)
+{
+	struct rte_soc_driver *drv;
+
+	/* Registering dummy drivers */
+	rte_eal_soc_register(&empty_pmd0.soc_drv);
+	rte_eal_soc_register(&empty_pmd1.soc_drv);
+	/* Assuming that test_register_unregister is working, not verifying
+	 * that drivers are indeed registered
+	*/
+
+	/* rte_eal_soc_init is called by rte_eal_init, which in turn calls the
+	 * scan_fn of each driver.
+	 */
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		if (drv && drv->scan_fn)
+			drv->scan_fn();
+	}
+
+	/* rte_eal_init() would perform other inits here */
+
+	/* Probe would link the SoC devices<=>drivers */
+	rte_eal_soc_probe();
+
+	/* Unregistering dummy drivers */
+	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
+	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
+
+	free(empty_pmd0.soc_dev.addr.name);
+
+	printf("%s has been successful\n", __func__);
+	return 0;
+}
+
 /* save real devices and drivers until the tests finishes */
 struct soc_driver_list real_soc_driver_list =
 	TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
 
+/* save real devices and drivers until the tests finishes */
+struct soc_device_list real_soc_device_list =
+	TAILQ_HEAD_INITIALIZER(real_soc_device_list);
+
 static int test_soc_setup(void)
 {
 	struct rte_soc_driver *drv;
+	struct rte_soc_device *dev;
 
 	/* no real drivers for the test */
 	while (!TAILQ_EMPTY(&soc_driver_list)) {
@@ -163,12 +280,20 @@ static int test_soc_setup(void)
 		TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
 	}
 
+	/* And, no real devices for the test */
+	while (!TAILQ_EMPTY(&soc_device_list)) {
+		dev = TAILQ_FIRST(&soc_device_list);
+		/* TODO: detach the device */
+		TAILQ_INSERT_TAIL(&real_soc_device_list, dev, next);
+	}
+
 	return 0;
 }
 
 static int test_soc_cleanup(void)
 {
 	struct rte_soc_driver *drv;
+	struct rte_soc_device *dev;
 
 	/* bring back real drivers after the test */
 	while (!TAILQ_EMPTY(&real_soc_driver_list)) {
@@ -177,6 +302,13 @@ static int test_soc_cleanup(void)
 		rte_eal_soc_register(drv);
 	}
 
+	/* And, bring back real devices after the test */
+	while (!TAILQ_EMPTY(&real_soc_device_list)) {
+		dev = TAILQ_FIRST(&real_soc_device_list);
+		TAILQ_REMOVE(&real_soc_device_list, dev, next);
+		/* TODO: Attach the device */
+	}
+
 	return 0;
 }
 
@@ -192,6 +324,10 @@ test_soc(void)
 	if (test_register_unregister())
 		return -1;
 
+	/* Assuming test_register_unregister has succeeded */
+	if (test_soc_init_and_probe())
+		return -1;
+
 	if (test_soc_cleanup())
 		return -1;
 
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index de38848..72b42d7 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -173,5 +173,8 @@ DPDK_16.11 {
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
 	rte_eal_soc_dump;
+	rte_eal_soc_detach;
+	rte_eal_soc_probe;
+	rte_eal_soc_probe_one;
 
 } DPDK_16.07;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 5dcddc5..4797dd9 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -36,6 +36,8 @@
 #include <sys/queue.h>
 
 #include <rte_log.h>
+#include <rte_common.h>
+#include <rte_soc.h>
 
 #include "eal_private.h"
 
@@ -45,6 +47,189 @@ struct soc_driver_list soc_driver_list =
 struct soc_device_list soc_device_list =
 	TAILQ_HEAD_INITIALIZER(soc_device_list);
 
+static int
+rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
+			     struct rte_soc_device *dev)
+{
+	int ret = 1;
+
+	ret = drv->match_fn(drv, dev);
+	if (!ret) {
+		RTE_LOG(DEBUG, EAL,
+			" match function failed, skipping\n");
+		return ret;
+	}
+
+	dev->driver = drv;
+	RTE_VERIFY(drv->devinit != NULL);
+	return drv->devinit(drv, dev);
+}
+
+static int
+soc_probe_all_drivers(struct rte_soc_device *dev)
+{
+	struct rte_soc_driver *dr = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dr, &soc_driver_list, next) {
+		rc = rte_eal_soc_probe_one_driver(dr, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+/* If the IDs match, call the devuninit() function of the driver. */
+static int
+rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
+		       struct rte_soc_device *dev)
+{
+	int ret;
+
+	if ((drv == NULL) || (dev == NULL))
+		return -EINVAL;
+
+	ret = drv->match_fn(drv, dev);
+	if (!ret) {
+		RTE_LOG(DEBUG, EAL,
+			" match function failed, skipping\n");
+		return ret;
+	}
+
+	RTE_LOG(DEBUG, EAL, "SoC device %s\n",
+		dev->addr.name);
+
+	RTE_LOG(DEBUG, EAL, "  remove driver: %s\n", drv->driver.name);
+
+	if (drv->devuninit && (drv->devuninit(dev) < 0))
+		return -1;	/* negative value is an error */
+
+	/* clear driver structure */
+	dev->driver = NULL;
+
+	return 0;
+}
+
+/*
+ * Call the devuninit() function of all registered drivers for the given
+ * device if their IDs match.
+ *
+ * @return
+ *       0 when successful
+ *      -1 if deinitialization fails
+ *       1 if no driver is found for this device.
+ */
+static int
+soc_detach_all_drivers(struct rte_soc_device *dev)
+{
+	struct rte_soc_driver *dr = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dr, &soc_driver_list, next) {
+		rc = rte_eal_soc_detach_dev(dr, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+/*
+ * Detach device specified by its SoC address.
+ */
+int
+rte_eal_soc_detach(const struct rte_soc_addr *addr)
+{
+	struct rte_soc_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		if (rte_eal_compare_soc_addr(&dev->addr, addr))
+			continue;
+
+		ret = soc_detach_all_drivers(dev);
+		if (ret < 0)
+			goto err_return;
+
+		TAILQ_REMOVE(&soc_device_list, dev, next);
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL, "Requested device %s cannot be used\n",
+		dev->addr.name);
+	return -1;
+}
+
+int
+rte_eal_soc_probe_one(const struct rte_soc_addr *addr)
+{
+	struct rte_soc_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	/* unlike pci, in case of soc, it the responsibility of the soc driver
+	 * to check during init whether device has been updated since last add.
+	 */
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		if (rte_eal_compare_soc_addr(&dev->addr, addr))
+			continue;
+
+		ret = soc_probe_all_drivers(dev);
+		if (ret < 0)
+			goto err_return;
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL,
+		"Requested device %s cannot be used\n", addr->name);
+	return -1;
+}
+
+/*
+ * Scan the SoC devices and call the devinit() function for all registered
+ * drivers that have a matching entry in its id_table for discovered devices.
+ */
+int
+rte_eal_soc_probe(void)
+{
+	struct rte_soc_device *dev = NULL;
+	int ret = 0;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		ret = soc_probe_all_drivers(dev);
+		if (ret < 0)
+			rte_exit(EXIT_FAILURE, "Requested device %s"
+				 " cannot be used\n", dev->addr.name);
+	}
+
+	return 0;
+}
+
 /* dump one device */
 static int
 soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
@@ -79,6 +264,12 @@ rte_eal_soc_dump(FILE *f)
 void
 rte_eal_soc_register(struct rte_soc_driver *driver)
 {
+	/* For a valid soc driver, match and scan function
+	 * should be provided.
+	 */
+	RTE_VERIFY(driver != NULL);
+	RTE_VERIFY(driver->match_fn != NULL);
+	RTE_VERIFY(driver->scan_fn != NULL);
 	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
 }
 
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index c6f98eb..cc17829 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -97,6 +97,16 @@ typedef int (soc_devinit_t)(struct rte_soc_driver *, struct rte_soc_device *);
 typedef int (soc_devuninit_t)(struct rte_soc_device *);
 
 /**
+ * SoC device scan callback, called from rte_eal_soc_init.
+ */
+typedef void (soc_scan_t)(void);
+
+/**
+ * Custom device<=>driver match callback for SoC
+ */
+typedef int (soc_match_t)(struct rte_soc_driver *, struct rte_soc_device *);
+
+/**
  * A structure describing a SoC driver.
  */
 struct rte_soc_driver {
@@ -104,6 +114,8 @@ struct rte_soc_driver {
 	struct rte_driver driver;          /**< Inherit core driver. */
 	soc_devinit_t *devinit;            /**< Device initialization */
 	soc_devuninit_t *devuninit;        /**< Device uninitialization */
+	soc_scan_t *scan_fn;               /**< Callback for scanning SoC bus*/
+	soc_match_t *match_fn;             /**< Callback to match dev<->drv */
 	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
 };
 
@@ -146,6 +158,31 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 }
 
 /**
+ * Probe SoC devices for registered drivers.
+ */
+int rte_eal_soc_probe(void);
+
+/**
+ * Probe the single SoC device.
+ */
+int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
+
+/**
+ * Close the single SoC device.
+ *
+ * Scan the SoC devices and find the SoC device specified by the SoC
+ * address, then call the devuninit() function for registered driver
+ * that has a matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The SoC address to close.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_eal_soc_detach(const struct rte_soc_addr *addr);
+
+/**
  * Dump discovered SoC devices.
  */
 void rte_eal_soc_dump(FILE *f);
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 15c8c3d..147b601 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -70,6 +70,7 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_common.h>
@@ -881,6 +882,10 @@ rte_eal_init(int argc, char **argv)
 	if (rte_eal_pci_probe())
 		rte_panic("Cannot probe PCI\n");
 
+	/* Probe & Initialize SoC devices */
+	if (rte_eal_soc_probe())
+		rte_panic("Cannot probe SoC\n");
+
 	rte_eal_mcfg_complete();
 
 	return fctret;
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index 04848b9..5f961c4 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -52,5 +52,21 @@
 int
 rte_eal_soc_init(void)
 {
+	struct rte_soc_driver *drv;
+
+	/* for debug purposes, SoC can be disabled */
+	if (internal_config.no_soc)
+		return 0;
+
+	/* For each registered driver, call their scan routine to perform any
+	 * custom scan for devices (for example, custom buses)
+	 */
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		if (drv && drv->scan_fn) {
+			drv->scan_fn();
+			/* Ignore all errors from this */
+		}
+	}
+
 	return 0;
 }
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index b9d1932..8092e62 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -179,5 +179,8 @@ DPDK_16.11 {
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
 	rte_eal_soc_dump;
+	rte_eal_soc_detach;
+	rte_eal_soc_probe;
+	rte_eal_soc_probe_one;
 
 } DPDK_16.07;
-- 
2.7.4

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

* [PATCH v2 07/14] eal/soc: extend and utilize devargs
  2016-08-31 11:00 ` [PATCH v2 00/14] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (5 preceding siblings ...)
  2016-08-31 11:00   ` [PATCH v2 06/14] eal/soc: implement probing of drivers Shreyansh Jain
@ 2016-08-31 11:00   ` Shreyansh Jain
  2016-08-31 11:00   ` [PATCH v2 08/14] eal/soc: add drv_flags Shreyansh Jain
                     ` (6 subsequent siblings)
  13 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-08-31 11:00 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, Jan Viktorin, Hemant Agrawal

It is assumed that SoC Devices provided on command line are prefixed with
"soc:". This patch adds parse and attach support for such devices.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/common/eal_common_dev.c      | 27 ++++++++++----
 lib/librte_eal/common/eal_common_devargs.c  | 17 +++++++++
 lib/librte_eal/common/eal_common_soc.c      | 55 ++++++++++++++++++++++++++---
 lib/librte_eal/common/include/rte_devargs.h |  8 +++++
 lib/librte_eal/common/include/rte_soc.h     | 24 +++++++++++++
 5 files changed, 119 insertions(+), 12 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index d1f0ad8..fbc4443 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -106,17 +106,23 @@ rte_eal_dev_init(void)
 
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
-	struct rte_pci_addr addr;
+	struct rte_soc_addr soc_addr;
+	struct rte_pci_addr pci_addr;
 
 	if (name == NULL || devargs == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
 		return -EINVAL;
 	}
 
-	if (eal_parse_pci_DomBDF(name, &addr) == 0) {
-		if (rte_eal_pci_probe_one(&addr) < 0)
+	memset(&soc_addr, 0, sizeof(soc_addr));
+	if (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+		if (rte_eal_soc_probe_one(&soc_addr) < 0) {
+			free(soc_addr.name);
+			goto err;
+		}
+	} else if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+		if (rte_eal_pci_probe_one(&pci_addr) < 0)
 			goto err;
-
 	} else {
 		if (rte_eal_vdev_init(name, devargs))
 			goto err;
@@ -131,15 +137,22 @@ err:
 
 int rte_eal_dev_detach(const char *name)
 {
-	struct rte_pci_addr addr;
+	struct rte_soc_addr soc_addr;
+	struct rte_pci_addr pci_addr;
 
 	if (name == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device provided.\n");
 		return -EINVAL;
 	}
 
-	if (eal_parse_pci_DomBDF(name, &addr) == 0) {
-		if (rte_eal_pci_detach(&addr) < 0)
+	memset(&soc_addr, 0, sizeof(soc_addr));
+	if (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+		if (rte_eal_soc_detach(&soc_addr) < 0) {
+			free(soc_addr.name);
+			goto err;
+		}
+	} else if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+		if (rte_eal_pci_detach(&pci_addr) < 0)
 			goto err;
 	} else {
 		if (rte_eal_vdev_uninit(name))
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index e403717..e1dae1a 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -41,6 +41,7 @@
 #include <string.h>
 
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_devargs.h>
 #include "eal_private.h"
 
@@ -105,6 +106,14 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
 			goto fail;
 
 		break;
+
+	case RTE_DEVTYPE_WHITELISTED_SOC:
+	case RTE_DEVTYPE_BLACKLISTED_SOC:
+		/* try to parse soc device with prefix "soc:" */
+		if (rte_eal_parse_soc_spec(buf, &devargs->soc.addr) != 0)
+			goto fail;
+		break;
+
 	case RTE_DEVTYPE_VIRTUAL:
 		/* save driver name */
 		ret = snprintf(devargs->virt.drv_name,
@@ -166,6 +175,14 @@ rte_eal_devargs_dump(FILE *f)
 			       devargs->pci.addr.devid,
 			       devargs->pci.addr.function,
 			       devargs->args);
+		else if (devargs->type == RTE_DEVTYPE_WHITELISTED_SOC)
+			fprintf(f, "  SoC whitelist %s %s\n",
+			       devargs->soc.addr.name,
+			       devargs->soc.addr.fdt_path);
+		else if (devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC)
+			fprintf(f, "  SoC blacklist %s %s\n",
+			       devargs->soc.addr.name,
+			       devargs->soc.addr.fdt_path);
 		else if (devargs->type == RTE_DEVTYPE_VIRTUAL)
 			fprintf(f, "  VIRTUAL %s %s\n",
 			       devargs->virt.drv_name,
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 4797dd9..efa722d 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -37,6 +37,8 @@
 
 #include <rte_log.h>
 #include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_eal.h>
 #include <rte_soc.h>
 
 #include "eal_private.h"
@@ -47,6 +49,21 @@ struct soc_driver_list soc_driver_list =
 struct soc_device_list soc_device_list =
 	TAILQ_HEAD_INITIALIZER(soc_device_list);
 
+static struct rte_devargs *soc_devargs_lookup(struct rte_soc_device *dev)
+{
+	struct rte_devargs *devargs;
+
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->type != RTE_DEVTYPE_BLACKLISTED_SOC &&
+			devargs->type != RTE_DEVTYPE_WHITELISTED_SOC)
+			continue;
+		if (!rte_eal_compare_soc_addr(&dev->addr, &devargs->soc.addr))
+			return devargs;
+	}
+
+	return NULL;
+}
+
 static int
 rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
 			     struct rte_soc_device *dev)
@@ -60,6 +77,18 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
 		return ret;
 	}
 
+	RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %d\n",
+			dev->addr.name, dev->device.numa_node);
+	RTE_LOG(DEBUG, EAL, "  probe driver %s\n", drv->driver.name);
+
+	/* no initialization when blacklisted, return without error */
+	if (dev->device.devargs != NULL
+		&& dev->device.devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC) {
+		RTE_LOG(DEBUG, EAL,
+			"  device is blacklisted, skipping\n");
+		return ret;
+	}
+
 	dev->driver = drv;
 	RTE_VERIFY(drv->devinit != NULL);
 	return drv->devinit(drv, dev);
@@ -104,8 +133,8 @@ rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
 		return ret;
 	}
 
-	RTE_LOG(DEBUG, EAL, "SoC device %s\n",
-		dev->addr.name);
+	RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %i\n",
+			dev->addr.name, dev->device.numa_node);
 
 	RTE_LOG(DEBUG, EAL, "  remove driver: %s\n", drv->driver.name);
 
@@ -218,13 +247,29 @@ int
 rte_eal_soc_probe(void)
 {
 	struct rte_soc_device *dev = NULL;
+	struct rte_devargs *devargs = NULL;
 	int ret = 0;
+	int probe_all = 0;
+
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_SOC) == 0)
+		probe_all = 1;
 
 	TAILQ_FOREACH(dev, &soc_device_list, next) {
-		ret = soc_probe_all_drivers(dev);
+
+		/* set devargs in SoC structure */
+		devargs = soc_devargs_lookup(dev);
+		if (devargs != NULL)
+			dev->device.devargs = devargs;
+
+		/* probe all or only whitelisted devices */
+		if (probe_all)
+			ret = soc_probe_all_drivers(dev);
+		else if (devargs != NULL &&
+			devargs->type == RTE_DEVTYPE_WHITELISTED_SOC)
+			ret = soc_probe_all_drivers(dev);
 		if (ret < 0)
-			rte_exit(EXIT_FAILURE, "Requested device %s"
-				 " cannot be used\n", dev->addr.name);
+			rte_exit(EXIT_FAILURE, "Requested device %s "
+				 "cannot be used\n", dev->addr.name);
 	}
 
 	return 0;
diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h
index 53c59f5..757320e 100644
--- a/lib/librte_eal/common/include/rte_devargs.h
+++ b/lib/librte_eal/common/include/rte_devargs.h
@@ -51,6 +51,7 @@ extern "C" {
 #include <stdio.h>
 #include <sys/queue.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 
 /**
  * Type of generic device
@@ -58,6 +59,8 @@ extern "C" {
 enum rte_devtype {
 	RTE_DEVTYPE_WHITELISTED_PCI,
 	RTE_DEVTYPE_BLACKLISTED_PCI,
+	RTE_DEVTYPE_WHITELISTED_SOC,
+	RTE_DEVTYPE_BLACKLISTED_SOC,
 	RTE_DEVTYPE_VIRTUAL,
 };
 
@@ -82,6 +85,11 @@ struct rte_devargs {
 			/** PCI location. */
 			struct rte_pci_addr addr;
 		} pci;
+		/** Used if type is RTE_DEVTYPE_*_SOC. */
+		struct {
+			/** SoC location. */
+			struct rte_soc_addr addr;
+		} soc;
 		/** Used if type is RTE_DEVTYPE_VIRTUAL. */
 		struct {
 			/** Driver name. */
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index cc17829..c45b37e 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -158,6 +158,30 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 }
 
 /**
+ * Parse a specification of a soc device. The specification must differentiate
+ * a SoC device specification from the PCI bus and virtual devices. We assume
+ * a SoC specification starts with "soc:". The function allocates the name
+ * entry of the given addr.
+ *
+ * @return
+ *      -  0 on success
+ *      -  1 when not a SoC spec
+ *      - -1 on failure
+ */
+static inline int
+rte_eal_parse_soc_spec(const char *spec, struct rte_soc_addr *addr)
+{
+	if (strstr(spec, "soc:") == spec) {
+		addr->name = strdup(spec + 4);
+		if (addr->name == NULL)
+			return -1;
+		return 0;
+	}
+
+	return 1;
+}
+
+/**
  * Probe SoC devices for registered drivers.
  */
 int rte_eal_soc_probe(void);
-- 
2.7.4

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

* [PATCH v2 08/14] eal/soc: add drv_flags
  2016-08-31 11:00 ` [PATCH v2 00/14] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (6 preceding siblings ...)
  2016-08-31 11:00   ` [PATCH v2 07/14] eal/soc: extend and utilize devargs Shreyansh Jain
@ 2016-08-31 11:00   ` Shreyansh Jain
  2016-08-31 11:00   ` [PATCH v2 09/14] eal/soc: add intr_handle Shreyansh Jain
                     ` (5 subsequent siblings)
  13 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-08-31 11:00 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, Jan Viktorin, Hemant Agrawal

The flags are copied from the PCI ones. They should be refactorized into a
general set of flags in the future.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/common/include/rte_soc.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index c45b37e..d453398 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -117,8 +117,18 @@ struct rte_soc_driver {
 	soc_scan_t *scan_fn;               /**< Callback for scanning SoC bus*/
 	soc_match_t *match_fn;             /**< Callback to match dev<->drv */
 	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
+	uint32_t drv_flags;                /**< Control handling of device */
 };
 
+/** Device needs to map its resources by EAL */
+#define RTE_SOC_DRV_NEED_MAPPING 0x0001
+/** Device needs to be unbound even if no module is provieded */
+#define RTE_SOC_DRV_FORCE_UNBIND 0x0004
+/** Device driver supports link state interrupt */
+#define RTE_SOC_DRV_INTR_LSC	 0x0008
+/** Device driver supports detaching capability */
+#define RTE_SOC_DRV_DETACHABLE	 0x0010
+
 /**
  * Utility function to write a SoC device name, this device name can later be
  * used to retrieve the corresponding rte_soc_addr using above functions.
-- 
2.7.4

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

* [PATCH v2 09/14] eal/soc: add intr_handle
  2016-08-31 11:00 ` [PATCH v2 00/14] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (7 preceding siblings ...)
  2016-08-31 11:00   ` [PATCH v2 08/14] eal/soc: add drv_flags Shreyansh Jain
@ 2016-08-31 11:00   ` Shreyansh Jain
  2016-08-31 11:00   ` [PATCH v2 10/14] ether: utilize container_of for pci_drv Shreyansh Jain
                     ` (4 subsequent siblings)
  13 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-08-31 11:00 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, Jan Viktorin, Hemant Agrawal

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/common/include/rte_soc.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index d453398..bd496ed 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -53,6 +53,7 @@ extern "C" {
 #include <rte_dev.h>
 #include <rte_eal.h>
 #include <rte_debug.h>
+#include <rte_interrupts.h>
 
 extern struct soc_driver_list soc_driver_list;
 /**< Global list of SoC Drivers */
@@ -81,6 +82,7 @@ struct rte_soc_device {
 	struct rte_device device;           /**< Inherit code device */
 	struct rte_soc_addr addr;           /**< SoC device Location */
 	struct rte_soc_id *id;              /**< SoC device ID list */
+	struct rte_intr_handle intr_handle; /**< Interrupt handle */
 	struct rte_soc_driver *driver;      /**< Associated driver */
 };
 
-- 
2.7.4

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

* [PATCH v2 10/14] ether: utilize container_of for pci_drv
  2016-08-31 11:00 ` [PATCH v2 00/14] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (8 preceding siblings ...)
  2016-08-31 11:00   ` [PATCH v2 09/14] eal/soc: add intr_handle Shreyansh Jain
@ 2016-08-31 11:00   ` Shreyansh Jain
  2016-08-31 11:00   ` [PATCH v2 11/14] ether: verify we copy info from a PCI device Shreyansh Jain
                     ` (3 subsequent siblings)
  13 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-08-31 11:00 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, Jan Viktorin, Hemant Agrawal

It is not necessary to place the rte_pci_driver at the beginning
of the rte_eth_dev struct anymore as we use the container_of macro
to get the parent pointer.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 4 ++--
 lib/librte_ether/rte_ethdev.h | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index d54ec9e..b10d985 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -242,7 +242,7 @@ rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
 
 	int diag;
 
-	eth_drv = (struct eth_driver *)pci_drv;
+	eth_drv = container_of(pci_drv, struct eth_driver, pci_drv);
 
 	rte_eal_pci_device_name(&pci_dev->addr, ethdev_name,
 			sizeof(ethdev_name));
@@ -303,7 +303,7 @@ rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
 	if (eth_dev == NULL)
 		return -ENODEV;
 
-	eth_drv = (const struct eth_driver *)pci_dev->driver;
+	eth_drv = container_of(pci_dev->driver, struct eth_driver, pci_drv);
 
 	/* Invoke PMD device uninit function */
 	if (*eth_drv->eth_dev_uninit) {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 2a697ec..8320dc4 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1842,7 +1842,7 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *eth_dev);
  * Each Ethernet driver acts as a PCI driver and is represented by a generic
  * *eth_driver* structure that holds:
  *
- * - An *rte_pci_driver* structure (which must be the first field).
+ * - An *rte_pci_driver* structure.
  *
  * - The *eth_dev_init* function invoked for each matching PCI device.
  *
-- 
2.7.4

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

* [PATCH v2 11/14] ether: verify we copy info from a PCI device
  2016-08-31 11:00 ` [PATCH v2 00/14] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (9 preceding siblings ...)
  2016-08-31 11:00   ` [PATCH v2 10/14] ether: utilize container_of for pci_drv Shreyansh Jain
@ 2016-08-31 11:00   ` Shreyansh Jain
  2016-08-31 11:00   ` [PATCH v2 12/14] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
                     ` (2 subsequent siblings)
  13 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-08-31 11:00 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, Jan Viktorin, Hemant Agrawal

Now that different types of ethdev exist, check for presence of PCI dev
while copying out the info.
Similar would be done for SoC.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index b10d985..e9f5467 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3200,6 +3200,8 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_de
 		return;
 	}
 
+	RTE_VERIFY(eth_dev->pci_dev != NULL);
+
 	eth_dev->data->dev_flags = 0;
 	if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC)
 		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
-- 
2.7.4

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

* [PATCH v2 12/14] ether: extract function eth_dev_get_intr_handle
  2016-08-31 11:00 ` [PATCH v2 00/14] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (10 preceding siblings ...)
  2016-08-31 11:00   ` [PATCH v2 11/14] ether: verify we copy info from a PCI device Shreyansh Jain
@ 2016-08-31 11:00   ` Shreyansh Jain
  2016-08-31 11:00   ` [PATCH v2 13/14] ether: extract function eth_dev_get_driver_name Shreyansh Jain
  2016-08-31 11:00   ` [PATCH v2 14/14] ether: Support rte_soc_driver/device for etherdev Shreyansh Jain
  13 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-08-31 11:00 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, Jan Viktorin, Hemant Agrawal

We abstract access to the intr_handle here as we want to get
it either from the pci_dev or soc_dev.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index e9f5467..104ea4a 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2526,6 +2526,17 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
 	rte_spinlock_unlock(&rte_eth_dev_cb_lock);
 }
 
+static inline
+struct rte_intr_handle *eth_dev_get_intr_handle(struct rte_eth_dev *dev)
+{
+	if (dev->pci_dev) {
+		return &dev->pci_dev->intr_handle;
+	}
+
+	RTE_VERIFY(0);
+	return NULL;
+}
+
 int
 rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 {
@@ -2538,7 +2549,7 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
-	intr_handle = &dev->pci_dev->intr_handle;
+	intr_handle = eth_dev_get_intr_handle(dev);
 	if (!intr_handle->intr_vec) {
 		RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
 		return -EPERM;
@@ -2598,7 +2609,7 @@ rte_eth_dev_rx_intr_ctl_q(uint8_t port_id, uint16_t queue_id,
 		return -EINVAL;
 	}
 
-	intr_handle = &dev->pci_dev->intr_handle;
+	intr_handle = eth_dev_get_intr_handle(dev);
 	if (!intr_handle->intr_vec) {
 		RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
 		return -EPERM;
-- 
2.7.4

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

* [PATCH v2 13/14] ether: extract function eth_dev_get_driver_name
  2016-08-31 11:00 ` [PATCH v2 00/14] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (11 preceding siblings ...)
  2016-08-31 11:00   ` [PATCH v2 12/14] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
@ 2016-08-31 11:00   ` Shreyansh Jain
  2016-08-31 11:00   ` [PATCH v2 14/14] ether: Support rte_soc_driver/device for etherdev Shreyansh Jain
  13 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-08-31 11:00 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, Jan Viktorin, Hemant Agrawal

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 104ea4a..4fa65ca 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2568,6 +2568,17 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 	return 0;
 }
 
+static inline
+const char *eth_dev_get_driver_name(const struct rte_eth_dev *dev)
+{
+	if (dev->pci_dev) {
+		return dev->driver->pci_drv.driver.name;
+	}
+
+	RTE_VERIFY(0);
+	return NULL;
+}
+
 const struct rte_memzone *
 rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 			 uint16_t queue_id, size_t size, unsigned align,
@@ -2575,9 +2586,11 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 {
 	char z_name[RTE_MEMZONE_NAMESIZE];
 	const struct rte_memzone *mz;
+	const char *drv_name;
 
+	drv_name = eth_dev_get_driver_name(dev);
 	snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
-		 dev->driver->pci_drv.driver.name, ring_name,
+		 drv_name, ring_name,
 		 dev->data->port_id, queue_id);
 
 	mz = rte_memzone_lookup(z_name);
-- 
2.7.4

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

* [PATCH v2 14/14] ether: Support rte_soc_driver/device for etherdev
  2016-08-31 11:00 ` [PATCH v2 00/14] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (12 preceding siblings ...)
  2016-08-31 11:00   ` [PATCH v2 13/14] ether: extract function eth_dev_get_driver_name Shreyansh Jain
@ 2016-08-31 11:00   ` Shreyansh Jain
  13 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-08-31 11:00 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, Jan Viktorin, Hemant Agrawal

- eth_driver/rte_eth_dev embeds rte_soc_driver/device for relating SoC
  PMDs to ethernet devices.
- Add probe and remove functions linked to eth_dev_init/uninit

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 129 ++++++++++++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h |  31 ++++++++++
 2 files changed, 160 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 4fa65ca..b57d7b2 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -326,6 +326,101 @@ rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
 }
 
 int
+rte_eth_dev_soc_probe(struct rte_soc_driver *soc_drv,
+		      struct rte_soc_device *soc_dev)
+{
+	struct eth_driver    *eth_drv;
+	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
+	int diag;
+
+	eth_drv = container_of(soc_drv, struct eth_driver, soc_drv);
+
+	rte_eal_soc_device_name(&soc_dev->addr, ethdev_name,
+			sizeof(ethdev_name));
+
+	eth_dev = rte_eth_dev_allocate(ethdev_name);
+	if (eth_dev == NULL)
+		return -ENOMEM;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		eth_dev->data->dev_private = rte_zmalloc(
+				  "ethdev private structure",
+				  eth_drv->dev_private_size,
+				  RTE_CACHE_LINE_SIZE);
+		if (eth_dev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private port "
+				  "data\n");
+	}
+	eth_dev->soc_dev = soc_dev;
+	eth_dev->driver = eth_drv;
+	eth_dev->data->rx_mbuf_alloc_failed = 0;
+
+	/* init user callbacks */
+	TAILQ_INIT(&(eth_dev->link_intr_cbs));
+
+	/*
+	 * Set the default MTU.
+	 */
+	eth_dev->data->mtu = ETHER_MTU;
+
+	/* Invoke PMD device initialization function */
+	diag = (*eth_drv->eth_dev_init)(eth_dev);
+	if (diag == 0)
+		return 0;
+
+	RTE_PMD_DEBUG_TRACE("driver %s: eth_dev_init(%s) failed\n",
+			soc_drv->driver.name,
+			soc_dev->addr.name);
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(eth_dev->data->dev_private);
+	rte_eth_dev_release_port(eth_dev);
+	return diag;
+}
+
+int
+rte_eth_dev_soc_remove(struct rte_soc_device *soc_dev)
+{
+	const struct eth_driver *eth_drv;
+	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+	int ret;
+
+	if (soc_dev == NULL)
+		return -EINVAL;
+
+	rte_eal_soc_device_name(&soc_dev->addr, ethdev_name,
+			sizeof(ethdev_name));
+
+	eth_dev = rte_eth_dev_allocated(ethdev_name);
+	if (eth_dev == NULL)
+		return -ENODEV;
+
+	eth_drv = container_of(soc_dev->driver, struct eth_driver, soc_drv);
+
+	/* Invoke PMD device uninit function */
+	if (*eth_drv->eth_dev_uninit) {
+		ret = (*eth_drv->eth_dev_uninit)(eth_dev);
+		if (ret)
+			return ret;
+	}
+
+	/* free ether device */
+	rte_eth_dev_release_port(eth_dev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(eth_dev->data->dev_private);
+
+	eth_dev->soc_dev = NULL;
+	eth_dev->driver = NULL;
+	eth_dev->data = NULL;
+
+	return 0;
+}
+
+
+int
 rte_eth_dev_is_valid_port(uint8_t port_id)
 {
 	if (port_id >= RTE_MAX_ETHPORTS ||
@@ -1555,6 +1650,7 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
 	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
 	dev_info->pci_dev = dev->pci_dev;
+	dev_info->soc_dev = dev->soc_dev;
 	dev_info->driver_name = dev->data->drv_name;
 	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
 	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
@@ -2530,8 +2626,13 @@ static inline
 struct rte_intr_handle *eth_dev_get_intr_handle(struct rte_eth_dev *dev)
 {
 	if (dev->pci_dev) {
+		RTE_VERIFY(dev->soc_dev == NULL);
 		return &dev->pci_dev->intr_handle;
 	}
+	if (dev->soc_dev) {
+		RTE_VERIFY(dev->pci_dev == NULL);
+		return &dev->soc_dev->intr_handle;
+	}
 
 	RTE_VERIFY(0);
 	return NULL;
@@ -2572,9 +2673,15 @@ static inline
 const char *eth_dev_get_driver_name(const struct rte_eth_dev *dev)
 {
 	if (dev->pci_dev) {
+		RTE_VERIFY(dev->soc_dev == NULL);
 		return dev->driver->pci_drv.driver.name;
 	}
 
+	if (dev->soc_dev) {
+		RTE_VERIFY(dev->pci_dev == NULL);
+		return dev->driver->soc_drv.driver.name;
+	}
+
 	RTE_VERIFY(0);
 	return NULL;
 }
@@ -3237,6 +3344,28 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_de
 	eth_dev->data->drv_name = pci_dev->driver->driver.name;
 }
 
+void
+rte_eth_copy_soc_info(struct rte_eth_dev *eth_dev,
+		      struct rte_soc_device *soc_dev)
+{
+	if ((eth_dev == NULL) || (soc_dev == NULL)) {
+		RTE_PMD_DEBUG_TRACE("NULL pointer eth_dev=%p soc_dev=%p\n",
+				eth_dev, soc_dev);
+		return;
+	}
+
+	RTE_VERIFY(eth_dev->soc_dev != NULL);
+
+	eth_dev->data->dev_flags = 0;
+	if (soc_dev->driver->drv_flags & RTE_SOC_DRV_INTR_LSC)
+		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
+	if (soc_dev->driver->drv_flags & RTE_SOC_DRV_DETACHABLE)
+		eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
+
+	eth_dev->data->numa_node = soc_dev->device.numa_node;
+	eth_dev->data->drv_name = soc_dev->driver->driver.name;
+}
+
 int
 rte_eth_dev_l2_tunnel_eth_type_conf(uint8_t port_id,
 				    struct rte_eth_l2_tunnel_conf *l2_tunnel)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 8320dc4..4ae22e9 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -180,6 +180,7 @@ extern "C" {
 #include <rte_log.h>
 #include <rte_interrupts.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include "rte_ether.h"
@@ -870,6 +871,7 @@ struct rte_eth_conf {
  */
 struct rte_eth_dev_info {
 	struct rte_pci_device *pci_dev; /**< Device PCI information. */
+	struct rte_soc_device *soc_dev; /**< Device SoC information. */
 	const char *driver_name; /**< Device Driver name. */
 	unsigned int if_index; /**< Index to bound host interface, or 0 if none.
 		Use if_indextoname() to translate into an interface name. */
@@ -1619,6 +1621,7 @@ struct rte_eth_dev {
 	const struct eth_driver *driver;/**< Driver for this device */
 	const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
 	struct rte_pci_device *pci_dev; /**< PCI info. supplied by probing */
+	struct rte_soc_device *soc_dev; /**< SoC info. supplied by probing */
 	/** User application callbacks for NIC interrupts */
 	struct rte_eth_dev_cb_list link_intr_cbs;
 	/**
@@ -1852,6 +1855,7 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *eth_dev);
  */
 struct eth_driver {
 	struct rte_pci_driver pci_drv;    /**< The PMD is also a PCI driver. */
+	struct rte_soc_driver soc_drv;    /**< The PMD is also a SoC driver. */
 	eth_dev_init_t eth_dev_init;      /**< Device init function. */
 	eth_dev_uninit_t eth_dev_uninit;  /**< Device uninit function. */
 	unsigned int dev_private_size;    /**< Size of device private data. */
@@ -4244,6 +4248,20 @@ void rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev,
 		struct rte_pci_device *pci_dev);
 
 /**
+ * Copy SoC device info to the Ethernet device data.
+ *
+ * @param eth_dev
+ * The *eth_dev* pointer is the address of the *rte_eth_dev* structure.
+ * @param soc_dev
+ * The *soc_dev* pointer is the address of the *rte_soc_device* structure.
+ *
+ * @return
+ *   - 0 on success, negative on error
+ */
+void rte_eth_copy_soc_info(struct rte_eth_dev *eth_dev,
+		struct rte_soc_device *soc_dev);
+
+/**
  * Create memzone for HW rings.
  * malloc can't be used as the physical address is needed.
  * If the memzone is already created, then this function returns a ptr
@@ -4356,6 +4374,19 @@ int rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
  */
 int rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev);
 
+/**
+ * Wrapper for use by SoC drivers as a .devinit function to attach to a ethdev
+ * interface.
+ */
+int rte_eth_dev_soc_probe(struct rte_soc_driver *soc_drv,
+			  struct rte_soc_device *soc_dev);
+
+/**
+ * Wrapper for use by SoC drivers as a .devuninit function to detach a ethdev
+ * interface.
+ */
+int rte_eth_dev_soc_remove(struct rte_soc_device *soc_dev);
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.7.4

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

* [PATCH v3 00/15] Introduce SoC device/driver framework for EAL
  2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
                   ` (36 preceding siblings ...)
  2016-08-31 11:00 ` [PATCH v2 00/14] Introduce SoC device/driver framework for EAL Shreyansh Jain
@ 2016-09-09  8:43 ` Shreyansh Jain
  2016-09-09  8:43   ` [PATCH v3 01/15] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
                     ` (17 more replies)
  37 siblings, 18 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-09  8:43 UTC (permalink / raw)
  To: dev; +Cc: viktorin, hemant.agrawal, Shreyansh Jain

Introduction:
=============

This patch set is direct derivative of Jan's original series [1],[2].

 - As this deviates substantially from original series, if need be I can 
   post it as a separate patch rather than v2. Please suggest.
 - Also, there are comments on original v1 ([4]) which are _not_
   incorporated in this series as they refer to section no more in new
   version.
 - This v3 version is based on the rte_driver/device patchset v9 [10].
   That series introduced device structures (rte_driver/rte_device)
   generalizing devices into PCI, VDEV, XXX. For the purpose of this
   patchset, XXX=>SOC.

Aim:
====

As of now EAL is primarly focused on PCI initialization/probing.
 
 rte_eal_init()
  |- rte_eal_pci_init(): Find PCI devices from sysfs
  |- ...
  |- rte_eal_memzone_init()
  |- ...
  `- rte_eal_pci_probe(): Driver<=>Device initialization

This patchset introduces SoC framework which would enable SoC drivers and
drivers to be plugged into EAL, very similar to how PCI drivers/devices are
done today.

This is a stripped down version of PCI framework which allows the SoC PMDs
to implement their own routines for detecting devices and linking devices to
drivers.

1) Changes to EAL 
 rte_eal_init()
  |- rte_eal_pci_init(): Find PCI devices from sysfs
  |- rte_eal_soc_init(): Calls PMDs->scan_fn
  |- ...
  |- rte_eal_memzone_init()
  |- ...
  |- rte_eal_pci_probe(): Driver<=>Device initialization, PMD->devinit()
  `- rte_eal_soc_probe(): Calls PMDs->match_fn and PMDs->devinit();

2) New device/driver structures:
  - rte_soc_driver (inheriting rte_driver)
  - rte_soc_device (inheriting rte_device)
  - rte_eth_dev and eth_driver embedded rte_soc_device and rte_soc_driver,
    respectively.

3) The SoC PMDs need to:
 - define rte_soc_driver with necessary scan and match callbacks
 - Register themselves using DRIVER_REGISTER_SOC()
 - Implement respective bus scanning in the scan callbacks to add necessary
   devices to SoC device list
 - Implement necessary eth_dev_init/uninint for ethernet instances

4) Design considerations that are same as PCI:
 - SoC initialization is being done through rte_eal_init(), just after PCI 
   initialization is done.
 - As in case of PCI, probe is done after rte_eal_pci_probe() to link the 
   devices detected with the drivers registered.
 - Device attach/detach functions are available and have been designed on 
   the lines of PCI framework.
 - PMDs register using DRIVER_REGISTER_SOC, very similar to 
   DRIVER_REGISTER_PCI for PCI devices.
 - Linked list of SoC driver and devices exists independent of the other 
   driver/device list, but inheriting rte_driver/rte_driver, these are also 
   part of a global list.

5) Design considerations that are different from PCI:
 - Each driver implements its own scan and match function. PCI uses the BDF 
   format to read the device from sysfs, but this _may_not_ be a case for a 
   SoC ethernet device.
   = This is an important change from initial proposal by Jan in [2]. Unlike 
   his attempt to use /sys/bus/platform, this patch relies on the PMD to
   detect the devices. This is because SoC may require specific or
   additional info for device detection. Further, SoC may have embedded
   devices/MACs which require initialization which cannot be covered through
   sysfs parsing.
   = PCI based PMDs rely on EAL's capability to detect devices. This 
   proposal puts the onus on PMD to detect devices, add to soc_device_list 
   and wait for Probe. Matching, of device<=>driver is again PMD's callback.

Patchset Overview:
==================
 - Patches 0001~0003 introduce the base infrastructure and test case
 - Patch 0004 is for command line support for no-soc, on lines of no-pci
 - Patch 0005 enables EAL to handle SoC type devices
 - Patch 0006 adds support for scan and probe callbacks and updates the test
   framework with relevant test case.
 - Patch 0007~0009 enable device argument, driver specific flags and
   interrupt handling related basic infra. Subsequent patches build up on
   them.
 - Patch 0010~0013 makes changes to PCI as well as ethdev code to remove 
   assumption that eth_driver is a PCI driver.
 - Patch 0014 adds necessary ethdev probe/remove functions for PMDs to use
 - Patch 0015 adds support for SoC driver/devices, along with probe/remove
   functions for Cryptodev devices.

Future/Pending Changes:
=======================
- Device whitelisting/blacklist still relies on command line '-b' and '-c'
  which are internally implemented using OPT_PCI_BLACKLIST/OPT_PCI_WHITELIST.
  This needs to be changed to a generic form - OPT_DEV_*LIST - probably.
- No cryptodriver currently uses SoC framework - probably a example driver
  can be created to demonstrate usage.

 [1] http://dpdk.org/ml/archives/dev/2016-January/030915.html
 [2] http://www.dpdk.org/ml/archives/dev/2016-May/038486.html
 [3] http://dpdk.org/ml/archives/dev/2016-August/045707.html
 [4] http://dpdk.org/ml/archives/dev/2016-May/038948.html
 [5] http://dpdk.org/ml/archives/dev/2016-May/038953.html
 [6] http://dpdk.org/ml/archives/dev/2016-May/038487.html
 [7] http://dpdk.org/ml/archives/dev/2016-May/038488.html
 [8] http://dpdk.org/ml/archives/dev/2016-May/038489.html
 [9] http://dpdk.org/ml/archives/dev/2016-May/038491.html
[10] http://dpdk.org/ml/archives/dev/2016-September/046256.html

Changes since v2:
 - Rebasing over rte_driver/device patchset v9 [10]
 - Added cryptodev support for SoC
 - Default match function for SoC device<=>Driver
 - Some variables renamed to reflect 'drv' rather than 'dr'

Change since v1 [2]:
 - Removed patch 1-5 which were for generalizing some PCI specific routines
   into EAL. These patches are good-to-have but not directly linked to SoC
   and hence would be proposed separately.
 - Removed support for sysfs parsing (patches 6~9)
 - Rebasing over the recent (v8) version of rte_driver/device patchset
 - Rebasing over master (16.07)
 - Changes to various map file to change API intro to 16.11 from 16.07

Shreyansh Jain (15):
  eal/soc: introduce very essential SoC infra definitions
  eal/soc: add rte_eal_soc_register/unregister logic
  eal/soc: Implement SoC device list and dump
  eal: introduce --no-soc option
  eal/soc: init SoC infra from EAL
  eal/soc: implement probing of drivers
  eal/soc: extend and utilize devargs
  eal/soc: add drv_flags
  eal/soc: add intr_handle
  ether: utilize container_of for pci_drv
  ether: verify we copy info from a PCI device
  ether: extract function eth_dev_get_intr_handle
  ether: extract function eth_dev_get_driver_name
  ether: Support rte_soc_driver/device for etherdev
  eal/crypto: Support rte_soc_driver/device for cryptodev

 app/test/Makefile                               |   1 +
 app/test/test_soc.c                             | 337 +++++++++++++++++++++++
 lib/librte_cryptodev/rte_cryptodev.c            | 122 ++++++++-
 lib/librte_cryptodev/rte_cryptodev.h            |   3 +
 lib/librte_cryptodev/rte_cryptodev_pmd.h        |  18 +-
 lib/librte_cryptodev/rte_cryptodev_version.map  |   3 +
 lib/librte_eal/bsdapp/eal/Makefile              |   1 +
 lib/librte_eal/bsdapp/eal/eal.c                 |   4 +
 lib/librte_eal/bsdapp/eal/eal_soc.c             |  46 ++++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  10 +
 lib/librte_eal/common/Makefile                  |   2 +-
 lib/librte_eal/common/eal_common_dev.c          |  27 +-
 lib/librte_eal/common/eal_common_devargs.c      |  17 ++
 lib/librte_eal/common/eal_common_options.c      |   5 +
 lib/librte_eal/common/eal_common_soc.c          | 350 ++++++++++++++++++++++++
 lib/librte_eal/common/eal_internal_cfg.h        |   1 +
 lib/librte_eal/common/eal_options.h             |   2 +
 lib/librte_eal/common/eal_private.h             |  14 +
 lib/librte_eal/common/include/rte_devargs.h     |   8 +
 lib/librte_eal/common/include/rte_soc.h         | 260 ++++++++++++++++++
 lib/librte_eal/linuxapp/eal/Makefile            |   2 +
 lib/librte_eal/linuxapp/eal/eal.c               |   8 +
 lib/librte_eal/linuxapp/eal/eal_soc.c           |  72 +++++
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   9 +
 lib/librte_ether/rte_ethdev.c                   | 165 ++++++++++-
 lib/librte_ether/rte_ethdev.h                   |  33 ++-
 26 files changed, 1501 insertions(+), 19 deletions(-)
 create mode 100644 app/test/test_soc.c
 create mode 100644 lib/librte_eal/bsdapp/eal/eal_soc.c
 create mode 100644 lib/librte_eal/common/eal_common_soc.c
 create mode 100644 lib/librte_eal/common/include/rte_soc.h
 create mode 100644 lib/librte_eal/linuxapp/eal/eal_soc.c

-- 
2.7.4

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

* [PATCH v3 01/15] eal/soc: introduce very essential SoC infra definitions
  2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
@ 2016-09-09  8:43   ` Shreyansh Jain
  2016-09-15 12:58     ` Hunt, David
  2016-09-09  8:43   ` [PATCH v3 02/15] eal/soc: add rte_eal_soc_register/unregister logic Shreyansh Jain
                     ` (16 subsequent siblings)
  17 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-09  8:43 UTC (permalink / raw)
  To: dev; +Cc: viktorin, hemant.agrawal, Shreyansh Jain

Define initial structures and functions for the SoC infrastructure.
This patch supports only a very minimal functions for now.
More features will be added in the following commits.

Includes rte_device/rte_driver inheritance of
rte_soc_device/rte_soc_driver.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 app/test/Makefile                       |   1 +
 app/test/test_soc.c                     |  90 +++++++++++++++++++++
 lib/librte_eal/common/Makefile          |   2 +-
 lib/librte_eal/common/eal_private.h     |   4 +
 lib/librte_eal/common/include/rte_soc.h | 138 ++++++++++++++++++++++++++++++++
 5 files changed, 234 insertions(+), 1 deletion(-)
 create mode 100644 app/test/test_soc.c
 create mode 100644 lib/librte_eal/common/include/rte_soc.h

diff --git a/app/test/Makefile b/app/test/Makefile
index 611d77a..64b261d 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -77,6 +77,7 @@ APP = test
 #
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) := commands.c
 SRCS-y += test.c
+SRCS-y += test_soc.c
 SRCS-y += resource.c
 SRCS-y += test_resource.c
 test_resource.res: test_resource.c
diff --git a/app/test/test_soc.c b/app/test/test_soc.c
new file mode 100644
index 0000000..916a863
--- /dev/null
+++ b/app/test/test_soc.c
@@ -0,0 +1,90 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <sys/queue.h>
+
+#include <rte_soc.h>
+#include <rte_devargs.h>
+#include <rte_debug.h>
+
+#include "test.h"
+
+static char *safe_strdup(const char *s)
+{
+	char *c = strdup(s);
+
+	if (c == NULL)
+		rte_panic("failed to strdup '%s'\n", s);
+
+	return c;
+}
+
+static int test_compare_addr(void)
+{
+	struct rte_soc_addr a0;
+	struct rte_soc_addr a1;
+	struct rte_soc_addr a2;
+
+	a0.name = safe_strdup("ethernet0");
+	a0.fdt_path = NULL;
+
+	a1.name = safe_strdup("ethernet0");
+	a1.fdt_path = NULL;
+
+	a2.name = safe_strdup("ethernet1");
+	a2.fdt_path = NULL;
+
+	TEST_ASSERT(!rte_eal_compare_soc_addr(&a0, &a1),
+		    "Failed to compare two soc addresses that equal");
+	TEST_ASSERT(rte_eal_compare_soc_addr(&a0, &a2),
+		    "Failed to compare two soc addresses that differs");
+
+	free(a2.name);
+	free(a1.name);
+	free(a0.name);
+	return 0;
+}
+
+static int
+test_soc(void)
+{
+	if (test_compare_addr())
+		return -1;
+
+	return 0;
+}
+
+REGISTER_TEST_COMMAND(soc_autotest, test_soc);
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index dfd64aa..b414008 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 INC := rte_branch_prediction.h rte_common.h
 INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
-INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
+INC += rte_log.h rte_memory.h rte_memzone.h rte_soc.h rte_pci.h
 INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 431d6c2..df6582d 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -36,6 +36,7 @@
 
 #include <stdio.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 
 /**
  * Initialize the memzone subsystem (private to eal).
@@ -126,6 +127,9 @@ int rte_eal_log_init(const char *id, int facility);
  */
 int rte_eal_pci_init(void);
 
+struct rte_soc_driver;
+struct rte_soc_device;
+
 struct rte_pci_driver;
 struct rte_pci_device;
 
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
new file mode 100644
index 0000000..bc0a43b
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -0,0 +1,138 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_SOC_H_
+#define _RTE_SOC_H_
+
+/**
+ * @file
+ *
+ * RTE SoC Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include <rte_dev.h>
+#include <rte_debug.h>
+
+struct rte_soc_id {
+	const char *compatible; /**< OF compatible specification */
+	uint64_t priv_data;     /**< SoC Driver specific data */
+};
+
+struct rte_soc_addr {
+	char *name;     /**< name used in sysfs */
+	char *fdt_path; /**< path to the associated node in FDT */
+};
+
+/**
+ * A structure describing a SoC device.
+ */
+struct rte_soc_device {
+	TAILQ_ENTRY(rte_soc_device) next;   /**< Next probed SoC device */
+	struct rte_device device;           /**< Inherit code device */
+	struct rte_soc_addr addr;           /**< SoC device Location */
+	struct rte_soc_id *id;              /**< SoC device ID list */
+	struct rte_soc_driver *driver;      /**< Associated driver */
+};
+
+struct rte_soc_driver;
+
+/**
+ * Initialization function for the driver called during SoC probing.
+ */
+typedef int (soc_devinit_t)(struct rte_soc_driver *, struct rte_soc_device *);
+
+/**
+ * Uninitialization function for the driver called during hotplugging.
+ */
+typedef int (soc_devuninit_t)(struct rte_soc_device *);
+
+/**
+ * A structure describing a SoC driver.
+ */
+struct rte_soc_driver {
+	TAILQ_ENTRY(rte_soc_driver) next;  /**< Next in list */
+	struct rte_driver driver;          /**< Inherit core driver. */
+	soc_devinit_t *devinit;            /**< Device initialization */
+	soc_devuninit_t *devuninit;        /**< Device uninitialization */
+	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
+};
+
+/**
+ * Utility function to write a SoC device name, this device name can later be
+ * used to retrieve the corresponding rte_soc_addr using above functions.
+ *
+ * @param addr
+ *	The SoC address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ * @return
+ *  0 on success, negative on error.
+ */
+static inline void
+rte_eal_soc_device_name(const struct rte_soc_addr *addr,
+			char *output, size_t size)
+{
+	int ret;
+
+	RTE_VERIFY(addr != NULL);
+	RTE_VERIFY(size >= strlen(addr->name));
+	ret = snprintf(output, size, "%s", addr->name);
+	RTE_VERIFY(ret >= 0);
+}
+
+static inline int
+rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
+			 const struct rte_soc_addr *a1)
+{
+	if (a0 == NULL || a1 == NULL)
+		return -1;
+
+	RTE_VERIFY(a0->name != NULL);
+	RTE_VERIFY(a1->name != NULL);
+
+	return strcmp(a0->name, a1->name);
+}
+
+#endif
-- 
2.7.4

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

* [PATCH v3 02/15] eal/soc: add rte_eal_soc_register/unregister logic
  2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
  2016-09-09  8:43   ` [PATCH v3 01/15] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
@ 2016-09-09  8:43   ` Shreyansh Jain
  2016-09-15 13:00     ` Hunt, David
  2016-09-09  8:43   ` [PATCH v3 03/15] eal/soc: Implement SoC device list and dump Shreyansh Jain
                     ` (15 subsequent siblings)
  17 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-09  8:43 UTC (permalink / raw)
  To: dev; +Cc: viktorin, hemant.agrawal, Shreyansh Jain

Registeration of a SoC driver through a helper DRIVER_REGISTER_SOC
(on the lines of DRIVER_REGISTER_PCI). soc_driver_list stores all the
registered drivers.

Test case has been introduced to verify the registration and
deregistration.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 app/test/test_soc.c                             | 111 ++++++++++++++++++++++++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   4 +
 lib/librte_eal/common/eal_common_soc.c          |  56 ++++++++++++
 lib/librte_eal/common/include/rte_soc.h         |  26 ++++++
 lib/librte_eal/linuxapp/eal/Makefile            |   1 +
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   3 +
 6 files changed, 201 insertions(+)
 create mode 100644 lib/librte_eal/common/eal_common_soc.c

diff --git a/app/test/test_soc.c b/app/test/test_soc.c
index 916a863..ac03e64 100644
--- a/app/test/test_soc.c
+++ b/app/test/test_soc.c
@@ -75,6 +75,108 @@ static int test_compare_addr(void)
 	free(a2.name);
 	free(a1.name);
 	free(a0.name);
+
+	return 0;
+}
+
+/**
+ * Empty PMD driver based on the SoC infra.
+ *
+ * The rte_soc_device is usually wrapped in some higher-level struct
+ * (eth_driver). We simulate such a wrapper with an anonymous struct here.
+ */
+struct test_wrapper {
+	struct rte_soc_driver soc_drv;
+};
+
+struct test_wrapper empty_pmd0 = {
+	.soc_drv = {
+		.driver = {
+			.name = "empty_pmd0"
+		},
+	},
+};
+
+struct test_wrapper empty_pmd1 = {
+	.soc_drv = {
+		.driver = {
+			.name = "empty_pmd1"
+		},
+	},
+};
+
+static int
+count_registered_socdrvs(void)
+{
+	int i;
+	struct rte_soc_driver *drv;
+
+	i = 0;
+	TAILQ_FOREACH(drv, &soc_driver_list, next)
+		i += 1;
+
+	return i;
+}
+
+static int
+test_register_unregister(void)
+{
+	struct rte_soc_driver *drv;
+	int count;
+
+	rte_eal_soc_register(&empty_pmd0.soc_drv);
+
+	TEST_ASSERT(!TAILQ_EMPTY(&soc_driver_list),
+		    "No PMD is present but the empty_pmd0 should be there");
+	drv = TAILQ_FIRST(&soc_driver_list);
+	TEST_ASSERT(!strcmp(drv->driver.name, "empty_pmd0"),
+		    "The registered PMD is not empty_pmd0 but '%s'",
+		drv->driver.name);
+
+	rte_eal_soc_register(&empty_pmd1.soc_drv);
+
+	count = count_registered_socdrvs();
+	TEST_ASSERT_EQUAL(count, 2, "Expected 2 PMDs but detected %d", count);
+
+	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
+	count = count_registered_socdrvs();
+	TEST_ASSERT_EQUAL(count, 1, "Expected 1 PMDs but detected %d", count);
+
+	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
+
+	printf("%s has been successful\n", __func__);
+	return 0;
+}
+
+/* save real devices and drivers until the tests finishes */
+struct soc_driver_list real_soc_driver_list =
+	TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
+
+static int test_soc_setup(void)
+{
+	struct rte_soc_driver *drv;
+
+	/* no real drivers for the test */
+	while (!TAILQ_EMPTY(&soc_driver_list)) {
+		drv = TAILQ_FIRST(&soc_driver_list);
+		rte_eal_soc_unregister(drv);
+		TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
+	}
+
+	return 0;
+}
+
+static int test_soc_cleanup(void)
+{
+	struct rte_soc_driver *drv;
+
+	/* bring back real drivers after the test */
+	while (!TAILQ_EMPTY(&real_soc_driver_list)) {
+		drv = TAILQ_FIRST(&real_soc_driver_list);
+		TAILQ_REMOVE(&real_soc_driver_list, drv, next);
+		rte_eal_soc_register(drv);
+	}
+
 	return 0;
 }
 
@@ -84,6 +186,15 @@ test_soc(void)
 	if (test_compare_addr())
 		return -1;
 
+	if (test_soc_setup())
+		return -1;
+
+	if (test_register_unregister())
+		return -1;
+
+	if (test_soc_cleanup())
+		return -1;
+
 	return 0;
 }
 
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 7b3d409..cda8009 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -168,4 +168,8 @@ DPDK_16.11 {
 
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
+	soc_driver_list;
+	rte_eal_soc_register;
+	rte_eal_soc_unregister;
+
 } DPDK_16.07;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
new file mode 100644
index 0000000..56135ed
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -0,0 +1,56 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/queue.h>
+
+#include <rte_log.h>
+
+#include "eal_private.h"
+
+/* Global SoC driver list */
+struct soc_driver_list soc_driver_list =
+	TAILQ_HEAD_INITIALIZER(soc_driver_list);
+
+/* register a driver */
+void
+rte_eal_soc_register(struct rte_soc_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_eal_soc_unregister(struct rte_soc_driver *driver)
+{
+	TAILQ_REMOVE(&soc_driver_list, driver, next);
+}
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index bc0a43b..16c5a1b 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -51,8 +51,14 @@ extern "C" {
 #include <string.h>
 
 #include <rte_dev.h>
+#include <rte_eal.h>
 #include <rte_debug.h>
 
+extern struct soc_driver_list soc_driver_list;
+/**< Global list of SoC Drivers */
+
+TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
+
 struct rte_soc_id {
 	const char *compatible; /**< OF compatible specification */
 	uint64_t priv_data;     /**< SoC Driver specific data */
@@ -135,4 +141,24 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 	return strcmp(a0->name, a1->name);
 }
 
+/**
+ * Register a SoC driver.
+ */
+void rte_eal_soc_register(struct rte_soc_driver *driver);
+
+/** Helper for SoC device registeration from PMD Drivers */
+#define DRIVER_REGISTER_SOC(nm, soc_drv) \
+RTE_INIT(socinitfn_ ##name); \
+static void socinitfn_ ##name(void) \
+{\
+	(soc_drv).driver.name = RTE_STR(nm);\
+	rte_eal_soc_register(&soc_drv); \
+} \
+DRIVER_EXPORT_NAME(nm, __COUNTER__)
+
+/**
+ * Unregister a SoC driver.
+ */
+void rte_eal_soc_unregister(struct rte_soc_driver *driver);
+
 #endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 4e206f0..a520477 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -77,6 +77,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index b8bfd4b..66c1258 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -174,5 +174,8 @@ DPDK_16.11 {
 	rte_eal_dev_detach;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
+	soc_driver_list;
+	rte_eal_soc_register;
+	rte_eal_soc_unregister;
 
 } DPDK_16.07;
-- 
2.7.4

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

* [PATCH v3 03/15] eal/soc: Implement SoC device list and dump
  2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
  2016-09-09  8:43   ` [PATCH v3 01/15] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
  2016-09-09  8:43   ` [PATCH v3 02/15] eal/soc: add rte_eal_soc_register/unregister logic Shreyansh Jain
@ 2016-09-09  8:43   ` Shreyansh Jain
  2016-09-09  8:43   ` [PATCH v3 04/15] eal: introduce --no-soc option Shreyansh Jain
                     ` (14 subsequent siblings)
  17 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-09  8:43 UTC (permalink / raw)
  To: dev; +Cc: viktorin, hemant.agrawal, Shreyansh Jain

SoC devices would be linked in a separate list (from PCI). This is used for
probe function.
A helper for dumping the device list is added.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  2 ++
 lib/librte_eal/common/eal_common_soc.c          | 34 +++++++++++++++++++++++++
 lib/librte_eal/common/include/rte_soc.h         |  9 +++++++
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  2 ++
 4 files changed, 47 insertions(+)

diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index cda8009..de38848 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -169,7 +169,9 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	soc_driver_list;
+	soc_device_list
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
+	rte_eal_soc_dump;
 
 } DPDK_16.07;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 56135ed..5dcddc5 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -31,6 +31,8 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <stddef.h>
+#include <stdio.h>
 #include <sys/queue.h>
 
 #include <rte_log.h>
@@ -40,6 +42,38 @@
 /* Global SoC driver list */
 struct soc_driver_list soc_driver_list =
 	TAILQ_HEAD_INITIALIZER(soc_driver_list);
+struct soc_device_list soc_device_list =
+	TAILQ_HEAD_INITIALIZER(soc_device_list);
+
+/* dump one device */
+static int
+soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
+{
+	int i;
+
+	fprintf(f, "%s", dev->addr.name);
+	fprintf(f, " - fdt_path: %s\n",
+			dev->addr.fdt_path ? dev->addr.fdt_path : "(none)");
+
+	for (i = 0; dev->id && dev->id[i].compatible; ++i)
+		fprintf(f, "   %s\n", dev->id[i].compatible);
+
+	return 0;
+}
+
+/* dump devices on the bus to an output stream */
+void
+rte_eal_soc_dump(FILE *f)
+{
+	struct rte_soc_device *dev = NULL;
+
+	if (!f)
+		return;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		soc_dump_one_device(f, dev);
+	}
+}
 
 /* register a driver */
 void
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 16c5a1b..c6f98eb 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -56,8 +56,12 @@ extern "C" {
 
 extern struct soc_driver_list soc_driver_list;
 /**< Global list of SoC Drivers */
+extern struct soc_device_list soc_device_list;
+/**< Global list of SoC Devices */
 
 TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
+TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
+
 
 struct rte_soc_id {
 	const char *compatible; /**< OF compatible specification */
@@ -142,6 +146,11 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 }
 
 /**
+ * Dump discovered SoC devices.
+ */
+void rte_eal_soc_dump(FILE *f);
+
+/**
  * Register a SoC driver.
  */
 void rte_eal_soc_register(struct rte_soc_driver *driver);
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 66c1258..b9d1932 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -175,7 +175,9 @@ DPDK_16.11 {
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
 	soc_driver_list;
+	soc_device_list;
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
+	rte_eal_soc_dump;
 
 } DPDK_16.07;
-- 
2.7.4

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

* [PATCH v3 04/15] eal: introduce --no-soc option
  2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (2 preceding siblings ...)
  2016-09-09  8:43   ` [PATCH v3 03/15] eal/soc: Implement SoC device list and dump Shreyansh Jain
@ 2016-09-09  8:43   ` Shreyansh Jain
  2016-09-16 11:36     ` Jan Viktorin
  2016-09-09  8:43   ` [PATCH v3 05/15] eal/soc: init SoC infra from EAL Shreyansh Jain
                     ` (13 subsequent siblings)
  17 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-09  8:43 UTC (permalink / raw)
  To: dev; +Cc: viktorin, hemant.agrawal, Shreyansh Jain

This option has the same meaning for the SoC infra as the --no-pci
for the PCI infra.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/common/eal_common_options.c | 5 +++++
 lib/librte_eal/common/eal_internal_cfg.h   | 1 +
 lib/librte_eal/common/eal_options.h        | 2 ++
 3 files changed, 8 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 1a1bab3..d97cf0a 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -85,6 +85,7 @@ eal_long_options[] = {
 	{OPT_NO_HPET,           0, NULL, OPT_NO_HPET_NUM          },
 	{OPT_NO_HUGE,           0, NULL, OPT_NO_HUGE_NUM          },
 	{OPT_NO_PCI,            0, NULL, OPT_NO_PCI_NUM           },
+	{OPT_NO_SOC,            0, NULL, OPT_NO_SOC_NUM           },
 	{OPT_NO_SHCONF,         0, NULL, OPT_NO_SHCONF_NUM        },
 	{OPT_PCI_BLACKLIST,     1, NULL, OPT_PCI_BLACKLIST_NUM    },
 	{OPT_PCI_WHITELIST,     1, NULL, OPT_PCI_WHITELIST_NUM    },
@@ -855,6 +856,10 @@ eal_parse_common_option(int opt, const char *optarg,
 		conf->no_pci = 1;
 		break;
 
+	case OPT_NO_SOC_NUM:
+		conf->no_soc = 1;
+		break;
+
 	case OPT_NO_HPET_NUM:
 		conf->no_hpet = 1;
 		break;
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 5f1367e..3a98e94 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -67,6 +67,7 @@ struct internal_config {
 	unsigned hugepage_unlink;         /**< true to unlink backing files */
 	volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
 	volatile unsigned no_pci;         /**< true to disable PCI */
+	volatile unsigned no_soc;         /**< true to disable SoC */
 	volatile unsigned no_hpet;        /**< true to disable HPET */
 	volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
 										* instead of native TSC */
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index a881c62..ba1e704 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -69,6 +69,8 @@ enum {
 	OPT_NO_HUGE_NUM,
 #define OPT_NO_PCI            "no-pci"
 	OPT_NO_PCI_NUM,
+#define OPT_NO_SOC            "no-soc"
+	OPT_NO_SOC_NUM,
 #define OPT_NO_SHCONF         "no-shconf"
 	OPT_NO_SHCONF_NUM,
 #define OPT_SOCKET_MEM        "socket-mem"
-- 
2.7.4

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

* [PATCH v3 05/15] eal/soc: init SoC infra from EAL
  2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (3 preceding siblings ...)
  2016-09-09  8:43   ` [PATCH v3 04/15] eal: introduce --no-soc option Shreyansh Jain
@ 2016-09-09  8:43   ` Shreyansh Jain
  2016-09-09  8:43   ` [PATCH v3 06/15] eal/soc: implement probing of drivers Shreyansh Jain
                     ` (12 subsequent siblings)
  17 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-09  8:43 UTC (permalink / raw)
  To: dev; +Cc: viktorin, hemant.agrawal, Shreyansh Jain

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/bsdapp/eal/Makefile    |  1 +
 lib/librte_eal/bsdapp/eal/eal.c       |  4 +++
 lib/librte_eal/bsdapp/eal/eal_soc.c   | 46 ++++++++++++++++++++++++++++
 lib/librte_eal/common/eal_private.h   | 10 +++++++
 lib/librte_eal/linuxapp/eal/Makefile  |  1 +
 lib/librte_eal/linuxapp/eal/eal.c     |  3 ++
 lib/librte_eal/linuxapp/eal/eal_soc.c | 56 +++++++++++++++++++++++++++++++++++
 7 files changed, 121 insertions(+)
 create mode 100644 lib/librte_eal/bsdapp/eal/eal_soc.c
 create mode 100644 lib/librte_eal/linuxapp/eal/eal_soc.c

diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 5a3fc1d..cf4bf78 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -57,6 +57,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_hugepage_info.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_pci.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_timer.c
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index a0c8f8c..7d8c3e8 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -64,6 +64,7 @@
 #include <rte_string_fns.h>
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
+#include <rte_soc.h>
 #include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
@@ -567,6 +568,9 @@ rte_eal_init(int argc, char **argv)
 	if (rte_eal_pci_init() < 0)
 		rte_panic("Cannot init PCI\n");
 
+	if (rte_eal_soc_init() < 0)
+		rte_panic("Cannot init SoC\n");
+
 	eal_check_mem_on_local_socket();
 
 	if (eal_plugins_init() < 0)
diff --git a/lib/librte_eal/bsdapp/eal/eal_soc.c b/lib/librte_eal/bsdapp/eal/eal_soc.c
new file mode 100644
index 0000000..cb297ff
--- /dev/null
+++ b/lib/librte_eal/bsdapp/eal/eal_soc.c
@@ -0,0 +1,46 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <rte_common.h>
+#include <rte_log.h>
+
+#include <eal_private.h>
+
+/* Init the SoC EAL subsystem */
+int
+rte_eal_soc_init(void)
+{
+	return 0;
+}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index df6582d..ba8407d 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -130,6 +130,16 @@ int rte_eal_pci_init(void);
 struct rte_soc_driver;
 struct rte_soc_device;
 
+/**
+ * Init the SoC infra.
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int rte_eal_soc_init(void);
+
 struct rte_pci_driver;
 struct rte_pci_device;
 
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index a520477..59e30fa 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -65,6 +65,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio_mp_sync.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_vfio.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 9412983..15c8c3d 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -798,6 +798,9 @@ rte_eal_init(int argc, char **argv)
 		rte_panic("Cannot init VFIO\n");
 #endif
 
+	if (rte_eal_soc_init() < 0)
+		rte_panic("Cannot init SoC\n");
+
 	if (rte_eal_memory_init() < 0)
 		rte_panic("Cannot init memory\n");
 
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
new file mode 100644
index 0000000..04848b9
--- /dev/null
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -0,0 +1,56 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <rte_log.h>
+#include <rte_soc.h>
+
+#include "eal_internal_cfg.h"
+#include "eal_filesystem.h"
+#include "eal_private.h"
+
+/* Init the SoC EAL subsystem */
+int
+rte_eal_soc_init(void)
+{
+	return 0;
+}
-- 
2.7.4

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

* [PATCH v3 06/15] eal/soc: implement probing of drivers
  2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (4 preceding siblings ...)
  2016-09-09  8:43   ` [PATCH v3 05/15] eal/soc: init SoC infra from EAL Shreyansh Jain
@ 2016-09-09  8:43   ` Shreyansh Jain
  2016-09-16 12:27     ` Jan Viktorin
  2016-09-09  8:43   ` [PATCH v3 07/15] eal/soc: extend and utilize devargs Shreyansh Jain
                     ` (11 subsequent siblings)
  17 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-09  8:43 UTC (permalink / raw)
  To: dev; +Cc: viktorin, hemant.agrawal, Shreyansh Jain

Each SoC PMD registers a set of callback for scanning its own bus/infra and
matching devices to drivers when probe is called.
This patch introduces the infra for calls to SoC scan on rte_eal_soc_init()
and match on rte_eal_soc_probe().

Patch also adds test case for scan and probe.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 app/test/test_soc.c                             | 138 ++++++++++++++-
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   4 +
 lib/librte_eal/common/eal_common_soc.c          | 215 ++++++++++++++++++++++++
 lib/librte_eal/common/include/rte_soc.h         |  51 ++++++
 lib/librte_eal/linuxapp/eal/eal.c               |   5 +
 lib/librte_eal/linuxapp/eal/eal_soc.c           |  16 ++
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   4 +
 7 files changed, 432 insertions(+), 1 deletion(-)

diff --git a/app/test/test_soc.c b/app/test/test_soc.c
index ac03e64..d2b9462 100644
--- a/app/test/test_soc.c
+++ b/app/test/test_soc.c
@@ -87,14 +87,45 @@ static int test_compare_addr(void)
  */
 struct test_wrapper {
 	struct rte_soc_driver soc_drv;
+	struct rte_soc_device soc_dev;
 };
 
+static int empty_pmd0_devinit(struct rte_soc_driver *drv,
+			      struct rte_soc_device *dev);
+static int empty_pmd0_devuninit(struct rte_soc_device *dev);
+static void test_soc_scan_dev0_cb(void);
+static int test_soc_match_dev0_cb(struct rte_soc_driver *drv,
+				  struct rte_soc_device *dev);
+static void test_soc_scan_dev1_cb(void);
+static int test_soc_match_dev1_cb(struct rte_soc_driver *drv,
+				  struct rte_soc_device *dev);
+
+static int
+empty_pmd0_devinit(struct rte_soc_driver *drv __rte_unused,
+		   struct rte_soc_device *dev __rte_unused)
+{
+	return 0;
+}
+
+static int
+empty_pmd0_devuninit(struct rte_soc_device *dev)
+{
+	/* Release the memory associated with dev->addr.name */
+	free(dev->addr.name);
+
+	return 0;
+}
+
 struct test_wrapper empty_pmd0 = {
 	.soc_drv = {
 		.driver = {
 			.name = "empty_pmd0"
 		},
-	},
+		.devinit = empty_pmd0_devinit,
+		.devuninit = empty_pmd0_devuninit,
+		.scan_fn = test_soc_scan_dev0_cb,
+		.match_fn = test_soc_match_dev0_cb,
+	}
 };
 
 struct test_wrapper empty_pmd1 = {
@@ -102,9 +133,54 @@ struct test_wrapper empty_pmd1 = {
 		.driver = {
 			.name = "empty_pmd1"
 		},
+		.scan_fn = test_soc_scan_dev1_cb,
+		.match_fn = test_soc_match_dev1_cb,
 	},
 };
 
+static void
+test_soc_scan_dev0_cb(void)
+{
+	/* SoC's scan would scan devices on its bus and add to
+	 * soc_device_list
+	 */
+	empty_pmd0.soc_dev.addr.name = strdup("empty_pmd0_dev");
+
+	TAILQ_INSERT_TAIL(&soc_device_list, &empty_pmd0.soc_dev, next);
+}
+
+static int
+test_soc_match_dev0_cb(struct rte_soc_driver *drv __rte_unused,
+		       struct rte_soc_device *dev)
+{
+	if (!dev->addr.name || strcmp(dev->addr.name, "empty_pmd0_dev"))
+		return 0;
+
+	return 1;
+}
+
+
+static void
+test_soc_scan_dev1_cb(void)
+{
+	/* SoC's scan would scan devices on its bus and add to
+	 * soc_device_list
+	 */
+	empty_pmd0.soc_dev.addr.name = strdup("empty_pmd1_dev");
+
+	TAILQ_INSERT_TAIL(&soc_device_list, &empty_pmd1.soc_dev, next);
+}
+
+static int
+test_soc_match_dev1_cb(struct rte_soc_driver *drv __rte_unused,
+		       struct rte_soc_device *dev)
+{
+	if (!dev->addr.name || strcmp(dev->addr.name, "empty_pmd1_dev"))
+		return 0;
+
+	return 1;
+}
+
 static int
 count_registered_socdrvs(void)
 {
@@ -148,13 +224,54 @@ test_register_unregister(void)
 	return 0;
 }
 
+/* Test Probe (scan and match) functionality */
+static int
+test_soc_init_and_probe(void)
+{
+	struct rte_soc_driver *drv;
+
+	/* Registering dummy drivers */
+	rte_eal_soc_register(&empty_pmd0.soc_drv);
+	rte_eal_soc_register(&empty_pmd1.soc_drv);
+	/* Assuming that test_register_unregister is working, not verifying
+	 * that drivers are indeed registered
+	*/
+
+	/* rte_eal_soc_init is called by rte_eal_init, which in turn calls the
+	 * scan_fn of each driver.
+	 */
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		if (drv && drv->scan_fn)
+			drv->scan_fn();
+	}
+
+	/* rte_eal_init() would perform other inits here */
+
+	/* Probe would link the SoC devices<=>drivers */
+	rte_eal_soc_probe();
+
+	/* Unregistering dummy drivers */
+	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
+	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
+
+	free(empty_pmd0.soc_dev.addr.name);
+
+	printf("%s has been successful\n", __func__);
+	return 0;
+}
+
 /* save real devices and drivers until the tests finishes */
 struct soc_driver_list real_soc_driver_list =
 	TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
 
+/* save real devices and drivers until the tests finishes */
+struct soc_device_list real_soc_device_list =
+	TAILQ_HEAD_INITIALIZER(real_soc_device_list);
+
 static int test_soc_setup(void)
 {
 	struct rte_soc_driver *drv;
+	struct rte_soc_device *dev;
 
 	/* no real drivers for the test */
 	while (!TAILQ_EMPTY(&soc_driver_list)) {
@@ -163,12 +280,20 @@ static int test_soc_setup(void)
 		TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
 	}
 
+	/* And, no real devices for the test */
+	while (!TAILQ_EMPTY(&soc_device_list)) {
+		dev = TAILQ_FIRST(&soc_device_list);
+		TAILQ_REMOVE(&soc_device_list, dev, next);
+		TAILQ_INSERT_TAIL(&real_soc_device_list, dev, next);
+	}
+
 	return 0;
 }
 
 static int test_soc_cleanup(void)
 {
 	struct rte_soc_driver *drv;
+	struct rte_soc_device *dev;
 
 	/* bring back real drivers after the test */
 	while (!TAILQ_EMPTY(&real_soc_driver_list)) {
@@ -177,6 +302,13 @@ static int test_soc_cleanup(void)
 		rte_eal_soc_register(drv);
 	}
 
+	/* And, bring back real devices after the test */
+	while (!TAILQ_EMPTY(&real_soc_device_list)) {
+		dev = TAILQ_FIRST(&real_soc_device_list);
+		TAILQ_REMOVE(&real_soc_device_list, dev, next);
+		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+	}
+
 	return 0;
 }
 
@@ -192,6 +324,10 @@ test_soc(void)
 	if (test_register_unregister())
 		return -1;
 
+	/* Assuming test_register_unregister has succeeded */
+	if (test_soc_init_and_probe())
+		return -1;
+
 	if (test_soc_cleanup())
 		return -1;
 
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index de38848..3c407be 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -173,5 +173,9 @@ DPDK_16.11 {
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
 	rte_eal_soc_dump;
+	rte_eal_soc_match;
+	rte_eal_soc_detach;
+	rte_eal_soc_probe;
+	rte_eal_soc_probe_one;
 
 } DPDK_16.07;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 5dcddc5..bb87a67 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -36,6 +36,8 @@
 #include <sys/queue.h>
 
 #include <rte_log.h>
+#include <rte_common.h>
+#include <rte_soc.h>
 
 #include "eal_private.h"
 
@@ -45,6 +47,213 @@ struct soc_driver_list soc_driver_list =
 struct soc_device_list soc_device_list =
 	TAILQ_HEAD_INITIALIZER(soc_device_list);
 
+/* Default SoC device<->Driver match handler function */
+int
+rte_eal_soc_match(struct rte_soc_driver *drv, struct rte_soc_device *dev)
+{
+	int i, j;
+
+	RTE_VERIFY(drv != NULL && drv->id_table != NULL);
+	RTE_VERIFY(dev != NULL && dev->id != NULL);
+
+	for (i = 0; drv->id_table[i].compatible; ++i) {
+		const char *drv_compat = drv->id_table[i].compatible;
+
+		for (j = 0; dev->id[j].compatible; ++j) {
+			const char *dev_compat = dev->id[j].compatible;
+
+			if (!strcmp(drv_compat, dev_compat))
+				return 0;
+		}
+	}
+
+	return 1;
+}
+
+
+static int
+rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
+			     struct rte_soc_device *dev)
+{
+	int ret = 1;
+
+	ret = drv->match_fn(drv, dev);
+	if (ret) {
+		RTE_LOG(DEBUG, EAL,
+			" match function failed, skipping\n");
+		return ret;
+	}
+
+	dev->driver = drv;
+	RTE_VERIFY(drv->devinit != NULL);
+	return drv->devinit(drv, dev);
+}
+
+static int
+soc_probe_all_drivers(struct rte_soc_device *dev)
+{
+	struct rte_soc_driver *drv = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		rc = rte_eal_soc_probe_one_driver(drv, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+/* If the IDs match, call the devuninit() function of the driver. */
+static int
+rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
+		       struct rte_soc_device *dev)
+{
+	int ret;
+
+	if ((drv == NULL) || (dev == NULL))
+		return -EINVAL;
+
+	ret = drv->match_fn(drv, dev);
+	if (ret) {
+		RTE_LOG(DEBUG, EAL,
+			" match function failed, skipping\n");
+		return ret;
+	}
+
+	RTE_LOG(DEBUG, EAL, "SoC device %s\n",
+		dev->addr.name);
+
+	RTE_LOG(DEBUG, EAL, "  remove driver: %s\n", drv->driver.name);
+
+	if (drv->devuninit && (drv->devuninit(dev) < 0))
+		return -1;	/* negative value is an error */
+
+	/* clear driver structure */
+	dev->driver = NULL;
+
+	return 0;
+}
+
+/*
+ * Call the devuninit() function of all registered drivers for the given
+ * device if their IDs match.
+ *
+ * @return
+ *       0 when successful
+ *      -1 if deinitialization fails
+ *       1 if no driver is found for this device.
+ */
+static int
+soc_detach_all_drivers(struct rte_soc_device *dev)
+{
+	struct rte_soc_driver *dr = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dr, &soc_driver_list, next) {
+		rc = rte_eal_soc_detach_dev(dr, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+/*
+ * Detach device specified by its SoC address.
+ */
+int
+rte_eal_soc_detach(const struct rte_soc_addr *addr)
+{
+	struct rte_soc_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		if (rte_eal_compare_soc_addr(&dev->addr, addr))
+			continue;
+
+		ret = soc_detach_all_drivers(dev);
+		if (ret < 0)
+			goto err_return;
+
+		TAILQ_REMOVE(&soc_device_list, dev, next);
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL, "Requested device %s cannot be used\n",
+		dev->addr.name);
+	return -1;
+}
+
+int
+rte_eal_soc_probe_one(const struct rte_soc_addr *addr)
+{
+	struct rte_soc_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	/* unlike pci, in case of soc, it the responsibility of the soc driver
+	 * to check during init whether device has been updated since last add.
+	 */
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		if (rte_eal_compare_soc_addr(&dev->addr, addr))
+			continue;
+
+		ret = soc_probe_all_drivers(dev);
+		if (ret < 0)
+			goto err_return;
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL,
+		"Requested device %s cannot be used\n", addr->name);
+	return -1;
+}
+
+/*
+ * Scan the SoC devices and call the devinit() function for all registered
+ * drivers that have a matching entry in its id_table for discovered devices.
+ */
+int
+rte_eal_soc_probe(void)
+{
+	struct rte_soc_device *dev = NULL;
+	int ret = 0;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		ret = soc_probe_all_drivers(dev);
+		if (ret < 0)
+			rte_exit(EXIT_FAILURE, "Requested device %s"
+				 " cannot be used\n", dev->addr.name);
+	}
+
+	return 0;
+}
+
 /* dump one device */
 static int
 soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
@@ -79,6 +288,12 @@ rte_eal_soc_dump(FILE *f)
 void
 rte_eal_soc_register(struct rte_soc_driver *driver)
 {
+	/* For a valid soc driver, match and scan function
+	 * should be provided.
+	 */
+	RTE_VERIFY(driver != NULL);
+	RTE_VERIFY(driver->match_fn != NULL);
+	RTE_VERIFY(driver->scan_fn != NULL);
 	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
 }
 
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index c6f98eb..bfb49a2 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -97,6 +97,16 @@ typedef int (soc_devinit_t)(struct rte_soc_driver *, struct rte_soc_device *);
 typedef int (soc_devuninit_t)(struct rte_soc_device *);
 
 /**
+ * SoC device scan callback, called from rte_eal_soc_init.
+ */
+typedef void (soc_scan_t)(void);
+
+/**
+ * Custom device<=>driver match callback for SoC
+ */
+typedef int (soc_match_t)(struct rte_soc_driver *, struct rte_soc_device *);
+
+/**
  * A structure describing a SoC driver.
  */
 struct rte_soc_driver {
@@ -104,6 +114,8 @@ struct rte_soc_driver {
 	struct rte_driver driver;          /**< Inherit core driver. */
 	soc_devinit_t *devinit;            /**< Device initialization */
 	soc_devuninit_t *devuninit;        /**< Device uninitialization */
+	soc_scan_t *scan_fn;               /**< Callback for scanning SoC bus*/
+	soc_match_t *match_fn;             /**< Callback to match dev<->drv */
 	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
 };
 
@@ -146,6 +158,45 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 }
 
 /**
+ * Default function for matching the Soc driver with device. Each driver can
+ * either use this function or define their own soc matching function.
+ * This function relies on the compatible string extracted from sysfs. But,
+ * a SoC might have different way of identifying its devices. Such SoC can
+ * override match_fn.
+ *
+ * @return
+ * 	 0 on success
+ *	-1 when no match found
+  */
+int
+rte_eal_soc_match(struct rte_soc_driver *drv, struct rte_soc_device *dev);
+
+/**
+ * Probe SoC devices for registered drivers.
+ */
+int rte_eal_soc_probe(void);
+
+/**
+ * Probe the single SoC device.
+ */
+int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
+
+/**
+ * Close the single SoC device.
+ *
+ * Scan the SoC devices and find the SoC device specified by the SoC
+ * address, then call the devuninit() function for registered driver
+ * that has a matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The SoC address to close.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_eal_soc_detach(const struct rte_soc_addr *addr);
+
+/**
  * Dump discovered SoC devices.
  */
 void rte_eal_soc_dump(FILE *f);
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 15c8c3d..147b601 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -70,6 +70,7 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_common.h>
@@ -881,6 +882,10 @@ rte_eal_init(int argc, char **argv)
 	if (rte_eal_pci_probe())
 		rte_panic("Cannot probe PCI\n");
 
+	/* Probe & Initialize SoC devices */
+	if (rte_eal_soc_probe())
+		rte_panic("Cannot probe SoC\n");
+
 	rte_eal_mcfg_complete();
 
 	return fctret;
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index 04848b9..5f961c4 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -52,5 +52,21 @@
 int
 rte_eal_soc_init(void)
 {
+	struct rte_soc_driver *drv;
+
+	/* for debug purposes, SoC can be disabled */
+	if (internal_config.no_soc)
+		return 0;
+
+	/* For each registered driver, call their scan routine to perform any
+	 * custom scan for devices (for example, custom buses)
+	 */
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		if (drv && drv->scan_fn) {
+			drv->scan_fn();
+			/* Ignore all errors from this */
+		}
+	}
+
 	return 0;
 }
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index b9d1932..adcfe7d 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -179,5 +179,9 @@ DPDK_16.11 {
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
 	rte_eal_soc_dump;
+	rte_eal_soc_match;
+	rte_eal_soc_detach;
+	rte_eal_soc_probe;
+	rte_eal_soc_probe_one;
 
 } DPDK_16.07;
-- 
2.7.4

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

* [PATCH v3 07/15] eal/soc: extend and utilize devargs
  2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (5 preceding siblings ...)
  2016-09-09  8:43   ` [PATCH v3 06/15] eal/soc: implement probing of drivers Shreyansh Jain
@ 2016-09-09  8:43   ` Shreyansh Jain
  2016-09-09  8:43   ` [PATCH v3 08/15] eal/soc: add drv_flags Shreyansh Jain
                     ` (10 subsequent siblings)
  17 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-09  8:43 UTC (permalink / raw)
  To: dev; +Cc: viktorin, hemant.agrawal, Shreyansh Jain

It is assumed that SoC Devices provided on command line are prefixed with
"soc:". This patch adds parse and attach support for such devices.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/common/eal_common_dev.c      | 27 ++++++++++----
 lib/librte_eal/common/eal_common_devargs.c  | 17 +++++++++
 lib/librte_eal/common/eal_common_soc.c      | 55 ++++++++++++++++++++++++++---
 lib/librte_eal/common/include/rte_devargs.h |  8 +++++
 lib/librte_eal/common/include/rte_soc.h     | 24 +++++++++++++
 5 files changed, 119 insertions(+), 12 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index d1f0ad8..fbc4443 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -106,17 +106,23 @@ rte_eal_dev_init(void)
 
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
-	struct rte_pci_addr addr;
+	struct rte_soc_addr soc_addr;
+	struct rte_pci_addr pci_addr;
 
 	if (name == NULL || devargs == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
 		return -EINVAL;
 	}
 
-	if (eal_parse_pci_DomBDF(name, &addr) == 0) {
-		if (rte_eal_pci_probe_one(&addr) < 0)
+	memset(&soc_addr, 0, sizeof(soc_addr));
+	if (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+		if (rte_eal_soc_probe_one(&soc_addr) < 0) {
+			free(soc_addr.name);
+			goto err;
+		}
+	} else if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+		if (rte_eal_pci_probe_one(&pci_addr) < 0)
 			goto err;
-
 	} else {
 		if (rte_eal_vdev_init(name, devargs))
 			goto err;
@@ -131,15 +137,22 @@ err:
 
 int rte_eal_dev_detach(const char *name)
 {
-	struct rte_pci_addr addr;
+	struct rte_soc_addr soc_addr;
+	struct rte_pci_addr pci_addr;
 
 	if (name == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device provided.\n");
 		return -EINVAL;
 	}
 
-	if (eal_parse_pci_DomBDF(name, &addr) == 0) {
-		if (rte_eal_pci_detach(&addr) < 0)
+	memset(&soc_addr, 0, sizeof(soc_addr));
+	if (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+		if (rte_eal_soc_detach(&soc_addr) < 0) {
+			free(soc_addr.name);
+			goto err;
+		}
+	} else if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+		if (rte_eal_pci_detach(&pci_addr) < 0)
 			goto err;
 	} else {
 		if (rte_eal_vdev_uninit(name))
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index e403717..e1dae1a 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -41,6 +41,7 @@
 #include <string.h>
 
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_devargs.h>
 #include "eal_private.h"
 
@@ -105,6 +106,14 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
 			goto fail;
 
 		break;
+
+	case RTE_DEVTYPE_WHITELISTED_SOC:
+	case RTE_DEVTYPE_BLACKLISTED_SOC:
+		/* try to parse soc device with prefix "soc:" */
+		if (rte_eal_parse_soc_spec(buf, &devargs->soc.addr) != 0)
+			goto fail;
+		break;
+
 	case RTE_DEVTYPE_VIRTUAL:
 		/* save driver name */
 		ret = snprintf(devargs->virt.drv_name,
@@ -166,6 +175,14 @@ rte_eal_devargs_dump(FILE *f)
 			       devargs->pci.addr.devid,
 			       devargs->pci.addr.function,
 			       devargs->args);
+		else if (devargs->type == RTE_DEVTYPE_WHITELISTED_SOC)
+			fprintf(f, "  SoC whitelist %s %s\n",
+			       devargs->soc.addr.name,
+			       devargs->soc.addr.fdt_path);
+		else if (devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC)
+			fprintf(f, "  SoC blacklist %s %s\n",
+			       devargs->soc.addr.name,
+			       devargs->soc.addr.fdt_path);
 		else if (devargs->type == RTE_DEVTYPE_VIRTUAL)
 			fprintf(f, "  VIRTUAL %s %s\n",
 			       devargs->virt.drv_name,
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index bb87a67..e9d413a 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -37,6 +37,8 @@
 
 #include <rte_log.h>
 #include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_eal.h>
 #include <rte_soc.h>
 
 #include "eal_private.h"
@@ -71,6 +73,21 @@ rte_eal_soc_match(struct rte_soc_driver *drv, struct rte_soc_device *dev)
 }
 
 
+static struct rte_devargs *soc_devargs_lookup(struct rte_soc_device *dev)
+{
+	struct rte_devargs *devargs;
+
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->type != RTE_DEVTYPE_BLACKLISTED_SOC &&
+			devargs->type != RTE_DEVTYPE_WHITELISTED_SOC)
+			continue;
+		if (!rte_eal_compare_soc_addr(&dev->addr, &devargs->soc.addr))
+			return devargs;
+	}
+
+	return NULL;
+}
+
 static int
 rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
 			     struct rte_soc_device *dev)
@@ -84,6 +101,18 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
 		return ret;
 	}
 
+	RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %d\n",
+			dev->addr.name, dev->device.numa_node);
+	RTE_LOG(DEBUG, EAL, "  probe driver %s\n", drv->driver.name);
+
+	/* no initialization when blacklisted, return without error */
+	if (dev->device.devargs != NULL
+		&& dev->device.devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC) {
+		RTE_LOG(DEBUG, EAL,
+			"  device is blacklisted, skipping\n");
+		return ret;
+	}
+
 	dev->driver = drv;
 	RTE_VERIFY(drv->devinit != NULL);
 	return drv->devinit(drv, dev);
@@ -128,8 +157,8 @@ rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
 		return ret;
 	}
 
-	RTE_LOG(DEBUG, EAL, "SoC device %s\n",
-		dev->addr.name);
+	RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %i\n",
+			dev->addr.name, dev->device.numa_node);
 
 	RTE_LOG(DEBUG, EAL, "  remove driver: %s\n", drv->driver.name);
 
@@ -242,13 +271,29 @@ int
 rte_eal_soc_probe(void)
 {
 	struct rte_soc_device *dev = NULL;
+	struct rte_devargs *devargs = NULL;
 	int ret = 0;
+	int probe_all = 0;
+
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_SOC) == 0)
+		probe_all = 1;
 
 	TAILQ_FOREACH(dev, &soc_device_list, next) {
-		ret = soc_probe_all_drivers(dev);
+
+		/* set devargs in SoC structure */
+		devargs = soc_devargs_lookup(dev);
+		if (devargs != NULL)
+			dev->device.devargs = devargs;
+
+		/* probe all or only whitelisted devices */
+		if (probe_all)
+			ret = soc_probe_all_drivers(dev);
+		else if (devargs != NULL &&
+			devargs->type == RTE_DEVTYPE_WHITELISTED_SOC)
+			ret = soc_probe_all_drivers(dev);
 		if (ret < 0)
-			rte_exit(EXIT_FAILURE, "Requested device %s"
-				 " cannot be used\n", dev->addr.name);
+			rte_exit(EXIT_FAILURE, "Requested device %s "
+				 "cannot be used\n", dev->addr.name);
 	}
 
 	return 0;
diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h
index 53c59f5..757320e 100644
--- a/lib/librte_eal/common/include/rte_devargs.h
+++ b/lib/librte_eal/common/include/rte_devargs.h
@@ -51,6 +51,7 @@ extern "C" {
 #include <stdio.h>
 #include <sys/queue.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 
 /**
  * Type of generic device
@@ -58,6 +59,8 @@ extern "C" {
 enum rte_devtype {
 	RTE_DEVTYPE_WHITELISTED_PCI,
 	RTE_DEVTYPE_BLACKLISTED_PCI,
+	RTE_DEVTYPE_WHITELISTED_SOC,
+	RTE_DEVTYPE_BLACKLISTED_SOC,
 	RTE_DEVTYPE_VIRTUAL,
 };
 
@@ -82,6 +85,11 @@ struct rte_devargs {
 			/** PCI location. */
 			struct rte_pci_addr addr;
 		} pci;
+		/** Used if type is RTE_DEVTYPE_*_SOC. */
+		struct {
+			/** SoC location. */
+			struct rte_soc_addr addr;
+		} soc;
 		/** Used if type is RTE_DEVTYPE_VIRTUAL. */
 		struct {
 			/** Driver name. */
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index bfb49a2..0bbef7d 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -158,6 +158,30 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 }
 
 /**
+ * Parse a specification of a soc device. The specification must differentiate
+ * a SoC device specification from the PCI bus and virtual devices. We assume
+ * a SoC specification starts with "soc:". The function allocates the name
+ * entry of the given addr.
+ *
+ * @return
+ *      -  0 on success
+ *      -  1 when not a SoC spec
+ *      - -1 on failure
+ */
+static inline int
+rte_eal_parse_soc_spec(const char *spec, struct rte_soc_addr *addr)
+{
+	if (strstr(spec, "soc:") == spec) {
+		addr->name = strdup(spec + 4);
+		if (addr->name == NULL)
+			return -1;
+		return 0;
+	}
+
+	return 1;
+}
+
+/**
  * Default function for matching the Soc driver with device. Each driver can
  * either use this function or define their own soc matching function.
  * This function relies on the compatible string extracted from sysfs. But,
-- 
2.7.4

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

* [PATCH v3 08/15] eal/soc: add drv_flags
  2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (6 preceding siblings ...)
  2016-09-09  8:43   ` [PATCH v3 07/15] eal/soc: extend and utilize devargs Shreyansh Jain
@ 2016-09-09  8:43   ` Shreyansh Jain
  2016-09-09  8:43   ` [PATCH v3 09/15] eal/soc: add intr_handle Shreyansh Jain
                     ` (9 subsequent siblings)
  17 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-09  8:43 UTC (permalink / raw)
  To: dev; +Cc: viktorin, hemant.agrawal, Shreyansh Jain

The flags are copied from the PCI ones. They should be refactorized into a
general set of flags in the future.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/common/include/rte_soc.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 0bbef7d..93d3a2f 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -117,8 +117,18 @@ struct rte_soc_driver {
 	soc_scan_t *scan_fn;               /**< Callback for scanning SoC bus*/
 	soc_match_t *match_fn;             /**< Callback to match dev<->drv */
 	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
+	uint32_t drv_flags;                /**< Control handling of device */
 };
 
+/** Device needs to map its resources by EAL */
+#define RTE_SOC_DRV_NEED_MAPPING 0x0001
+/** Device needs to be unbound even if no module is provieded */
+#define RTE_SOC_DRV_FORCE_UNBIND 0x0004
+/** Device driver supports link state interrupt */
+#define RTE_SOC_DRV_INTR_LSC	 0x0008
+/** Device driver supports detaching capability */
+#define RTE_SOC_DRV_DETACHABLE	 0x0010
+
 /**
  * Utility function to write a SoC device name, this device name can later be
  * used to retrieve the corresponding rte_soc_addr using above functions.
-- 
2.7.4

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

* [PATCH v3 09/15] eal/soc: add intr_handle
  2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (7 preceding siblings ...)
  2016-09-09  8:43   ` [PATCH v3 08/15] eal/soc: add drv_flags Shreyansh Jain
@ 2016-09-09  8:43   ` Shreyansh Jain
  2016-09-09  8:43   ` [PATCH v3 10/15] ether: utilize container_of for pci_drv Shreyansh Jain
                     ` (8 subsequent siblings)
  17 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-09  8:43 UTC (permalink / raw)
  To: dev; +Cc: viktorin, hemant.agrawal, Shreyansh Jain

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/common/include/rte_soc.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 93d3a2f..aa4c678 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -53,6 +53,7 @@ extern "C" {
 #include <rte_dev.h>
 #include <rte_eal.h>
 #include <rte_debug.h>
+#include <rte_interrupts.h>
 
 extern struct soc_driver_list soc_driver_list;
 /**< Global list of SoC Drivers */
@@ -81,6 +82,7 @@ struct rte_soc_device {
 	struct rte_device device;           /**< Inherit code device */
 	struct rte_soc_addr addr;           /**< SoC device Location */
 	struct rte_soc_id *id;              /**< SoC device ID list */
+	struct rte_intr_handle intr_handle; /**< Interrupt handle */
 	struct rte_soc_driver *driver;      /**< Associated driver */
 };
 
-- 
2.7.4

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

* [PATCH v3 10/15] ether: utilize container_of for pci_drv
  2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (8 preceding siblings ...)
  2016-09-09  8:43   ` [PATCH v3 09/15] eal/soc: add intr_handle Shreyansh Jain
@ 2016-09-09  8:43   ` Shreyansh Jain
  2016-09-09  8:43   ` [PATCH v3 11/15] ether: verify we copy info from a PCI device Shreyansh Jain
                     ` (7 subsequent siblings)
  17 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-09  8:43 UTC (permalink / raw)
  To: dev; +Cc: viktorin, hemant.agrawal, Shreyansh Jain

It is not necessary to place the rte_pci_driver at the beginning
of the rte_eth_dev struct anymore as we use the container_of macro
to get the parent pointer.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 4 ++--
 lib/librte_ether/rte_ethdev.h | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index d54ec9e..b10d985 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -242,7 +242,7 @@ rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
 
 	int diag;
 
-	eth_drv = (struct eth_driver *)pci_drv;
+	eth_drv = container_of(pci_drv, struct eth_driver, pci_drv);
 
 	rte_eal_pci_device_name(&pci_dev->addr, ethdev_name,
 			sizeof(ethdev_name));
@@ -303,7 +303,7 @@ rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
 	if (eth_dev == NULL)
 		return -ENODEV;
 
-	eth_drv = (const struct eth_driver *)pci_dev->driver;
+	eth_drv = container_of(pci_dev->driver, struct eth_driver, pci_drv);
 
 	/* Invoke PMD device uninit function */
 	if (*eth_drv->eth_dev_uninit) {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 2a697ec..8320dc4 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1842,7 +1842,7 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *eth_dev);
  * Each Ethernet driver acts as a PCI driver and is represented by a generic
  * *eth_driver* structure that holds:
  *
- * - An *rte_pci_driver* structure (which must be the first field).
+ * - An *rte_pci_driver* structure.
  *
  * - The *eth_dev_init* function invoked for each matching PCI device.
  *
-- 
2.7.4

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

* [PATCH v3 11/15] ether: verify we copy info from a PCI device
  2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (9 preceding siblings ...)
  2016-09-09  8:43   ` [PATCH v3 10/15] ether: utilize container_of for pci_drv Shreyansh Jain
@ 2016-09-09  8:43   ` Shreyansh Jain
  2016-09-09  8:43   ` [PATCH v3 12/15] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
                     ` (6 subsequent siblings)
  17 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-09  8:43 UTC (permalink / raw)
  To: dev; +Cc: viktorin, hemant.agrawal, Shreyansh Jain

Now that different types of ethdev exist, check for presence of PCI dev
while copying out the info.
Similar would be done for SoC.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index b10d985..e9f5467 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3200,6 +3200,8 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_de
 		return;
 	}
 
+	RTE_VERIFY(eth_dev->pci_dev != NULL);
+
 	eth_dev->data->dev_flags = 0;
 	if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC)
 		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
-- 
2.7.4

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

* [PATCH v3 12/15] ether: extract function eth_dev_get_intr_handle
  2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (10 preceding siblings ...)
  2016-09-09  8:43   ` [PATCH v3 11/15] ether: verify we copy info from a PCI device Shreyansh Jain
@ 2016-09-09  8:43   ` Shreyansh Jain
  2016-09-15 13:02     ` Hunt, David
  2016-09-09  8:43   ` [PATCH v3 13/15] ether: extract function eth_dev_get_driver_name Shreyansh Jain
                     ` (5 subsequent siblings)
  17 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-09  8:43 UTC (permalink / raw)
  To: dev; +Cc: viktorin, hemant.agrawal, Shreyansh Jain

We abstract access to the intr_handle here as we want to get
it either from the pci_dev or soc_dev.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index e9f5467..104ea4a 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2526,6 +2526,17 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
 	rte_spinlock_unlock(&rte_eth_dev_cb_lock);
 }
 
+static inline
+struct rte_intr_handle *eth_dev_get_intr_handle(struct rte_eth_dev *dev)
+{
+	if (dev->pci_dev) {
+		return &dev->pci_dev->intr_handle;
+	}
+
+	RTE_VERIFY(0);
+	return NULL;
+}
+
 int
 rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 {
@@ -2538,7 +2549,7 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
-	intr_handle = &dev->pci_dev->intr_handle;
+	intr_handle = eth_dev_get_intr_handle(dev);
 	if (!intr_handle->intr_vec) {
 		RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
 		return -EPERM;
@@ -2598,7 +2609,7 @@ rte_eth_dev_rx_intr_ctl_q(uint8_t port_id, uint16_t queue_id,
 		return -EINVAL;
 	}
 
-	intr_handle = &dev->pci_dev->intr_handle;
+	intr_handle = eth_dev_get_intr_handle(dev);
 	if (!intr_handle->intr_vec) {
 		RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
 		return -EPERM;
-- 
2.7.4

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

* [PATCH v3 13/15] ether: extract function eth_dev_get_driver_name
  2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (11 preceding siblings ...)
  2016-09-09  8:43   ` [PATCH v3 12/15] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
@ 2016-09-09  8:43   ` Shreyansh Jain
  2016-09-15 13:03     ` Hunt, David
  2016-09-09  8:43   ` [PATCH v3 14/15] ether: Support rte_soc_driver/device for etherdev Shreyansh Jain
                     ` (4 subsequent siblings)
  17 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-09  8:43 UTC (permalink / raw)
  To: dev; +Cc: viktorin, hemant.agrawal, Shreyansh Jain

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 104ea4a..4fa65ca 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2568,6 +2568,17 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 	return 0;
 }
 
+static inline
+const char *eth_dev_get_driver_name(const struct rte_eth_dev *dev)
+{
+	if (dev->pci_dev) {
+		return dev->driver->pci_drv.driver.name;
+	}
+
+	RTE_VERIFY(0);
+	return NULL;
+}
+
 const struct rte_memzone *
 rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 			 uint16_t queue_id, size_t size, unsigned align,
@@ -2575,9 +2586,11 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 {
 	char z_name[RTE_MEMZONE_NAMESIZE];
 	const struct rte_memzone *mz;
+	const char *drv_name;
 
+	drv_name = eth_dev_get_driver_name(dev);
 	snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
-		 dev->driver->pci_drv.driver.name, ring_name,
+		 drv_name, ring_name,
 		 dev->data->port_id, queue_id);
 
 	mz = rte_memzone_lookup(z_name);
-- 
2.7.4

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

* [PATCH v3 14/15] ether: Support rte_soc_driver/device for etherdev
  2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (12 preceding siblings ...)
  2016-09-09  8:43   ` [PATCH v3 13/15] ether: extract function eth_dev_get_driver_name Shreyansh Jain
@ 2016-09-09  8:43   ` Shreyansh Jain
  2016-09-09  8:43   ` [PATCH v3 15/15] eal/crypto: Support rte_soc_driver/device for cryptodev Shreyansh Jain
                     ` (3 subsequent siblings)
  17 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-09  8:43 UTC (permalink / raw)
  To: dev; +Cc: viktorin, hemant.agrawal, Shreyansh Jain

- eth_driver/rte_eth_dev embeds rte_soc_driver/device for relating SoC
  PMDs to ethernet devices.
- Add probe and remove functions linked to eth_dev_init/uninit

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 129 ++++++++++++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h |  31 ++++++++++
 2 files changed, 160 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 4fa65ca..b57d7b2 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -326,6 +326,101 @@ rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
 }
 
 int
+rte_eth_dev_soc_probe(struct rte_soc_driver *soc_drv,
+		      struct rte_soc_device *soc_dev)
+{
+	struct eth_driver    *eth_drv;
+	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
+	int diag;
+
+	eth_drv = container_of(soc_drv, struct eth_driver, soc_drv);
+
+	rte_eal_soc_device_name(&soc_dev->addr, ethdev_name,
+			sizeof(ethdev_name));
+
+	eth_dev = rte_eth_dev_allocate(ethdev_name);
+	if (eth_dev == NULL)
+		return -ENOMEM;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		eth_dev->data->dev_private = rte_zmalloc(
+				  "ethdev private structure",
+				  eth_drv->dev_private_size,
+				  RTE_CACHE_LINE_SIZE);
+		if (eth_dev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private port "
+				  "data\n");
+	}
+	eth_dev->soc_dev = soc_dev;
+	eth_dev->driver = eth_drv;
+	eth_dev->data->rx_mbuf_alloc_failed = 0;
+
+	/* init user callbacks */
+	TAILQ_INIT(&(eth_dev->link_intr_cbs));
+
+	/*
+	 * Set the default MTU.
+	 */
+	eth_dev->data->mtu = ETHER_MTU;
+
+	/* Invoke PMD device initialization function */
+	diag = (*eth_drv->eth_dev_init)(eth_dev);
+	if (diag == 0)
+		return 0;
+
+	RTE_PMD_DEBUG_TRACE("driver %s: eth_dev_init(%s) failed\n",
+			soc_drv->driver.name,
+			soc_dev->addr.name);
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(eth_dev->data->dev_private);
+	rte_eth_dev_release_port(eth_dev);
+	return diag;
+}
+
+int
+rte_eth_dev_soc_remove(struct rte_soc_device *soc_dev)
+{
+	const struct eth_driver *eth_drv;
+	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+	int ret;
+
+	if (soc_dev == NULL)
+		return -EINVAL;
+
+	rte_eal_soc_device_name(&soc_dev->addr, ethdev_name,
+			sizeof(ethdev_name));
+
+	eth_dev = rte_eth_dev_allocated(ethdev_name);
+	if (eth_dev == NULL)
+		return -ENODEV;
+
+	eth_drv = container_of(soc_dev->driver, struct eth_driver, soc_drv);
+
+	/* Invoke PMD device uninit function */
+	if (*eth_drv->eth_dev_uninit) {
+		ret = (*eth_drv->eth_dev_uninit)(eth_dev);
+		if (ret)
+			return ret;
+	}
+
+	/* free ether device */
+	rte_eth_dev_release_port(eth_dev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(eth_dev->data->dev_private);
+
+	eth_dev->soc_dev = NULL;
+	eth_dev->driver = NULL;
+	eth_dev->data = NULL;
+
+	return 0;
+}
+
+
+int
 rte_eth_dev_is_valid_port(uint8_t port_id)
 {
 	if (port_id >= RTE_MAX_ETHPORTS ||
@@ -1555,6 +1650,7 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
 	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
 	dev_info->pci_dev = dev->pci_dev;
+	dev_info->soc_dev = dev->soc_dev;
 	dev_info->driver_name = dev->data->drv_name;
 	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
 	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
@@ -2530,8 +2626,13 @@ static inline
 struct rte_intr_handle *eth_dev_get_intr_handle(struct rte_eth_dev *dev)
 {
 	if (dev->pci_dev) {
+		RTE_VERIFY(dev->soc_dev == NULL);
 		return &dev->pci_dev->intr_handle;
 	}
+	if (dev->soc_dev) {
+		RTE_VERIFY(dev->pci_dev == NULL);
+		return &dev->soc_dev->intr_handle;
+	}
 
 	RTE_VERIFY(0);
 	return NULL;
@@ -2572,9 +2673,15 @@ static inline
 const char *eth_dev_get_driver_name(const struct rte_eth_dev *dev)
 {
 	if (dev->pci_dev) {
+		RTE_VERIFY(dev->soc_dev == NULL);
 		return dev->driver->pci_drv.driver.name;
 	}
 
+	if (dev->soc_dev) {
+		RTE_VERIFY(dev->pci_dev == NULL);
+		return dev->driver->soc_drv.driver.name;
+	}
+
 	RTE_VERIFY(0);
 	return NULL;
 }
@@ -3237,6 +3344,28 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_de
 	eth_dev->data->drv_name = pci_dev->driver->driver.name;
 }
 
+void
+rte_eth_copy_soc_info(struct rte_eth_dev *eth_dev,
+		      struct rte_soc_device *soc_dev)
+{
+	if ((eth_dev == NULL) || (soc_dev == NULL)) {
+		RTE_PMD_DEBUG_TRACE("NULL pointer eth_dev=%p soc_dev=%p\n",
+				eth_dev, soc_dev);
+		return;
+	}
+
+	RTE_VERIFY(eth_dev->soc_dev != NULL);
+
+	eth_dev->data->dev_flags = 0;
+	if (soc_dev->driver->drv_flags & RTE_SOC_DRV_INTR_LSC)
+		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
+	if (soc_dev->driver->drv_flags & RTE_SOC_DRV_DETACHABLE)
+		eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
+
+	eth_dev->data->numa_node = soc_dev->device.numa_node;
+	eth_dev->data->drv_name = soc_dev->driver->driver.name;
+}
+
 int
 rte_eth_dev_l2_tunnel_eth_type_conf(uint8_t port_id,
 				    struct rte_eth_l2_tunnel_conf *l2_tunnel)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 8320dc4..4ae22e9 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -180,6 +180,7 @@ extern "C" {
 #include <rte_log.h>
 #include <rte_interrupts.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include "rte_ether.h"
@@ -870,6 +871,7 @@ struct rte_eth_conf {
  */
 struct rte_eth_dev_info {
 	struct rte_pci_device *pci_dev; /**< Device PCI information. */
+	struct rte_soc_device *soc_dev; /**< Device SoC information. */
 	const char *driver_name; /**< Device Driver name. */
 	unsigned int if_index; /**< Index to bound host interface, or 0 if none.
 		Use if_indextoname() to translate into an interface name. */
@@ -1619,6 +1621,7 @@ struct rte_eth_dev {
 	const struct eth_driver *driver;/**< Driver for this device */
 	const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
 	struct rte_pci_device *pci_dev; /**< PCI info. supplied by probing */
+	struct rte_soc_device *soc_dev; /**< SoC info. supplied by probing */
 	/** User application callbacks for NIC interrupts */
 	struct rte_eth_dev_cb_list link_intr_cbs;
 	/**
@@ -1852,6 +1855,7 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *eth_dev);
  */
 struct eth_driver {
 	struct rte_pci_driver pci_drv;    /**< The PMD is also a PCI driver. */
+	struct rte_soc_driver soc_drv;    /**< The PMD is also a SoC driver. */
 	eth_dev_init_t eth_dev_init;      /**< Device init function. */
 	eth_dev_uninit_t eth_dev_uninit;  /**< Device uninit function. */
 	unsigned int dev_private_size;    /**< Size of device private data. */
@@ -4244,6 +4248,20 @@ void rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev,
 		struct rte_pci_device *pci_dev);
 
 /**
+ * Copy SoC device info to the Ethernet device data.
+ *
+ * @param eth_dev
+ * The *eth_dev* pointer is the address of the *rte_eth_dev* structure.
+ * @param soc_dev
+ * The *soc_dev* pointer is the address of the *rte_soc_device* structure.
+ *
+ * @return
+ *   - 0 on success, negative on error
+ */
+void rte_eth_copy_soc_info(struct rte_eth_dev *eth_dev,
+		struct rte_soc_device *soc_dev);
+
+/**
  * Create memzone for HW rings.
  * malloc can't be used as the physical address is needed.
  * If the memzone is already created, then this function returns a ptr
@@ -4356,6 +4374,19 @@ int rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
  */
 int rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev);
 
+/**
+ * Wrapper for use by SoC drivers as a .devinit function to attach to a ethdev
+ * interface.
+ */
+int rte_eth_dev_soc_probe(struct rte_soc_driver *soc_drv,
+			  struct rte_soc_device *soc_dev);
+
+/**
+ * Wrapper for use by SoC drivers as a .devuninit function to detach a ethdev
+ * interface.
+ */
+int rte_eth_dev_soc_remove(struct rte_soc_device *soc_dev);
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.7.4

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

* [PATCH v3 15/15] eal/crypto: Support rte_soc_driver/device for cryptodev
  2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (13 preceding siblings ...)
  2016-09-09  8:43   ` [PATCH v3 14/15] ether: Support rte_soc_driver/device for etherdev Shreyansh Jain
@ 2016-09-09  8:43   ` Shreyansh Jain
  2016-09-15 12:56   ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Hunt, David
                     ` (2 subsequent siblings)
  17 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-09  8:43 UTC (permalink / raw)
  To: dev; +Cc: viktorin, hemant.agrawal, Shreyansh Jain

- rte_cryptodev_driver/rte_cryptodev_dev embeds rte_soc_driver/device for
  linking SoC PMDs to crypto devices.
- Add probe and remove functions linked

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_cryptodev/rte_cryptodev.c           | 122 ++++++++++++++++++++++++-
 lib/librte_cryptodev/rte_cryptodev.h           |   3 +
 lib/librte_cryptodev/rte_cryptodev_pmd.h       |  18 +++-
 lib/librte_cryptodev/rte_cryptodev_version.map |   3 +
 4 files changed, 141 insertions(+), 5 deletions(-)

diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 2e17169..43e8685 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -423,7 +423,8 @@ rte_cryptodev_pci_probe(struct rte_pci_driver *pci_drv,
 
 	int retval;
 
-	cryptodrv = (struct rte_cryptodev_driver *)pci_drv;
+	cryptodrv = container_of(pci_drv, struct rte_cryptodev_driver,
+				 pci_drv);
 	if (cryptodrv == NULL)
 		return -ENODEV;
 
@@ -490,7 +491,8 @@ rte_cryptodev_pci_remove(struct rte_pci_device *pci_dev)
 	if (cryptodev == NULL)
 		return -ENODEV;
 
-	cryptodrv = (const struct rte_cryptodev_driver *)pci_dev->driver;
+	cryptodrv = container_of(pci_dev->driver, struct rte_cryptodev_driver,
+				 pci_drv);
 	if (cryptodrv == NULL)
 		return -ENODEV;
 
@@ -514,6 +516,111 @@ rte_cryptodev_pci_remove(struct rte_pci_device *pci_dev)
 	return 0;
 }
 
+
+int
+rte_cryptodev_soc_probe(struct rte_soc_driver *soc_drv,
+		      struct rte_soc_device *soc_dev)
+{
+	struct rte_cryptodev_driver *cryptodrv;
+	struct rte_cryptodev *cryptodev;
+
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+
+	int retval;
+
+	cryptodrv = container_of(soc_drv, struct rte_cryptodev_driver,
+				 soc_drv);
+
+	rte_eal_soc_device_name(&soc_dev->addr, cryptodev_name,
+			sizeof(cryptodev_name));
+
+	cryptodev = rte_cryptodev_pmd_allocate(cryptodev_name,
+					       rte_socket_id());
+	if (cryptodev == NULL)
+		return -ENOMEM;
+
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		cryptodev->data->dev_private =
+				rte_zmalloc_socket(
+						"cryptodev private structure",
+						cryptodrv->dev_private_size,
+						RTE_CACHE_LINE_SIZE,
+						rte_socket_id());
+
+		if (cryptodev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private "
+					"device data");
+	}
+
+	cryptodev->soc_dev = soc_dev;
+	cryptodev->driver = cryptodrv;
+
+	/* init user callbacks */
+	TAILQ_INIT(&(cryptodev->link_intr_cbs));
+
+	/* Invoke PMD device initialization function */
+	retval = (*cryptodrv->cryptodev_init)(cryptodrv, cryptodev);
+	if (retval == 0)
+		return 0;
+
+	CDEV_LOG_ERR("driver %s: cryptodev_init(%s) failed\n",
+			soc_drv->driver.name,
+			soc_dev->addr.name);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	cryptodev->attached = RTE_CRYPTODEV_DETACHED;
+	cryptodev_globals.nb_devs--;
+
+	return -ENXIO;
+}
+
+int
+rte_cryptodev_soc_remove(struct rte_soc_device *soc_dev)
+{
+	const struct rte_cryptodev_driver *cryptodrv;
+	struct rte_cryptodev *cryptodev;
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+	int ret;
+
+	if (soc_dev == NULL)
+		return -EINVAL;
+
+	rte_eal_soc_device_name(&soc_dev->addr, cryptodev_name,
+			sizeof(cryptodev_name));
+
+	cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name);
+	if (cryptodev == NULL)
+		return -ENODEV;
+
+	cryptodrv = container_of(soc_dev->driver,
+		struct rte_cryptodev_driver, soc_drv);
+	if (cryptodrv == NULL)
+		return -ENODEV;
+
+	/* Invoke PMD device uninit function */
+	if (*cryptodrv->cryptodev_uninit) {
+		ret = (*cryptodrv->cryptodev_uninit)(cryptodrv, cryptodev);
+		if (ret)
+			return ret;
+	}
+
+	/* free crypto device */
+	rte_cryptodev_pmd_release_device(cryptodev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	cryptodev->pci_dev = NULL;
+	cryptodev->soc_dev = NULL;
+	cryptodev->driver = NULL;
+	cryptodev->data = NULL;
+
+	return 0;
+}
+
 uint16_t
 rte_cryptodev_queue_pair_count(uint8_t dev_id)
 {
@@ -869,8 +976,15 @@ rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
 
 	dev_info->pci_dev = dev->pci_dev;
-	if (dev->driver)
-		dev_info->driver_name = dev->driver->pci_drv.driver.name;
+	dev_info->soc_dev = dev->soc_dev;
+	if (dev->driver) {
+		if (dev->soc_dev)
+			dev_info->driver_name
+				= dev->driver->soc_drv.driver.name;
+		else
+			dev_info->driver_name
+				= dev->driver->pci_drv.driver.name;
+	}
 }
 
 
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 13f46e4..d10f62e 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -231,6 +231,7 @@ struct rte_cryptodev_info {
 	const char *driver_name;		/**< Driver name. */
 	enum rte_cryptodev_type dev_type;	/**< Device type */
 	struct rte_pci_device *pci_dev;		/**< PCI information. */
+	struct rte_soc_device *soc_dev;		/**< SoC information. */
 
 	uint64_t feature_flags;			/**< Feature flags */
 
@@ -610,6 +611,8 @@ struct rte_cryptodev {
 	/**< Supported features */
 	struct rte_pci_device *pci_dev;
 	/**< PCI info. supplied by probing */
+	struct rte_soc_device *soc_dev;
+	/**< SoC info. supplied by probing/Scanning */
 
 	enum rte_cryptodev_type dev_type;
 	/**< Crypto device type */
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index 99fd69e..db1756e 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -48,6 +48,7 @@ extern "C" {
 
 #include <rte_dev.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_malloc.h>
 #include <rte_mbuf.h>
 #include <rte_mempool.h>
@@ -129,7 +130,8 @@ typedef int (*cryptodev_uninit_t)(const struct rte_cryptodev_driver  *drv,
  * - The size of the private data to allocate for each matching device.
  */
 struct rte_cryptodev_driver {
-	struct rte_pci_driver pci_drv;	/**< The PMD is also a PCI driver. */
+	struct rte_pci_driver pci_drv;	/**< The PMD is PCI type driver. */
+	struct rte_soc_driver soc_drv;	/**< The PMD is SoC type driver. */
 	unsigned dev_private_size;	/**< Size of device private data. */
 
 	cryptodev_init_t cryptodev_init;	/**< Device init function. */
@@ -517,6 +519,20 @@ int rte_cryptodev_pci_probe(struct rte_pci_driver *pci_drv,
  */
 int rte_cryptodev_pci_remove(struct rte_pci_device *pci_dev);
 
+/**
+ * Wrapper for use by SoC drivers as a .devinit function to attach to a
+ * cryptodev interface.
+ */
+int rte_cryptodev_soc_probe(struct rte_soc_driver *soc_drv,
+			  struct rte_soc_device *soc_dev);
+
+/**
+ * Wrapper for use by SoC drivers as a .devuninit function to detach a
+ * cryptodev interface.
+ */
+int rte_cryptodev_soc_remove(struct rte_soc_device *soc_dev);
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index 9627ac4..d81073e 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -44,4 +44,7 @@ DPDK_16.11 {
 
 	rte_cryptodev_pci_probe;
 	rte_cryptodev_pci_remove;
+	rte_cryptodev_soc_probe;
+	rte_cryptodev_soc_remove;
+
 } DPDK_16.07;
-- 
2.7.4

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

* Re: [PATCH v3 00/15] Introduce SoC device/driver framework for EAL
  2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (14 preceding siblings ...)
  2016-09-09  8:43   ` [PATCH v3 15/15] eal/crypto: Support rte_soc_driver/device for cryptodev Shreyansh Jain
@ 2016-09-15 12:56   ` Hunt, David
  2016-09-16  6:14     ` Shreyansh Jain
  2016-09-18  5:58   ` Jianbo Liu
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
  17 siblings, 1 reply; 231+ messages in thread
From: Hunt, David @ 2016-09-15 12:56 UTC (permalink / raw)
  To: Shreyansh Jain, dev; +Cc: viktorin, hemant.agrawal

Shreyansh, Jan, Hemant,

On 9/9/2016 9:43 AM, Shreyansh Jain wrote:
> Introduction:
> =============
>
> This patch set is direct derivative of Jan's original series [1],[2].
>
>   - As this deviates substantially from original series, if need be I can
>     post it as a separate patch rather than v2. Please suggest.
>   - Also, there are comments on original v1 ([4]) which are _not_
>     incorporated in this series as they refer to section no more in new
>     version.
>   - This v3 version is based on the rte_driver/device patchset v9 [10].
>     That series introduced device structures (rte_driver/rte_device)
>     generalizing devices into PCI, VDEV, XXX. For the purpose of this
>     patchset, XXX=>SOC.
>
>
---snip---

     FYI, I've reviewed this patch set, and it looks to me like there's 
some very good work here. Each patch in the set builds nicely on the one 
before, and logically introduces the changes one by one.

    I've no functional suggestions as the implementation looks clean, 
but I've one or two tiny suggestions on headers and error messages. I'll 
add a reply to the relevant patches in the set.

Also, there's one or two issues thrown up by checkpatch, but I suspect 
they're false positives, as I'm using the 4.6 kernel version.

Regards,
Dave

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

* Re: [PATCH v3 01/15] eal/soc: introduce very essential SoC infra definitions
  2016-09-09  8:43   ` [PATCH v3 01/15] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
@ 2016-09-15 12:58     ` Hunt, David
  2016-09-16  6:17       ` Shreyansh Jain
  0 siblings, 1 reply; 231+ messages in thread
From: Hunt, David @ 2016-09-15 12:58 UTC (permalink / raw)
  To: Shreyansh Jain, dev; +Cc: viktorin, hemant.agrawal

Some small comments below:

On 9/9/2016 9:43 AM, Shreyansh Jain wrote:
> Define initial structures and functions for the SoC infrastructure.
> This patch supports only a very minimal functions for now.
> More features will be added in the following commits.
>
> Includes rte_device/rte_driver inheritance of
> rte_soc_device/rte_soc_driver.
>
> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
>   app/test/Makefile                       |   1 +
>   app/test/test_soc.c                     |  90 +++++++++++++++++++++
>   lib/librte_eal/common/Makefile          |   2 +-
>   lib/librte_eal/common/eal_private.h     |   4 +
>   lib/librte_eal/common/include/rte_soc.h | 138 ++++++++++++++++++++++++++++++++
>   5 files changed, 234 insertions(+), 1 deletion(-)
>   create mode 100644 app/test/test_soc.c
>   create mode 100644 lib/librte_eal/common/include/rte_soc.h
>
> diff --git a/app/test/Makefile b/app/test/Makefile
> index 611d77a..64b261d 100644
> --- a/app/test/Makefile
> +++ b/app/test/Makefile
> @@ -77,6 +77,7 @@ APP = test
>   #
>   SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) := commands.c
>   SRCS-y += test.c
> +SRCS-y += test_soc.c
>   SRCS-y += resource.c
>   SRCS-y += test_resource.c
>   test_resource.res: test_resource.c
> diff --git a/app/test/test_soc.c b/app/test/test_soc.c
> new file mode 100644
> index 0000000..916a863
> --- /dev/null
> +++ b/app/test/test_soc.c
> @@ -0,0 +1,90 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2016 RehiveTech. All rights reserved.
> + *   All rights reserved.

Remove un-needed "All rights reserved"

> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of RehiveTech nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <stdio.h>
> +#include <string.h>
> +#include <stdint.h>
> +#include <sys/queue.h>
> +
> +#include <rte_soc.h>
> +#include <rte_devargs.h>
> +#include <rte_debug.h>
> +
> +#include "test.h"
> +
> +static char *safe_strdup(const char *s)
> +{
> +	char *c = strdup(s);
> +
> +	if (c == NULL)
> +		rte_panic("failed to strdup '%s'\n", s);
> +
> +	return c;
> +}
> +
> +static int test_compare_addr(void)
> +{
> +	struct rte_soc_addr a0;
> +	struct rte_soc_addr a1;
> +	struct rte_soc_addr a2;
> +
> +	a0.name = safe_strdup("ethernet0");
> +	a0.fdt_path = NULL;
> +
> +	a1.name = safe_strdup("ethernet0");
> +	a1.fdt_path = NULL;
> +
> +	a2.name = safe_strdup("ethernet1");
> +	a2.fdt_path = NULL;
> +
> +	TEST_ASSERT(!rte_eal_compare_soc_addr(&a0, &a1),
> +		    "Failed to compare two soc addresses that equal");
> +	TEST_ASSERT(rte_eal_compare_soc_addr(&a0, &a2),
> +		    "Failed to compare two soc addresses that differs");
> +
> +	free(a2.name);
> +	free(a1.name);
> +	free(a0.name);
> +	return 0;
> +}
> +
> +static int
> +test_soc(void)
> +{
> +	if (test_compare_addr())
> +		return -1;
> +
> +	return 0;
> +}
> +
> +REGISTER_TEST_COMMAND(soc_autotest, test_soc);
> diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
> index dfd64aa..b414008 100644
> --- a/lib/librte_eal/common/Makefile
> +++ b/lib/librte_eal/common/Makefile
> @@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
>   
>   INC := rte_branch_prediction.h rte_common.h
>   INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
> -INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
> +INC += rte_log.h rte_memory.h rte_memzone.h rte_soc.h rte_pci.h
>   INC += rte_per_lcore.h rte_random.h
>   INC += rte_tailq.h rte_interrupts.h rte_alarm.h
>   INC += rte_string_fns.h rte_version.h
> diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
> index 431d6c2..df6582d 100644
> --- a/lib/librte_eal/common/eal_private.h
> +++ b/lib/librte_eal/common/eal_private.h
> @@ -36,6 +36,7 @@
>   
>   #include <stdio.h>
>   #include <rte_pci.h>
> +#include <rte_soc.h>
>   
>   /**
>    * Initialize the memzone subsystem (private to eal).
> @@ -126,6 +127,9 @@ int rte_eal_log_init(const char *id, int facility);
>    */
>   int rte_eal_pci_init(void);
>   
> +struct rte_soc_driver;
> +struct rte_soc_device;
> +
>   struct rte_pci_driver;
>   struct rte_pci_device;
>   
> diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
> new file mode 100644
> index 0000000..bc0a43b
> --- /dev/null
> +++ b/lib/librte_eal/common/include/rte_soc.h
> @@ -0,0 +1,138 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2016 RehiveTech. All rights reserved.
> + *   All rights reserved.

Remove un-needed "All rights reserved"

> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of RehiveTech nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef _RTE_SOC_H_
> +#define _RTE_SOC_H_
> +
> +/**
> + * @file
> + *
> + * RTE SoC Interface
> + */
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <stdint.h>
> +#include <inttypes.h>
> +#include <string.h>
> +
> +#include <rte_dev.h>
> +#include <rte_debug.h>
> +
> +struct rte_soc_id {
> +	const char *compatible; /**< OF compatible specification */
> +	uint64_t priv_data;     /**< SoC Driver specific data */
> +};
> +
> +struct rte_soc_addr {
> +	char *name;     /**< name used in sysfs */
> +	char *fdt_path; /**< path to the associated node in FDT */
> +};
> +
> +/**
> + * A structure describing a SoC device.
> + */
> +struct rte_soc_device {
> +	TAILQ_ENTRY(rte_soc_device) next;   /**< Next probed SoC device */
> +	struct rte_device device;           /**< Inherit code device */
> +	struct rte_soc_addr addr;           /**< SoC device Location */
> +	struct rte_soc_id *id;              /**< SoC device ID list */
> +	struct rte_soc_driver *driver;      /**< Associated driver */
> +};
> +
> +struct rte_soc_driver;
> +
> +/**
> + * Initialization function for the driver called during SoC probing.
> + */
> +typedef int (soc_devinit_t)(struct rte_soc_driver *, struct rte_soc_device *);
> +
> +/**
> + * Uninitialization function for the driver called during hotplugging.
> + */
> +typedef int (soc_devuninit_t)(struct rte_soc_device *);
> +
> +/**
> + * A structure describing a SoC driver.
> + */
> +struct rte_soc_driver {
> +	TAILQ_ENTRY(rte_soc_driver) next;  /**< Next in list */
> +	struct rte_driver driver;          /**< Inherit core driver. */
> +	soc_devinit_t *devinit;            /**< Device initialization */
> +	soc_devuninit_t *devuninit;        /**< Device uninitialization */
> +	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
> +};
> +
> +/**
> + * Utility function to write a SoC device name, this device name can later be
> + * used to retrieve the corresponding rte_soc_addr using above functions.
> + *
> + * @param addr
> + *	The SoC address
> + * @param output
> + *	The output buffer string
> + * @param size
> + *	The output buffer size
> + * @return
> + *  0 on success, negative on error.
> + */
> +static inline void
> +rte_eal_soc_device_name(const struct rte_soc_addr *addr,
> +			char *output, size_t size)
> +{
> +	int ret;
> +
> +	RTE_VERIFY(addr != NULL);
> +	RTE_VERIFY(size >= strlen(addr->name));
> +	ret = snprintf(output, size, "%s", addr->name);
> +	RTE_VERIFY(ret >= 0);
> +}
> +
> +static inline int
> +rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
> +			 const struct rte_soc_addr *a1)
> +{
> +	if (a0 == NULL || a1 == NULL)
> +		return -1;
> +
> +	RTE_VERIFY(a0->name != NULL);
> +	RTE_VERIFY(a1->name != NULL);
> +
> +	return strcmp(a0->name, a1->name);
> +}
> +
> +#endif

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

* Re: [PATCH v3 02/15] eal/soc: add rte_eal_soc_register/unregister logic
  2016-09-09  8:43   ` [PATCH v3 02/15] eal/soc: add rte_eal_soc_register/unregister logic Shreyansh Jain
@ 2016-09-15 13:00     ` Hunt, David
  2016-09-15 13:09       ` Jan Viktorin
  0 siblings, 1 reply; 231+ messages in thread
From: Hunt, David @ 2016-09-15 13:00 UTC (permalink / raw)
  To: Shreyansh Jain, dev; +Cc: viktorin, hemant.agrawal



On 9/9/2016 9:43 AM, Shreyansh Jain wrote:
> Registeration of a SoC driver through a helper DRIVER_REGISTER_SOC
> (on the lines of DRIVER_REGISTER_PCI). soc_driver_list stores all the
> registered drivers.
>
> Test case has been introduced to verify the registration and
> deregistration.
>
> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
>   app/test/test_soc.c                             | 111 ++++++++++++++++++++++++
>   lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   4 +
>   lib/librte_eal/common/eal_common_soc.c          |  56 ++++++++++++
>   lib/librte_eal/common/include/rte_soc.h         |  26 ++++++
>   lib/librte_eal/linuxapp/eal/Makefile            |   1 +
>   lib/librte_eal/linuxapp/eal/rte_eal_version.map |   3 +
>   6 files changed, 201 insertions(+)
>   create mode 100644 lib/librte_eal/common/eal_common_soc.c
>
> diff --git a/app/test/test_soc.c b/app/test/test_soc.c
> index 916a863..ac03e64 100644
> --- a/app/test/test_soc.c
> +++ b/app/test/test_soc.c
> @@ -75,6 +75,108 @@ static int test_compare_addr(void)
>   	free(a2.name);
>   	free(a1.name);
>   	free(a0.name);
> +
> +	return 0;
> +}
> +
> +/**
> + * Empty PMD driver based on the SoC infra.
> + *
> + * The rte_soc_device is usually wrapped in some higher-level struct
> + * (eth_driver). We simulate such a wrapper with an anonymous struct here.
> + */
> +struct test_wrapper {
> +	struct rte_soc_driver soc_drv;
> +};
> +
> +struct test_wrapper empty_pmd0 = {
> +	.soc_drv = {
> +		.driver = {
> +			.name = "empty_pmd0"
> +		},
> +	},
> +};
> +
> +struct test_wrapper empty_pmd1 = {
> +	.soc_drv = {
> +		.driver = {
> +			.name = "empty_pmd1"
> +		},
> +	},
> +};
> +
> +static int
> +count_registered_socdrvs(void)
> +{
> +	int i;
> +	struct rte_soc_driver *drv;
> +
> +	i = 0;
> +	TAILQ_FOREACH(drv, &soc_driver_list, next)
> +		i += 1;
> +
> +	return i;
> +}
> +
> +static int
> +test_register_unregister(void)
> +{
> +	struct rte_soc_driver *drv;
> +	int count;
> +
> +	rte_eal_soc_register(&empty_pmd0.soc_drv);
> +
> +	TEST_ASSERT(!TAILQ_EMPTY(&soc_driver_list),
> +		    "No PMD is present but the empty_pmd0 should be there");
> +	drv = TAILQ_FIRST(&soc_driver_list);
> +	TEST_ASSERT(!strcmp(drv->driver.name, "empty_pmd0"),
> +		    "The registered PMD is not empty_pmd0 but '%s'",
> +		drv->driver.name);
> +
> +	rte_eal_soc_register(&empty_pmd1.soc_drv);
> +
> +	count = count_registered_socdrvs();
> +	TEST_ASSERT_EQUAL(count, 2, "Expected 2 PMDs but detected %d", count);
> +
> +	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
> +	count = count_registered_socdrvs();
> +	TEST_ASSERT_EQUAL(count, 1, "Expected 1 PMDs but detected %d", count);
> +
> +	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
> +
> +	printf("%s has been successful\n", __func__);
> +	return 0;
> +}
> +
> +/* save real devices and drivers until the tests finishes */
> +struct soc_driver_list real_soc_driver_list =
> +	TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
> +
> +static int test_soc_setup(void)
> +{
> +	struct rte_soc_driver *drv;
> +
> +	/* no real drivers for the test */
> +	while (!TAILQ_EMPTY(&soc_driver_list)) {
> +		drv = TAILQ_FIRST(&soc_driver_list);
> +		rte_eal_soc_unregister(drv);
> +		TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
> +	}
> +
> +	return 0;
> +}
> +
> +static int test_soc_cleanup(void)
> +{
> +	struct rte_soc_driver *drv;
> +
> +	/* bring back real drivers after the test */
> +	while (!TAILQ_EMPTY(&real_soc_driver_list)) {
> +		drv = TAILQ_FIRST(&real_soc_driver_list);
> +		TAILQ_REMOVE(&real_soc_driver_list, drv, next);
> +		rte_eal_soc_register(drv);
> +	}
> +
>   	return 0;
>   }
>   
> @@ -84,6 +186,15 @@ test_soc(void)
>   	if (test_compare_addr())
>   		return -1;
>   
> +	if (test_soc_setup())
> +		return -1;
> +
> +	if (test_register_unregister())
> +		return -1;
> +
> +	if (test_soc_cleanup())
> +		return -1;
> +
>   	return 0;
>   }
>   
> diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> index 7b3d409..cda8009 100644
> --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> @@ -168,4 +168,8 @@ DPDK_16.11 {
>   
>   	rte_eal_dev_attach;
>   	rte_eal_dev_detach;
> +	soc_driver_list;
> +	rte_eal_soc_register;
> +	rte_eal_soc_unregister;
> +
>   } DPDK_16.07;
> diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
> new file mode 100644
> index 0000000..56135ed
> --- /dev/null
> +++ b/lib/librte_eal/common/eal_common_soc.c
> @@ -0,0 +1,56 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2016 RehiveTech. All rights reserved.
> + *   All rights reserved.

Duplicate "All rights reserved"

> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of RehiveTech nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <sys/queue.h>
> +
> +#include <rte_log.h>
> +
> +#include "eal_private.h"
> +
> +/* Global SoC driver list */
> +struct soc_driver_list soc_driver_list =
> +	TAILQ_HEAD_INITIALIZER(soc_driver_list);
> +
> +/* register a driver */
> +void
> +rte_eal_soc_register(struct rte_soc_driver *driver)
> +{
> +	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
> +}
> +
> +/* unregister a driver */
> +void
> +rte_eal_soc_unregister(struct rte_soc_driver *driver)
> +{
> +	TAILQ_REMOVE(&soc_driver_list, driver, next);
> +}
> diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
> index bc0a43b..16c5a1b 100644
> --- a/lib/librte_eal/common/include/rte_soc.h
> +++ b/lib/librte_eal/common/include/rte_soc.h
> @@ -51,8 +51,14 @@ extern "C" {
>   #include <string.h>
>   
>   #include <rte_dev.h>
> +#include <rte_eal.h>
>   #include <rte_debug.h>
>   
> +extern struct soc_driver_list soc_driver_list;
> +/**< Global list of SoC Drivers */
> +
> +TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
> +
>   struct rte_soc_id {
>   	const char *compatible; /**< OF compatible specification */
>   	uint64_t priv_data;     /**< SoC Driver specific data */
> @@ -135,4 +141,24 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
>   	return strcmp(a0->name, a1->name);
>   }
>   
> +/**
> + * Register a SoC driver.
> + */
> +void rte_eal_soc_register(struct rte_soc_driver *driver);
> +
> +/** Helper for SoC device registeration from PMD Drivers */
> +#define DRIVER_REGISTER_SOC(nm, soc_drv) \
> +RTE_INIT(socinitfn_ ##name); \
> +static void socinitfn_ ##name(void) \
> +{\
> +	(soc_drv).driver.name = RTE_STR(nm);\
> +	rte_eal_soc_register(&soc_drv); \
> +} \
> +DRIVER_EXPORT_NAME(nm, __COUNTER__)
> +
> +/**
> + * Unregister a SoC driver.
> + */
> +void rte_eal_soc_unregister(struct rte_soc_driver *driver);
> +
>   #endif
> diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
> index 4e206f0..a520477 100644
> --- a/lib/librte_eal/linuxapp/eal/Makefile
> +++ b/lib/librte_eal/linuxapp/eal/Makefile
> @@ -77,6 +77,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
> +SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_soc.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
> diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> index b8bfd4b..66c1258 100644
> --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> @@ -174,5 +174,8 @@ DPDK_16.11 {
>   	rte_eal_dev_detach;
>   	rte_eal_vdrv_register;
>   	rte_eal_vdrv_unregister;
> +	soc_driver_list;
> +	rte_eal_soc_register;
> +	rte_eal_soc_unregister;

I believe people prefer these entries to be in alphabetical order.

>   
>   } DPDK_16.07;

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

* Re: [PATCH v3 12/15] ether: extract function eth_dev_get_intr_handle
  2016-09-09  8:43   ` [PATCH v3 12/15] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
@ 2016-09-15 13:02     ` Hunt, David
  2016-09-15 14:05       ` Thomas Monjalon
  0 siblings, 1 reply; 231+ messages in thread
From: Hunt, David @ 2016-09-15 13:02 UTC (permalink / raw)
  To: Shreyansh Jain, dev; +Cc: viktorin, hemant.agrawal


On 9/9/2016 9:43 AM, Shreyansh Jain wrote:
> We abstract access to the intr_handle here as we want to get
> it either from the pci_dev or soc_dev.
>
> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
>   lib/librte_ether/rte_ethdev.c | 15 +++++++++++++--
>   1 file changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index e9f5467..104ea4a 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -2526,6 +2526,17 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
>   	rte_spinlock_unlock(&rte_eth_dev_cb_lock);
>   }
>   
> +static inline
> +struct rte_intr_handle *eth_dev_get_intr_handle(struct rte_eth_dev *dev)
> +{
> +	if (dev->pci_dev) {
> +		return &dev->pci_dev->intr_handle;
> +	}
> +
> +	RTE_VERIFY(0);

Rather than RTE_VERIFY(0), might I suggest using rte_panic with a more 
relevant error message?


> +	return NULL;
> +}
> +
>   int
>   rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
>   {
> @@ -2538,7 +2549,7 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>   
>   	dev = &rte_eth_devices[port_id];
> -	intr_handle = &dev->pci_dev->intr_handle;
> +	intr_handle = eth_dev_get_intr_handle(dev);
>   	if (!intr_handle->intr_vec) {
>   		RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
>   		return -EPERM;
> @@ -2598,7 +2609,7 @@ rte_eth_dev_rx_intr_ctl_q(uint8_t port_id, uint16_t queue_id,
>   		return -EINVAL;
>   	}
>   
> -	intr_handle = &dev->pci_dev->intr_handle;
> +	intr_handle = eth_dev_get_intr_handle(dev);
>   	if (!intr_handle->intr_vec) {
>   		RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
>   		return -EPERM;

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

* Re: [PATCH v3 13/15] ether: extract function eth_dev_get_driver_name
  2016-09-09  8:43   ` [PATCH v3 13/15] ether: extract function eth_dev_get_driver_name Shreyansh Jain
@ 2016-09-15 13:03     ` Hunt, David
  0 siblings, 0 replies; 231+ messages in thread
From: Hunt, David @ 2016-09-15 13:03 UTC (permalink / raw)
  To: Shreyansh Jain, dev; +Cc: viktorin, hemant.agrawal



On 9/9/2016 9:43 AM, Shreyansh Jain wrote:
> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
>   lib/librte_ether/rte_ethdev.c | 15 ++++++++++++++-
>   1 file changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index 104ea4a..4fa65ca 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -2568,6 +2568,17 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
>   	return 0;
>   }
>   
> +static inline
> +const char *eth_dev_get_driver_name(const struct rte_eth_dev *dev)
> +{
> +	if (dev->pci_dev) {
> +		return dev->driver->pci_drv.driver.name;
> +	}
> +
> +	RTE_VERIFY(0);

Same comment as last patch, maybe add an rte_panic with more descriptive 
error message.

> +	return NULL;
> +}
> +
>   const struct rte_memzone *
>   rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
>   			 uint16_t queue_id, size_t size, unsigned align,
> @@ -2575,9 +2586,11 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
>   {
>   	char z_name[RTE_MEMZONE_NAMESIZE];
>   	const struct rte_memzone *mz;
> +	const char *drv_name;
>   
> +	drv_name = eth_dev_get_driver_name(dev);
>   	snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
> -		 dev->driver->pci_drv.driver.name, ring_name,
> +		 drv_name, ring_name,
>   		 dev->data->port_id, queue_id);
>   
>   	mz = rte_memzone_lookup(z_name);

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

* Re: [PATCH v3 02/15] eal/soc: add rte_eal_soc_register/unregister logic
  2016-09-15 13:00     ` Hunt, David
@ 2016-09-15 13:09       ` Jan Viktorin
  2016-09-15 14:09         ` Thomas Monjalon
  0 siblings, 1 reply; 231+ messages in thread
From: Jan Viktorin @ 2016-09-15 13:09 UTC (permalink / raw)
  To: Hunt, David; +Cc: Shreyansh Jain, dev, hemant.agrawal

On Thu, 15 Sep 2016 14:00:25 +0100
"Hunt, David" <david.hunt@intel.com> wrote:

> > new file mode 100644
> > index 0000000..56135ed
> > --- /dev/null
> > +++ b/lib/librte_eal/common/eal_common_soc.c
> > @@ -0,0 +1,56 @@
> > +/*-
> > + *   BSD LICENSE
> > + *
> > + *   Copyright(c) 2016 RehiveTech. All rights reserved.
> > + *   All rights reserved.  
> 
> Duplicate "All rights reserved"

This is present in many source files in DPDK... I don't know why.

lib/librte_eal/common/eal_common_pci.c
lib/librte_eal/common/eal_common_dev.c
...

Jan

> 
> > + *
> > + *   Redistribution and use in source and binary forms, with or without
> > + *   modification, are permitted provided that the following conditions
> > + *   are met:
> > + *
> > + *     * Redistributions of source code must retain the above copyright
> > + *       notice, this list of conditions and the following disclaimer.
> > + *     * Redistributions in binary form must reproduce the above copyright
> > + *       notice, this list of conditions and the following disclaimer in
> > + *       the documentation and/or other materials provided with the
> > + *       distribution.
> > + *     * Neither the name of RehiveTech nor the names of its
> > + *       contributors may be used to endorse or promote products derived
> > + *       from this software without specific prior written permission.
> > + *

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

* Re: [PATCH v3 12/15] ether: extract function eth_dev_get_intr_handle
  2016-09-15 13:02     ` Hunt, David
@ 2016-09-15 14:05       ` Thomas Monjalon
  2016-09-16  7:17         ` Panu Matilainen
  0 siblings, 1 reply; 231+ messages in thread
From: Thomas Monjalon @ 2016-09-15 14:05 UTC (permalink / raw)
  To: Hunt, David, Shreyansh Jain; +Cc: dev, viktorin, hemant.agrawal

2016-09-15 14:02, Hunt, David:
> On 9/9/2016 9:43 AM, Shreyansh Jain wrote:
> > +static inline
> > +struct rte_intr_handle *eth_dev_get_intr_handle(struct rte_eth_dev *dev)
> > +{
> > +	if (dev->pci_dev) {
> > +		return &dev->pci_dev->intr_handle;
> > +	}
> > +
> > +	RTE_VERIFY(0);
> 
> Rather than RTE_VERIFY(0), might I suggest using rte_panic with a more 
> relevant error message?

RTE_ASSERT is preferred.
We must stop adding some rte_panic calls except for debug.

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

* Re: [PATCH v3 02/15] eal/soc: add rte_eal_soc_register/unregister logic
  2016-09-15 13:09       ` Jan Viktorin
@ 2016-09-15 14:09         ` Thomas Monjalon
  2016-09-16  7:32           ` Panu Matilainen
  0 siblings, 1 reply; 231+ messages in thread
From: Thomas Monjalon @ 2016-09-15 14:09 UTC (permalink / raw)
  To: Jan Viktorin, Hunt, David, Shreyansh Jain; +Cc: dev, hemant.agrawal

2016-09-15 15:09, Jan Viktorin:
> On Thu, 15 Sep 2016 14:00:25 +0100
> "Hunt, David" <david.hunt@intel.com> wrote:
> 
> > > new file mode 100644
> > > index 0000000..56135ed
> > > --- /dev/null
> > > +++ b/lib/librte_eal/common/eal_common_soc.c
> > > @@ -0,0 +1,56 @@
> > > +/*-
> > > + *   BSD LICENSE
> > > + *
> > > + *   Copyright(c) 2016 RehiveTech. All rights reserved.
> > > + *   All rights reserved.  
> > 
> > Duplicate "All rights reserved"
> 
> This is present in many source files in DPDK... I don't know why.
> 
> lib/librte_eal/common/eal_common_pci.c
> lib/librte_eal/common/eal_common_dev.c
> ...

It would deserve a dedicated thread to discuss legal sense of these things.
I'm not a lawyer but I think "All rights reserved." has no real sense.

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

* Re: [PATCH v3 00/15] Introduce SoC device/driver framework for EAL
  2016-09-15 12:56   ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Hunt, David
@ 2016-09-16  6:14     ` Shreyansh Jain
  0 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-16  6:14 UTC (permalink / raw)
  To: Hunt, David, dev; +Cc: viktorin, Hemant Agrawal

Hi David,

> -----Original Message-----
> From: Hunt, David [mailto:david.hunt@intel.com]
> Sent: Thursday, September 15, 2016 6:26 PM
> To: Shreyansh Jain <shreyansh.jain@nxp.com>; dev@dpdk.org
> Cc: viktorin@rehivetech.com; Hemant Agrawal <hemant.agrawal@nxp.com>
> Subject: Re: [dpdk-dev] [PATCH v3 00/15] Introduce SoC device/driver
> framework for EAL
> 
> Shreyansh, Jan, Hemant,
> 
> On 9/9/2016 9:43 AM, Shreyansh Jain wrote:
> > Introduction:
> > =============
> >
> > This patch set is direct derivative of Jan's original series [1],[2].
> >
> >   - As this deviates substantially from original series, if need be I can
> >     post it as a separate patch rather than v2. Please suggest.
> >   - Also, there are comments on original v1 ([4]) which are _not_
> >     incorporated in this series as they refer to section no more in new
> >     version.
> >   - This v3 version is based on the rte_driver/device patchset v9 [10].
> >     That series introduced device structures (rte_driver/rte_device)
> >     generalizing devices into PCI, VDEV, XXX. For the purpose of this
> >     patchset, XXX=>SOC.
> >
> >
> ---snip---
> 
>      FYI, I've reviewed this patch set, and it looks to me like there's
> some very good work here. Each patch in the set builds nicely on the one
> before, and logically introduces the changes one by one.

Great. Thank you so much for reviewing this series. It would really help us move it ahead and introduce other series which are based on it.

> 
>     I've no functional suggestions as the implementation looks clean,
> but I've one or two tiny suggestions on headers and error messages. I'll
> add a reply to the relevant patches in the set.

I will have a look at those and fix them soon (v4). 

> 
> Also, there's one or two issues thrown up by checkpatch, but I suspect
> they're false positives, as I'm using the 4.6 kernel version.

Thanks for headup - I will see/fix those in v4, if any. 


> 
> Regards,
> Dave
> 

-
Shreyansh

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

* Re: [PATCH v3 01/15] eal/soc: introduce very essential SoC infra definitions
  2016-09-15 12:58     ` Hunt, David
@ 2016-09-16  6:17       ` Shreyansh Jain
  0 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-16  6:17 UTC (permalink / raw)
  To: Hunt, David, dev; +Cc: viktorin, Hemant Agrawal

Hi David,

> -----Original Message-----
> From: Hunt, David [mailto:david.hunt@intel.com]
> Sent: Thursday, September 15, 2016 6:29 PM
> To: Shreyansh Jain <shreyansh.jain@nxp.com>; dev@dpdk.org
> Cc: viktorin@rehivetech.com; Hemant Agrawal <hemant.agrawal@nxp.com>
> Subject: Re: [dpdk-dev] [PATCH v3 01/15] eal/soc: introduce very essential
> SoC infra definitions
> 
> Some small comments below:
> 
> On 9/9/2016 9:43 AM, Shreyansh Jain wrote:
> > Define initial structures and functions for the SoC infrastructure.
> > This patch supports only a very minimal functions for now.
> > More features will be added in the following commits.
> >
> > Includes rte_device/rte_driver inheritance of
> > rte_soc_device/rte_soc_driver.
> >
> > Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> > Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> > Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> > ---
> >   app/test/Makefile                       |   1 +
> >   app/test/test_soc.c                     |  90 +++++++++++++++++++++
> >   lib/librte_eal/common/Makefile          |   2 +-
> >   lib/librte_eal/common/eal_private.h     |   4 +
> >   lib/librte_eal/common/include/rte_soc.h | 138
> ++++++++++++++++++++++++++++++++
> >   5 files changed, 234 insertions(+), 1 deletion(-)
> >   create mode 100644 app/test/test_soc.c
> >   create mode 100644 lib/librte_eal/common/include/rte_soc.h
> >
> > diff --git a/app/test/Makefile b/app/test/Makefile
> > index 611d77a..64b261d 100644
> > --- a/app/test/Makefile
> > +++ b/app/test/Makefile
> > @@ -77,6 +77,7 @@ APP = test
> >   #
> >   SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) := commands.c
> >   SRCS-y += test.c
> > +SRCS-y += test_soc.c
> >   SRCS-y += resource.c
> >   SRCS-y += test_resource.c
> >   test_resource.res: test_resource.c
> > diff --git a/app/test/test_soc.c b/app/test/test_soc.c
> > new file mode 100644
> > index 0000000..916a863
> > --- /dev/null
> > +++ b/app/test/test_soc.c
> > @@ -0,0 +1,90 @@
> > +/*-
> > + *   BSD LICENSE
> > + *
> > + *   Copyright(c) 2016 RehiveTech. All rights reserved.
> > + *   All rights reserved.
> 
> Remove un-needed "All rights reserved"
 
I think duplicated messages doesn't make sense. I can remove them. But, I would like to wait a while based on the mails from Jan and Thomas - in case this is expected.
As far as I know, only a single 'All rights reserved' is required - probably the lower one got left out in some very early license copy operations and continued unnoticed. (git blame? :D)

> 
> > + *
> > + *   Redistribution and use in source and binary forms, with or without
> > + *   modification, are permitted provided that the following conditions
> > + *   are met:
> > + *
> > + *     * Redistributions of source code must retain the above copyright
> > + *       notice, this list of conditions and the following disclaimer.
> > + *     * Redistributions in binary form must reproduce the above copyright
> > + *       notice, this list of conditions and the following disclaimer in
> > + *       the documentation and/or other materials provided with the
> > + *       distribution.
> > + *     * Neither the name of RehiveTech nor the names of its
> > + *       contributors may be used to endorse or promote products derived
> > + *       from this software without specific prior written permission.
> > + *
> > + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> > + */
> > +
> > +#include <stdio.h>
> > +#include <string.h>
> > +#include <stdint.h>
> > +#include <sys/queue.h>
> > +
> > +#include <rte_soc.h>
> > +#include <rte_devargs.h>
> > +#include <rte_debug.h>
> > +
> > +#include "test.h"
> > +
> > +static char *safe_strdup(const char *s)
> > +{
> > +	char *c = strdup(s);
> > +
> > +	if (c == NULL)
> > +		rte_panic("failed to strdup '%s'\n", s);
> > +
> > +	return c;
> > +}
> > +
> > +static int test_compare_addr(void)
> > +{
> > +	struct rte_soc_addr a0;
> > +	struct rte_soc_addr a1;
> > +	struct rte_soc_addr a2;
> > +
> > +	a0.name = safe_strdup("ethernet0");
> > +	a0.fdt_path = NULL;
> > +
> > +	a1.name = safe_strdup("ethernet0");
> > +	a1.fdt_path = NULL;
> > +
> > +	a2.name = safe_strdup("ethernet1");
> > +	a2.fdt_path = NULL;
> > +
> > +	TEST_ASSERT(!rte_eal_compare_soc_addr(&a0, &a1),
> > +		    "Failed to compare two soc addresses that equal");
> > +	TEST_ASSERT(rte_eal_compare_soc_addr(&a0, &a2),
> > +		    "Failed to compare two soc addresses that differs");
> > +
> > +	free(a2.name);
> > +	free(a1.name);
> > +	free(a0.name);
> > +	return 0;
> > +}
> > +
> > +static int
> > +test_soc(void)
> > +{
> > +	if (test_compare_addr())
> > +		return -1;
> > +
> > +	return 0;
> > +}
> > +
> > +REGISTER_TEST_COMMAND(soc_autotest, test_soc);
> > diff --git a/lib/librte_eal/common/Makefile
> b/lib/librte_eal/common/Makefile
> > index dfd64aa..b414008 100644
> > --- a/lib/librte_eal/common/Makefile
> > +++ b/lib/librte_eal/common/Makefile
> > @@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
> >
> >   INC := rte_branch_prediction.h rte_common.h
> >   INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
> > -INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
> > +INC += rte_log.h rte_memory.h rte_memzone.h rte_soc.h rte_pci.h
> >   INC += rte_per_lcore.h rte_random.h
> >   INC += rte_tailq.h rte_interrupts.h rte_alarm.h
> >   INC += rte_string_fns.h rte_version.h
> > diff --git a/lib/librte_eal/common/eal_private.h
> b/lib/librte_eal/common/eal_private.h
> > index 431d6c2..df6582d 100644
> > --- a/lib/librte_eal/common/eal_private.h
> > +++ b/lib/librte_eal/common/eal_private.h
> > @@ -36,6 +36,7 @@
> >
> >   #include <stdio.h>
> >   #include <rte_pci.h>
> > +#include <rte_soc.h>
> >
> >   /**
> >    * Initialize the memzone subsystem (private to eal).
> > @@ -126,6 +127,9 @@ int rte_eal_log_init(const char *id, int facility);
> >    */
> >   int rte_eal_pci_init(void);
> >
> > +struct rte_soc_driver;
> > +struct rte_soc_device;
> > +
> >   struct rte_pci_driver;
> >   struct rte_pci_device;
> >
> > diff --git a/lib/librte_eal/common/include/rte_soc.h
> b/lib/librte_eal/common/include/rte_soc.h
> > new file mode 100644
> > index 0000000..bc0a43b
> > --- /dev/null
> > +++ b/lib/librte_eal/common/include/rte_soc.h
> > @@ -0,0 +1,138 @@
> > +/*-
> > + *   BSD LICENSE
> > + *
> > + *   Copyright(c) 2016 RehiveTech. All rights reserved.
> > + *   All rights reserved.
> 
> Remove un-needed "All rights reserved"

Same as above. I prefer to remove but I'll wait a while in case someone has anything else to add to this.

> 
> > + *
> > + *   Redistribution and use in source and binary forms, with or without
> > + *   modification, are permitted provided that the following conditions
> > + *   are met:
> > + *
> > + *     * Redistributions of source code must retain the above copyright
> > + *       notice, this list of conditions and the following disclaimer.
> > + *     * Redistributions in binary form must reproduce the above copyright
> > + *       notice, this list of conditions and the following disclaimer in
> > + *       the documentation and/or other materials provided with the
> > + *       distribution.
> > + *     * Neither the name of RehiveTech nor the names of its
> > + *       contributors may be used to endorse or promote products derived
> > + *       from this software without specific prior written permission.
> > + *
> > + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> > + */
> > +
> > +#ifndef _RTE_SOC_H_
> > +#define _RTE_SOC_H_
> > +
> > +/**
> > + * @file
> > + *
> > + * RTE SoC Interface
> > + */
> > +
> > +#ifdef __cplusplus
> > +extern "C" {
> > +#endif
> > +
> > +#include <stdio.h>
> > +#include <stdlib.h>
> > +#include <stdint.h>
> > +#include <inttypes.h>
> > +#include <string.h>
> > +
> > +#include <rte_dev.h>
> > +#include <rte_debug.h>
> > +
> > +struct rte_soc_id {
> > +	const char *compatible; /**< OF compatible specification */
> > +	uint64_t priv_data;     /**< SoC Driver specific data */
> > +};
> > +
> > +struct rte_soc_addr {
> > +	char *name;     /**< name used in sysfs */
> > +	char *fdt_path; /**< path to the associated node in FDT */
> > +};
> > +
> > +/**
> > + * A structure describing a SoC device.
> > + */
> > +struct rte_soc_device {
> > +	TAILQ_ENTRY(rte_soc_device) next;   /**< Next probed SoC device */
> > +	struct rte_device device;           /**< Inherit code device */
> > +	struct rte_soc_addr addr;           /**< SoC device Location */
> > +	struct rte_soc_id *id;              /**< SoC device ID list */
> > +	struct rte_soc_driver *driver;      /**< Associated driver */
> > +};
> > +
> > +struct rte_soc_driver;
> > +
> > +/**
> > + * Initialization function for the driver called during SoC probing.
> > + */
> > +typedef int (soc_devinit_t)(struct rte_soc_driver *, struct rte_soc_device
> *);
> > +
> > +/**
> > + * Uninitialization function for the driver called during hotplugging.
> > + */
> > +typedef int (soc_devuninit_t)(struct rte_soc_device *);
> > +
> > +/**
> > + * A structure describing a SoC driver.
> > + */
> > +struct rte_soc_driver {
> > +	TAILQ_ENTRY(rte_soc_driver) next;  /**< Next in list */
> > +	struct rte_driver driver;          /**< Inherit core driver. */
> > +	soc_devinit_t *devinit;            /**< Device initialization */
> > +	soc_devuninit_t *devuninit;        /**< Device uninitialization */
> > +	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
> > +};
> > +
> > +/**
> > + * Utility function to write a SoC device name, this device name can later
> be
> > + * used to retrieve the corresponding rte_soc_addr using above functions.
> > + *
> > + * @param addr
> > + *	The SoC address
> > + * @param output
> > + *	The output buffer string
> > + * @param size
> > + *	The output buffer size
> > + * @return
> > + *  0 on success, negative on error.
> > + */
> > +static inline void
> > +rte_eal_soc_device_name(const struct rte_soc_addr *addr,
> > +			char *output, size_t size)
> > +{
> > +	int ret;
> > +
> > +	RTE_VERIFY(addr != NULL);
> > +	RTE_VERIFY(size >= strlen(addr->name));
> > +	ret = snprintf(output, size, "%s", addr->name);
> > +	RTE_VERIFY(ret >= 0);
> > +}
> > +
> > +static inline int
> > +rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
> > +			 const struct rte_soc_addr *a1)
> > +{
> > +	if (a0 == NULL || a1 == NULL)
> > +		return -1;
> > +
> > +	RTE_VERIFY(a0->name != NULL);
> > +	RTE_VERIFY(a1->name != NULL);
> > +
> > +	return strcmp(a0->name, a1->name);
> > +}
> > +
> > +#endif

-
Shreyansh

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

* Re: [PATCH v3 12/15] ether: extract function eth_dev_get_intr_handle
  2016-09-15 14:05       ` Thomas Monjalon
@ 2016-09-16  7:17         ` Panu Matilainen
  0 siblings, 0 replies; 231+ messages in thread
From: Panu Matilainen @ 2016-09-16  7:17 UTC (permalink / raw)
  To: Thomas Monjalon, Hunt, David, Shreyansh Jain
  Cc: dev, viktorin, hemant.agrawal

On 09/15/2016 05:05 PM, Thomas Monjalon wrote:
> 2016-09-15 14:02, Hunt, David:
>> On 9/9/2016 9:43 AM, Shreyansh Jain wrote:
>>> +static inline
>>> +struct rte_intr_handle *eth_dev_get_intr_handle(struct rte_eth_dev *dev)
>>> +{
>>> +	if (dev->pci_dev) {
>>> +		return &dev->pci_dev->intr_handle;
>>> +	}
>>> +
>>> +	RTE_VERIFY(0);
>>
>> Rather than RTE_VERIFY(0), might I suggest using rte_panic with a more
>> relevant error message?
>
> RTE_ASSERT is preferred.
> We must stop adding some rte_panic calls except for debug.

+1

It wouldn't hurt to make that a hard rule.

	- Panu -

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

* Re: [PATCH v3 02/15] eal/soc: add rte_eal_soc_register/unregister logic
  2016-09-15 14:09         ` Thomas Monjalon
@ 2016-09-16  7:32           ` Panu Matilainen
  0 siblings, 0 replies; 231+ messages in thread
From: Panu Matilainen @ 2016-09-16  7:32 UTC (permalink / raw)
  To: Thomas Monjalon, Jan Viktorin, Hunt, David, Shreyansh Jain
  Cc: dev, hemant.agrawal

On 09/15/2016 05:09 PM, Thomas Monjalon wrote:
> 2016-09-15 15:09, Jan Viktorin:
>> On Thu, 15 Sep 2016 14:00:25 +0100
>> "Hunt, David" <david.hunt@intel.com> wrote:
>>
>>>> new file mode 100644
>>>> index 0000000..56135ed
>>>> --- /dev/null
>>>> +++ b/lib/librte_eal/common/eal_common_soc.c
>>>> @@ -0,0 +1,56 @@
>>>> +/*-
>>>> + *   BSD LICENSE
>>>> + *
>>>> + *   Copyright(c) 2016 RehiveTech. All rights reserved.
>>>> + *   All rights reserved.
>>>
>>> Duplicate "All rights reserved"
>>
>> This is present in many source files in DPDK... I don't know why.
>>
>> lib/librte_eal/common/eal_common_pci.c
>> lib/librte_eal/common/eal_common_dev.c
>> ...
>
> It would deserve a dedicated thread to discuss legal sense of these things.
> I'm not a lawyer but I think "All rights reserved." has no real sense.
>

 From a layman (such as myself) perspective it indeed seems totally 
ludicrous in the context of this particular license :) Whether it makes 
more sense to lawyers I wouldn't know, but as for the background: it's 
present in both 2- and 3-clause BSD licenses so *one* of them is 
probably best left alone.

According to https://fedoraproject.org/wiki/Licensing:BSD, in the 
3-clause BSD license "All rights reserved" is on a line of its own. In 
the other variants it follows the copyright holder. So that's probably 
where the duplicates originate from.

	- Panu -

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

* Re: [PATCH v3 04/15] eal: introduce --no-soc option
  2016-09-09  8:43   ` [PATCH v3 04/15] eal: introduce --no-soc option Shreyansh Jain
@ 2016-09-16 11:36     ` Jan Viktorin
  2016-09-16 11:55       ` Shreyansh Jain
  0 siblings, 1 reply; 231+ messages in thread
From: Jan Viktorin @ 2016-09-16 11:36 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, hemant.agrawal, Thomas Monjalon, David Marchand

Hello Shreyansh,

there was an objection to reverse this option from negative
to positive semantics:

http://dpdk.org/ml/archives/dev/2016-May/038953.html

As SoC infrastructure would to be experimental for some time,
I think it is a good idea to disable it as default.

Regards
Jan

On Fri, 9 Sep 2016 14:13:48 +0530
Shreyansh Jain <shreyansh.jain@nxp.com> wrote:

> This option has the same meaning for the SoC infra as the --no-pci
> for the PCI infra.
> 
> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
>  lib/librte_eal/common/eal_common_options.c | 5 +++++
>  lib/librte_eal/common/eal_internal_cfg.h   | 1 +
>  lib/librte_eal/common/eal_options.h        | 2 ++
>  3 files changed, 8 insertions(+)
> 
> diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
> index 1a1bab3..d97cf0a 100644
> --- a/lib/librte_eal/common/eal_common_options.c
> +++ b/lib/librte_eal/common/eal_common_options.c
> @@ -85,6 +85,7 @@ eal_long_options[] = {
>  	{OPT_NO_HPET,           0, NULL, OPT_NO_HPET_NUM          },
>  	{OPT_NO_HUGE,           0, NULL, OPT_NO_HUGE_NUM          },
>  	{OPT_NO_PCI,            0, NULL, OPT_NO_PCI_NUM           },
> +	{OPT_NO_SOC,            0, NULL, OPT_NO_SOC_NUM           },
>  	{OPT_NO_SHCONF,         0, NULL, OPT_NO_SHCONF_NUM        },
>  	{OPT_PCI_BLACKLIST,     1, NULL, OPT_PCI_BLACKLIST_NUM    },
>  	{OPT_PCI_WHITELIST,     1, NULL, OPT_PCI_WHITELIST_NUM    },
> @@ -855,6 +856,10 @@ eal_parse_common_option(int opt, const char *optarg,
>  		conf->no_pci = 1;
>  		break;
>  
> +	case OPT_NO_SOC_NUM:
> +		conf->no_soc = 1;
> +		break;
> +
>  	case OPT_NO_HPET_NUM:
>  		conf->no_hpet = 1;
>  		break;
> diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
> index 5f1367e..3a98e94 100644
> --- a/lib/librte_eal/common/eal_internal_cfg.h
> +++ b/lib/librte_eal/common/eal_internal_cfg.h
> @@ -67,6 +67,7 @@ struct internal_config {
>  	unsigned hugepage_unlink;         /**< true to unlink backing files */
>  	volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
>  	volatile unsigned no_pci;         /**< true to disable PCI */
> +	volatile unsigned no_soc;         /**< true to disable SoC */
>  	volatile unsigned no_hpet;        /**< true to disable HPET */
>  	volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
>  										* instead of native TSC */
> diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
> index a881c62..ba1e704 100644
> --- a/lib/librte_eal/common/eal_options.h
> +++ b/lib/librte_eal/common/eal_options.h
> @@ -69,6 +69,8 @@ enum {
>  	OPT_NO_HUGE_NUM,
>  #define OPT_NO_PCI            "no-pci"
>  	OPT_NO_PCI_NUM,
> +#define OPT_NO_SOC            "no-soc"
> +	OPT_NO_SOC_NUM,
>  #define OPT_NO_SHCONF         "no-shconf"
>  	OPT_NO_SHCONF_NUM,
>  #define OPT_SOCKET_MEM        "socket-mem"



-- 
   Jan Viktorin                  E-mail: Viktorin@RehiveTech.com
   System Architect              Web:    www.RehiveTech.com
   RehiveTech
   Brno, Czech Republic

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

* Re: [PATCH v3 04/15] eal: introduce --no-soc option
  2016-09-16 11:36     ` Jan Viktorin
@ 2016-09-16 11:55       ` Shreyansh Jain
  0 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-16 11:55 UTC (permalink / raw)
  To: Jan Viktorin; +Cc: dev, hemant.agrawal, Thomas Monjalon, David Marchand

Hello Jan,

On Friday 16 September 2016 05:06 PM, Jan Viktorin wrote:
> Hello Shreyansh,
>
> there was an objection to reverse this option from negative
> to positive semantics:
>
> http://dpdk.org/ml/archives/dev/2016-May/038953.html

Ok. I wasn't aware of this. Sounds reasonable as SoC is experimental for 
some time.

>
> As SoC infrastructure would to be experimental for some time,
> I think it is a good idea to disable it as default.

Agree - I will update this in v4. Thanks for bringing it to notice.

>
> Regards
> Jan
>
> On Fri, 9 Sep 2016 14:13:48 +0530
> Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
>
>> This option has the same meaning for the SoC infra as the --no-pci
>> for the PCI infra.
>>
>> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
>> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>> ---
>>  lib/librte_eal/common/eal_common_options.c | 5 +++++
>>  lib/librte_eal/common/eal_internal_cfg.h   | 1 +
>>  lib/librte_eal/common/eal_options.h        | 2 ++
>>  3 files changed, 8 insertions(+)
>>
>> diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
>> index 1a1bab3..d97cf0a 100644
>> --- a/lib/librte_eal/common/eal_common_options.c
>> +++ b/lib/librte_eal/common/eal_common_options.c
>> @@ -85,6 +85,7 @@ eal_long_options[] = {
>>  	{OPT_NO_HPET,           0, NULL, OPT_NO_HPET_NUM          },
>>  	{OPT_NO_HUGE,           0, NULL, OPT_NO_HUGE_NUM          },
>>  	{OPT_NO_PCI,            0, NULL, OPT_NO_PCI_NUM           },
>> +	{OPT_NO_SOC,            0, NULL, OPT_NO_SOC_NUM           },
>>  	{OPT_NO_SHCONF,         0, NULL, OPT_NO_SHCONF_NUM        },
>>  	{OPT_PCI_BLACKLIST,     1, NULL, OPT_PCI_BLACKLIST_NUM    },
>>  	{OPT_PCI_WHITELIST,     1, NULL, OPT_PCI_WHITELIST_NUM    },
>> @@ -855,6 +856,10 @@ eal_parse_common_option(int opt, const char *optarg,
>>  		conf->no_pci = 1;
>>  		break;
>>
>> +	case OPT_NO_SOC_NUM:
>> +		conf->no_soc = 1;
>> +		break;
>> +
>>  	case OPT_NO_HPET_NUM:
>>  		conf->no_hpet = 1;
>>  		break;
>> diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
>> index 5f1367e..3a98e94 100644
>> --- a/lib/librte_eal/common/eal_internal_cfg.h
>> +++ b/lib/librte_eal/common/eal_internal_cfg.h
>> @@ -67,6 +67,7 @@ struct internal_config {
>>  	unsigned hugepage_unlink;         /**< true to unlink backing files */
>>  	volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
>>  	volatile unsigned no_pci;         /**< true to disable PCI */
>> +	volatile unsigned no_soc;         /**< true to disable SoC */
>>  	volatile unsigned no_hpet;        /**< true to disable HPET */
>>  	volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
>>  										* instead of native TSC */
>> diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
>> index a881c62..ba1e704 100644
>> --- a/lib/librte_eal/common/eal_options.h
>> +++ b/lib/librte_eal/common/eal_options.h
>> @@ -69,6 +69,8 @@ enum {
>>  	OPT_NO_HUGE_NUM,
>>  #define OPT_NO_PCI            "no-pci"
>>  	OPT_NO_PCI_NUM,
>> +#define OPT_NO_SOC            "no-soc"
>> +	OPT_NO_SOC_NUM,
>>  #define OPT_NO_SHCONF         "no-shconf"
>>  	OPT_NO_SHCONF_NUM,
>>  #define OPT_SOCKET_MEM        "socket-mem"
>
>
>

-
Shreyansh

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

* Re: [PATCH v3 06/15] eal/soc: implement probing of drivers
  2016-09-09  8:43   ` [PATCH v3 06/15] eal/soc: implement probing of drivers Shreyansh Jain
@ 2016-09-16 12:27     ` Jan Viktorin
  2016-09-19  6:47       ` Shreyansh Jain
  0 siblings, 1 reply; 231+ messages in thread
From: Jan Viktorin @ 2016-09-16 12:27 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, hemant.agrawal

On Fri, 9 Sep 2016 14:13:50 +0530
Shreyansh Jain <shreyansh.jain@nxp.com> wrote:

> Each SoC PMD registers a set of callback for scanning its own bus/infra and
> matching devices to drivers when probe is called.
> This patch introduces the infra for calls to SoC scan on rte_eal_soc_init()
> and match on rte_eal_soc_probe().
> 
> Patch also adds test case for scan and probe.
> 
> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
>  app/test/test_soc.c                             | 138 ++++++++++++++-
>  lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   4 +
>  lib/librte_eal/common/eal_common_soc.c          | 215 ++++++++++++++++++++++++
>  lib/librte_eal/common/include/rte_soc.h         |  51 ++++++
>  lib/librte_eal/linuxapp/eal/eal.c               |   5 +
>  lib/librte_eal/linuxapp/eal/eal_soc.c           |  16 ++
>  lib/librte_eal/linuxapp/eal/rte_eal_version.map |   4 +
>  7 files changed, 432 insertions(+), 1 deletion(-)
> 
> diff --git a/app/test/test_soc.c b/app/test/test_soc.c
> index ac03e64..d2b9462 100644
> --- a/app/test/test_soc.c
> +++ b/app/test/test_soc.c
> @@ -87,14 +87,45 @@ static int test_compare_addr(void)
>   */
>  struct test_wrapper {
>  	struct rte_soc_driver soc_drv;
> +	struct rte_soc_device soc_dev;
>  };
>  
> +static int empty_pmd0_devinit(struct rte_soc_driver *drv,
> +			      struct rte_soc_device *dev);
> +static int empty_pmd0_devuninit(struct rte_soc_device *dev);

I prefer an empty line here.


What is the prupose of the scan here? What device does it provide
to the test? I'd prefer to call it e.g. "allways_find_device0" or
something describing the purpose and explaining what is the goal
of the related test.

Probably a comment explaining "provide a device named 'empty_pmd0_dev'
would be helpful.

> +static void test_soc_scan_dev0_cb(void);

Similar here, something like "match_by_name".

> +static int test_soc_match_dev0_cb(struct rte_soc_driver *drv,
> +				  struct rte_soc_device *dev);

I prefer an empty line here.


ditto...

> +static void test_soc_scan_dev1_cb(void);

ditto...

> +static int test_soc_match_dev1_cb(struct rte_soc_driver *drv,
> +				  struct rte_soc_device *dev);
> +
> +static int
> +empty_pmd0_devinit(struct rte_soc_driver *drv __rte_unused,
> +		   struct rte_soc_device *dev __rte_unused)
> +{
> +	return 0;
> +}
> +
> +static int
> +empty_pmd0_devuninit(struct rte_soc_device *dev)
> +{
> +	/* Release the memory associated with dev->addr.name */
> +	free(dev->addr.name);
> +
> +	return 0;
> +}
> +
>  struct test_wrapper empty_pmd0 = {
>  	.soc_drv = {
>  		.driver = {
>  			.name = "empty_pmd0"
>  		},
> -	},
> +		.devinit = empty_pmd0_devinit,
> +		.devuninit = empty_pmd0_devuninit,
> +		.scan_fn = test_soc_scan_dev0_cb,
> +		.match_fn = test_soc_match_dev0_cb,
> +	}
>  };
>  
>  struct test_wrapper empty_pmd1 = {
> @@ -102,9 +133,54 @@ struct test_wrapper empty_pmd1 = {
>  		.driver = {
>  			.name = "empty_pmd1"
>  		},
> +		.scan_fn = test_soc_scan_dev1_cb,
> +		.match_fn = test_soc_match_dev1_cb,
>  	},
>  };
>  
> +static void
> +test_soc_scan_dev0_cb(void)
> +{
> +	/* SoC's scan would scan devices on its bus and add to
> +	 * soc_device_list
> +	 */
> +	empty_pmd0.soc_dev.addr.name = strdup("empty_pmd0_dev");
> +
> +	TAILQ_INSERT_TAIL(&soc_device_list, &empty_pmd0.soc_dev, next);
> +}
> +
> +static int
> +test_soc_match_dev0_cb(struct rte_soc_driver *drv __rte_unused,
> +		       struct rte_soc_device *dev)
> +{
> +	if (!dev->addr.name || strcmp(dev->addr.name, "empty_pmd0_dev"))
> +		return 0;
> +
> +	return 1;
> +}
> +
> +
> +static void
> +test_soc_scan_dev1_cb(void)
> +{
> +	/* SoC's scan would scan devices on its bus and add to
> +	 * soc_device_list
> +	 */
> +	empty_pmd0.soc_dev.addr.name = strdup("empty_pmd1_dev");
> +
> +	TAILQ_INSERT_TAIL(&soc_device_list, &empty_pmd1.soc_dev, next);
> +}
> +
> +static int
> +test_soc_match_dev1_cb(struct rte_soc_driver *drv __rte_unused,
> +		       struct rte_soc_device *dev)
> +{
> +	if (!dev->addr.name || strcmp(dev->addr.name, "empty_pmd1_dev"))
> +		return 0;
> +
> +	return 1;
> +}
> +
>  static int
>  count_registered_socdrvs(void)
>  {
> @@ -148,13 +224,54 @@ test_register_unregister(void)
>  	return 0;
>  }
>  
> +/* Test Probe (scan and match) functionality */
> +static int
> +test_soc_init_and_probe(void)

You say to test scan and match. I'd prefer to reflect this in the name
of the test. Otherwise, it seems you are testing init and probe which
is not true, I think.

Do you test that "match principle works" or that "match functions are OK"
or "match functions are called as expected", ...?

> +{
> +	struct rte_soc_driver *drv;
> +
> +	/* Registering dummy drivers */
> +	rte_eal_soc_register(&empty_pmd0.soc_drv);
> +	rte_eal_soc_register(&empty_pmd1.soc_drv);
> +	/* Assuming that test_register_unregister is working, not verifying
> +	 * that drivers are indeed registered
> +	*/
> +
> +	/* rte_eal_soc_init is called by rte_eal_init, which in turn calls the
> +	 * scan_fn of each driver.
> +	 */
> +	TAILQ_FOREACH(drv, &soc_driver_list, next) {
> +		if (drv && drv->scan_fn)
> +			drv->scan_fn();
> +	}

Here, I suppose you mimic the rte_eal_soc_init?

> +
> +	/* rte_eal_init() would perform other inits here */
> +
> +	/* Probe would link the SoC devices<=>drivers */
> +	rte_eal_soc_probe();
> +
> +	/* Unregistering dummy drivers */
> +	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
> +	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
> +
> +	free(empty_pmd0.soc_dev.addr.name);
> +
> +	printf("%s has been successful\n", __func__);

How you detect it is unsuccessful? Is it possible to fail in this test?
A test that can never fail is in fact not a test :).

> +	return 0;
> +}
> +
>  /* save real devices and drivers until the tests finishes */
>  struct soc_driver_list real_soc_driver_list =
>  	TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
>  
> +/* save real devices and drivers until the tests finishes */
> +struct soc_device_list real_soc_device_list =
> +	TAILQ_HEAD_INITIALIZER(real_soc_device_list);
> +
>  static int test_soc_setup(void)
>  {
>  	struct rte_soc_driver *drv;
> +	struct rte_soc_device *dev;
>  
>  	/* no real drivers for the test */
>  	while (!TAILQ_EMPTY(&soc_driver_list)) {
> @@ -163,12 +280,20 @@ static int test_soc_setup(void)
>  		TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
>  	}
>  
> +	/* And, no real devices for the test */
> +	while (!TAILQ_EMPTY(&soc_device_list)) {
> +		dev = TAILQ_FIRST(&soc_device_list);
> +		TAILQ_REMOVE(&soc_device_list, dev, next);
> +		TAILQ_INSERT_TAIL(&real_soc_device_list, dev, next);
> +	}
> +
>  	return 0;
>  }
>  
>  static int test_soc_cleanup(void)
>  {
>  	struct rte_soc_driver *drv;
> +	struct rte_soc_device *dev;
>  
>  	/* bring back real drivers after the test */
>  	while (!TAILQ_EMPTY(&real_soc_driver_list)) {
> @@ -177,6 +302,13 @@ static int test_soc_cleanup(void)
>  		rte_eal_soc_register(drv);
>  	}
>  
> +	/* And, bring back real devices after the test */
> +	while (!TAILQ_EMPTY(&real_soc_device_list)) {
> +		dev = TAILQ_FIRST(&real_soc_device_list);
> +		TAILQ_REMOVE(&real_soc_device_list, dev, next);
> +		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
> +	}
> +
>  	return 0;
>  }
>  
> @@ -192,6 +324,10 @@ test_soc(void)
>  	if (test_register_unregister())
>  		return -1;
>  
> +	/* Assuming test_register_unregister has succeeded */
> +	if (test_soc_init_and_probe())
> +		return -1;
> +
>  	if (test_soc_cleanup())
>  		return -1;
>  
> diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> index de38848..3c407be 100644
> --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> @@ -173,5 +173,9 @@ DPDK_16.11 {
>  	rte_eal_soc_register;
>  	rte_eal_soc_unregister;
>  	rte_eal_soc_dump;
> +	rte_eal_soc_match;
> +	rte_eal_soc_detach;
> +	rte_eal_soc_probe;
> +	rte_eal_soc_probe_one;
>  
>  } DPDK_16.07;
> diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
> index 5dcddc5..bb87a67 100644
> --- a/lib/librte_eal/common/eal_common_soc.c
> +++ b/lib/librte_eal/common/eal_common_soc.c
> @@ -36,6 +36,8 @@
>  #include <sys/queue.h>
>  
>  #include <rte_log.h>
> +#include <rte_common.h>
> +#include <rte_soc.h>
>  
>  #include "eal_private.h"
>  
> @@ -45,6 +47,213 @@ struct soc_driver_list soc_driver_list =
>  struct soc_device_list soc_device_list =
>  	TAILQ_HEAD_INITIALIZER(soc_device_list);
>  
> +/* Default SoC device<->Driver match handler function */

I think this comment is redundant. All this is already said in the rte_soc.h.

> +int
> +rte_eal_soc_match(struct rte_soc_driver *drv, struct rte_soc_device *dev)
> +{
> +	int i, j;
> +
> +	RTE_VERIFY(drv != NULL && drv->id_table != NULL);
> +	RTE_VERIFY(dev != NULL && dev->id != NULL);
> +
> +	for (i = 0; drv->id_table[i].compatible; ++i) {
> +		const char *drv_compat = drv->id_table[i].compatible;
> +
> +		for (j = 0; dev->id[j].compatible; ++j) {
> +			const char *dev_compat = dev->id[j].compatible;
> +
> +			if (!strcmp(drv_compat, dev_compat))
> +				return 0;
> +		}
> +	}
> +
> +	return 1;
> +}
> +
> +
> +static int
> +rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
> +			     struct rte_soc_device *dev)
> +{
> +	int ret = 1;
> +

I think, the RTE_VERIFY(dev->match_fn) might be good here.
It avoids any doubts about the validity of the pointer.

> +	ret = drv->match_fn(drv, dev);
> +	if (ret) {
> +		RTE_LOG(DEBUG, EAL,
> +			" match function failed, skipping\n");

Is this a failure? I think it is not. Failure would be if the match
function cannot execute correctly. This is more like "no-match".

When debugging, I'd like to see more a message like "driver <name> does not match".

> +		return ret;
> +	}
> +
> +	dev->driver = drv;
> +	RTE_VERIFY(drv->devinit != NULL);
> +	return drv->devinit(drv, dev);
> +}
> +
> +static int
> +soc_probe_all_drivers(struct rte_soc_device *dev)
> +{
> +	struct rte_soc_driver *drv = NULL;
> +	int rc = 0;
> +
> +	if (dev == NULL)
> +		return -1;
> +
> +	TAILQ_FOREACH(drv, &soc_driver_list, next) {
> +		rc = rte_eal_soc_probe_one_driver(drv, dev);
> +		if (rc < 0)
> +			/* negative value is an error */
> +			return -1;
> +		if (rc > 0)
> +			/* positive value means driver doesn't support it */
> +			continue;
> +		return 0;
> +	}
> +	return 1;
> +}
> +
> +/* If the IDs match, call the devuninit() function of the driver. */

Again, I think this comment is redudant. I'd leave it if it explains some
implementation-specific detail but it does not seem to...

> +static int
> +rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
> +		       struct rte_soc_device *dev)
> +{
> +	int ret;
> +
> +	if ((drv == NULL) || (dev == NULL))
> +		return -EINVAL;
> +
> +	ret = drv->match_fn(drv, dev);
> +	if (ret) {
> +		RTE_LOG(DEBUG, EAL,
> +			" match function failed, skipping\n");

When debugging, I'd like to see more "driver <name> does not match".

> +		return ret;
> +	}
> +
> +	RTE_LOG(DEBUG, EAL, "SoC device %s\n",
> +		dev->addr.name);
> +
> +	RTE_LOG(DEBUG, EAL, "  remove driver: %s\n", drv->driver.name);
> +
> +	if (drv->devuninit && (drv->devuninit(dev) < 0))
> +		return -1;	/* negative value is an error */
> +
> +	/* clear driver structure */
> +	dev->driver = NULL;
> +
> +	return 0;
> +}
> +
> +/*
> + * Call the devuninit() function of all registered drivers for the given
> + * device if their IDs match.

I think, the "IDs match" is obsolete becase the match_fn may work in a different way now.

> + *
> + * @return
> + *       0 when successful
> + *      -1 if deinitialization fails
> + *       1 if no driver is found for this device.
> + */
> +static int
> +soc_detach_all_drivers(struct rte_soc_device *dev)
> +{
> +	struct rte_soc_driver *dr = NULL;
> +	int rc = 0;
> +
> +	if (dev == NULL)
> +		return -1;
> +
> +	TAILQ_FOREACH(dr, &soc_driver_list, next) {
> +		rc = rte_eal_soc_detach_dev(dr, dev);
> +		if (rc < 0)
> +			/* negative value is an error */
> +			return -1;
> +		if (rc > 0)
> +			/* positive value means driver doesn't support it */
> +			continue;
> +		return 0;
> +	}
> +	return 1;
> +}
> +
> +/*
> + * Detach device specified by its SoC address.
> + */
> +int
> +rte_eal_soc_detach(const struct rte_soc_addr *addr)
> +{
> +	struct rte_soc_device *dev = NULL;
> +	int ret = 0;
> +
> +	if (addr == NULL)
> +		return -1;
> +
> +	TAILQ_FOREACH(dev, &soc_device_list, next) {
> +		if (rte_eal_compare_soc_addr(&dev->addr, addr))
> +			continue;
> +
> +		ret = soc_detach_all_drivers(dev);
> +		if (ret < 0)
> +			goto err_return;
> +
> +		TAILQ_REMOVE(&soc_device_list, dev, next);
> +		return 0;
> +	}
> +	return -1;
> +
> +err_return:
> +	RTE_LOG(WARNING, EAL, "Requested device %s cannot be used\n",
> +		dev->addr.name);
> +	return -1;
> +}
> +
> +int
> +rte_eal_soc_probe_one(const struct rte_soc_addr *addr)
> +{
> +	struct rte_soc_device *dev = NULL;
> +	int ret = 0;
> +
> +	if (addr == NULL)
> +		return -1;
> +
> +	/* unlike pci, in case of soc, it the responsibility of the soc driver
> +	 * to check during init whether device has been updated since last add.

Why? Can you give a more detailed explanation?

> +	 */
> +
> +	TAILQ_FOREACH(dev, &soc_device_list, next) {
> +		if (rte_eal_compare_soc_addr(&dev->addr, addr))
> +			continue;
> +
> +		ret = soc_probe_all_drivers(dev);
> +		if (ret < 0)
> +			goto err_return;
> +		return 0;
> +	}
> +	return -1;
> +
> +err_return:
> +	RTE_LOG(WARNING, EAL,
> +		"Requested device %s cannot be used\n", addr->name);
> +	return -1;
> +}
> +
> +/*
> + * Scan the SoC devices and call the devinit() function for all registered
> + * drivers that have a matching entry in its id_table for discovered devices.
> + */

Should be in header. Here it is redundant.

> +int
> +rte_eal_soc_probe(void)
> +{
> +	struct rte_soc_device *dev = NULL;
> +	int ret = 0;
> +
> +	TAILQ_FOREACH(dev, &soc_device_list, next) {
> +		ret = soc_probe_all_drivers(dev);
> +		if (ret < 0)
> +			rte_exit(EXIT_FAILURE, "Requested device %s"
> +				 " cannot be used\n", dev->addr.name);
> +	}
> +
> +	return 0;
> +}
> +
>  /* dump one device */
>  static int
>  soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
> @@ -79,6 +288,12 @@ rte_eal_soc_dump(FILE *f)
>  void
>  rte_eal_soc_register(struct rte_soc_driver *driver)
>  {
> +	/* For a valid soc driver, match and scan function
> +	 * should be provided.
> +	 */

This comment should be in the header file.

> +	RTE_VERIFY(driver != NULL);
> +	RTE_VERIFY(driver->match_fn != NULL);
> +	RTE_VERIFY(driver->scan_fn != NULL);
>  	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
>  }
>  
> diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
> index c6f98eb..bfb49a2 100644
> --- a/lib/librte_eal/common/include/rte_soc.h
> +++ b/lib/librte_eal/common/include/rte_soc.h
> @@ -97,6 +97,16 @@ typedef int (soc_devinit_t)(struct rte_soc_driver *, struct rte_soc_device *);
>  typedef int (soc_devuninit_t)(struct rte_soc_device *);
>  
>  /**
> + * SoC device scan callback, called from rte_eal_soc_init.

Can you explain what is the goal of the callback?
What is the expected behaviour.

It returns void so it seems it can never fail. Is this correct?
I can image that to scan for devices, I need to check some file-system
structure which can be unavailable...

> + */
> +typedef void (soc_scan_t)(void);

You are missing the '*' in (*soc_scan_t).

> +
> +/**
> + * Custom device<=>driver match callback for SoC

Can you explain the semantics (return values), please?

> + */
> +typedef int (soc_match_t)(struct rte_soc_driver *, struct rte_soc_device *);

You are missing the '*' in (*soc_match_t).

> +
> +/**
>   * A structure describing a SoC driver.
>   */
>  struct rte_soc_driver {
> @@ -104,6 +114,8 @@ struct rte_soc_driver {
>  	struct rte_driver driver;          /**< Inherit core driver. */
>  	soc_devinit_t *devinit;            /**< Device initialization */
>  	soc_devuninit_t *devuninit;        /**< Device uninitialization */

Those should be renamed to probe/remove.

> +	soc_scan_t *scan_fn;               /**< Callback for scanning SoC bus*/
> +	soc_match_t *match_fn;             /**< Callback to match dev<->drv */

Here the '*' would be redundant if you add them to the typedefs.

I think, we should tell the users that scan_fn and match_fn must be always set
to something.

>  	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
>  };
>  
> @@ -146,6 +158,45 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
>  }
>  
>  /**
> + * Default function for matching the Soc driver with device. Each driver can
> + * either use this function or define their own soc matching function.
> + * This function relies on the compatible string extracted from sysfs. But,
> + * a SoC might have different way of identifying its devices. Such SoC can
> + * override match_fn.
> + *
> + * @return
> + * 	 0 on success
> + *	-1 when no match found
> +  */
> +int
> +rte_eal_soc_match(struct rte_soc_driver *drv, struct rte_soc_device *dev);

What about naming it

	rte_eal_soc_match_default

or maybe better

	rte_eal_soc_match_compatible

what do you think?

> +
> +/**
> + * Probe SoC devices for registered drivers.
> + */
> +int rte_eal_soc_probe(void);
> +
> +/**
> + * Probe the single SoC device.
> + */
> +int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
> +
> +/**
> + * Close the single SoC device.
> + *
> + * Scan the SoC devices and find the SoC device specified by the SoC
> + * address, then call the devuninit() function for registered driver
> + * that has a matching entry in its id_table for discovered device.
> + *
> + * @param addr
> + *	The SoC address to close.
> + * @return
> + *   - 0 on success.
> + *   - Negative on error.
> + */
> +int rte_eal_soc_detach(const struct rte_soc_addr *addr);
> +
> +/**
>   * Dump discovered SoC devices.
>   */
>  void rte_eal_soc_dump(FILE *f);
> diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
> index 15c8c3d..147b601 100644
> --- a/lib/librte_eal/linuxapp/eal/eal.c
> +++ b/lib/librte_eal/linuxapp/eal/eal.c
> @@ -70,6 +70,7 @@
>  #include <rte_cpuflags.h>
>  #include <rte_interrupts.h>
>  #include <rte_pci.h>
> +#include <rte_soc.h>
>  #include <rte_dev.h>
>  #include <rte_devargs.h>
>  #include <rte_common.h>
> @@ -881,6 +882,10 @@ rte_eal_init(int argc, char **argv)
>  	if (rte_eal_pci_probe())
>  		rte_panic("Cannot probe PCI\n");
>  
> +	/* Probe & Initialize SoC devices */
> +	if (rte_eal_soc_probe())
> +		rte_panic("Cannot probe SoC\n");
> +
>  	rte_eal_mcfg_complete();
>  
>  	return fctret;
> diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
> index 04848b9..5f961c4 100644
> --- a/lib/librte_eal/linuxapp/eal/eal_soc.c
> +++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
> @@ -52,5 +52,21 @@
>  int
>  rte_eal_soc_init(void)
>  {
> +	struct rte_soc_driver *drv;
> +
> +	/* for debug purposes, SoC can be disabled */
> +	if (internal_config.no_soc)
> +		return 0;
> +
> +	/* For each registered driver, call their scan routine to perform any
> +	 * custom scan for devices (for example, custom buses)
> +	 */
> +	TAILQ_FOREACH(drv, &soc_driver_list, next) {

Is it possible to have drv->scan_fn == NULL? I suppose, this is invalid.
I'd prefer to have RTE_VERIFY for this check.

> +		if (drv && drv->scan_fn) {
> +			drv->scan_fn();
> +			/* Ignore all errors from this */
> +		}

> +	}
> +
>  	return 0;
>  }
> diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> index b9d1932..adcfe7d 100644
> --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> @@ -179,5 +179,9 @@ DPDK_16.11 {
>  	rte_eal_soc_register;
>  	rte_eal_soc_unregister;
>  	rte_eal_soc_dump;
> +	rte_eal_soc_match;
> +	rte_eal_soc_detach;
> +	rte_eal_soc_probe;
> +	rte_eal_soc_probe_one;
>  
>  } DPDK_16.07;

Regards
Jan

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

* Re: [PATCH v3 00/15] Introduce SoC device/driver framework for EAL
  2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (15 preceding siblings ...)
  2016-09-15 12:56   ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Hunt, David
@ 2016-09-18  5:58   ` Jianbo Liu
  2016-09-18  7:22     ` Jan Viktorin
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
  17 siblings, 1 reply; 231+ messages in thread
From: Jianbo Liu @ 2016-09-18  5:58 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, Jan Viktorin, Hemant Agrawal

On 9 September 2016 at 16:43, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
> Introduction:
> =============
>
> This patch set is direct derivative of Jan's original series [1],[2].
>
>  - As this deviates substantially from original series, if need be I can
>    post it as a separate patch rather than v2. Please suggest.
>  - Also, there are comments on original v1 ([4]) which are _not_
>    incorporated in this series as they refer to section no more in new
>    version.
>  - This v3 version is based on the rte_driver/device patchset v9 [10].
>    That series introduced device structures (rte_driver/rte_device)
>    generalizing devices into PCI, VDEV, XXX. For the purpose of this
>    patchset, XXX=>SOC.
>
> Aim:
> ====
>
> As of now EAL is primarly focused on PCI initialization/probing.
>
>  rte_eal_init()
>   |- rte_eal_pci_init(): Find PCI devices from sysfs
>   |- ...
>   |- rte_eal_memzone_init()
>   |- ...
>   `- rte_eal_pci_probe(): Driver<=>Device initialization
>
> This patchset introduces SoC framework which would enable SoC drivers and
> drivers to be plugged into EAL, very similar to how PCI drivers/devices are
> done today.
>
> This is a stripped down version of PCI framework which allows the SoC PMDs
> to implement their own routines for detecting devices and linking devices to
> drivers.
>
> 1) Changes to EAL
>  rte_eal_init()
>   |- rte_eal_pci_init(): Find PCI devices from sysfs
>   |- rte_eal_soc_init(): Calls PMDs->scan_fn
>   |- ...
>   |- rte_eal_memzone_init()
>   |- ...
>   |- rte_eal_pci_probe(): Driver<=>Device initialization, PMD->devinit()
>   `- rte_eal_soc_probe(): Calls PMDs->match_fn and PMDs->devinit();
>
> 2) New device/driver structures:
>   - rte_soc_driver (inheriting rte_driver)
>   - rte_soc_device (inheriting rte_device)
>   - rte_eth_dev and eth_driver embedded rte_soc_device and rte_soc_driver,
>     respectively.
>
> 3) The SoC PMDs need to:
>  - define rte_soc_driver with necessary scan and match callbacks
>  - Register themselves using DRIVER_REGISTER_SOC()
>  - Implement respective bus scanning in the scan callbacks to add necessary
>    devices to SoC device list
>  - Implement necessary eth_dev_init/uninint for ethernet instances
>
> 4) Design considerations that are same as PCI:
>  - SoC initialization is being done through rte_eal_init(), just after PCI
>    initialization is done.
>  - As in case of PCI, probe is done after rte_eal_pci_probe() to link the
>    devices detected with the drivers registered.
>  - Device attach/detach functions are available and have been designed on
>    the lines of PCI framework.
>  - PMDs register using DRIVER_REGISTER_SOC, very similar to
>    DRIVER_REGISTER_PCI for PCI devices.
>  - Linked list of SoC driver and devices exists independent of the other
>    driver/device list, but inheriting rte_driver/rte_driver, these are also
>    part of a global list.
>
> 5) Design considerations that are different from PCI:
>  - Each driver implements its own scan and match function. PCI uses the BDF
>    format to read the device from sysfs, but this _may_not_ be a case for a
>    SoC ethernet device.
>    = This is an important change from initial proposal by Jan in [2]. Unlike
>    his attempt to use /sys/bus/platform, this patch relies on the PMD to

It could be many redundant code if Each PMD driver has the scan
function if its own.
I think Jan's implementation is common to many platform drivers.

>    detect the devices. This is because SoC may require specific or
>    additional info for device detection. Further, SoC may have embedded

Can you give us more precise definition about SoC driver? Does it
include the driver in ARM server?

>    devices/MACs which require initialization which cannot be covered through
>    sysfs parsing.

I think it can be done in devinit, not in scan function. devinit can
be different for each driver.

>    = PCI based PMDs rely on EAL's capability to detect devices. This
>    proposal puts the onus on PMD to detect devices, add to soc_device_list
>    and wait for Probe. Matching, of device<=>driver is again PMD's callback.
>

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

* Re: [PATCH v3 00/15] Introduce SoC device/driver framework for EAL
  2016-09-18  5:58   ` Jianbo Liu
@ 2016-09-18  7:22     ` Jan Viktorin
  2016-09-18  8:56       ` Jianbo Liu
  0 siblings, 1 reply; 231+ messages in thread
From: Jan Viktorin @ 2016-09-18  7:22 UTC (permalink / raw)
  To: Jianbo Liu; +Cc: Shreyansh Jain, dev, Hemant Agrawal

On Sun, 18 Sep 2016 13:58:50 +0800
Jianbo Liu <jianbo.liu@linaro.org> wrote:

> On 9 September 2016 at 16:43, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
> > Introduction:
> > =============
> >
> > This patch set is direct derivative of Jan's original series [1],[2].
> >
> >  - As this deviates substantially from original series, if need be I can
> >    post it as a separate patch rather than v2. Please suggest.
> >  - Also, there are comments on original v1 ([4]) which are _not_
> >    incorporated in this series as they refer to section no more in new
> >    version.
> >  - This v3 version is based on the rte_driver/device patchset v9 [10].
> >    That series introduced device structures (rte_driver/rte_device)
> >    generalizing devices into PCI, VDEV, XXX. For the purpose of this
> >    patchset, XXX=>SOC.

[...]

> >
> > 5) Design considerations that are different from PCI:
> >  - Each driver implements its own scan and match function. PCI uses the BDF
> >    format to read the device from sysfs, but this _may_not_ be a case for a
> >    SoC ethernet device.
> >    = This is an important change from initial proposal by Jan in [2]. Unlike
> >    his attempt to use /sys/bus/platform, this patch relies on the PMD to  
> 
> It could be many redundant code if Each PMD driver has the scan
> function if its own.
> I think Jan's implementation is common to many platform drivers.

I personally can find a use case for having a custom scan function.
However, we should at least provide a default implementation. Probably,
both the scan and match functions should be used to _override_ a default
behaviour. So, only drivers that require to scan devices in a specific
way would provide a custom function for this.

I agree, that this can sometimes lead to code duplication. Moreover, it
opens door for a very non-standard, unsecure and wrong-by-design
approaches. I'd like more to provide one or more scan implementations
in EAL and do not put this responsibility on PMDs.

> 
> >    detect the devices. This is because SoC may require specific or
> >    additional info for device detection. Further, SoC may have embedded  

Can you provide an example for "additional info for device detection"?

> 
> Can you give us more precise definition about SoC driver? Does it
> include the driver in ARM server?

I am sorry but I don't understand this question.

What you mean by a "driver in ARM server"? Do you mean a kernel driver?

There is no "SoC driver" in the text so what definition are asking for?

> 
> >    devices/MACs which require initialization which cannot be covered through
> >    sysfs parsing.  

I think, the description itself is incorrect.

If a device's initialization cannot be satisfied vie sysfs, it means
that you have to write a specific probe function. This is not related to
scan in any way.

However, there may be a group of devices which are not managed by the
standard platform_driver of the Linux Kernel (or other OS). In that
case, the custom scan function would be helpful. I can imagine a device
in a fully I/O coherent platform that only requires to access
the /dev/mem only (for the register space). It is unsecure but it would
work without any OS-driver. However, I consider it a corner case.
It can be useful for testing sometimes but not very helpful for
production.

We should however support mainly the standard devices which are always
represented by the OS. Otherwise, such system would introduce security
issues.

> 
> I think it can be done in devinit, not in scan function. devinit can
> be different for each driver.

+1

> 
> >    = PCI based PMDs rely on EAL's capability to detect devices. This
> >    proposal puts the onus on PMD to detect devices, add to soc_device_list
> >    and wait for Probe. Matching, of device<=>driver is again PMD's callback.
> >  

Regards
Jan

-- 
  Jan Viktorin                E-mail: Viktorin@RehiveTech.com
  System Architect            Web:    www.RehiveTech.com
  RehiveTech
  Brno, Czech Republic

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

* Re: [PATCH v3 00/15] Introduce SoC device/driver framework for EAL
  2016-09-18  7:22     ` Jan Viktorin
@ 2016-09-18  8:56       ` Jianbo Liu
  2016-09-18  9:17         ` Jan Viktorin
  0 siblings, 1 reply; 231+ messages in thread
From: Jianbo Liu @ 2016-09-18  8:56 UTC (permalink / raw)
  To: Jan Viktorin; +Cc: Shreyansh Jain, dev, Hemant Agrawal

On 18 September 2016 at 15:22, Jan Viktorin <viktorin@rehivetech.com> wrote:
> On Sun, 18 Sep 2016 13:58:50 +0800
> Jianbo Liu <jianbo.liu@linaro.org> wrote:
>
>> On 9 September 2016 at 16:43, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
>> > Introduction:
>> > =============
>> >
>> > This patch set is direct derivative of Jan's original series [1],[2].
>> >
>> >  - As this deviates substantially from original series, if need be I can
>> >    post it as a separate patch rather than v2. Please suggest.
>> >  - Also, there are comments on original v1 ([4]) which are _not_
>> >    incorporated in this series as they refer to section no more in new
>> >    version.
>> >  - This v3 version is based on the rte_driver/device patchset v9 [10].
>> >    That series introduced device structures (rte_driver/rte_device)
>> >    generalizing devices into PCI, VDEV, XXX. For the purpose of this
>> >    patchset, XXX=>SOC.
>
> [...]
>
>> >
>> > 5) Design considerations that are different from PCI:
>> >  - Each driver implements its own scan and match function. PCI uses the BDF
>> >    format to read the device from sysfs, but this _may_not_ be a case for a
>> >    SoC ethernet device.
>> >    = This is an important change from initial proposal by Jan in [2]. Unlike
>> >    his attempt to use /sys/bus/platform, this patch relies on the PMD to
>>
>> It could be many redundant code if Each PMD driver has the scan
>> function if its own.
>> I think Jan's implementation is common to many platform drivers.
>
> I personally can find a use case for having a custom scan function.
> However, we should at least provide a default implementation. Probably,
> both the scan and match functions should be used to _override_ a default
> behaviour. So, only drivers that require to scan devices in a specific
> way would provide a custom function for this.
>
And for each platform/product....

> I agree, that this can sometimes lead to code duplication. Moreover, it
> opens door for a very non-standard, unsecure and wrong-by-design
> approaches. I'd like more to provide one or more scan implementations
> in EAL and do not put this responsibility on PMDs.
>
>>
>> >    detect the devices. This is because SoC may require specific or
>> >    additional info for device detection. Further, SoC may have embedded
>
> Can you provide an example for "additional info for device detection"?
>
>>
>> Can you give us more precise definition about SoC driver? Does it
>> include the driver in ARM server?
>
> I am sorry but I don't understand this question.
>
> What you mean by a "driver in ARM server"? Do you mean a kernel driver?
>
> There is no "SoC driver" in the text so what definition are asking for?
>
This patchset introduces rte_soc_driver, which is inheriting from rte_driver.
I want to know what devices can use this SoC driver/device framework.
Is it for the devices from ARM servers, or embedded systems of
different vendors?
And this framework is too generalized, if we don't try to understand
"soc" in rte_soc_driver, we can use it for PCI devices. :)

Thanks!
Jianbo

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

* Re: [PATCH v3 00/15] Introduce SoC device/driver framework for EAL
  2016-09-18  8:56       ` Jianbo Liu
@ 2016-09-18  9:17         ` Jan Viktorin
  2016-09-18  9:41           ` Hemant Agrawal
  0 siblings, 1 reply; 231+ messages in thread
From: Jan Viktorin @ 2016-09-18  9:17 UTC (permalink / raw)
  To: Jianbo Liu; +Cc: Shreyansh Jain, dev, Hemant Agrawal

On Sun, 18 Sep 2016 16:56:54 +0800
Jianbo Liu <jianbo.liu@linaro.org> wrote:

> On 18 September 2016 at 15:22, Jan Viktorin <viktorin@rehivetech.com> wrote:
> > On Sun, 18 Sep 2016 13:58:50 +0800
> > Jianbo Liu <jianbo.liu@linaro.org> wrote:
> >  
> >> On 9 September 2016 at 16:43, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:  
> >> > Introduction:
> >> > =============
> >> >
> >> > This patch set is direct derivative of Jan's original series [1],[2].
> >> >
> >> >  - As this deviates substantially from original series, if need be I can
> >> >    post it as a separate patch rather than v2. Please suggest.
> >> >  - Also, there are comments on original v1 ([4]) which are _not_
> >> >    incorporated in this series as they refer to section no more in new
> >> >    version.
> >> >  - This v3 version is based on the rte_driver/device patchset v9 [10].
> >> >    That series introduced device structures (rte_driver/rte_device)
> >> >    generalizing devices into PCI, VDEV, XXX. For the purpose of this
> >> >    patchset, XXX=>SOC.  
> >
> > [...]
> >  
> >> >
> >> > 5) Design considerations that are different from PCI:
> >> >  - Each driver implements its own scan and match function. PCI uses the BDF
> >> >    format to read the device from sysfs, but this _may_not_ be a case for a
> >> >    SoC ethernet device.
> >> >    = This is an important change from initial proposal by Jan in [2]. Unlike
> >> >    his attempt to use /sys/bus/platform, this patch relies on the PMD to  
> >>
> >> It could be many redundant code if Each PMD driver has the scan
> >> function if its own.
> >> I think Jan's implementation is common to many platform drivers.  
> >
> > I personally can find a use case for having a custom scan function.
> > However, we should at least provide a default implementation. Probably,
> > both the scan and match functions should be used to _override_ a default
> > behaviour. So, only drivers that require to scan devices in a specific
> > way would provide a custom function for this.
> >  
> And for each platform/product....
> 
> > I agree, that this can sometimes lead to code duplication. Moreover, it
> > opens door for a very non-standard, unsecure and wrong-by-design
> > approaches. I'd like more to provide one or more scan implementations
> > in EAL and do not put this responsibility on PMDs.
> >  
> >>  
> >> >    detect the devices. This is because SoC may require specific or
> >> >    additional info for device detection. Further, SoC may have embedded  
> >
> > Can you provide an example for "additional info for device detection"?
> >  
> >>
> >> Can you give us more precise definition about SoC driver? Does it
> >> include the driver in ARM server?  
> >
> > I am sorry but I don't understand this question.
> >
> > What you mean by a "driver in ARM server"? Do you mean a kernel driver?
> >
> > There is no "SoC driver" in the text so what definition are asking for?
> >  
> This patchset introduces rte_soc_driver, which is inheriting from rte_driver.
> I want to know what devices can use this SoC driver/device framework.
> Is it for the devices from ARM servers, or embedded systems of
> different vendors?

First, this is not an ARM-specific feature. Consider any MAC connected to
the processor via some on-chip bus. In the world of ARM, it is usually
a kind of AMBA bus. I think, the Intel Xeon with FPGA would be a
good non-ARM example. Here they provide the Quick Path bus (but I don't
know the details). So, you cannot access such device as PCI. It is
usually not possible to distinguish the bus type easily (Linux calls
this a platform device).

So, an rte_soc_device denotes a device integrated on the chip
(SoC, System-on-Chip). Such devices can have a lower access latency
because they are closer to the processor.

So, if you have a server system driver by a SoC with integrated MACs
(no PCI-E involved), there is no way how to access them from DPDK. An
rte_soc_device represents such devices and provides a way how to access
them from DPDK. That is the goal...

You can have an embedded device (router, switch, monitoring device,
NAT, firewall, anything in a "small box" with high throughput demands)
that perfectly fits into this SoC framework because it would be usually
based on some SoC (ARM, ARM64, ...).

> And this framework is too generalized, if we don't try to understand
> "soc" in rte_soc_driver, we can use it for PCI devices. :)

No, you cannot use it for PCI devices, don't worry. There should be no
PCI facilities like access to BARs :). But, I think I got your point.

It seems to be generalized because there is no real standard in this
area. Any vendor of SoC can provide her custom on-chip bus. The
original idea was to build on top of the platform_device from Linux
which hides this information from you (unless there is some bus-specific
DMA which we must handle in the DPDK PMD).

We could provide an rte_amba_device instead but there is no advantage in
this. The amba bus is defined on the RTL level and not on the software
level (no BARs, no device discovery). And there are other buses working
in a similar way.

> 
> Thanks!
> Jianbo



-- 
  Jan Viktorin                E-mail: Viktorin@RehiveTech.com
  System Architect            Web:    www.RehiveTech.com
  RehiveTech
  Brno, Czech Republic

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

* Re: [PATCH v3 00/15] Introduce SoC device/driver framework for EAL
  2016-09-18  9:17         ` Jan Viktorin
@ 2016-09-18  9:41           ` Hemant Agrawal
  2016-09-18 10:04             ` Jan Viktorin
  0 siblings, 1 reply; 231+ messages in thread
From: Hemant Agrawal @ 2016-09-18  9:41 UTC (permalink / raw)
  To: Jan Viktorin, Jianbo Liu; +Cc: Shreyansh Jain, dev



> -----Original Message-----
> From: Jan Viktorin [mailto:viktorin@rehivetech.com]

> On Sun, 18 Sep 2016 16:56:54 +0800
> Jianbo Liu <jianbo.liu@linaro.org> wrote:
> 
> > On 18 September 2016 at 15:22, Jan Viktorin <viktorin@rehivetech.com>
> wrote:
> > > On Sun, 18 Sep 2016 13:58:50 +0800
> > > Jianbo Liu <jianbo.liu@linaro.org> wrote:
> > >
> > >> On 9 September 2016 at 16:43, Shreyansh Jain <shreyansh.jain@nxp.com>
> wrote:
> > >> > Introduction:
> > >> > =============
> > >> >
> > >> > This patch set is direct derivative of Jan's original series [1],[2].
> > >> >
> > >> >  - As this deviates substantially from original series, if need be I can
> > >> >    post it as a separate patch rather than v2. Please suggest.
> > >> >  - Also, there are comments on original v1 ([4]) which are _not_
> > >> >    incorporated in this series as they refer to section no more in new
> > >> >    version.
> > >> >  - This v3 version is based on the rte_driver/device patchset v9 [10].
> > >> >    That series introduced device structures (rte_driver/rte_device)
> > >> >    generalizing devices into PCI, VDEV, XXX. For the purpose of this
> > >> >    patchset, XXX=>SOC.
> > >
> > > [...]
> > >
> > >> >
> > >> > 5) Design considerations that are different from PCI:
> > >> >  - Each driver implements its own scan and match function. PCI uses the
> BDF
> > >> >    format to read the device from sysfs, but this _may_not_ be a case for a
> > >> >    SoC ethernet device.
> > >> >    = This is an important change from initial proposal by Jan in [2]. Unlike
> > >> >    his attempt to use /sys/bus/platform, this patch relies on the
> > >> > PMD to
> > >>
> > >> It could be many redundant code if Each PMD driver has the scan
> > >> function if its own.
> > >> I think Jan's implementation is common to many platform drivers.
> > >
> > > I personally can find a use case for having a custom scan function.
> > > However, we should at least provide a default implementation.
> > > Probably, both the scan and match functions should be used to
> > > _override_ a default behaviour. So, only drivers that require to
> > > scan devices in a specific way would provide a custom function for this.
> > >
> > And for each platform/product....
> >
> > > I agree, that this can sometimes lead to code duplication. Moreover,
> > > it opens door for a very non-standard, unsecure and wrong-by-design
> > > approaches. I'd like more to provide one or more scan
> > > implementations in EAL and do not put this responsibility on PMDs.

 [Hemant]  A common/default scan function can be added, provided at least one or more  PMD driver support it. 
w.r.t Jan's original scan function, it was not suitable for any of the NXP SoC's whether ARM or PowerPC.

Unable to validate the Jan's scan function on a real platform, we have skipped it for next phase.  
Addition of a default scan function can only be done in next phase, when we find a suitable SoC PMD driver supporting it.
> > >
> > >>
> > >> >    detect the devices. This is because SoC may require specific or
> > >> >    additional info for device detection. Further, SoC may have
> > >> > embedded
> > >
> > > Can you provide an example for "additional info for device detection"?
> > >
> > >>
> > >> Can you give us more precise definition about SoC driver? Does it
> > >> include the driver in ARM server?
> > >
> > > I am sorry but I don't understand this question.
> > >
> > > What you mean by a "driver in ARM server"? Do you mean a kernel driver?
> > >
> > > There is no "SoC driver" in the text so what definition are asking for?
> > >
> > This patchset introduces rte_soc_driver, which is inheriting from rte_driver.
> > I want to know what devices can use this SoC driver/device framework.
> > Is it for the devices from ARM servers, or embedded systems of
> > different vendors?
> 
> First, this is not an ARM-specific feature. Consider any MAC connected to the
> processor via some on-chip bus. In the world of ARM, it is usually a kind of
> AMBA bus. I think, the Intel Xeon with FPGA would be a good non-ARM example.
> Here they provide the Quick Path bus (but I don't know the details). So, you
> cannot access such device as PCI. It is usually not possible to distinguish the bus
> type easily (Linux calls this a platform device).
> 
> So, an rte_soc_device denotes a device integrated on the chip (SoC, System-on-
> Chip). Such devices can have a lower access latency because they are closer to
> the processor.
> 
> So, if you have a server system driver by a SoC with integrated MACs (no PCI-E
> involved), there is no way how to access them from DPDK. An rte_soc_device
> represents such devices and provides a way how to access them from DPDK.
> That is the goal...
> 
> You can have an embedded device (router, switch, monitoring device, NAT,
> firewall, anything in a "small box" with high throughput demands) that perfectly
> fits into this SoC framework because it would be usually based on some SoC
> (ARM, ARM64, ...).
> 
> > And this framework is too generalized, if we don't try to understand
> > "soc" in rte_soc_driver, we can use it for PCI devices. :)
> 
> No, you cannot use it for PCI devices, don't worry. There should be no PCI
> facilities like access to BARs :). But, I think I got your point.
> 
> It seems to be generalized because there is no real standard in this area. Any
> vendor of SoC can provide her custom on-chip bus. The original idea was to build
> on top of the platform_device from Linux which hides this information from you
> (unless there is some bus-specific DMA which we must handle in the DPDK PMD).
> 
 [Hemant] Agree with Jan's comments. 
This "SoC" term is coined to differentiate the non-PCI based  devices.  It is not specific to ARM or embedded systems. 
So, now we have two categories of device drivers, 
	- one which can be represented by standard PCI device framework; 
	- others, which does not fit into PCI devices model. 

The framework has to be generic to accommodate different types of drivers, as there is no "standard" driver model for SoCs.

> We could provide an rte_amba_device instead but there is no advantage in this.
> The amba bus is defined on the RTL level and not on the software level (no BARs,
> no device discovery). And there are other buses working in a similar way.
> 
> >
> > Thanks!
> > Jianbo
> 

Thanks
[Hemant] 
> 
> 
> --
>   Jan Viktorin                E-mail: Viktorin@RehiveTech.com
>   System Architect            Web:    www.RehiveTech.com
>   RehiveTech
>   Brno, Czech Republic

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

* Re: [PATCH v3 00/15] Introduce SoC device/driver framework for EAL
  2016-09-18  9:41           ` Hemant Agrawal
@ 2016-09-18 10:04             ` Jan Viktorin
  2016-09-19 12:33               ` Hemant Agrawal
  0 siblings, 1 reply; 231+ messages in thread
From: Jan Viktorin @ 2016-09-18 10:04 UTC (permalink / raw)
  To: Hemant Agrawal; +Cc: Jianbo Liu, Shreyansh Jain, dev, David Marchand

On Sun, 18 Sep 2016 09:41:55 +0000
Hemant Agrawal <hemant.agrawal@nxp.com> wrote:

> > -----Original Message-----
> > From: Jan Viktorin [mailto:viktorin@rehivetech.com]  
> 

[...]

> > > And for each platform/product....
> > >  
> > > > I agree, that this can sometimes lead to code duplication. Moreover,
> > > > it opens door for a very non-standard, unsecure and wrong-by-design
> > > > approaches. I'd like more to provide one or more scan
> > > > implementations in EAL and do not put this responsibility on PMDs.  
> 

Hi Hemant.

>  [Hemant]  A common/default scan function can be added, provided at least one or more  PMD driver support it. 
> w.r.t Jan's original scan function, it was not suitable for any of the NXP SoC's whether ARM or PowerPC.
> 
> Unable to validate the Jan's scan function on a real platform, we have skipped it for next phase.  
> Addition of a default scan function can only be done in next phase, when we find a suitable SoC PMD driver supporting it.

Quite frankly, the situation is same for me. I still have no clue about
your approach which seems to be pretty non-standard. I have no way how
to test it.

My approach can be tested on any Linux machine with platform devices
and device-tree enabled. You would see that I detect those devices (I
don't mean any certain network device, I mean all platform devices) and
if you provide a driver with a proper compatible string it will be set
for you.

I presume that I don't have any upstreamable PMD for this at the moment.

From the very generic scan approach, I cannot see, what kernel
infrastructure are you going to use. We should support at least the
VFIO-platform which is standard and with IOMMU, it is considered secure.
Any other approach would require an out-of-tree kernel driver or some
non-secure access to devices. I don't say it is very wrong, but we
should be careful about this.

> > > >  
> > > >>  
> > > >> >    detect the devices. This is because SoC may require specific or
> > > >> >    additional info for device detection. Further, SoC may have
> > > >> > embedded  
> > > >
> > > > Can you provide an example for "additional info for device detection"?

Can you?

Regards
Jan

[...]

-- 
  Jan Viktorin                E-mail: Viktorin@RehiveTech.com
  System Architect            Web:    www.RehiveTech.com
  RehiveTech
  Brno, Czech Republic

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

* Re: [PATCH v3 06/15] eal/soc: implement probing of drivers
  2016-09-16 12:27     ` Jan Viktorin
@ 2016-09-19  6:47       ` Shreyansh Jain
  2016-09-19 11:34         ` Jan Viktorin
  0 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-19  6:47 UTC (permalink / raw)
  To: Jan Viktorin; +Cc: dev, hemant.agrawal

Hi Jan,

On Friday 16 September 2016 05:57 PM, Jan Viktorin wrote:
> On Fri, 9 Sep 2016 14:13:50 +0530
> Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
>
>> Each SoC PMD registers a set of callback for scanning its own bus/infra and
>> matching devices to drivers when probe is called.
>> This patch introduces the infra for calls to SoC scan on rte_eal_soc_init()
>> and match on rte_eal_soc_probe().
>>
>> Patch also adds test case for scan and probe.
>>
>> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
>> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>> ---
>>  app/test/test_soc.c                             | 138 ++++++++++++++-
>>  lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   4 +
>>  lib/librte_eal/common/eal_common_soc.c          | 215 ++++++++++++++++++++++++
>>  lib/librte_eal/common/include/rte_soc.h         |  51 ++++++
>>  lib/librte_eal/linuxapp/eal/eal.c               |   5 +
>>  lib/librte_eal/linuxapp/eal/eal_soc.c           |  16 ++
>>  lib/librte_eal/linuxapp/eal/rte_eal_version.map |   4 +
>>  7 files changed, 432 insertions(+), 1 deletion(-)
>>
>> diff --git a/app/test/test_soc.c b/app/test/test_soc.c
>> index ac03e64..d2b9462 100644
>> --- a/app/test/test_soc.c
>> +++ b/app/test/test_soc.c
>> @@ -87,14 +87,45 @@ static int test_compare_addr(void)
>>   */
>>  struct test_wrapper {
>>  	struct rte_soc_driver soc_drv;
>> +	struct rte_soc_device soc_dev;
>>  };
>>
>> +static int empty_pmd0_devinit(struct rte_soc_driver *drv,
>> +			      struct rte_soc_device *dev);
>> +static int empty_pmd0_devuninit(struct rte_soc_device *dev);
>
> I prefer an empty line here.

Ok. I will add that.

>
>
> What is the prupose of the scan here? What device does it provide
> to the test? I'd prefer to call it e.g. "allways_find_device0" or
> something describing the purpose and explaining what is the goal
> of the related test.

I understand what you are hinting at. Purpose of scan is obviously to 
'always add a device0'. I will update the code.

>
> Probably a comment explaining "provide a device named 'empty_pmd0_dev'
> would be helpful.

Ok.

>
>> +static void test_soc_scan_dev0_cb(void);
>
> Similar here, something like "match_by_name".
>
>> +static int test_soc_match_dev0_cb(struct rte_soc_driver *drv,
>> +				  struct rte_soc_device *dev);
>
> I prefer an empty line here.

Do we really place newlines in function declarations? That doesn't 
really help anything, until and unless some comments are added to those. 
Anyways, rather than added blank lines, I will add some comments - those 
are indeed misssing.

>
>
> ditto...

Will add comments.

>
>> +static void test_soc_scan_dev1_cb(void);
>
> ditto...

Same here, I prefer comment rather than blank line.

>
>> +static int test_soc_match_dev1_cb(struct rte_soc_driver *drv,
>> +				  struct rte_soc_device *dev);
>> +
>> +static int
>> +empty_pmd0_devinit(struct rte_soc_driver *drv __rte_unused,
>> +		   struct rte_soc_device *dev __rte_unused)
>> +{
>> +	return 0;
>> +}
>> +
>> +static int
>> +empty_pmd0_devuninit(struct rte_soc_device *dev)
>> +{
>> +	/* Release the memory associated with dev->addr.name */
>> +	free(dev->addr.name);
>> +
>> +	return 0;
>> +}
>> +
>>  struct test_wrapper empty_pmd0 = {
>>  	.soc_drv = {
>>  		.driver = {
>>  			.name = "empty_pmd0"
>>  		},
>> -	},
>> +		.devinit = empty_pmd0_devinit,
>> +		.devuninit = empty_pmd0_devuninit,
>> +		.scan_fn = test_soc_scan_dev0_cb,
>> +		.match_fn = test_soc_match_dev0_cb,
>> +	}
>>  };
>>
>>  struct test_wrapper empty_pmd1 = {
>> @@ -102,9 +133,54 @@ struct test_wrapper empty_pmd1 = {
>>  		.driver = {
>>  			.name = "empty_pmd1"
>>  		},
>> +		.scan_fn = test_soc_scan_dev1_cb,
>> +		.match_fn = test_soc_match_dev1_cb,
>>  	},
>>  };
>>
>> +static void
>> +test_soc_scan_dev0_cb(void)
>> +{
>> +	/* SoC's scan would scan devices on its bus and add to
>> +	 * soc_device_list
>> +	 */
>> +	empty_pmd0.soc_dev.addr.name = strdup("empty_pmd0_dev");
>> +
>> +	TAILQ_INSERT_TAIL(&soc_device_list, &empty_pmd0.soc_dev, next);
>> +}
>> +
>> +static int
>> +test_soc_match_dev0_cb(struct rte_soc_driver *drv __rte_unused,
>> +		       struct rte_soc_device *dev)
>> +{
>> +	if (!dev->addr.name || strcmp(dev->addr.name, "empty_pmd0_dev"))
>> +		return 0;
>> +
>> +	return 1;
>> +}
>> +
>> +
>> +static void
>> +test_soc_scan_dev1_cb(void)
>> +{
>> +	/* SoC's scan would scan devices on its bus and add to
>> +	 * soc_device_list
>> +	 */
>> +	empty_pmd0.soc_dev.addr.name = strdup("empty_pmd1_dev");
>> +
>> +	TAILQ_INSERT_TAIL(&soc_device_list, &empty_pmd1.soc_dev, next);
>> +}
>> +
>> +static int
>> +test_soc_match_dev1_cb(struct rte_soc_driver *drv __rte_unused,
>> +		       struct rte_soc_device *dev)
>> +{
>> +	if (!dev->addr.name || strcmp(dev->addr.name, "empty_pmd1_dev"))
>> +		return 0;
>> +
>> +	return 1;
>> +}
>> +
>>  static int
>>  count_registered_socdrvs(void)
>>  {
>> @@ -148,13 +224,54 @@ test_register_unregister(void)
>>  	return 0;
>>  }
>>
>> +/* Test Probe (scan and match) functionality */
>> +static int
>> +test_soc_init_and_probe(void)
>
> You say to test scan and match. I'd prefer to reflect this in the name
> of the test. Otherwise, it seems you are testing init and probe which
> is not true, I think.

I agree. I will update the name of the function.

>
> Do you test that "match principle works" or that "match functions are OK"
> or "match functions are called as expected", ...?

"match functions are called as expected"
The model for the patchset was to allow PMDs to write their own match 
and hence, verifying a particular match is not definitive. Rather, the 
test case simply confirms that a SoC based PMD would be able to 
implement its own match/scan and these would be called from EAL as expected.

>
>> +{
>> +	struct rte_soc_driver *drv;
>> +
>> +	/* Registering dummy drivers */
>> +	rte_eal_soc_register(&empty_pmd0.soc_drv);
>> +	rte_eal_soc_register(&empty_pmd1.soc_drv);
>> +	/* Assuming that test_register_unregister is working, not verifying
>> +	 * that drivers are indeed registered
>> +	*/
>> +
>> +	/* rte_eal_soc_init is called by rte_eal_init, which in turn calls the
>> +	 * scan_fn of each driver.
>> +	 */
>> +	TAILQ_FOREACH(drv, &soc_driver_list, next) {
>> +		if (drv && drv->scan_fn)
>> +			drv->scan_fn();
>> +	}
>
> Here, I suppose you mimic the rte_eal_soc_init?

Yes.

>
>> +
>> +	/* rte_eal_init() would perform other inits here */
>> +
>> +	/* Probe would link the SoC devices<=>drivers */
>> +	rte_eal_soc_probe();
>> +
>> +	/* Unregistering dummy drivers */
>> +	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
>> +	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
>> +
>> +	free(empty_pmd0.soc_dev.addr.name);
>> +
>> +	printf("%s has been successful\n", __func__);
>
> How you detect it is unsuccessful? Is it possible to fail in this test?
> A test that can never fail is in fact not a test :).

The design assumption for SoC patcheset was: A PMDs scan is called to 
find devices on its bus (PMD ~ bus). Whether devices are found or not, 
is irrelevant to EAL - whether that is because of error or actually no 
devices were available.
With the above logic, no 'success/failure' is checked in the test. It is 
simply a verification of EAL's ability to link the PMD with it 
(scan/match function pointers).

>
>> +	return 0;
>> +}
>> +
>>  /* save real devices and drivers until the tests finishes */
>>  struct soc_driver_list real_soc_driver_list =
>>  	TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
>>
>> +/* save real devices and drivers until the tests finishes */
>> +struct soc_device_list real_soc_device_list =
>> +	TAILQ_HEAD_INITIALIZER(real_soc_device_list);
>> +
>>  static int test_soc_setup(void)
>>  {
>>  	struct rte_soc_driver *drv;
>> +	struct rte_soc_device *dev;
>>
>>  	/* no real drivers for the test */
>>  	while (!TAILQ_EMPTY(&soc_driver_list)) {
>> @@ -163,12 +280,20 @@ static int test_soc_setup(void)
>>  		TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
>>  	}
>>
>> +	/* And, no real devices for the test */
>> +	while (!TAILQ_EMPTY(&soc_device_list)) {
>> +		dev = TAILQ_FIRST(&soc_device_list);
>> +		TAILQ_REMOVE(&soc_device_list, dev, next);
>> +		TAILQ_INSERT_TAIL(&real_soc_device_list, dev, next);
>> +	}
>> +
>>  	return 0;
>>  }
>>
>>  static int test_soc_cleanup(void)
>>  {
>>  	struct rte_soc_driver *drv;
>> +	struct rte_soc_device *dev;
>>
>>  	/* bring back real drivers after the test */
>>  	while (!TAILQ_EMPTY(&real_soc_driver_list)) {
>> @@ -177,6 +302,13 @@ static int test_soc_cleanup(void)
>>  		rte_eal_soc_register(drv);
>>  	}
>>
>> +	/* And, bring back real devices after the test */
>> +	while (!TAILQ_EMPTY(&real_soc_device_list)) {
>> +		dev = TAILQ_FIRST(&real_soc_device_list);
>> +		TAILQ_REMOVE(&real_soc_device_list, dev, next);
>> +		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
>> +	}
>> +
>>  	return 0;
>>  }
>>
>> @@ -192,6 +324,10 @@ test_soc(void)
>>  	if (test_register_unregister())
>>  		return -1;
>>
>> +	/* Assuming test_register_unregister has succeeded */
>> +	if (test_soc_init_and_probe())
>> +		return -1;
>> +
>>  	if (test_soc_cleanup())
>>  		return -1;
>>
>> diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
>> index de38848..3c407be 100644
>> --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
>> +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
>> @@ -173,5 +173,9 @@ DPDK_16.11 {
>>  	rte_eal_soc_register;
>>  	rte_eal_soc_unregister;
>>  	rte_eal_soc_dump;
>> +	rte_eal_soc_match;
>> +	rte_eal_soc_detach;
>> +	rte_eal_soc_probe;
>> +	rte_eal_soc_probe_one;
>>
>>  } DPDK_16.07;
>> diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
>> index 5dcddc5..bb87a67 100644
>> --- a/lib/librte_eal/common/eal_common_soc.c
>> +++ b/lib/librte_eal/common/eal_common_soc.c
>> @@ -36,6 +36,8 @@
>>  #include <sys/queue.h>
>>
>>  #include <rte_log.h>
>> +#include <rte_common.h>
>> +#include <rte_soc.h>
>>
>>  #include "eal_private.h"
>>
>> @@ -45,6 +47,213 @@ struct soc_driver_list soc_driver_list =
>>  struct soc_device_list soc_device_list =
>>  	TAILQ_HEAD_INITIALIZER(soc_device_list);
>>
>> +/* Default SoC device<->Driver match handler function */
>
> I think this comment is redundant. All this is already said in the rte_soc.h.

Ok. I will remove it from here and if need be, update the rte_soc.h to 
have elaborate comments.

>
>> +int
>> +rte_eal_soc_match(struct rte_soc_driver *drv, struct rte_soc_device *dev)
>> +{
>> +	int i, j;
>> +
>> +	RTE_VERIFY(drv != NULL && drv->id_table != NULL);
>> +	RTE_VERIFY(dev != NULL && dev->id != NULL);
>> +
>> +	for (i = 0; drv->id_table[i].compatible; ++i) {
>> +		const char *drv_compat = drv->id_table[i].compatible;
>> +
>> +		for (j = 0; dev->id[j].compatible; ++j) {
>> +			const char *dev_compat = dev->id[j].compatible;
>> +
>> +			if (!strcmp(drv_compat, dev_compat))
>> +				return 0;
>> +		}
>> +	}
>> +
>> +	return 1;
>> +}
>> +
>> +
>> +static int
>> +rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
>> +			     struct rte_soc_device *dev)
>> +{
>> +	int ret = 1;
>> +
>
> I think, the RTE_VERIFY(dev->match_fn) might be good here.
> It avoids any doubts about the validity of the pointer.

That has already been done in rte_eal_soc_register which is called when 
PMDs are registering themselves through DRIVER_REGISTER_SOC. That would 
prevent any PMD leaking through to this stage without a proper 
match_fn/scan_fn.

>
>> +	ret = drv->match_fn(drv, dev);
>> +	if (ret) {
>> +		RTE_LOG(DEBUG, EAL,
>> +			" match function failed, skipping\n");
>
> Is this a failure? I think it is not. Failure would be if the match
> function cannot execute correctly. This is more like "no-match".

The log message is misleading. This is _not_ a failure but simply a 
'no-match'. I will update this.

>
> When debugging, I'd like to see more a message like "driver <name> does not match".

Problem would be about '<name>' of a driver. There is already another 
discussion about SoC capability/platform bus definitions - probably I 
will wait for that so as to define what a '<name>' for a driver and 
device is.
In this case, the key reason for not adding such a message was because 
it was assumed PMDs are black boxes with EAL not even assuming what 
'<name>' means. Anyways, it is better to discuss these things in that 
other email.

>
>> +		return ret;
>> +	}
>> +
>> +	dev->driver = drv;
>> +	RTE_VERIFY(drv->devinit != NULL);
>> +	return drv->devinit(drv, dev);
>> +}
>> +
>> +static int
>> +soc_probe_all_drivers(struct rte_soc_device *dev)
>> +{
>> +	struct rte_soc_driver *drv = NULL;
>> +	int rc = 0;
>> +
>> +	if (dev == NULL)
>> +		return -1;
>> +
>> +	TAILQ_FOREACH(drv, &soc_driver_list, next) {
>> +		rc = rte_eal_soc_probe_one_driver(drv, dev);
>> +		if (rc < 0)
>> +			/* negative value is an error */
>> +			return -1;
>> +		if (rc > 0)
>> +			/* positive value means driver doesn't support it */
>> +			continue;
>> +		return 0;
>> +	}
>> +	return 1;
>> +}
>> +
>> +/* If the IDs match, call the devuninit() function of the driver. */
>
> Again, I think this comment is redudant. I'd leave it if it explains some
> implementation-specific detail but it does not seem to...

Ok.

>
>> +static int
>> +rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
>> +		       struct rte_soc_device *dev)
>> +{
>> +	int ret;
>> +
>> +	if ((drv == NULL) || (dev == NULL))
>> +		return -EINVAL;
>> +
>> +	ret = drv->match_fn(drv, dev);
>> +	if (ret) {
>> +		RTE_LOG(DEBUG, EAL,
>> +			" match function failed, skipping\n");
>
> When debugging, I'd like to see more "driver <name> does not match".

My reply is same as above - I will like to wait and see what we conclude 
from the other discussion on SoC scan/match.

>
>> +		return ret;
>> +	}
>> +
>> +	RTE_LOG(DEBUG, EAL, "SoC device %s\n",
>> +		dev->addr.name);
>> +
>> +	RTE_LOG(DEBUG, EAL, "  remove driver: %s\n", drv->driver.name);
>> +
>> +	if (drv->devuninit && (drv->devuninit(dev) < 0))
>> +		return -1;	/* negative value is an error */
>> +
>> +	/* clear driver structure */
>> +	dev->driver = NULL;
>> +
>> +	return 0;
>> +}
>> +
>> +/*
>> + * Call the devuninit() function of all registered drivers for the given
>> + * device if their IDs match.
>
> I think, the "IDs match" is obsolete becase the match_fn may work in a different way now.

Yes, I will remove this comment.

>
>> + *
>> + * @return
>> + *       0 when successful
>> + *      -1 if deinitialization fails
>> + *       1 if no driver is found for this device.
>> + */
>> +static int
>> +soc_detach_all_drivers(struct rte_soc_device *dev)
>> +{
>> +	struct rte_soc_driver *dr = NULL;
>> +	int rc = 0;
>> +
>> +	if (dev == NULL)
>> +		return -1;
>> +
>> +	TAILQ_FOREACH(dr, &soc_driver_list, next) {
>> +		rc = rte_eal_soc_detach_dev(dr, dev);
>> +		if (rc < 0)
>> +			/* negative value is an error */
>> +			return -1;
>> +		if (rc > 0)
>> +			/* positive value means driver doesn't support it */
>> +			continue;
>> +		return 0;
>> +	}
>> +	return 1;
>> +}
>> +
>> +/*
>> + * Detach device specified by its SoC address.
>> + */
>> +int
>> +rte_eal_soc_detach(const struct rte_soc_addr *addr)
>> +{
>> +	struct rte_soc_device *dev = NULL;
>> +	int ret = 0;
>> +
>> +	if (addr == NULL)
>> +		return -1;
>> +
>> +	TAILQ_FOREACH(dev, &soc_device_list, next) {
>> +		if (rte_eal_compare_soc_addr(&dev->addr, addr))
>> +			continue;
>> +
>> +		ret = soc_detach_all_drivers(dev);
>> +		if (ret < 0)
>> +			goto err_return;
>> +
>> +		TAILQ_REMOVE(&soc_device_list, dev, next);
>> +		return 0;
>> +	}
>> +	return -1;
>> +
>> +err_return:
>> +	RTE_LOG(WARNING, EAL, "Requested device %s cannot be used\n",
>> +		dev->addr.name);
>> +	return -1;
>> +}
>> +
>> +int
>> +rte_eal_soc_probe_one(const struct rte_soc_addr *addr)
>> +{
>> +	struct rte_soc_device *dev = NULL;
>> +	int ret = 0;
>> +
>> +	if (addr == NULL)
>> +		return -1;
>> +
>> +	/* unlike pci, in case of soc, it the responsibility of the soc driver
>> +	 * to check during init whether device has been updated since last add.
>
> Why? Can you give a more detailed explanation?

For this patch, I have _not_ assumed anything for a SoC's 
bus/driver/device model. In absence of a proper standard, each SoC is 
unique - categorizing all SoC under a platform bus, for example, would 
only mean assuming platform bus is a standard.
Best judge for the layout of SoC devices is the SoC PMD (which is also 
like a bus driver, other than being a device driver).

Once again, if the discussion in other thread comes to a logical 
conclusion, this would get updated.

>
>> +	 */
>> +
>> +	TAILQ_FOREACH(dev, &soc_device_list, next) {
>> +		if (rte_eal_compare_soc_addr(&dev->addr, addr))
>> +			continue;
>> +
>> +		ret = soc_probe_all_drivers(dev);
>> +		if (ret < 0)
>> +			goto err_return;
>> +		return 0;
>> +	}
>> +	return -1;
>> +
>> +err_return:
>> +	RTE_LOG(WARNING, EAL,
>> +		"Requested device %s cannot be used\n", addr->name);
>> +	return -1;
>> +}
>> +
>> +/*
>> + * Scan the SoC devices and call the devinit() function for all registered
>> + * drivers that have a matching entry in its id_table for discovered devices.
>> + */
>
> Should be in header. Here it is redundant.

Ok. I will move to rte_soc.h.

>
>> +int
>> +rte_eal_soc_probe(void)
>> +{
>> +	struct rte_soc_device *dev = NULL;
>> +	int ret = 0;
>> +
>> +	TAILQ_FOREACH(dev, &soc_device_list, next) {
>> +		ret = soc_probe_all_drivers(dev);
>> +		if (ret < 0)
>> +			rte_exit(EXIT_FAILURE, "Requested device %s"
>> +				 " cannot be used\n", dev->addr.name);
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>>  /* dump one device */
>>  static int
>>  soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
>> @@ -79,6 +288,12 @@ rte_eal_soc_dump(FILE *f)
>>  void
>>  rte_eal_soc_register(struct rte_soc_driver *driver)
>>  {
>> +	/* For a valid soc driver, match and scan function
>> +	 * should be provided.
>> +	 */
>
> This comment should be in the header file.

Actually there is no valueable addition made by this comment. RTE_VERIFY 
is self explanatory. I will remove the comment all together.

>
>> +	RTE_VERIFY(driver != NULL);
>> +	RTE_VERIFY(driver->match_fn != NULL);
>> +	RTE_VERIFY(driver->scan_fn != NULL);
>>  	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
>>  }
>>
>> diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
>> index c6f98eb..bfb49a2 100644
>> --- a/lib/librte_eal/common/include/rte_soc.h
>> +++ b/lib/librte_eal/common/include/rte_soc.h
>> @@ -97,6 +97,16 @@ typedef int (soc_devinit_t)(struct rte_soc_driver *, struct rte_soc_device *);
>>  typedef int (soc_devuninit_t)(struct rte_soc_device *);
>>
>>  /**
>> + * SoC device scan callback, called from rte_eal_soc_init.
>
> Can you explain what is the goal of the callback?
> What is the expected behaviour.

EAL would call the scan of each registered SoC PMD 
(DRIVER_REGISTER_SOC). This scan is responsible for finding devices on 
SoC's specific bus and add them to SoC device_list. This is a callback 
because SoC don't have a generalization like PCI. A SoC is not 
necessarily a platform bus either (what original patch series assumed).

>
> It returns void so it seems it can never fail. Is this correct?
> I can image that to scan for devices, I need to check some file-system
> structure which can be unavailable...

This is what I had in mind:
That is true, it never fails. It is expected that scan function simply 
ignores (logs error) and moves ahead. A local error for a particular SoC 
(I agree, there might not be more than one SoC) doesn't necessarily mean 
that complete DPDK Application should quit. It only means that 
application user should get some error/warning/message about failure.

>
>> + */
>> +typedef void (soc_scan_t)(void);
>
> You are missing the '*' in (*soc_scan_t).

That was put in the definition in the rte_soc_driver - but, I see you 
have already commented there. I will add the '*' here and remove from there.

>
>> +
>> +/**
>> + * Custom device<=>driver match callback for SoC
>
> Can you explain the semantics (return values), please?

rte_soc.h already has explanation on the expected semantics over 
rte_eal_soc_match - the default implementation. But, I agree, it should 
be above this declaration.

>
>> + */
>> +typedef int (soc_match_t)(struct rte_soc_driver *, struct rte_soc_device *);
>
> You are missing the '*' in (*soc_match_t).

Same as above - I will add '*' and remove from rte_soc_driver.

>
>> +
>> +/**
>>   * A structure describing a SoC driver.
>>   */
>>  struct rte_soc_driver {
>> @@ -104,6 +114,8 @@ struct rte_soc_driver {
>>  	struct rte_driver driver;          /**< Inherit core driver. */
>>  	soc_devinit_t *devinit;            /**< Device initialization */
>>  	soc_devuninit_t *devuninit;        /**< Device uninitialization */
>
> Those should be renamed to probe/remove.

Yes, agree with that.

>
>> +	soc_scan_t *scan_fn;               /**< Callback for scanning SoC bus*/
>> +	soc_match_t *match_fn;             /**< Callback to match dev<->drv */
>
> Here the '*' would be redundant if you add them to the typedefs.

As stated above, I will remove from there and add to typedefs.

>
> I think, we should tell the users that scan_fn and match_fn must be always set
> to something.

How? I think it would be part of documentation, isn't it?
Also, rte_eal_soc_init() already enforces this check with RTE_VERIFY.

>
>>  	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
>>  };
>>
>> @@ -146,6 +158,45 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
>>  }
>>
>>  /**
>> + * Default function for matching the Soc driver with device. Each driver can
>> + * either use this function or define their own soc matching function.
>> + * This function relies on the compatible string extracted from sysfs. But,
>> + * a SoC might have different way of identifying its devices. Such SoC can
>> + * override match_fn.
>> + *
>> + * @return
>> + * 	 0 on success
>> + *	-1 when no match found
>> +  */
>> +int
>> +rte_eal_soc_match(struct rte_soc_driver *drv, struct rte_soc_device *dev);
>
> What about naming it
>
> 	rte_eal_soc_match_default

Ok.

>
> or maybe better
>
> 	rte_eal_soc_match_compatible
>
> what do you think?

 From what I had in mind - the discussion about SoC not necessarily 
being a Platform bus - 'compatible' doesn't look fine to me. But again, 
it is still open debate so - I will wait until that is conlcuded.

>
>> +
>> +/**
>> + * Probe SoC devices for registered drivers.
>> + */
>> +int rte_eal_soc_probe(void);
>> +
>> +/**
>> + * Probe the single SoC device.
>> + */
>> +int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
>> +
>> +/**
>> + * Close the single SoC device.
>> + *
>> + * Scan the SoC devices and find the SoC device specified by the SoC
>> + * address, then call the devuninit() function for registered driver
>> + * that has a matching entry in its id_table for discovered device.
>> + *
>> + * @param addr
>> + *	The SoC address to close.
>> + * @return
>> + *   - 0 on success.
>> + *   - Negative on error.
>> + */
>> +int rte_eal_soc_detach(const struct rte_soc_addr *addr);
>> +
>> +/**
>>   * Dump discovered SoC devices.
>>   */
>>  void rte_eal_soc_dump(FILE *f);
>> diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
>> index 15c8c3d..147b601 100644
>> --- a/lib/librte_eal/linuxapp/eal/eal.c
>> +++ b/lib/librte_eal/linuxapp/eal/eal.c
>> @@ -70,6 +70,7 @@
>>  #include <rte_cpuflags.h>
>>  #include <rte_interrupts.h>
>>  #include <rte_pci.h>
>> +#include <rte_soc.h>
>>  #include <rte_dev.h>
>>  #include <rte_devargs.h>
>>  #include <rte_common.h>
>> @@ -881,6 +882,10 @@ rte_eal_init(int argc, char **argv)
>>  	if (rte_eal_pci_probe())
>>  		rte_panic("Cannot probe PCI\n");
>>
>> +	/* Probe & Initialize SoC devices */
>> +	if (rte_eal_soc_probe())
>> +		rte_panic("Cannot probe SoC\n");
>> +
>>  	rte_eal_mcfg_complete();
>>
>>  	return fctret;
>> diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
>> index 04848b9..5f961c4 100644
>> --- a/lib/librte_eal/linuxapp/eal/eal_soc.c
>> +++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
>> @@ -52,5 +52,21 @@
>>  int
>>  rte_eal_soc_init(void)
>>  {
>> +	struct rte_soc_driver *drv;
>> +
>> +	/* for debug purposes, SoC can be disabled */
>> +	if (internal_config.no_soc)
>> +		return 0;
>> +
>> +	/* For each registered driver, call their scan routine to perform any
>> +	 * custom scan for devices (for example, custom buses)
>> +	 */
>> +	TAILQ_FOREACH(drv, &soc_driver_list, next) {
>
> Is it possible to have drv->scan_fn == NULL? I suppose, this is invalid.
> I'd prefer to have RTE_VERIFY for this check.

rte_eal_soc_init() has this check already. Driver wouldn't even be 
registered in case scan/match are not implemented.

>
>> +		if (drv && drv->scan_fn) {
>> +			drv->scan_fn();
>> +			/* Ignore all errors from this */
>> +		}
>
>> +	}
>> +
>>  	return 0;
>>  }
>> diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
>> index b9d1932..adcfe7d 100644
>> --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
>> +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
>> @@ -179,5 +179,9 @@ DPDK_16.11 {
>>  	rte_eal_soc_register;
>>  	rte_eal_soc_unregister;
>>  	rte_eal_soc_dump;
>> +	rte_eal_soc_match;
>> +	rte_eal_soc_detach;
>> +	rte_eal_soc_probe;
>> +	rte_eal_soc_probe_one;
>>
>>  } DPDK_16.07;
>
> Regards
> Jan
>

I hope I have covered all your comments. That was an exhaustive review. 
Thanks a lot for your time.

Lets work to resolve the architectural issues revolving around SoC 
scan/match.

-
Shreyansh

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

* Re: [PATCH v3 06/15] eal/soc: implement probing of drivers
  2016-09-19  6:47       ` Shreyansh Jain
@ 2016-09-19 11:34         ` Jan Viktorin
  2016-09-20  6:46           ` Shreyansh Jain
  0 siblings, 1 reply; 231+ messages in thread
From: Jan Viktorin @ 2016-09-19 11:34 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, hemant.agrawal

On Mon, 19 Sep 2016 12:17:53 +0530
Shreyansh Jain <shreyansh.jain@nxp.com> wrote:

> Hi Jan,
> 
> On Friday 16 September 2016 05:57 PM, Jan Viktorin wrote:
> > On Fri, 9 Sep 2016 14:13:50 +0530
> > Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
> >  
> >> Each SoC PMD registers a set of callback for scanning its own bus/infra and
> >> matching devices to drivers when probe is called.
> >> This patch introduces the infra for calls to SoC scan on rte_eal_soc_init()
> >> and match on rte_eal_soc_probe().
> >>
> >> Patch also adds test case for scan and probe.
> >>
> >> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> >> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> >> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> >> ---
> >>  app/test/test_soc.c                             | 138 ++++++++++++++-
> >>  lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   4 +
> >>  lib/librte_eal/common/eal_common_soc.c          | 215 ++++++++++++++++++++++++
> >>  lib/librte_eal/common/include/rte_soc.h         |  51 ++++++
> >>  lib/librte_eal/linuxapp/eal/eal.c               |   5 +
> >>  lib/librte_eal/linuxapp/eal/eal_soc.c           |  16 ++
> >>  lib/librte_eal/linuxapp/eal/rte_eal_version.map |   4 +
> >>  7 files changed, 432 insertions(+), 1 deletion(-)
> >>

[...]

> 
> >  
> >> +static void test_soc_scan_dev0_cb(void);  
> >
> > Similar here, something like "match_by_name".
> >  
> >> +static int test_soc_match_dev0_cb(struct rte_soc_driver *drv,
> >> +				  struct rte_soc_device *dev);  
> >
> > I prefer an empty line here.  
> 
> Do we really place newlines in function declarations? That doesn't 
> really help anything, until and unless some comments are added to those. 
> Anyways, rather than added blank lines, I will add some comments - those 
> are indeed misssing.

It took me a while to parse those lines... If they are logically grouped,
it'd be ok. Comments might be helpful. However, here these are forward
declarations so it's a question whether to put comments here or to the
implementations below.

> 
> >
> >
> > ditto...  
> 
> Will add comments.
> 
> >  
> >> +static void test_soc_scan_dev1_cb(void);  
> >
> > ditto...  
> 
> Same here, I prefer comment rather than blank line.
> 
> >  

[...]

> >>
> >> +/* Test Probe (scan and match) functionality */
> >> +static int
> >> +test_soc_init_and_probe(void)  
> >
> > You say to test scan and match. I'd prefer to reflect this in the name
> > of the test. Otherwise, it seems you are testing init and probe which
> > is not true, I think.  
> 
> I agree. I will update the name of the function.
> 
> >
> > Do you test that "match principle works" or that "match functions are OK"
> > or "match functions are called as expected", ...?  
> 
> "match functions are called as expected"

OK, but there is no assert that says "yes, the match function has been called".
In other words, it is not an automatic test and it does not help to verify
that the code is working.

I think that you should test that a particular match function succeeds or not.
So again, I don't consider this to be a test. It does not verify anything.

> The model for the patchset was to allow PMDs to write their own match 
> and hence, verifying a particular match is not definitive. Rather, the 

If you want to verify a particular match implementation then there should
be a particular test verifying that implementation, e.g. test_match_compatible(),
test_match_proprietary, test_match_by_name.

However, this is testing the rte_eal_soc_probe (at least, I understand it that way).
The probe iterates over devices and drivers and matches them. Thus, the argument
"a particular match is not definitive" seems to be irrelevant here. You should build
a testing match function like "match_always" that verifies the probe is working. Not
that the "match" is working.

> test case simply confirms that a SoC based PMD would be able to 

It does not confirm anything from my point of view. You *always* print "successful"
at the end of this test (see below).

> implement its own match/scan and these would be called from EAL as expected.
> 
> >  
> >> +{
> >> +	struct rte_soc_driver *drv;
> >> +
> >> +	/* Registering dummy drivers */
> >> +	rte_eal_soc_register(&empty_pmd0.soc_drv);
> >> +	rte_eal_soc_register(&empty_pmd1.soc_drv);
> >> +	/* Assuming that test_register_unregister is working, not verifying
> >> +	 * that drivers are indeed registered
> >> +	*/
> >> +
> >> +	/* rte_eal_soc_init is called by rte_eal_init, which in turn calls the
> >> +	 * scan_fn of each driver.

So, I'd comment this as something like:

"mimic rte_eal_soc_init to prepare for the rte_eal_soc_probe"

> >> +	 */
> >> +	TAILQ_FOREACH(drv, &soc_driver_list, next) {
> >> +		if (drv && drv->scan_fn)
> >> +			drv->scan_fn();
> >> +	}  
> >
> > Here, I suppose you mimic the rte_eal_soc_init?  
> 
> Yes.
> 
> >  
> >> +
> >> +	/* rte_eal_init() would perform other inits here */
> >> +
> >> +	/* Probe would link the SoC devices<=>drivers */
> >> +	rte_eal_soc_probe();
> >> +
> >> +	/* Unregistering dummy drivers */
> >> +	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
> >> +	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
> >> +
> >> +	free(empty_pmd0.soc_dev.addr.name);
> >> +
> >> +	printf("%s has been successful\n", __func__);  
> >
> > How you detect it is unsuccessful? Is it possible to fail in this test?
> > A test that can never fail is in fact not a test :).  
> 
> The design assumption for SoC patcheset was: A PMDs scan is called to 
> find devices on its bus (PMD ~ bus). Whether devices are found or not, 
> is irrelevant to EAL - whether that is because of error or actually no 
> devices were available.
> With the above logic, no 'success/failure' is checked in the test. It is 
> simply a verification of EAL's ability to link the PMD with it 
> (scan/match function pointers).

I am sorry, I disagree. You always print "successful". The only way to fail
here is a SIGSEGV or other very serious system failure. But we test rte_eal_soc_probe
and not system failures.

> 
> >  
> >> +	return 0;
> >> +}
> >> +
> >>  /* save real devices and drivers until the tests finishes */

[...]

> >> diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
> >> index 5dcddc5..bb87a67 100644
> >> --- a/lib/librte_eal/common/eal_common_soc.c
> >> +++ b/lib/librte_eal/common/eal_common_soc.c
> >> @@ -36,6 +36,8 @@
> >>  #include <sys/queue.h>
> >>
> >>  #include <rte_log.h>
> >> +#include <rte_common.h>
> >> +#include <rte_soc.h>
> >>
> >>  #include "eal_private.h"
> >>
> >> @@ -45,6 +47,213 @@ struct soc_driver_list soc_driver_list =
> >>  struct soc_device_list soc_device_list =
> >>  	TAILQ_HEAD_INITIALIZER(soc_device_list);
> >>
> >> +/* Default SoC device<->Driver match handler function */  
> >
> > I think this comment is redundant. All this is already said in the rte_soc.h.  
> 
> Ok. I will remove it from here and if need be, update the rte_soc.h to 
> have elaborate comments.
> 
> >  
> >> +int
> >> +rte_eal_soc_match(struct rte_soc_driver *drv, struct rte_soc_device *dev)
> >> +{
> >> +	int i, j;
> >> +
> >> +	RTE_VERIFY(drv != NULL && drv->id_table != NULL);
> >> +	RTE_VERIFY(dev != NULL && dev->id != NULL);
> >> +
> >> +	for (i = 0; drv->id_table[i].compatible; ++i) {
> >> +		const char *drv_compat = drv->id_table[i].compatible;
> >> +
> >> +		for (j = 0; dev->id[j].compatible; ++j) {
> >> +			const char *dev_compat = dev->id[j].compatible;
> >> +
> >> +			if (!strcmp(drv_compat, dev_compat))
> >> +				return 0;
> >> +		}
> >> +	}
> >> +
> >> +	return 1;
> >> +}
> >> +

A redundant empty line here...

> >> +
> >> +static int
> >> +rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
> >> +			     struct rte_soc_device *dev)
> >> +{
> >> +	int ret = 1;
> >> +  
> >
> > I think, the RTE_VERIFY(dev->match_fn) might be good here.
> > It avoids any doubts about the validity of the pointer.  
> 
> That has already been done in rte_eal_soc_register which is called when 
> PMDs are registering themselves through DRIVER_REGISTER_SOC. That would 
> prevent any PMD leaking through to this stage without a proper 
> match_fn/scan_fn.

Well, yes. It seems to be redundant. However, it would emphesize the fact
that this function expects that match_fn is set.

In the rte_eal_soc_register, the RTE_VERIFY says "The API requires those".

But when I review I do not always see all the context. It is not safe for
me to assume that there was probably some RTE_VERIFY in the path... It is
not a fast path so it does not hurt the performance in anyway.

> 
> >  
> >> +	ret = drv->match_fn(drv, dev);
> >> +	if (ret) {
> >> +		RTE_LOG(DEBUG, EAL,
> >> +			" match function failed, skipping\n");  
> >
> > Is this a failure? I think it is not. Failure would be if the match
> > function cannot execute correctly. This is more like "no-match".  
> 
> The log message is misleading. This is _not_ a failure but simply a 
> 'no-match'. I will update this.
> 
> >
> > When debugging, I'd like to see more a message like "driver <name> does not match".  
> 
> Problem would be about '<name>' of a driver. There is already another 
> discussion about SoC capability/platform bus definitions - probably I 
> will wait for that so as to define what a '<name>' for a driver and 
> device is.
> In this case, the key reason for not adding such a message was because 
> it was assumed PMDs are black boxes with EAL not even assuming what 
> '<name>' means. Anyways, it is better to discuss these things in that 
> other email.

I am not sure which thread do you mean... Can you point me there, please?

> 
> >  
> >> +		return ret;

[...]

> >> +
> >> +int
> >> +rte_eal_soc_probe_one(const struct rte_soc_addr *addr)
> >> +{
> >> +	struct rte_soc_device *dev = NULL;
> >> +	int ret = 0;
> >> +
> >> +	if (addr == NULL)
> >> +		return -1;
> >> +
> >> +	/* unlike pci, in case of soc, it the responsibility of the soc driver
> >> +	 * to check during init whether device has been updated since last add.  
> >
> > Why? Can you give a more detailed explanation?  
> 
> For this patch, I have _not_ assumed anything for a SoC's 
> bus/driver/device model. In absence of a proper standard, each SoC is 
> unique - categorizing all SoC under a platform bus, for example, would 
> only mean assuming platform bus is a standard.
> Best judge for the layout of SoC devices is the SoC PMD (which is also 
> like a bus driver, other than being a device driver).
> 
> Once again, if the discussion in other thread comes to a logical 
> conclusion, this would get updated.

Again, I am not sure which thread discusses this topic.

I just don't like the idea to leave update responsibility on PMDs.
Maybe, there can be a callback update in rte_soc_device (set or not-set
by the custom scan function) that is to be called here.

> 
> >  
> >> +	 */
> >> +
> >> +	TAILQ_FOREACH(dev, &soc_device_list, next) {
> >> +		if (rte_eal_compare_soc_addr(&dev->addr, addr))
> >> +			continue;
> >> +
> >> +		ret = soc_probe_all_drivers(dev);
> >> +		if (ret < 0)
> >> +			goto err_return;
> >> +		return 0;
> >> +	}
> >> +	return -1;
> >> +
> >> +err_return:
> >> +	RTE_LOG(WARNING, EAL,
> >> +		"Requested device %s cannot be used\n", addr->name);
> >> +	return -1;
> >> +}
> >> +
> >> +/*
> >> + * Scan the SoC devices and call the devinit() function for all registered
> >> + * drivers that have a matching entry in its id_table for discovered devices.
> >> + */  
> >
> > Should be in header. Here it is redundant.  
> 
> Ok. I will move to rte_soc.h.
> 
> >  
> >> +int
> >> +rte_eal_soc_probe(void)
> >> +{
> >> +	struct rte_soc_device *dev = NULL;
> >> +	int ret = 0;
> >> +
> >> +	TAILQ_FOREACH(dev, &soc_device_list, next) {
> >> +		ret = soc_probe_all_drivers(dev);
> >> +		if (ret < 0)
> >> +			rte_exit(EXIT_FAILURE, "Requested device %s"
> >> +				 " cannot be used\n", dev->addr.name);
> >> +	}
> >> +
> >> +	return 0;
> >> +}
> >> +
> >>  /* dump one device */
> >>  static int
> >>  soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
> >> @@ -79,6 +288,12 @@ rte_eal_soc_dump(FILE *f)
> >>  void
> >>  rte_eal_soc_register(struct rte_soc_driver *driver)
> >>  {
> >> +	/* For a valid soc driver, match and scan function
> >> +	 * should be provided.
> >> +	 */  
> >
> > This comment should be in the header file.  
> 
> Actually there is no valueable addition made by this comment. RTE_VERIFY 
> is self explanatory. I will remove the comment all together.

No, the comment must be present for the rte_eal_soc_register function as
its documentation. The RTE_VERIFY is not an excuse, it just verifies the
fact that the caller understands the documentation and that she didn't make
a mistake.

> 
> >  
> >> +	RTE_VERIFY(driver != NULL);
> >> +	RTE_VERIFY(driver->match_fn != NULL);
> >> +	RTE_VERIFY(driver->scan_fn != NULL);
> >>  	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
> >>  }
> >>
> >> diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
> >> index c6f98eb..bfb49a2 100644
> >> --- a/lib/librte_eal/common/include/rte_soc.h
> >> +++ b/lib/librte_eal/common/include/rte_soc.h
> >> @@ -97,6 +97,16 @@ typedef int (soc_devinit_t)(struct rte_soc_driver *, struct rte_soc_device *);
> >>  typedef int (soc_devuninit_t)(struct rte_soc_device *);
> >>
> >>  /**
> >> + * SoC device scan callback, called from rte_eal_soc_init.  
> >
> > Can you explain what is the goal of the callback?
> > What is the expected behaviour.  
> 
> EAL would call the scan of each registered SoC PMD 
> (DRIVER_REGISTER_SOC). This scan is responsible for finding devices on 
> SoC's specific bus and add them to SoC device_list. This is a callback 
> because SoC don't have a generalization like PCI. A SoC is not 
> necessarily a platform bus either (what original patch series assumed).

In doc comment...

> 
> >
> > It returns void so it seems it can never fail. Is this correct?
> > I can image that to scan for devices, I need to check some file-system
> > structure which can be unavailable...  
> 
> This is what I had in mind:
> That is true, it never fails. It is expected that scan function simply 
> ignores (logs error) and moves ahead. A local error for a particular SoC 
> (I agree, there might not be more than one SoC) doesn't necessarily mean 
> that complete DPDK Application should quit. It only means that 
> application user should get some error/warning/message about failure.

I understand, this is OK then.

> 
> >  
> >> + */
> >> +typedef void (soc_scan_t)(void);  
> >
> > You are missing the '*' in (*soc_scan_t).  
> 
> That was put in the definition in the rte_soc_driver - but, I see you 
> have already commented there. I will add the '*' here and remove from there.
> 
> >  
> >> +
> >> +/**
> >> + * Custom device<=>driver match callback for SoC  
> >
> > Can you explain the semantics (return values), please?  
> 
> rte_soc.h already has explanation on the expected semantics over 
> rte_eal_soc_match - the default implementation. But, I agree, it should 
> be above this declaration.

True ;).

> 
> >  
> >> + */
> >> +typedef int (soc_match_t)(struct rte_soc_driver *, struct rte_soc_device *);  
> >

[...]

> 
> >
> > I think, we should tell the users that scan_fn and match_fn must be always set
> > to something.  
> 
> How? I think it would be part of documentation, isn't it?

Yes. It should be documented in the comment for rte_eal_soc_init.
My comment was misplaced a bit...

> Also, rte_eal_soc_init() already enforces this check with RTE_VERIFY.
> 
> >  
> >>  	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
> >>  };
> >>
> >> @@ -146,6 +158,45 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
> >>  }
> >>
> >>  /**
> >> + * Default function for matching the Soc driver with device. Each driver can
> >> + * either use this function or define their own soc matching function.
> >> + * This function relies on the compatible string extracted from sysfs. But,
> >> + * a SoC might have different way of identifying its devices. Such SoC can
> >> + * override match_fn.
> >> + *
> >> + * @return
> >> + * 	 0 on success
> >> + *	-1 when no match found
> >> +  */
> >> +int
> >> +rte_eal_soc_match(struct rte_soc_driver *drv, struct rte_soc_device *dev);  
> >
> > What about naming it
> >
> > 	rte_eal_soc_match_default  
> 
> Ok.
> 
> >
> > or maybe better
> >
> > 	rte_eal_soc_match_compatible
> >
> > what do you think?  
> 
>  From what I had in mind - the discussion about SoC not necessarily 
> being a Platform bus - 'compatible' doesn't look fine to me. But again, 
> it is still open debate so - I will wait until that is conlcuded.

Why? The current implementation works this way:

int
rte_eal_soc_match(struct rte_soc_driver *drv, struct rte_soc_device *dev)
{
	int i, j;

	RTE_VERIFY(drv != NULL && drv->id_table != NULL);
	RTE_VERIFY(dev != NULL && dev->id != NULL);

	for (i = 0; drv->id_table[i].compatible; ++i) {
		const char *drv_compat = drv->id_table[i].compatible;

		for (j = 0; dev->id[j].compatible; ++j) {
			const char *dev_compat = dev->id[j].compatible;

			if (!strcmp(drv_compat, dev_compat))
				return 0;
		}
	}

	return 1;
}

It checks for compatible. So why not to name it that way? If you provide
a match testing the name of devices then it can be named *_match_name.

> 
> >  
> >> +
> >> +/**
> >> + * Probe SoC devices for registered drivers.
> >> + */
> >> +int rte_eal_soc_probe(void);
> >> +
> >> +/**
> >> + * Probe the single SoC device.
> >> + */
> >> +int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
> >> +
> >> +/**
> >> + * Close the single SoC device.
> >> + *
> >> + * Scan the SoC devices and find the SoC device specified by the SoC
> >> + * address, then call the devuninit() function for registered driver
> >> + * that has a matching entry in its id_table for discovered device.
> >> + *
> >> + * @param addr
> >> + *	The SoC address to close.
> >> + * @return
> >> + *   - 0 on success.
> >> + *   - Negative on error.
> >> + */
> >> +int rte_eal_soc_detach(const struct rte_soc_addr *addr);
> >> +
> >> +/**
> >>   * Dump discovered SoC devices.
> >>   */
> >>  void rte_eal_soc_dump(FILE *f);
> >> diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
> >> index 15c8c3d..147b601 100644
> >> --- a/lib/librte_eal/linuxapp/eal/eal.c
> >> +++ b/lib/librte_eal/linuxapp/eal/eal.c
> >> @@ -70,6 +70,7 @@
> >>  #include <rte_cpuflags.h>
> >>  #include <rte_interrupts.h>
> >>  #include <rte_pci.h>
> >> +#include <rte_soc.h>
> >>  #include <rte_dev.h>
> >>  #include <rte_devargs.h>
> >>  #include <rte_common.h>
> >> @@ -881,6 +882,10 @@ rte_eal_init(int argc, char **argv)
> >>  	if (rte_eal_pci_probe())
> >>  		rte_panic("Cannot probe PCI\n");
> >>
> >> +	/* Probe & Initialize SoC devices */
> >> +	if (rte_eal_soc_probe())
> >> +		rte_panic("Cannot probe SoC\n");
> >> +
> >>  	rte_eal_mcfg_complete();
> >>
> >>  	return fctret;
> >> diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
> >> index 04848b9..5f961c4 100644
> >> --- a/lib/librte_eal/linuxapp/eal/eal_soc.c
> >> +++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
> >> @@ -52,5 +52,21 @@
> >>  int
> >>  rte_eal_soc_init(void)
> >>  {
> >> +	struct rte_soc_driver *drv;
> >> +
> >> +	/* for debug purposes, SoC can be disabled */
> >> +	if (internal_config.no_soc)
> >> +		return 0;
> >> +
> >> +	/* For each registered driver, call their scan routine to perform any
> >> +	 * custom scan for devices (for example, custom buses)
> >> +	 */
> >> +	TAILQ_FOREACH(drv, &soc_driver_list, next) {  
> >
> > Is it possible to have drv->scan_fn == NULL? I suppose, this is invalid.
> > I'd prefer to have RTE_VERIFY for this check.  
> 
> rte_eal_soc_init() has this check already. Driver wouldn't even be 
> registered in case scan/match are not implemented.

True, but when reviewing or refactoring, you cannot see always all this context.
It is more defensive to explain here "don't worry, the scan_fn is always set here".

> 
> >  
> >> +		if (drv && drv->scan_fn) {
> >> +			drv->scan_fn();
> >> +			/* Ignore all errors from this */
> >> +		}  
> >  
> >> +	}
> >> +
> >>  	return 0;
> >>  }
> >> diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> >> index b9d1932..adcfe7d 100644
> >> --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> >> +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> >> @@ -179,5 +179,9 @@ DPDK_16.11 {
> >>  	rte_eal_soc_register;
> >>  	rte_eal_soc_unregister;
> >>  	rte_eal_soc_dump;
> >> +	rte_eal_soc_match;
> >> +	rte_eal_soc_detach;
> >> +	rte_eal_soc_probe;
> >> +	rte_eal_soc_probe_one;
> >>
> >>  } DPDK_16.07;  
> >
> > Regards
> > Jan
> >  
> 
> I hope I have covered all your comments. That was an exhaustive review. 
> Thanks a lot for your time.
> 
> Lets work to resolve the architectural issues revolving around SoC 
> scan/match.

;)

> 
> -
> Shreyansh



-- 
   Jan Viktorin                  E-mail: Viktorin@RehiveTech.com
   System Architect              Web:    www.RehiveTech.com
   RehiveTech
   Brno, Czech Republic

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

* Re: [PATCH v3 00/15] Introduce SoC device/driver framework for EAL
  2016-09-18 10:04             ` Jan Viktorin
@ 2016-09-19 12:33               ` Hemant Agrawal
  0 siblings, 0 replies; 231+ messages in thread
From: Hemant Agrawal @ 2016-09-19 12:33 UTC (permalink / raw)
  To: Jan Viktorin; +Cc: Jianbo Liu, Shreyansh Jain, dev, David Marchand

On 9/18/2016 3:34 PM, Jan Viktorin wrote:
> On Sun, 18 Sep 2016 09:41:55 +0000
> Hemant Agrawal <hemant.agrawal@nxp.com> wrote:
>
>>> -----Original Message-----
>>> From: Jan Viktorin [mailto:viktorin@rehivetech.com]
>>
>
> [...]
>
>>>> And for each platform/product....
>>>>
>>>>> I agree, that this can sometimes lead to code duplication. Moreover,
>>>>> it opens door for a very non-standard, unsecure and wrong-by-design
>>>>> approaches. I'd like more to provide one or more scan
>>>>> implementations in EAL and do not put this responsibility on PMDs.
>>
>
> Hi Hemant.
>
>>  [Hemant]  A common/default scan function can be added, provided at least one or more  PMD driver support it.
>> w.r.t Jan's original scan function, it was not suitable for any of the NXP SoC's whether ARM or PowerPC.
>>
>> Unable to validate the Jan's scan function on a real platform, we have skipped it for next phase.
>> Addition of a default scan function can only be done in next phase, when we find a suitable SoC PMD driver supporting it.
>
> Quite frankly, the situation is same for me. I still have no clue about
> your approach which seems to be pretty non-standard. I have no way how
> to test it.
>
Yes! Our first sample to test the above proposal is with a specific bus; 
NXP's new generation Layerscape devices use fsl-mc bus.

https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt

This is neither a platform bus nor a PCI bus. It does not fit the 
default implementation for platform bus.

Our objective is to make the first design of SoC patchset very simple 
and extendable for future. This will improve, when we have more SoC 
vendor participation and sharing their requirements.

Also, we definitely have a plan to provide default implementation for 
buses which are generic or have more than one PMD implementation 
depending on them e.g. use your Platform Bus scan function

> My approach can be tested on any Linux machine with platform devices
> and device-tree enabled. You would see that I detect those devices (I
> don't mean any certain network device, I mean all platform devices) and
> if you provide a driver with a proper compatible string it will be set
> for you.
>
> I presume that I don't have any upstreamable PMD for this at the moment.
>
> From the very generic scan approach, I cannot see, what kernel
> infrastructure are you going to use. We should support at least the
> VFIO-platform which is standard and with IOMMU, it is considered secure.
> Any other approach would require an out-of-tree kernel driver or some
> non-secure access to devices. I don't say it is very wrong, but we
> should be careful about this.
>

I agree with your description and approach when the devices are on 
platform-bus.

We plan to address it in next phase. We have identified another NXP 
device, which uses platform-bus for device detection. We will use that 
for our testing.


>>>>>
>>>>>>
>>>>>>>    detect the devices. This is because SoC may require specific or
>>>>>>>    additional info for device detection. Further, SoC may have
>>>>>>> embedded
>>>>>
>>>>> Can you provide an example for "additional info for device detection"?
>
> Can you?
>
e.g. our fsl-mc bus is more close to PCI bus, where we get object 
identifiers instead of compatible string.


> Regards
> Jan
>
> [...]
>

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

* Re: [PATCH v3 06/15] eal/soc: implement probing of drivers
  2016-09-19 11:34         ` Jan Viktorin
@ 2016-09-20  6:46           ` Shreyansh Jain
  2016-09-20 10:49             ` Jan Viktorin
  0 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-09-20  6:46 UTC (permalink / raw)
  To: Jan Viktorin; +Cc: dev, Hemant Agrawal

Hi Jan,

> -----Original Message-----
> From: Jan Viktorin [mailto:viktorin@rehivetech.com]
> Sent: Monday, September 19, 2016 5:04 PM
> To: Shreyansh Jain <shreyansh.jain@nxp.com>
> Cc: dev@dpdk.org; Hemant Agrawal <hemant.agrawal@nxp.com>
> Subject: Re: [PATCH v3 06/15] eal/soc: implement probing of drivers
> 
> On Mon, 19 Sep 2016 12:17:53 +0530
> Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
> 
> > Hi Jan,
> >
> > On Friday 16 September 2016 05:57 PM, Jan Viktorin wrote:
> > > On Fri, 9 Sep 2016 14:13:50 +0530
> > > Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
> > >
> > >> Each SoC PMD registers a set of callback for scanning its own bus/infra
> and
> > >> matching devices to drivers when probe is called.
> > >> This patch introduces the infra for calls to SoC scan on
> rte_eal_soc_init()
> > >> and match on rte_eal_soc_probe().
> > >>
> > >> Patch also adds test case for scan and probe.
> > >>
> > >> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> > >> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> > >> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> > >> ---
> > >>  app/test/test_soc.c                             | 138 ++++++++++++++-
> > >>  lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   4 +
> > >>  lib/librte_eal/common/eal_common_soc.c          | 215
> ++++++++++++++++++++++++
> > >>  lib/librte_eal/common/include/rte_soc.h         |  51 ++++++
> > >>  lib/librte_eal/linuxapp/eal/eal.c               |   5 +
> > >>  lib/librte_eal/linuxapp/eal/eal_soc.c           |  16 ++
> > >>  lib/librte_eal/linuxapp/eal/rte_eal_version.map |   4 +
> > >>  7 files changed, 432 insertions(+), 1 deletion(-)
> > >>
> 
> [...]
> 
> >
> > >
> > >> +static void test_soc_scan_dev0_cb(void);
> > >
> > > Similar here, something like "match_by_name".
> > >
> > >> +static int test_soc_match_dev0_cb(struct rte_soc_driver *drv,
> > >> +				  struct rte_soc_device *dev);
> > >
> > > I prefer an empty line here.
> >
> > Do we really place newlines in function declarations? That doesn't
> > really help anything, until and unless some comments are added to those.
> > Anyways, rather than added blank lines, I will add some comments - those
> > are indeed misssing.
> 
> It took me a while to parse those lines... If they are logically grouped,
> it'd be ok. Comments might be helpful. However, here these are forward
> declarations so it's a question whether to put comments here or to the
> implementations below.

Ok. I will keep this mind in v4.

> 
> >
> > >
> > >
> > > ditto...
> >
> > Will add comments.
> >
> > >
> > >> +static void test_soc_scan_dev1_cb(void);
> > >
> > > ditto...
> >
> > Same here, I prefer comment rather than blank line.
> >
> > >
> 
> [...]
> 
> > >>
> > >> +/* Test Probe (scan and match) functionality */
> > >> +static int
> > >> +test_soc_init_and_probe(void)
> > >
> > > You say to test scan and match. I'd prefer to reflect this in the name
> > > of the test. Otherwise, it seems you are testing init and probe which
> > > is not true, I think.
> >
> > I agree. I will update the name of the function.
> >
> > >
> > > Do you test that "match principle works" or that "match functions are OK"
> > > or "match functions are called as expected", ...?
> >
> > "match functions are called as expected"
> 
> OK, but there is no assert that says "yes, the match function has been
> called".
> In other words, it is not an automatic test and it does not help to verify
> that the code is working.
> 
> I think that you should test that a particular match function succeeds or
> not.
> So again, I don't consider this to be a test. It does not verify anything.
 
Agree with you. This is not a 'test' in real sense. I will revisit and see what can be done about this. Probably your method of 'match' succeeds with 'always_find_device0' style function.

> 
> > The model for the patchset was to allow PMDs to write their own match
> > and hence, verifying a particular match is not definitive. Rather, the
> 
> If you want to verify a particular match implementation then there should
> be a particular test verifying that implementation, e.g.
> test_match_compatible(),
> test_match_proprietary, test_match_by_name.
> 
> However, this is testing the rte_eal_soc_probe (at least, I understand it
> that way).
> The probe iterates over devices and drivers and matches them. Thus, the
> argument
> "a particular match is not definitive" seems to be irrelevant here. You
> should build
> a testing match function like "match_always" that verifies the probe is
> working. Not
> that the "match" is working.
 
Ok. 'match_always' called after 'always_find_device0' like scan function. So, essentially rather than a functional match, the testcase only checks if these handlers can be called or not. The naming of such handlers in test case would explain the user what the intention of the test is, rather than its outcome. Is this what you are suggesting? 

> 
> > test case simply confirms that a SoC based PMD would be able to
> 
> It does not confirm anything from my point of view. You *always* print
> "successful"
> at the end of this test (see below).
> 
> > implement its own match/scan and these would be called from EAL as
> expected.
> >
> > >
> > >> +{
> > >> +	struct rte_soc_driver *drv;
> > >> +
> > >> +	/* Registering dummy drivers */
> > >> +	rte_eal_soc_register(&empty_pmd0.soc_drv);
> > >> +	rte_eal_soc_register(&empty_pmd1.soc_drv);
> > >> +	/* Assuming that test_register_unregister is working, not
> verifying
> > >> +	 * that drivers are indeed registered
> > >> +	*/
> > >> +
> > >> +	/* rte_eal_soc_init is called by rte_eal_init, which in turn
> calls the
> > >> +	 * scan_fn of each driver.
> 
> So, I'd comment this as something like:
> 
> "mimic rte_eal_soc_init to prepare for the rte_eal_soc_probe"
 
Agree.

> 
> > >> +	 */
> > >> +	TAILQ_FOREACH(drv, &soc_driver_list, next) {
> > >> +		if (drv && drv->scan_fn)
> > >> +			drv->scan_fn();
> > >> +	}
> > >
> > > Here, I suppose you mimic the rte_eal_soc_init?
> >
> > Yes.
> >
> > >
> > >> +
> > >> +	/* rte_eal_init() would perform other inits here */
> > >> +
> > >> +	/* Probe would link the SoC devices<=>drivers */
> > >> +	rte_eal_soc_probe();
> > >> +
> > >> +	/* Unregistering dummy drivers */
> > >> +	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
> > >> +	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
> > >> +
> > >> +	free(empty_pmd0.soc_dev.addr.name);
> > >> +
> > >> +	printf("%s has been successful\n", __func__);
> > >
> > > How you detect it is unsuccessful? Is it possible to fail in this test?
> > > A test that can never fail is in fact not a test :).
> >
> > The design assumption for SoC patcheset was: A PMDs scan is called to
> > find devices on its bus (PMD ~ bus). Whether devices are found or not,
> > is irrelevant to EAL - whether that is because of error or actually no
> > devices were available.
> > With the above logic, no 'success/failure' is checked in the test. It is
> > simply a verification of EAL's ability to link the PMD with it
> > (scan/match function pointers).
> 
> I am sorry, I disagree. You always print "successful". The only way to fail
> here is a SIGSEGV or other very serious system failure. But we test
> rte_eal_soc_probe
> and not system failures.
 
Ok. I am not yet clear how the test case would be created, except what I have mentioned above that rather than being functional, testcase only explains the case through function naming.
The premise on which match/scan are based is that they would be implemented by the respective PMD. Which makes testing of such function either irrelevant or simply a help to user to understand how SoC PMD should be created.
If this persists, probably I would rather remove this test case all together. It doesn't serve any purpose, which you have rightly pointed out.

> 
> >
> > >
> > >> +	return 0;
> > >> +}
> > >> +
> > >>  /* save real devices and drivers until the tests finishes */
> 
> [...]
> 
> > >> diff --git a/lib/librte_eal/common/eal_common_soc.c
> b/lib/librte_eal/common/eal_common_soc.c
> > >> index 5dcddc5..bb87a67 100644
> > >> --- a/lib/librte_eal/common/eal_common_soc.c
> > >> +++ b/lib/librte_eal/common/eal_common_soc.c
> > >> @@ -36,6 +36,8 @@
> > >>  #include <sys/queue.h>
> > >>
> > >>  #include <rte_log.h>
> > >> +#include <rte_common.h>
> > >> +#include <rte_soc.h>
> > >>
> > >>  #include "eal_private.h"
> > >>
> > >> @@ -45,6 +47,213 @@ struct soc_driver_list soc_driver_list =
> > >>  struct soc_device_list soc_device_list =
> > >>  	TAILQ_HEAD_INITIALIZER(soc_device_list);
> > >>
> > >> +/* Default SoC device<->Driver match handler function */
> > >
> > > I think this comment is redundant. All this is already said in the
> rte_soc.h.
> >
> > Ok. I will remove it from here and if need be, update the rte_soc.h to
> > have elaborate comments.
> >
> > >
> > >> +int
> > >> +rte_eal_soc_match(struct rte_soc_driver *drv, struct rte_soc_device
> *dev)
> > >> +{
> > >> +	int i, j;
> > >> +
> > >> +	RTE_VERIFY(drv != NULL && drv->id_table != NULL);
> > >> +	RTE_VERIFY(dev != NULL && dev->id != NULL);
> > >> +
> > >> +	for (i = 0; drv->id_table[i].compatible; ++i) {
> > >> +		const char *drv_compat = drv->id_table[i].compatible;
> > >> +
> > >> +		for (j = 0; dev->id[j].compatible; ++j) {
> > >> +			const char *dev_compat = dev->id[j].compatible;
> > >> +
> > >> +			if (!strcmp(drv_compat, dev_compat))
> > >> +				return 0;
> > >> +		}
> > >> +	}
> > >> +
> > >> +	return 1;
> > >> +}
> > >> +
> 
> A redundant empty line here...

Yes, I will remove this. 

> 
> > >> +
> > >> +static int
> > >> +rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
> > >> +			     struct rte_soc_device *dev)
> > >> +{
> > >> +	int ret = 1;
> > >> +
> > >
> > > I think, the RTE_VERIFY(dev->match_fn) might be good here.
> > > It avoids any doubts about the validity of the pointer.
> >
> > That has already been done in rte_eal_soc_register which is called when
> > PMDs are registering themselves through DRIVER_REGISTER_SOC. That would
> > prevent any PMD leaking through to this stage without a proper
> > match_fn/scan_fn.
> 
> Well, yes. It seems to be redundant. However, it would emphesize the fact
> that this function expects that match_fn is set.
> 
> In the rte_eal_soc_register, the RTE_VERIFY says "The API requires those".
> 
> But when I review I do not always see all the context. It is not safe for
> me to assume that there was probably some RTE_VERIFY in the path... It is
> not a fast path so it does not hurt the performance in anyway.
> 

You mean RTE_VERIFY should be duplicated so that code readability increases?
I am not really convinced on that.
My opinion: rte_eal_soc_*probe* series shouldn't actually worry about whether a valid PMD has been plugged in or. It should simply assume that having reached here, all is well on the PMDs definition side.

On the contrary, placing a RTE_VERIFY here would only state the reader that it is possible to reach this code path without a valid match function.

> >
> > >
> > >> +	ret = drv->match_fn(drv, dev);
> > >> +	if (ret) {
> > >> +		RTE_LOG(DEBUG, EAL,
> > >> +			" match function failed, skipping\n");
> > >
> > > Is this a failure? I think it is not. Failure would be if the match
> > > function cannot execute correctly. This is more like "no-match".
> >
> > The log message is misleading. This is _not_ a failure but simply a
> > 'no-match'. I will update this.
> >
> > >
> > > When debugging, I'd like to see more a message like "driver <name> does
> not match".
> >
> > Problem would be about '<name>' of a driver. There is already another
> > discussion about SoC capability/platform bus definitions - probably I
> > will wait for that so as to define what a '<name>' for a driver and
> > device is.
> > In this case, the key reason for not adding such a message was because
> > it was assumed PMDs are black boxes with EAL not even assuming what
> > '<name>' means. Anyways, it is better to discuss these things in that
> > other email.
> 
> I am not sure which thread do you mean... Can you point me there, please?
 
Sorry, somehow I forgot to add that:
http://dpdk.org/ml/archives/dev/2016-September/046933.html

One of the discussion point in above thread is whether platform bus is a good assumption for a SoC driver or not. Based on that '<name>' (or any other identifier, like 'compatible'), the log can be printed as you suggested above.

> 
> >
> > >
> > >> +		return ret;
> 
> [...]
> 
> > >> +
> > >> +int
> > >> +rte_eal_soc_probe_one(const struct rte_soc_addr *addr)
> > >> +{
> > >> +	struct rte_soc_device *dev = NULL;
> > >> +	int ret = 0;
> > >> +
> > >> +	if (addr == NULL)
> > >> +		return -1;
> > >> +
> > >> +	/* unlike pci, in case of soc, it the responsibility of the soc
> driver
> > >> +	 * to check during init whether device has been updated since
> last add.
> > >
> > > Why? Can you give a more detailed explanation?
> >
> > For this patch, I have _not_ assumed anything for a SoC's
> > bus/driver/device model. In absence of a proper standard, each SoC is
> > unique - categorizing all SoC under a platform bus, for example, would
> > only mean assuming platform bus is a standard.
> > Best judge for the layout of SoC devices is the SoC PMD (which is also
> > like a bus driver, other than being a device driver).
> >
> > Once again, if the discussion in other thread comes to a logical
> > conclusion, this would get updated.
> 
> Again, I am not sure which thread discusses this topic.

Copying the link again: http://dpdk.org/ml/archives/dev/2016-September/046933.html

> 
> I just don't like the idea to leave update responsibility on PMDs.
> Maybe, there can be a callback update in rte_soc_device (set or not-set
> by the custom scan function) that is to be called here.
 
And for me, the very idea of 'leave update responsibility to PMD' is appealing in case of SoC.
Though, I think your suggestion of 'callback' is pretty good. Just to clarify, is my understanding correct: PMD registers a callback for 'update' and EAL would call that when it reaches this code path (of update device information during probe). The callback can be passed the device found so that PMD can update that. Is that what you too had in mind?

> 
> >
> > >
> > >> +	 */
> > >> +
> > >> +	TAILQ_FOREACH(dev, &soc_device_list, next) {
> > >> +		if (rte_eal_compare_soc_addr(&dev->addr, addr))
> > >> +			continue;
> > >> +
> > >> +		ret = soc_probe_all_drivers(dev);
> > >> +		if (ret < 0)
> > >> +			goto err_return;
> > >> +		return 0;
> > >> +	}
> > >> +	return -1;
> > >> +
> > >> +err_return:
> > >> +	RTE_LOG(WARNING, EAL,
> > >> +		"Requested device %s cannot be used\n", addr->name);
> > >> +	return -1;
> > >> +}
> > >> +
> > >> +/*
> > >> + * Scan the SoC devices and call the devinit() function for all
> registered
> > >> + * drivers that have a matching entry in its id_table for discovered
> devices.
> > >> + */
> > >
> > > Should be in header. Here it is redundant.
> >
> > Ok. I will move to rte_soc.h.
> >
> > >
> > >> +int
> > >> +rte_eal_soc_probe(void)
> > >> +{
> > >> +	struct rte_soc_device *dev = NULL;
> > >> +	int ret = 0;
> > >> +
> > >> +	TAILQ_FOREACH(dev, &soc_device_list, next) {
> > >> +		ret = soc_probe_all_drivers(dev);
> > >> +		if (ret < 0)
> > >> +			rte_exit(EXIT_FAILURE, "Requested device %s"
> > >> +				 " cannot be used\n", dev->addr.name);
> > >> +	}
> > >> +
> > >> +	return 0;
> > >> +}
> > >> +
> > >>  /* dump one device */
> > >>  static int
> > >>  soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
> > >> @@ -79,6 +288,12 @@ rte_eal_soc_dump(FILE *f)
> > >>  void
> > >>  rte_eal_soc_register(struct rte_soc_driver *driver)
> > >>  {
> > >> +	/* For a valid soc driver, match and scan function
> > >> +	 * should be provided.
> > >> +	 */
> > >
> > > This comment should be in the header file.
> >
> > Actually there is no valueable addition made by this comment. RTE_VERIFY
> > is self explanatory. I will remove the comment all together.
> 
> No, the comment must be present for the rte_eal_soc_register function as
> its documentation. The RTE_VERIFY is not an excuse, it just verifies the
> fact that the caller understands the documentation and that she didn't make
> a mistake.

Ok. It doesn't hurt to have a comment. I will add that. 

> 
> >
> > >
> > >> +	RTE_VERIFY(driver != NULL);
> > >> +	RTE_VERIFY(driver->match_fn != NULL);
> > >> +	RTE_VERIFY(driver->scan_fn != NULL);
> > >>  	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
> > >>  }
> > >>
> > >> diff --git a/lib/librte_eal/common/include/rte_soc.h
> b/lib/librte_eal/common/include/rte_soc.h
> > >> index c6f98eb..bfb49a2 100644
> > >> --- a/lib/librte_eal/common/include/rte_soc.h
> > >> +++ b/lib/librte_eal/common/include/rte_soc.h
> > >> @@ -97,6 +97,16 @@ typedef int (soc_devinit_t)(struct rte_soc_driver *,
> struct rte_soc_device *);
> > >>  typedef int (soc_devuninit_t)(struct rte_soc_device *);
> > >>
> > >>  /**
> > >> + * SoC device scan callback, called from rte_eal_soc_init.
> > >
> > > Can you explain what is the goal of the callback?
> > > What is the expected behaviour.
> >
> > EAL would call the scan of each registered SoC PMD
> > (DRIVER_REGISTER_SOC). This scan is responsible for finding devices on
> > SoC's specific bus and add them to SoC device_list. This is a callback
> > because SoC don't have a generalization like PCI. A SoC is not
> > necessarily a platform bus either (what original patch series assumed).
> 
> In doc comment...
> 
> >
> > >
> > > It returns void so it seems it can never fail. Is this correct?
> > > I can image that to scan for devices, I need to check some file-system
> > > structure which can be unavailable...
> >
> > This is what I had in mind:
> > That is true, it never fails. It is expected that scan function simply
> > ignores (logs error) and moves ahead. A local error for a particular SoC
> > (I agree, there might not be more than one SoC) doesn't necessarily mean
> > that complete DPDK Application should quit. It only means that
> > application user should get some error/warning/message about failure.
> 
> I understand, this is OK then.
> 
> >
> > >
> > >> + */
> > >> +typedef void (soc_scan_t)(void);
> > >
> > > You are missing the '*' in (*soc_scan_t).
> >
> > That was put in the definition in the rte_soc_driver - but, I see you
> > have already commented there. I will add the '*' here and remove from
> there.
> >
> > >
> > >> +
> > >> +/**
> > >> + * Custom device<=>driver match callback for SoC
> > >
> > > Can you explain the semantics (return values), please?
> >
> > rte_soc.h already has explanation on the expected semantics over
> > rte_eal_soc_match - the default implementation. But, I agree, it should
> > be above this declaration.
> 
> True ;).
> 
> >
> > >
> > >> + */
> > >> +typedef int (soc_match_t)(struct rte_soc_driver *, struct
> rte_soc_device *);
> > >
> 
> [...]
> 
> >
> > >
> > > I think, we should tell the users that scan_fn and match_fn must be
> always set
> > > to something.
> >
> > How? I think it would be part of documentation, isn't it?
> 
> Yes. It should be documented in the comment for rte_eal_soc_init.
> My comment was misplaced a bit...
 
Ok.

> 
> > Also, rte_eal_soc_init() already enforces this check with RTE_VERIFY.
> >
> > >
> > >>  	const struct rte_soc_id *id_table; /**< ID table, NULL terminated
> */
> > >>  };
> > >>
> > >> @@ -146,6 +158,45 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr
> *a0,
> > >>  }
> > >>
> > >>  /**
> > >> + * Default function for matching the Soc driver with device. Each
> driver can
> > >> + * either use this function or define their own soc matching function.
> > >> + * This function relies on the compatible string extracted from sysfs.
> But,
> > >> + * a SoC might have different way of identifying its devices. Such SoC
> can
> > >> + * override match_fn.
> > >> + *
> > >> + * @return
> > >> + * 	 0 on success
> > >> + *	-1 when no match found
> > >> +  */
> > >> +int
> > >> +rte_eal_soc_match(struct rte_soc_driver *drv, struct rte_soc_device
> *dev);
> > >
> > > What about naming it
> > >
> > > 	rte_eal_soc_match_default
> >
> > Ok.
> >
> > >
> > > or maybe better
> > >
> > > 	rte_eal_soc_match_compatible
> > >
> > > what do you think?
> >
> >  From what I had in mind - the discussion about SoC not necessarily
> > being a Platform bus - 'compatible' doesn't look fine to me. But again,
> > it is still open debate so - I will wait until that is conlcuded.
> 
> Why? The current implementation works this way:
> 
> int
> rte_eal_soc_match(struct rte_soc_driver *drv, struct rte_soc_device *dev)
> {
> 	int i, j;
> 
> 	RTE_VERIFY(drv != NULL && drv->id_table != NULL);
> 	RTE_VERIFY(dev != NULL && dev->id != NULL);
> 
> 	for (i = 0; drv->id_table[i].compatible; ++i) {
> 		const char *drv_compat = drv->id_table[i].compatible;
> 
> 		for (j = 0; dev->id[j].compatible; ++j) {
> 			const char *dev_compat = dev->id[j].compatible;
> 
> 			if (!strcmp(drv_compat, dev_compat))
> 				return 0;
> 		}
> 	}
> 
> 	return 1;
> }
> 
> It checks for compatible. So why not to name it that way? If you provide
> a match testing the name of devices then it can be named *_match_name.
 
I think all the confusion is about whether match on compatible string should be kept as default or not.
My opinion: No.
Because I have a usecase where the SoC PMD is not a platform bus. [1]
By keeping a 'compatible' string based match, it would be obvious to have a scan for /sys/bus/platform. That in itself is based on assumption that a SoC is platform bus and would adhere to generally known semantics of a platform bus.

Other the other hand, as Hemant has suggested in [1], plan is to have a skeletal code for SoC framework - one which allows any SoC PMD to be plugged in irrespective of the bus/device design. Thereafter, when more PMDs become part of the DPDK framework, generalize functions (which is where your implementations of scan/match over /sys/bus/platform fit pretty well).

[1] http://dpdk.org/ml/archives/dev/2016-September/046967.html

> 
> >
> > >
> > >> +
> > >> +/**
> > >> + * Probe SoC devices for registered drivers.
> > >> + */
> > >> +int rte_eal_soc_probe(void);
> > >> +
> > >> +/**
> > >> + * Probe the single SoC device.
> > >> + */
> > >> +int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
> > >> +
> > >> +/**
> > >> + * Close the single SoC device.
> > >> + *
> > >> + * Scan the SoC devices and find the SoC device specified by the SoC
> > >> + * address, then call the devuninit() function for registered driver
> > >> + * that has a matching entry in its id_table for discovered device.
> > >> + *
> > >> + * @param addr
> > >> + *	The SoC address to close.
> > >> + * @return
> > >> + *   - 0 on success.
> > >> + *   - Negative on error.
> > >> + */
> > >> +int rte_eal_soc_detach(const struct rte_soc_addr *addr);
> > >> +
> > >> +/**
> > >>   * Dump discovered SoC devices.
> > >>   */
> > >>  void rte_eal_soc_dump(FILE *f);
> > >> diff --git a/lib/librte_eal/linuxapp/eal/eal.c
> b/lib/librte_eal/linuxapp/eal/eal.c
> > >> index 15c8c3d..147b601 100644
> > >> --- a/lib/librte_eal/linuxapp/eal/eal.c
> > >> +++ b/lib/librte_eal/linuxapp/eal/eal.c
> > >> @@ -70,6 +70,7 @@
> > >>  #include <rte_cpuflags.h>
> > >>  #include <rte_interrupts.h>
> > >>  #include <rte_pci.h>
> > >> +#include <rte_soc.h>
> > >>  #include <rte_dev.h>
> > >>  #include <rte_devargs.h>
> > >>  #include <rte_common.h>
> > >> @@ -881,6 +882,10 @@ rte_eal_init(int argc, char **argv)
> > >>  	if (rte_eal_pci_probe())
> > >>  		rte_panic("Cannot probe PCI\n");
> > >>
> > >> +	/* Probe & Initialize SoC devices */
> > >> +	if (rte_eal_soc_probe())
> > >> +		rte_panic("Cannot probe SoC\n");
> > >> +
> > >>  	rte_eal_mcfg_complete();
> > >>
> > >>  	return fctret;
> > >> diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c
> b/lib/librte_eal/linuxapp/eal/eal_soc.c
> > >> index 04848b9..5f961c4 100644
> > >> --- a/lib/librte_eal/linuxapp/eal/eal_soc.c
> > >> +++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
> > >> @@ -52,5 +52,21 @@
> > >>  int
> > >>  rte_eal_soc_init(void)
> > >>  {
> > >> +	struct rte_soc_driver *drv;
> > >> +
> > >> +	/* for debug purposes, SoC can be disabled */
> > >> +	if (internal_config.no_soc)
> > >> +		return 0;
> > >> +
> > >> +	/* For each registered driver, call their scan routine to perform
> any
> > >> +	 * custom scan for devices (for example, custom buses)
> > >> +	 */
> > >> +	TAILQ_FOREACH(drv, &soc_driver_list, next) {
> > >
> > > Is it possible to have drv->scan_fn == NULL? I suppose, this is invalid.
> > > I'd prefer to have RTE_VERIFY for this check.
> >
> > rte_eal_soc_init() has this check already. Driver wouldn't even be
> > registered in case scan/match are not implemented.
> 
> True, but when reviewing or refactoring, you cannot see always all this
> context.
> It is more defensive to explain here "don't worry, the scan_fn is always set
> here".
 
Ok. I will add this.

> 
> >
> > >
> > >> +		if (drv && drv->scan_fn) {
> > >> +			drv->scan_fn();
> > >> +			/* Ignore all errors from this */
> > >> +		}
> > >
> > >> +	}
> > >> +
> > >>  	return 0;
> > >>  }
> > >> diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> > >> index b9d1932..adcfe7d 100644
> > >> --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> > >> +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> > >> @@ -179,5 +179,9 @@ DPDK_16.11 {
> > >>  	rte_eal_soc_register;
> > >>  	rte_eal_soc_unregister;
> > >>  	rte_eal_soc_dump;
> > >> +	rte_eal_soc_match;
> > >> +	rte_eal_soc_detach;
> > >> +	rte_eal_soc_probe;
> > >> +	rte_eal_soc_probe_one;
> > >>
> > >>  } DPDK_16.07;
> > >
> > > Regards
> > > Jan
> > >
> >
> > I hope I have covered all your comments. That was an exhaustive review.
> > Thanks a lot for your time.
> >
> > Lets work to resolve the architectural issues revolving around SoC
> > scan/match.
> 
> ;)
 
Phew!
I am already loosing track of things you have suggested.
What if we can chat on IRC and resolve the issue surrounding the 'default match/scan', 'platform or not platform dependent SoC' etc? I think it would save a lot of ping-pong effort. 
(For today (20/Sep), I might not be available, but I am OK any other time).

> 
> >
> > -
> > Shreyansh
> 
> 
> 
> --
>    Jan Viktorin                  E-mail: Viktorin@RehiveTech.com
>    System Architect              Web:    www.RehiveTech.com
>    RehiveTech
>    Brno, Czech Republic

Thanks a lot.

-
Shreyansh

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

* Re: [PATCH v3 06/15] eal/soc: implement probing of drivers
  2016-09-20  6:46           ` Shreyansh Jain
@ 2016-09-20 10:49             ` Jan Viktorin
  0 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-09-20 10:49 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, Hemant Agrawal, David Marchand

On Tue, 20 Sep 2016 06:46:31 +0000
Shreyansh Jain <shreyansh.jain@nxp.com> wrote:

> Hi Jan,
> 
> > -----Original Message-----
> > From: Jan Viktorin [mailto:viktorin@rehivetech.com]
> > Sent: Monday, September 19, 2016 5:04 PM
> > To: Shreyansh Jain <shreyansh.jain@nxp.com>
> > Cc: dev@dpdk.org; Hemant Agrawal <hemant.agrawal@nxp.com>
> > Subject: Re: [PATCH v3 06/15] eal/soc: implement probing of drivers
> > 
> > On Mon, 19 Sep 2016 12:17:53 +0530
> > Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
> >   
> > > Hi Jan,

[...]

> 
> >   
> > > The model for the patchset was to allow PMDs to write their own match
> > > and hence, verifying a particular match is not definitive. Rather, the  
> > 
> > If you want to verify a particular match implementation then there should
> > be a particular test verifying that implementation, e.g.
> > test_match_compatible(),
> > test_match_proprietary, test_match_by_name.
> > 
> > However, this is testing the rte_eal_soc_probe (at least, I understand it
> > that way).
> > The probe iterates over devices and drivers and matches them. Thus, the
> > argument
> > "a particular match is not definitive" seems to be irrelevant here. You
> > should build
> > a testing match function like "match_always" that verifies the probe is
> > working. Not
> > that the "match" is working.  
>  
> Ok. 'match_always' called after 'always_find_device0' like scan function. So, essentially rather than a functional match, the testcase only checks if these handlers can be called or not. The naming of such handlers in test case would explain the user what the intention of the test is, rather than its outcome. Is this what you are suggesting? 

Yes, it seems to be ;).

> 
> >   
> > > test case simply confirms that a SoC based PMD would be able to  
> > 
> > It does not confirm anything from my point of view. You *always* print
> > "successful"
> > at the end of this test (see below).
> >   
> > > implement its own match/scan and these would be called from EAL as  
> > expected.  
> > >  
> > > >  
> > > >> +{
> > > >> +	struct rte_soc_driver *drv;
> > > >> +
> > > >> +	/* Registering dummy drivers */
> > > >> +	rte_eal_soc_register(&empty_pmd0.soc_drv);
> > > >> +	rte_eal_soc_register(&empty_pmd1.soc_drv);
> > > >> +	/* Assuming that test_register_unregister is working, not  
> > verifying  
> > > >> +	 * that drivers are indeed registered
> > > >> +	*/
> > > >> +
> > > >> +	/* rte_eal_soc_init is called by rte_eal_init, which in turn  
> > calls the  
> > > >> +	 * scan_fn of each driver.  
> > 
> > So, I'd comment this as something like:
> > 
> > "mimic rte_eal_soc_init to prepare for the rte_eal_soc_probe"  
>  
> Agree.
> 
> >   
> > > >> +	 */
> > > >> +	TAILQ_FOREACH(drv, &soc_driver_list, next) {
> > > >> +		if (drv && drv->scan_fn)
> > > >> +			drv->scan_fn();
> > > >> +	}  
> > > >
> > > > Here, I suppose you mimic the rte_eal_soc_init?  
> > >
> > > Yes.
> > >  
> > > >  
> > > >> +
> > > >> +	/* rte_eal_init() would perform other inits here */
> > > >> +
> > > >> +	/* Probe would link the SoC devices<=>drivers */
> > > >> +	rte_eal_soc_probe();
> > > >> +
> > > >> +	/* Unregistering dummy drivers */
> > > >> +	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
> > > >> +	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
> > > >> +
> > > >> +	free(empty_pmd0.soc_dev.addr.name);
> > > >> +
> > > >> +	printf("%s has been successful\n", __func__);  
> > > >
> > > > How you detect it is unsuccessful? Is it possible to fail in this test?
> > > > A test that can never fail is in fact not a test :).  
> > >
> > > The design assumption for SoC patcheset was: A PMDs scan is called to
> > > find devices on its bus (PMD ~ bus). Whether devices are found or not,
> > > is irrelevant to EAL - whether that is because of error or actually no
> > > devices were available.
> > > With the above logic, no 'success/failure' is checked in the test. It is
> > > simply a verification of EAL's ability to link the PMD with it
> > > (scan/match function pointers).  
> > 
> > I am sorry, I disagree. You always print "successful". The only way to fail
> > here is a SIGSEGV or other very serious system failure. But we test
> > rte_eal_soc_probe
> > and not system failures.  
>  
> Ok. I am not yet clear how the test case would be created, except what I have mentioned above that rather than being functional, testcase only explains the case through function naming.
> The premise on which match/scan are based is that they would be implemented by the respective PMD. Which makes testing of such function either irrelevant or simply a help to user to understand how SoC PMD should be created.
> If this persists, probably I would rather remove this test case all together. It doesn't serve any purpose, which you have rightly pointed out.

I'd vote to have this test to check for regressions. See the test_pci.c, e.g. test_pci_blacklist(). It is not
ideal but it works. You can check how many devices have been matched or seen.

Unfortunately, I am not familiar with DPAA2 API. I assume that it works via /sys as well as platform_device
but with different properties. You can create a fake /sys sub-tree (see app/test/test_pci_sysfs/) and test
whether your scan function reads data successfully and fills all the structures as expected. I think, there
is a lot of space in this area.

Next, is it possible to write a generic DPAA2 backend for the SoC Framework? I mean to not introduce the DPAA2
into PMDs (this looks like mixing of responsibilities) but have it in EAL as an alternative to UIO, VFIO, etc.
I suppose that as DPAA2 is a kind of API, it should be possible to go this way.

> 
> >   
> > >  
> > > >  
> > > >> +	return 0;
> > > >> +}
> > > >> +
> > > >>  /* save real devices and drivers until the tests finishes */  
> > 

[...]

> > >  
> > > >  
> > > >> +int
> > > >> +rte_eal_soc_match(struct rte_soc_driver *drv, struct rte_soc_device  
> > *dev)  
> > > >> +{
> > > >> +	int i, j;
> > > >> +
> > > >> +	RTE_VERIFY(drv != NULL && drv->id_table != NULL);
> > > >> +	RTE_VERIFY(dev != NULL && dev->id != NULL);
> > > >> +
> > > >> +	for (i = 0; drv->id_table[i].compatible; ++i) {
> > > >> +		const char *drv_compat = drv->id_table[i].compatible;
> > > >> +
> > > >> +		for (j = 0; dev->id[j].compatible; ++j) {
> > > >> +			const char *dev_compat = dev->id[j].compatible;
> > > >> +
> > > >> +			if (!strcmp(drv_compat, dev_compat))
> > > >> +				return 0;
> > > >> +		}
> > > >> +	}
> > > >> +
> > > >> +	return 1;
> > > >> +}
> > > >> +  
> > 
> > A redundant empty line here...  
> 
> Yes, I will remove this. 
> 
> >   
> > > >> +
> > > >> +static int
> > > >> +rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
> > > >> +			     struct rte_soc_device *dev)
> > > >> +{
> > > >> +	int ret = 1;
> > > >> +  
> > > >
> > > > I think, the RTE_VERIFY(dev->match_fn) might be good here.
> > > > It avoids any doubts about the validity of the pointer.  
> > >
> > > That has already been done in rte_eal_soc_register which is called when
> > > PMDs are registering themselves through DRIVER_REGISTER_SOC. That would
> > > prevent any PMD leaking through to this stage without a proper
> > > match_fn/scan_fn.  
> > 
> > Well, yes. It seems to be redundant. However, it would emphesize the fact
> > that this function expects that match_fn is set.
> > 
> > In the rte_eal_soc_register, the RTE_VERIFY says "The API requires those".
> > 
> > But when I review I do not always see all the context. It is not safe for
> > me to assume that there was probably some RTE_VERIFY in the path... It is
> > not a fast path so it does not hurt the performance in anyway.
> >   
> 
> You mean RTE_VERIFY should be duplicated so that code readability increases?
> I am not really convinced on that.
> My opinion: rte_eal_soc_*probe* series shouldn't actually worry about whether a valid PMD has been plugged in or. It should simply assume that having reached here, all is well on the PMDs definition side.
> 
> On the contrary, placing a RTE_VERIFY here would only state the reader that it is possible to reach this code path without a valid match function.

Yes, it would state that the match function must always be valid here. That's the point.

> 
> > >  
> > > >  
> > > >> +	ret = drv->match_fn(drv, dev);
> > > >> +	if (ret) {
> > > >> +		RTE_LOG(DEBUG, EAL,
> > > >> +			" match function failed, skipping\n");  
> > > >
> > > > Is this a failure? I think it is not. Failure would be if the match
> > > > function cannot execute correctly. This is more like "no-match".  
> > >
> > > The log message is misleading. This is _not_ a failure but simply a
> > > 'no-match'. I will update this.
> > >  
> > > >
> > > > When debugging, I'd like to see more a message like "driver <name> does  
> > not match".  
> > >
> > > Problem would be about '<name>' of a driver. There is already another
> > > discussion about SoC capability/platform bus definitions - probably I
> > > will wait for that so as to define what a '<name>' for a driver and
> > > device is.
> > > In this case, the key reason for not adding such a message was because
> > > it was assumed PMDs are black boxes with EAL not even assuming what
> > > '<name>' means. Anyways, it is better to discuss these things in that
> > > other email.  
> > 
> > I am not sure which thread do you mean... Can you point me there, please?  
>  
> Sorry, somehow I forgot to add that:
> http://dpdk.org/ml/archives/dev/2016-September/046933.html
> 
> One of the discussion point in above thread is whether platform bus is a good assumption for a SoC driver or not. Based on that '<name>' (or any other identifier, like 'compatible'), the log can be printed as you suggested above.

Quite frankly, I don't know. The platform bus seemed the obvious starting point to me when I started working
on this topic. There was no DPAA2 (as far as I know), nothing more suitable. I write custom kernel drivers
as platform devices.

However, if you look into PCI infrastructure you can see that the UIO, VFIO and custom approaches are available.
And there is no PMD-specific scan function. I'd rather go the way it is already done to not diverge a lot from
the base code. Otherwise, we can easily come to a point like "drop DPDK and write again" :).

> 
> >   
> > >  
> > > >  

[...]

> 
> >   
> > >  
> > > >  
> > > >> +		if (drv && drv->scan_fn) {
> > > >> +			drv->scan_fn();
> > > >> +			/* Ignore all errors from this */
> > > >> +		}  
> > > >  
> > > >> +	}
> > > >> +
> > > >>  	return 0;
> > > >>  }
> > > >> diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map  
> > b/lib/librte_eal/linuxapp/eal/rte_eal_version.map  
> > > >> index b9d1932..adcfe7d 100644
> > > >> --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> > > >> +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> > > >> @@ -179,5 +179,9 @@ DPDK_16.11 {
> > > >>  	rte_eal_soc_register;
> > > >>  	rte_eal_soc_unregister;
> > > >>  	rte_eal_soc_dump;
> > > >> +	rte_eal_soc_match;
> > > >> +	rte_eal_soc_detach;
> > > >> +	rte_eal_soc_probe;
> > > >> +	rte_eal_soc_probe_one;
> > > >>
> > > >>  } DPDK_16.07;  
> > > >
> > > > Regards
> > > > Jan
> > > >  
> > >
> > > I hope I have covered all your comments. That was an exhaustive review.
> > > Thanks a lot for your time.
> > >
> > > Lets work to resolve the architectural issues revolving around SoC
> > > scan/match.  
> > 
> > ;)  
>  
> Phew!
> I am already loosing track of things you have suggested.
> What if we can chat on IRC and resolve the issue surrounding the 'default match/scan', 'platform or not platform dependent SoC' etc? I think it would save a lot of ping-pong effort. 
> (For today (20/Sep), I might not be available, but I am OK any other time).

Sure... write me when you are available. I maybe temporarily away.

> 
> >   
> > >
> > > -
> > > Shreyansh  
> > 
> > 
> > 
> > --
> >    Jan Viktorin                  E-mail: Viktorin@RehiveTech.com
> >    System Architect              Web:    www.RehiveTech.com
> >    RehiveTech
> >    Brno, Czech Republic  
> 
> Thanks a lot.
> 
> -
> Shreyansh



-- 
   Jan Viktorin                  E-mail: Viktorin@RehiveTech.com
   System Architect              Web:    www.RehiveTech.com
   RehiveTech
   Brno, Czech Republic

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

* [PATCH v4 00/17] Introduce SoC device/driver framework for EAL
  2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
                     ` (16 preceding siblings ...)
  2016-09-18  5:58   ` Jianbo Liu
@ 2016-10-15 13:44   ` Shreyansh Jain
  2016-10-15 13:44     ` [PATCH v4 01/17] eal: define container macro Shreyansh Jain
                       ` (18 more replies)
  17 siblings, 19 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-15 13:44 UTC (permalink / raw)
  To: dev; +Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain

Introduction:
=============

This patch set is direct derivative of Jan's original series [1],[2].

 - This version is based on HEAD (tag: v16.11-rc1) + patch series [11]

Aim:
====

As of now EAL is primarly focused on PCI initialization/probing.
 
 rte_eal_init()
  |- rte_eal_pci_init(): Find PCI devices from sysfs
  |- ...
  |- rte_eal_memzone_init()
  |- ...
  `- rte_eal_pci_probe(): Driver<=>Device initialization

This patchset introduces SoC framework which would enable SoC drivers and
drivers to be plugged into EAL, very similar to how PCI drivers/devices are
done today.

This is a stripped down version of PCI framework which allows the SoC PMDs
to implement their own routines for detecting devices and linking devices to
drivers.

1) Changes to EAL 
 rte_eal_init()
  |- rte_eal_pci_init(): Find PCI devices from sysfs
  |- rte_eal_soc_init(): Calls PMDs->scan_fn
  |- ...
  |- rte_eal_memzone_init()
  |- ...
  |- rte_eal_pci_probe(): Driver<=>Device initialization, PMD->devinit()
  `- rte_eal_soc_probe(): Calls PMDs->match_fn and PMDs->devinit();

2) New device/driver structures:
  - rte_soc_driver (inheriting rte_driver)
  - rte_soc_device (inheriting rte_device)
  - rte_eth_dev and eth_driver embedded rte_soc_device and rte_soc_driver,
    respectively.

3) The SoC PMDs need to:
 - define rte_soc_driver with necessary scan and match callbacks
 - Register themselves using DRIVER_REGISTER_SOC()
 - Implement respective bus scanning in the scan callbacks to add necessary
   devices to SoC device list
 - Implement necessary eth_dev_init/uninint for ethernet instances

4) Design considerations that are same as PCI:
 - SoC initialization is being done through rte_eal_init(), just after PCI 
   initialization is done.
 - As in case of PCI, probe is done after rte_eal_pci_probe() to link the 
   devices detected with the drivers registered.
 - Device attach/detach functions are available and have been designed on 
   the lines of PCI framework.
 - PMDs register using DRIVER_REGISTER_SOC, very similar to 
   DRIVER_REGISTER_PCI for PCI devices.
 - Linked list of SoC driver and devices exists independent of the other 
   driver/device list, but inheriting rte_driver/rte_driver, these are
   also part of a global list.

5) Design considerations that are different from PCI:
 - Each driver implements its own scan and match function. PCI uses the BDF 
   format to read the device from sysfs, but this _may_not_ be a case for a 
   SoC ethernet device.
   = This is an important change from initial proposal by Jan in [2].
   Unlike his attempt to use /sys/bus/platform, this patch relies on the
   PMD to detect the devices. This is because SoC may require specific or
   additional info for device detection. Further, SoC may have embedded
   devices/MACs which require initialization which cannot be covered
   through sysfs parsing.
   `-> Point (6) below is a side note to above.
   = PCI based PMDs rely on EAL's capability to detect devices. This 
   proposal puts the onus on PMD to detect devices, add to soc_device_list 
   and wait for Probe. Matching, of device<=>driver is again PMD's
   callback.

6) Adding default scan and match helpers for PMDs
 - The design warrrants the PMDs implement their own scan of devices
   on bus, and match routines for probe implementation.
   This patch introduces helpers which can be used by PMDs for scan of
   the platform bus and matching devices against the compatible string
   extracted from the scan.
 - Intention is to make it easier to integrate known SoC which expose
   platform bus compliant information (compat, sys/bus/platform...).
 - PMDs which have deviations from this standard model can implement and
   hook their bus scanning and probe match callbacks while registering
   driver.

Patchset Overview:
==================
 - Patches 0001~0004 introduce the base infrastructure and test case
 - Patch 0005 is for command line support for no-soc, on lines of no-pci
 - Patch 0006 enables EAL to handle SoC type devices
 - Patch 0007 adds support for scan and probe callbacks and updates the test
   framework with relevant test case.
 - Patch 0008~0010 enable device argument, driver specific flags and
   interrupt handling related basic infra. Subsequent patches build up on
   them.
 - Patch 0011~0012 add support for default function which PMDs can use for
   scanning platform bus. These functions are optional and need to be hooked
   to by PMDs.
 - Patch 0013~0014 makes changes to PCI as well as ethdev code to remove 
   assumption that eth_driver is a PCI driver.
 - Patch 0016 adds necessary ethdev probe/remove functions for PMDs to use
 - Patch 0017 adds support for SoC driver/devices, along with probe/remove
   functions for Cryptodev devices.

Future/Pending Changes:
=======================
- Device whitelisting/blacklist still relies on command line '-b' and '-c'
  which are internally implemented using OPT_PCI_BLACKLIST/OPT_PCI_WHITELIST.
  This needs to be changed to a generic form - OPT_DEV_*LIST - probably.
- No cryptodriver currently uses SoC framework - probably a example driver
  can be created to demonstrate usage.
- test case for enable-soc command line parameter

 [1] http://dpdk.org/ml/archives/dev/2016-January/030915.html
 [2] http://www.dpdk.org/ml/archives/dev/2016-May/038486.html
 [3] http://dpdk.org/ml/archives/dev/2016-August/045707.html
 [4] http://dpdk.org/ml/archives/dev/2016-May/038948.html
 [5] http://dpdk.org/ml/archives/dev/2016-May/038953.html
 [6] http://dpdk.org/ml/archives/dev/2016-May/038487.html
 [7] http://dpdk.org/ml/archives/dev/2016-May/038488.html
 [8] http://dpdk.org/ml/archives/dev/2016-May/038489.html
 [9] http://dpdk.org/ml/archives/dev/2016-May/038491.html
[10] http://dpdk.org/ml/archives/dev/2016-September/046256.html
[11] http://dpdk.org/ml/archives/dev/2016-October/048915.html

Changes since v3:
 - rebasing over HEAD (fed622df tag: v16.11-rc1)
 - Add support for default scan function; PMD can use this for
   scanning on platform bus.
 - Support for kernel driver bind/unbind, numa and DMA from
   Jan's original patches.
 - SoC is disabled by default. '--enable-soc' command line parameter
   enables it. doc updated.
 - Updated testcase function names and comments
 - Map file addition alphabetically ordered
 - Patch author corrected

Changes since v2:
 - Rebasing over rte_driver/device patchset v9 [10]
 - Added cryptodev support for SoC
 - Default match function for SoC device<=>Driver
 - Some variables renamed to reflect 'drv' rather than 'dr'

Change since v1 [2]:
 - Removed patch 1-5 which were for generalizing some PCI specific routines
   into EAL. These patches are good-to-have but not directly linked to SoC
   and hence would be proposed separately.
 - Removed support for sysfs parsing (patches 6~9)
 - Rebasing over the recent (v8) version of rte_driver/device patchset
 - Rebasing over master (16.07)
 - Changes to various map file to change API intro to 16.11 from 16.07

Jan Viktorin (15):
  eal: define container macro
  eal/soc: introduce very essential SoC infra definitions
  eal/soc: add SoC PMD register/unregister logic
  eal/soc: implement SoC device list and dump
  eal: introduce command line enable SoC option
  eal/soc: init SoC infra from EAL
  eal/soc: extend and utilize devargs
  eal/soc: add drv_flags
  eal/soc: add intr_handle
  eal/soc: add default scan for Soc devices
  eal/soc: additional features for SoC
  ether: utilize container_of for pci_drv
  ether: verify we copy info from a PCI device
  ether: extract function eth_dev_get_intr_handle
  ether: introduce ethernet dev probe remove

Shreyansh Jain (2):
  eal/soc: implement probing of drivers
  eal/crypto: Support rte_soc_driver/device for cryptodev

 app/test/Makefile                               |   1 +
 app/test/test_soc.c                             | 404 +++++++++++++++++++
 doc/guides/testpmd_app_ug/run_app.rst           |   4 +
 lib/librte_cryptodev/rte_cryptodev.c            | 122 +++++-
 lib/librte_cryptodev/rte_cryptodev.h            |   3 +
 lib/librte_cryptodev/rte_cryptodev_pmd.h        |  18 +-
 lib/librte_cryptodev/rte_cryptodev_version.map  |   2 +
 lib/librte_eal/bsdapp/eal/Makefile              |   1 +
 lib/librte_eal/bsdapp/eal/eal.c                 |   4 +
 lib/librte_eal/bsdapp/eal/eal_soc.c             |  46 +++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   9 +
 lib/librte_eal/common/Makefile                  |   2 +-
 lib/librte_eal/common/eal_common_dev.c          |  27 +-
 lib/librte_eal/common/eal_common_devargs.c      |  17 +
 lib/librte_eal/common/eal_common_options.c      |   5 +
 lib/librte_eal/common/eal_common_soc.c          | 368 +++++++++++++++++
 lib/librte_eal/common/eal_internal_cfg.h        |   1 +
 lib/librte_eal/common/eal_options.h             |   2 +
 lib/librte_eal/common/eal_private.h             |  37 ++
 lib/librte_eal/common/include/rte_common.h      |  18 +
 lib/librte_eal/common/include/rte_devargs.h     |   8 +
 lib/librte_eal/common/include/rte_soc.h         | 318 +++++++++++++++
 lib/librte_eal/linuxapp/eal/Makefile            |   2 +
 lib/librte_eal/linuxapp/eal/eal.c               |   8 +
 lib/librte_eal/linuxapp/eal/eal_soc.c           | 515 ++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   9 +
 lib/librte_ether/rte_ethdev.c                   | 166 +++++++-
 lib/librte_ether/rte_ethdev.h                   |  33 +-
 28 files changed, 2131 insertions(+), 19 deletions(-)
 create mode 100644 app/test/test_soc.c
 create mode 100644 lib/librte_eal/bsdapp/eal/eal_soc.c
 create mode 100644 lib/librte_eal/common/eal_common_soc.c
 create mode 100644 lib/librte_eal/common/include/rte_soc.h
 create mode 100644 lib/librte_eal/linuxapp/eal/eal_soc.c

-- 
2.7.4

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

* [PATCH v4 01/17] eal: define container macro
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
@ 2016-10-15 13:44     ` Shreyansh Jain
  2016-10-15 13:44     ` [PATCH v4 02/17] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
                       ` (17 subsequent siblings)
  18 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-15 13:44 UTC (permalink / raw)
  To: dev; +Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain

From: Jan Viktorin <viktorin@rehivetech.com>

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_eal/common/include/rte_common.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h
index db5ac91..8152bd9 100644
--- a/lib/librte_eal/common/include/rte_common.h
+++ b/lib/librte_eal/common/include/rte_common.h
@@ -331,6 +331,24 @@ rte_bsf32(uint32_t v)
 #define offsetof(TYPE, MEMBER)  __builtin_offsetof (TYPE, MEMBER)
 #endif
 
+/**
+ * Return pointer to the wrapping struct instance.
+ * Example:
+ *
+ *  struct wrapper {
+ *      ...
+ *      struct child c;
+ *      ...
+ *  };
+ *
+ *  struct child *x = obtain(...);
+ *  struct wrapper *w = container_of(x, struct wrapper, c);
+ */
+#ifndef container_of
+#define container_of(p, type, member) \
+	((type *) (((char *) (p)) - offsetof(type, member)))
+#endif
+
 #define _RTE_STR(x) #x
 /** Take a macro value and get a string version of it */
 #define RTE_STR(x) _RTE_STR(x)
-- 
2.7.4

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

* [PATCH v4 02/17] eal/soc: introduce very essential SoC infra definitions
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
  2016-10-15 13:44     ` [PATCH v4 01/17] eal: define container macro Shreyansh Jain
@ 2016-10-15 13:44     ` Shreyansh Jain
  2016-10-15 13:44     ` [PATCH v4 03/17] eal/soc: add SoC PMD register/unregister logic Shreyansh Jain
                       ` (16 subsequent siblings)
  18 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-15 13:44 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

Define initial structures and functions for the SoC infrastructure.
This patch supports only a very minimal functions for now.
More features will be added in the following commits.

Includes rte_device/rte_driver inheritance of
rte_soc_device/rte_soc_driver.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 app/test/Makefile                       |   1 +
 app/test/test_soc.c                     |  90 +++++++++++++++++++++
 lib/librte_eal/common/Makefile          |   2 +-
 lib/librte_eal/common/eal_private.h     |   4 +
 lib/librte_eal/common/include/rte_soc.h | 138 ++++++++++++++++++++++++++++++++
 5 files changed, 234 insertions(+), 1 deletion(-)
 create mode 100644 app/test/test_soc.c
 create mode 100644 lib/librte_eal/common/include/rte_soc.h

diff --git a/app/test/Makefile b/app/test/Makefile
index 5be023a..30295af 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -77,6 +77,7 @@ APP = test
 #
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) := commands.c
 SRCS-y += test.c
+SRCS-y += test_soc.c
 SRCS-y += resource.c
 SRCS-y += test_resource.c
 test_resource.res: test_resource.c
diff --git a/app/test/test_soc.c b/app/test/test_soc.c
new file mode 100644
index 0000000..916a863
--- /dev/null
+++ b/app/test/test_soc.c
@@ -0,0 +1,90 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <sys/queue.h>
+
+#include <rte_soc.h>
+#include <rte_devargs.h>
+#include <rte_debug.h>
+
+#include "test.h"
+
+static char *safe_strdup(const char *s)
+{
+	char *c = strdup(s);
+
+	if (c == NULL)
+		rte_panic("failed to strdup '%s'\n", s);
+
+	return c;
+}
+
+static int test_compare_addr(void)
+{
+	struct rte_soc_addr a0;
+	struct rte_soc_addr a1;
+	struct rte_soc_addr a2;
+
+	a0.name = safe_strdup("ethernet0");
+	a0.fdt_path = NULL;
+
+	a1.name = safe_strdup("ethernet0");
+	a1.fdt_path = NULL;
+
+	a2.name = safe_strdup("ethernet1");
+	a2.fdt_path = NULL;
+
+	TEST_ASSERT(!rte_eal_compare_soc_addr(&a0, &a1),
+		    "Failed to compare two soc addresses that equal");
+	TEST_ASSERT(rte_eal_compare_soc_addr(&a0, &a2),
+		    "Failed to compare two soc addresses that differs");
+
+	free(a2.name);
+	free(a1.name);
+	free(a0.name);
+	return 0;
+}
+
+static int
+test_soc(void)
+{
+	if (test_compare_addr())
+		return -1;
+
+	return 0;
+}
+
+REGISTER_TEST_COMMAND(soc_autotest, test_soc);
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index dfd64aa..b414008 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 INC := rte_branch_prediction.h rte_common.h
 INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
-INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
+INC += rte_log.h rte_memory.h rte_memzone.h rte_soc.h rte_pci.h
 INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index c8c2131..0e8d6f7 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -36,6 +36,7 @@
 
 #include <stdio.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 
 /**
  * Initialize the memzone subsystem (private to eal).
@@ -118,6 +119,9 @@ int rte_eal_log_init(const char *id, int facility);
  */
 int rte_eal_pci_init(void);
 
+struct rte_soc_driver;
+struct rte_soc_device;
+
 struct rte_pci_driver;
 struct rte_pci_device;
 
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
new file mode 100644
index 0000000..bc0a43b
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -0,0 +1,138 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_SOC_H_
+#define _RTE_SOC_H_
+
+/**
+ * @file
+ *
+ * RTE SoC Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include <rte_dev.h>
+#include <rte_debug.h>
+
+struct rte_soc_id {
+	const char *compatible; /**< OF compatible specification */
+	uint64_t priv_data;     /**< SoC Driver specific data */
+};
+
+struct rte_soc_addr {
+	char *name;     /**< name used in sysfs */
+	char *fdt_path; /**< path to the associated node in FDT */
+};
+
+/**
+ * A structure describing a SoC device.
+ */
+struct rte_soc_device {
+	TAILQ_ENTRY(rte_soc_device) next;   /**< Next probed SoC device */
+	struct rte_device device;           /**< Inherit code device */
+	struct rte_soc_addr addr;           /**< SoC device Location */
+	struct rte_soc_id *id;              /**< SoC device ID list */
+	struct rte_soc_driver *driver;      /**< Associated driver */
+};
+
+struct rte_soc_driver;
+
+/**
+ * Initialization function for the driver called during SoC probing.
+ */
+typedef int (soc_devinit_t)(struct rte_soc_driver *, struct rte_soc_device *);
+
+/**
+ * Uninitialization function for the driver called during hotplugging.
+ */
+typedef int (soc_devuninit_t)(struct rte_soc_device *);
+
+/**
+ * A structure describing a SoC driver.
+ */
+struct rte_soc_driver {
+	TAILQ_ENTRY(rte_soc_driver) next;  /**< Next in list */
+	struct rte_driver driver;          /**< Inherit core driver. */
+	soc_devinit_t *devinit;            /**< Device initialization */
+	soc_devuninit_t *devuninit;        /**< Device uninitialization */
+	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
+};
+
+/**
+ * Utility function to write a SoC device name, this device name can later be
+ * used to retrieve the corresponding rte_soc_addr using above functions.
+ *
+ * @param addr
+ *	The SoC address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ * @return
+ *  0 on success, negative on error.
+ */
+static inline void
+rte_eal_soc_device_name(const struct rte_soc_addr *addr,
+			char *output, size_t size)
+{
+	int ret;
+
+	RTE_VERIFY(addr != NULL);
+	RTE_VERIFY(size >= strlen(addr->name));
+	ret = snprintf(output, size, "%s", addr->name);
+	RTE_VERIFY(ret >= 0);
+}
+
+static inline int
+rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
+			 const struct rte_soc_addr *a1)
+{
+	if (a0 == NULL || a1 == NULL)
+		return -1;
+
+	RTE_VERIFY(a0->name != NULL);
+	RTE_VERIFY(a1->name != NULL);
+
+	return strcmp(a0->name, a1->name);
+}
+
+#endif
-- 
2.7.4

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

* [PATCH v4 03/17] eal/soc: add SoC PMD register/unregister logic
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
  2016-10-15 13:44     ` [PATCH v4 01/17] eal: define container macro Shreyansh Jain
  2016-10-15 13:44     ` [PATCH v4 02/17] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
@ 2016-10-15 13:44     ` Shreyansh Jain
  2016-10-15 13:44     ` [PATCH v4 04/17] eal/soc: implement SoC device list and dump Shreyansh Jain
                       ` (15 subsequent siblings)
  18 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-15 13:44 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

Registeration of a SoC driver through a helper RTE_PMD_REGISTER_SOC
(on the lines of RTE_PMD_REGISTER_PCI). soc_driver_list stores all the
registered drivers.

Test case has been introduced to verify the registration and
deregistration.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: update PMD registration method]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 app/test/test_soc.c                             | 111 ++++++++++++++++++++++++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   3 +
 lib/librte_eal/common/eal_common_soc.c          |  56 ++++++++++++
 lib/librte_eal/common/include/rte_soc.h         |  26 ++++++
 lib/librte_eal/linuxapp/eal/Makefile            |   1 +
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   3 +
 6 files changed, 200 insertions(+)
 create mode 100644 lib/librte_eal/common/eal_common_soc.c

diff --git a/app/test/test_soc.c b/app/test/test_soc.c
index 916a863..ac03e64 100644
--- a/app/test/test_soc.c
+++ b/app/test/test_soc.c
@@ -75,6 +75,108 @@ static int test_compare_addr(void)
 	free(a2.name);
 	free(a1.name);
 	free(a0.name);
+
+	return 0;
+}
+
+/**
+ * Empty PMD driver based on the SoC infra.
+ *
+ * The rte_soc_device is usually wrapped in some higher-level struct
+ * (eth_driver). We simulate such a wrapper with an anonymous struct here.
+ */
+struct test_wrapper {
+	struct rte_soc_driver soc_drv;
+};
+
+struct test_wrapper empty_pmd0 = {
+	.soc_drv = {
+		.driver = {
+			.name = "empty_pmd0"
+		},
+	},
+};
+
+struct test_wrapper empty_pmd1 = {
+	.soc_drv = {
+		.driver = {
+			.name = "empty_pmd1"
+		},
+	},
+};
+
+static int
+count_registered_socdrvs(void)
+{
+	int i;
+	struct rte_soc_driver *drv;
+
+	i = 0;
+	TAILQ_FOREACH(drv, &soc_driver_list, next)
+		i += 1;
+
+	return i;
+}
+
+static int
+test_register_unregister(void)
+{
+	struct rte_soc_driver *drv;
+	int count;
+
+	rte_eal_soc_register(&empty_pmd0.soc_drv);
+
+	TEST_ASSERT(!TAILQ_EMPTY(&soc_driver_list),
+		    "No PMD is present but the empty_pmd0 should be there");
+	drv = TAILQ_FIRST(&soc_driver_list);
+	TEST_ASSERT(!strcmp(drv->driver.name, "empty_pmd0"),
+		    "The registered PMD is not empty_pmd0 but '%s'",
+		drv->driver.name);
+
+	rte_eal_soc_register(&empty_pmd1.soc_drv);
+
+	count = count_registered_socdrvs();
+	TEST_ASSERT_EQUAL(count, 2, "Expected 2 PMDs but detected %d", count);
+
+	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
+	count = count_registered_socdrvs();
+	TEST_ASSERT_EQUAL(count, 1, "Expected 1 PMDs but detected %d", count);
+
+	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
+
+	printf("%s has been successful\n", __func__);
+	return 0;
+}
+
+/* save real devices and drivers until the tests finishes */
+struct soc_driver_list real_soc_driver_list =
+	TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
+
+static int test_soc_setup(void)
+{
+	struct rte_soc_driver *drv;
+
+	/* no real drivers for the test */
+	while (!TAILQ_EMPTY(&soc_driver_list)) {
+		drv = TAILQ_FIRST(&soc_driver_list);
+		rte_eal_soc_unregister(drv);
+		TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
+	}
+
+	return 0;
+}
+
+static int test_soc_cleanup(void)
+{
+	struct rte_soc_driver *drv;
+
+	/* bring back real drivers after the test */
+	while (!TAILQ_EMPTY(&real_soc_driver_list)) {
+		drv = TAILQ_FIRST(&real_soc_driver_list);
+		TAILQ_REMOVE(&real_soc_driver_list, drv, next);
+		rte_eal_soc_register(drv);
+	}
+
 	return 0;
 }
 
@@ -84,6 +186,15 @@ test_soc(void)
 	if (test_compare_addr())
 		return -1;
 
+	if (test_soc_setup())
+		return -1;
+
+	if (test_register_unregister())
+		return -1;
+
+	if (test_soc_cleanup())
+		return -1;
+
 	return 0;
 }
 
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 11d9f59..cf6fb8e 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -171,8 +171,11 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_register;
+	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
+	soc_driver_list;
 
 } DPDK_16.07;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
new file mode 100644
index 0000000..56135ed
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -0,0 +1,56 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/queue.h>
+
+#include <rte_log.h>
+
+#include "eal_private.h"
+
+/* Global SoC driver list */
+struct soc_driver_list soc_driver_list =
+	TAILQ_HEAD_INITIALIZER(soc_driver_list);
+
+/* register a driver */
+void
+rte_eal_soc_register(struct rte_soc_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_eal_soc_unregister(struct rte_soc_driver *driver)
+{
+	TAILQ_REMOVE(&soc_driver_list, driver, next);
+}
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index bc0a43b..d17b20f 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -51,8 +51,14 @@ extern "C" {
 #include <string.h>
 
 #include <rte_dev.h>
+#include <rte_eal.h>
 #include <rte_debug.h>
 
+extern struct soc_driver_list soc_driver_list;
+/**< Global list of SoC Drivers */
+
+TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
+
 struct rte_soc_id {
 	const char *compatible; /**< OF compatible specification */
 	uint64_t priv_data;     /**< SoC Driver specific data */
@@ -135,4 +141,24 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 	return strcmp(a0->name, a1->name);
 }
 
+/**
+ * Register a SoC driver.
+ */
+void rte_eal_soc_register(struct rte_soc_driver *driver);
+
+/** Helper for SoC device registeration from PMD Drivers */
+#define RTE_PMD_REGISTER_SOC(nm, soc_drv) \
+RTE_INIT(socinitfn_ ##name); \
+static void socinitfn_ ##name(void) \
+{\
+	(soc_drv).driver.name = RTE_STR(nm);\
+	rte_eal_soc_register(&soc_drv); \
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+/**
+ * Unregister a SoC driver.
+ */
+void rte_eal_soc_unregister(struct rte_soc_driver *driver);
+
 #endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 4e206f0..a520477 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -77,6 +77,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 22b5b59..ab6b985 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -175,8 +175,11 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_register;
+	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
+	soc_driver_list;
 
 } DPDK_16.07;
-- 
2.7.4

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

* [PATCH v4 04/17] eal/soc: implement SoC device list and dump
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
                       ` (2 preceding siblings ...)
  2016-10-15 13:44     ` [PATCH v4 03/17] eal/soc: add SoC PMD register/unregister logic Shreyansh Jain
@ 2016-10-15 13:44     ` Shreyansh Jain
  2016-10-15 13:44     ` [PATCH v4 05/17] eal: introduce command line enable SoC option Shreyansh Jain
                       ` (14 subsequent siblings)
  18 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-15 13:44 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

SoC devices would be linked in a separate list (from PCI). This is used for
probe function.
A helper for dumping the device list is added.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  2 ++
 lib/librte_eal/common/eal_common_soc.c          | 34 +++++++++++++++++++++++++
 lib/librte_eal/common/include/rte_soc.h         |  9 +++++++
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  2 ++
 4 files changed, 47 insertions(+)

diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index cf6fb8e..86e3cfd 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -171,11 +171,13 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_dump;
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
+	soc_device_list;
 	soc_driver_list;
 
 } DPDK_16.07;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 56135ed..5dcddc5 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -31,6 +31,8 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <stddef.h>
+#include <stdio.h>
 #include <sys/queue.h>
 
 #include <rte_log.h>
@@ -40,6 +42,38 @@
 /* Global SoC driver list */
 struct soc_driver_list soc_driver_list =
 	TAILQ_HEAD_INITIALIZER(soc_driver_list);
+struct soc_device_list soc_device_list =
+	TAILQ_HEAD_INITIALIZER(soc_device_list);
+
+/* dump one device */
+static int
+soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
+{
+	int i;
+
+	fprintf(f, "%s", dev->addr.name);
+	fprintf(f, " - fdt_path: %s\n",
+			dev->addr.fdt_path ? dev->addr.fdt_path : "(none)");
+
+	for (i = 0; dev->id && dev->id[i].compatible; ++i)
+		fprintf(f, "   %s\n", dev->id[i].compatible);
+
+	return 0;
+}
+
+/* dump devices on the bus to an output stream */
+void
+rte_eal_soc_dump(FILE *f)
+{
+	struct rte_soc_device *dev = NULL;
+
+	if (!f)
+		return;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		soc_dump_one_device(f, dev);
+	}
+}
 
 /* register a driver */
 void
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index d17b20f..4a01af5 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -56,8 +56,12 @@ extern "C" {
 
 extern struct soc_driver_list soc_driver_list;
 /**< Global list of SoC Drivers */
+extern struct soc_device_list soc_device_list;
+/**< Global list of SoC Devices */
 
 TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
+TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
+
 
 struct rte_soc_id {
 	const char *compatible; /**< OF compatible specification */
@@ -142,6 +146,11 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 }
 
 /**
+ * Dump discovered SoC devices.
+ */
+void rte_eal_soc_dump(FILE *f);
+
+/**
  * Register a SoC driver.
  */
 void rte_eal_soc_register(struct rte_soc_driver *driver);
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index ab6b985..0155025 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -175,11 +175,13 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_dump;
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
+	soc_device_list;
 	soc_driver_list;
 
 } DPDK_16.07;
-- 
2.7.4

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

* [PATCH v4 05/17] eal: introduce command line enable SoC option
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
                       ` (3 preceding siblings ...)
  2016-10-15 13:44     ` [PATCH v4 04/17] eal/soc: implement SoC device list and dump Shreyansh Jain
@ 2016-10-15 13:44     ` Shreyansh Jain
  2016-10-15 13:44     ` [PATCH v4 06/17] eal/soc: init SoC infra from EAL Shreyansh Jain
                       ` (13 subsequent siblings)
  18 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-15 13:44 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

Support --enable-soc. SoC support is disabled by default.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: Change --no-soc to --enable-soc; disabled by default]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 doc/guides/testpmd_app_ug/run_app.rst      | 4 ++++
 lib/librte_eal/common/eal_common_options.c | 5 +++++
 lib/librte_eal/common/eal_internal_cfg.h   | 1 +
 lib/librte_eal/common/eal_options.h        | 2 ++
 4 files changed, 12 insertions(+)

diff --git a/doc/guides/testpmd_app_ug/run_app.rst b/doc/guides/testpmd_app_ug/run_app.rst
index d7c5120..4dafe5f 100644
--- a/doc/guides/testpmd_app_ug/run_app.rst
+++ b/doc/guides/testpmd_app_ug/run_app.rst
@@ -156,6 +156,10 @@ See the DPDK Getting Started Guides for more information on these options.
 
     Use malloc instead of hugetlbfs.
 
+*   ``--enable-soc``
+
+    Enable SoC framework support
+
 
 Testpmd Command-line Options
 ----------------------------
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 6ca8af1..2156ab3 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -75,6 +75,7 @@ const struct option
 eal_long_options[] = {
 	{OPT_BASE_VIRTADDR,     1, NULL, OPT_BASE_VIRTADDR_NUM    },
 	{OPT_CREATE_UIO_DEV,    0, NULL, OPT_CREATE_UIO_DEV_NUM   },
+	{OPT_ENABLE_SOC,        0, NULL, OPT_ENABLE_SOC_NUM       },
 	{OPT_FILE_PREFIX,       1, NULL, OPT_FILE_PREFIX_NUM      },
 	{OPT_HELP,              0, NULL, OPT_HELP_NUM             },
 	{OPT_HUGE_DIR,          1, NULL, OPT_HUGE_DIR_NUM         },
@@ -843,6 +844,10 @@ eal_parse_common_option(int opt, const char *optarg,
 		break;
 
 	/* long options */
+	case OPT_ENABLE_SOC_NUM:
+		conf->enable_soc = 1;
+		break;
+
 	case OPT_HUGE_UNLINK_NUM:
 		conf->hugepage_unlink = 1;
 		break;
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 5f1367e..2a6e3ea 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -67,6 +67,7 @@ struct internal_config {
 	unsigned hugepage_unlink;         /**< true to unlink backing files */
 	volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
 	volatile unsigned no_pci;         /**< true to disable PCI */
+	volatile unsigned enable_soc;     /**< true to enable SoC */
 	volatile unsigned no_hpet;        /**< true to disable HPET */
 	volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
 										* instead of native TSC */
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index a881c62..6e679c3 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -49,6 +49,8 @@ enum {
 	OPT_BASE_VIRTADDR_NUM,
 #define OPT_CREATE_UIO_DEV    "create-uio-dev"
 	OPT_CREATE_UIO_DEV_NUM,
+#define OPT_ENABLE_SOC        "enable-soc"
+	OPT_ENABLE_SOC_NUM,
 #define OPT_FILE_PREFIX       "file-prefix"
 	OPT_FILE_PREFIX_NUM,
 #define OPT_HUGE_DIR          "huge-dir"
-- 
2.7.4

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

* [PATCH v4 06/17] eal/soc: init SoC infra from EAL
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
                       ` (4 preceding siblings ...)
  2016-10-15 13:44     ` [PATCH v4 05/17] eal: introduce command line enable SoC option Shreyansh Jain
@ 2016-10-15 13:44     ` Shreyansh Jain
  2016-10-15 13:44     ` [PATCH v4 07/17] eal/soc: implement probing of drivers Shreyansh Jain
                       ` (12 subsequent siblings)
  18 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-15 13:44 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/bsdapp/eal/Makefile    |  1 +
 lib/librte_eal/bsdapp/eal/eal.c       |  4 +++
 lib/librte_eal/bsdapp/eal/eal_soc.c   | 46 ++++++++++++++++++++++++++++
 lib/librte_eal/common/eal_private.h   | 10 +++++++
 lib/librte_eal/linuxapp/eal/Makefile  |  1 +
 lib/librte_eal/linuxapp/eal/eal.c     |  3 ++
 lib/librte_eal/linuxapp/eal/eal_soc.c | 56 +++++++++++++++++++++++++++++++++++
 7 files changed, 121 insertions(+)
 create mode 100644 lib/librte_eal/bsdapp/eal/eal_soc.c
 create mode 100644 lib/librte_eal/linuxapp/eal/eal_soc.c

diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index a15b762..42b3a2b 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -56,6 +56,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_hugepage_info.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_pci.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_timer.c
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 9b93da3..2d62b9d 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -64,6 +64,7 @@
 #include <rte_string_fns.h>
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
+#include <rte_soc.h>
 #include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
@@ -564,6 +565,9 @@ rte_eal_init(int argc, char **argv)
 	if (rte_eal_pci_init() < 0)
 		rte_panic("Cannot init PCI\n");
 
+	if (rte_eal_soc_init() < 0)
+		rte_panic("Cannot init SoC\n");
+
 	eal_check_mem_on_local_socket();
 
 	if (eal_plugins_init() < 0)
diff --git a/lib/librte_eal/bsdapp/eal/eal_soc.c b/lib/librte_eal/bsdapp/eal/eal_soc.c
new file mode 100644
index 0000000..cb297ff
--- /dev/null
+++ b/lib/librte_eal/bsdapp/eal/eal_soc.c
@@ -0,0 +1,46 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <rte_common.h>
+#include <rte_log.h>
+
+#include <eal_private.h>
+
+/* Init the SoC EAL subsystem */
+int
+rte_eal_soc_init(void)
+{
+	return 0;
+}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 0e8d6f7..d810f9f 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -122,6 +122,16 @@ int rte_eal_pci_init(void);
 struct rte_soc_driver;
 struct rte_soc_device;
 
+/**
+ * Init the SoC infra.
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int rte_eal_soc_init(void);
+
 struct rte_pci_driver;
 struct rte_pci_device;
 
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index a520477..59e30fa 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -65,6 +65,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio_mp_sync.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_vfio.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 00af21c..098ba02 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -810,6 +810,9 @@ rte_eal_init(int argc, char **argv)
 		rte_panic("Cannot init VFIO\n");
 #endif
 
+	if (rte_eal_soc_init() < 0)
+		rte_panic("Cannot init SoC\n");
+
 	if (rte_eal_memory_init() < 0)
 		rte_panic("Cannot init memory\n");
 
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
new file mode 100644
index 0000000..04848b9
--- /dev/null
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -0,0 +1,56 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <rte_log.h>
+#include <rte_soc.h>
+
+#include "eal_internal_cfg.h"
+#include "eal_filesystem.h"
+#include "eal_private.h"
+
+/* Init the SoC EAL subsystem */
+int
+rte_eal_soc_init(void)
+{
+	return 0;
+}
-- 
2.7.4

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

* [PATCH v4 07/17] eal/soc: implement probing of drivers
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
                       ` (5 preceding siblings ...)
  2016-10-15 13:44     ` [PATCH v4 06/17] eal/soc: init SoC infra from EAL Shreyansh Jain
@ 2016-10-15 13:44     ` Shreyansh Jain
  2016-10-15 13:44     ` [PATCH v4 08/17] eal/soc: extend and utilize devargs Shreyansh Jain
                       ` (11 subsequent siblings)
  18 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-15 13:44 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

Each SoC PMD registers a set of callback for scanning its own bus/infra and
matching devices to drivers when probe is called.
This patch introduces the infra for calls to SoC scan on rte_eal_soc_init()
and match on rte_eal_soc_probe().

Patch also adds test case for scan and probe.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
--
v4:
 - Update test_soc for descriptive test function names
 - Comments over test functions
 - devinit and devuninint --> probe/remove
 - RTE_VERIFY at some places
---
 app/test/test_soc.c                             | 205 ++++++++++++++++++++++-
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   4 +
 lib/librte_eal/common/eal_common_soc.c          | 213 +++++++++++++++++++++++-
 lib/librte_eal/common/include/rte_soc.h         |  83 ++++++++-
 lib/librte_eal/linuxapp/eal/eal.c               |   5 +
 lib/librte_eal/linuxapp/eal/eal_soc.c           |  21 ++-
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   4 +
 7 files changed, 523 insertions(+), 12 deletions(-)

diff --git a/app/test/test_soc.c b/app/test/test_soc.c
index ac03e64..b587d5e 100644
--- a/app/test/test_soc.c
+++ b/app/test/test_soc.c
@@ -87,14 +87,65 @@ static int test_compare_addr(void)
  */
 struct test_wrapper {
 	struct rte_soc_driver soc_drv;
+	struct rte_soc_device soc_dev;
 };
 
+static int empty_pmd0_probe(struct rte_soc_driver *drv,
+			      struct rte_soc_device *dev);
+static int empty_pmd0_remove(struct rte_soc_device *dev);
+
+static void always_find_dev0_cb(void);
+static int match_dev0_by_name(struct rte_soc_driver *drv,
+				  struct rte_soc_device *dev);
+
+static void always_find_dev1_cb(void);
+static int match_dev1_by_name(struct rte_soc_driver *drv,
+				  struct rte_soc_device *dev);
+
+/**
+ * Dummy probe handler for PMD driver 'pmd0'.
+ *
+ * @param drv
+ *	driver object
+ * @param dev
+ *	device object
+ * @return
+ *	0 on success
+ */
+static int
+empty_pmd0_probe(struct rte_soc_driver *drv __rte_unused,
+		   struct rte_soc_device *dev __rte_unused)
+{
+	return 0;
+}
+
+/**
+ * Remove handler for PMD driver 'pmd0'.
+ *
+ * @param dev
+ *	device to remove
+ * @return
+ *	0 on success
+ */
+static int
+empty_pmd0_remove(struct rte_soc_device *dev)
+{
+	/* Release the memory associated with dev->addr.name */
+	free(dev->addr.name);
+
+	return 0;
+}
+
 struct test_wrapper empty_pmd0 = {
 	.soc_drv = {
 		.driver = {
 			.name = "empty_pmd0"
 		},
-	},
+		.probe = empty_pmd0_probe,
+		.remove = empty_pmd0_remove,
+		.scan_fn = always_find_dev0_cb,
+		.match_fn = match_dev0_by_name,
+	}
 };
 
 struct test_wrapper empty_pmd1 = {
@@ -102,9 +153,87 @@ struct test_wrapper empty_pmd1 = {
 		.driver = {
 			.name = "empty_pmd1"
 		},
+		.scan_fn = always_find_dev1_cb,
+		.match_fn = match_dev1_by_name,
 	},
 };
 
+/**
+ * Bus scan by PMD 'pmd0' for adding device 'dev0'
+ *
+ * @param void
+ * @return void
+ */
+static void
+always_find_dev0_cb(void)
+{
+	/* SoC's scan would scan devices on its bus and add to
+	 * soc_device_list
+	 */
+	empty_pmd0.soc_dev.addr.name = strdup("empty_pmd0_dev");
+
+	TAILQ_INSERT_TAIL(&soc_device_list, &empty_pmd0.soc_dev, next);
+}
+
+/**
+ * Match device 'dev0' with driver PMD pmd0
+ *
+ * @param drv
+ *	Driver with this matching needs to be done; unused here
+ * @param dev
+ *	device to be matched against driver
+ * @return
+ *	0 on successful matched
+ *	1 if driver<=>device don't match
+ */
+static int
+match_dev0_by_name(struct rte_soc_driver *drv __rte_unused,
+		       struct rte_soc_device *dev)
+{
+	if (!dev->addr.name || strcmp(dev->addr.name, "empty_pmd0_dev"))
+		return 0;
+
+	return 1;
+}
+
+/**
+ * Bus scan by PMD 'pmd0' for adding device 'dev1'
+ *
+ * @param void
+ * @return void
+ */
+static void
+always_find_dev1_cb(void)
+{
+	/* SoC's scan would scan devices on its bus and add to
+	 * soc_device_list
+	 */
+	empty_pmd0.soc_dev.addr.name = strdup("empty_pmd1_dev");
+
+	TAILQ_INSERT_TAIL(&soc_device_list, &empty_pmd1.soc_dev, next);
+}
+
+/**
+ * Match device 'dev1' with driver PMD pmd0
+ *
+ * @param drv
+ *	Driver with this matching needs to be done; unused here
+ * @param dev
+ *	device to be matched against driver
+ * @return
+ *	0 on successful matched
+ *	1 if driver<=>device don't match
+ */
+static int
+match_dev1_by_name(struct rte_soc_driver *drv __rte_unused,
+		       struct rte_soc_device *dev)
+{
+	if (!dev->addr.name || strcmp(dev->addr.name, "empty_pmd1_dev"))
+		return 0;
+
+	return 1;
+}
+
 static int
 count_registered_socdrvs(void)
 {
@@ -148,13 +277,68 @@ test_register_unregister(void)
 	return 0;
 }
 
+/* Test Probe (scan and match) functionality */
+static int
+test_soc_scan_and_match(void)
+{
+	int drv_count = 0;
+	struct rte_soc_driver *drv;
+
+	/* Registering dummy drivers */
+	rte_eal_soc_register(&empty_pmd0.soc_drv);
+	rte_eal_soc_register(&empty_pmd1.soc_drv);
+	/* Assuming that test_register_unregister is working, not verifying
+	 * that drivers are indeed registered
+	*/
+
+	/* rte_eal_soc_init is called by rte_eal_init, which in turn calls the
+	 * scan_fn of each driver.
+	 */
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		if (drv && drv->scan_fn)
+			drv->scan_fn();
+		drv_count++;
+	}
+
+	/* rte_eal_init() would perform other inits here */
+
+	/* Probe would link the SoC devices<=>drivers */
+	rte_eal_soc_probe();
+
+	/* Unregistering dummy drivers */
+	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
+	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
+
+	/* Verify the Unregistering has removed the driver from list */
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		if (drv)
+			drv_count--;
+	}
+
+	free(empty_pmd0.soc_dev.addr.name);
+
+	/* If drv_count is anything other than 0, Unregistering failed */
+	if (drv_count) {
+		printf("%s has failed\n", __func__);
+		return 1;
+	}
+
+	printf("%s has been successful\n", __func__);
+	return 0;
+}
+
 /* save real devices and drivers until the tests finishes */
 struct soc_driver_list real_soc_driver_list =
 	TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
 
+/* save real devices and drivers until the tests finishes */
+struct soc_device_list real_soc_device_list =
+	TAILQ_HEAD_INITIALIZER(real_soc_device_list);
+
 static int test_soc_setup(void)
 {
 	struct rte_soc_driver *drv;
+	struct rte_soc_device *dev;
 
 	/* no real drivers for the test */
 	while (!TAILQ_EMPTY(&soc_driver_list)) {
@@ -163,12 +347,20 @@ static int test_soc_setup(void)
 		TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
 	}
 
+	/* And, no real devices for the test */
+	while (!TAILQ_EMPTY(&soc_device_list)) {
+		dev = TAILQ_FIRST(&soc_device_list);
+		TAILQ_REMOVE(&soc_device_list, dev, next);
+		TAILQ_INSERT_TAIL(&real_soc_device_list, dev, next);
+	}
+
 	return 0;
 }
 
 static int test_soc_cleanup(void)
 {
 	struct rte_soc_driver *drv;
+	struct rte_soc_device *dev;
 
 	/* bring back real drivers after the test */
 	while (!TAILQ_EMPTY(&real_soc_driver_list)) {
@@ -177,6 +369,13 @@ static int test_soc_cleanup(void)
 		rte_eal_soc_register(drv);
 	}
 
+	/* And, bring back real devices after the test */
+	while (!TAILQ_EMPTY(&real_soc_device_list)) {
+		dev = TAILQ_FIRST(&real_soc_device_list);
+		TAILQ_REMOVE(&real_soc_device_list, dev, next);
+		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+	}
+
 	return 0;
 }
 
@@ -192,6 +391,10 @@ test_soc(void)
 	if (test_register_unregister())
 		return -1;
 
+	/* Assuming test_register_unregister has succeeded */
+	if (test_soc_scan_and_match())
+		return -1;
+
 	if (test_soc_cleanup())
 		return -1;
 
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 86e3cfd..dfbb1ac 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -171,7 +171,11 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_detach;
 	rte_eal_soc_dump;
+	rte_eal_soc_match;
+	rte_eal_soc_probe;
+	rte_eal_soc_probe_one;
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 5dcddc5..256cef8 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -36,6 +36,8 @@
 #include <sys/queue.h>
 
 #include <rte_log.h>
+#include <rte_common.h>
+#include <rte_soc.h>
 
 #include "eal_private.h"
 
@@ -45,6 +47,208 @@ struct soc_driver_list soc_driver_list =
 struct soc_device_list soc_device_list =
 	TAILQ_HEAD_INITIALIZER(soc_device_list);
 
+int
+rte_eal_soc_match_compat(struct rte_soc_driver *drv,
+			 struct rte_soc_device *dev)
+{
+	int i, j;
+
+	RTE_VERIFY(drv != NULL && drv->id_table != NULL);
+	RTE_VERIFY(dev != NULL && dev->id != NULL);
+
+	for (i = 0; drv->id_table[i].compatible; ++i) {
+		const char *drv_compat = drv->id_table[i].compatible;
+
+		for (j = 0; dev->id[j].compatible; ++j) {
+			const char *dev_compat = dev->id[j].compatible;
+
+			if (!strcmp(drv_compat, dev_compat))
+				return 0;
+		}
+	}
+
+	return 1;
+}
+
+static int
+rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
+			     struct rte_soc_device *dev)
+{
+	int ret = 1;
+
+	RTE_VERIFY(drv->match_fn);
+
+	ret = drv->match_fn(drv, dev);
+	if (ret) {
+		RTE_LOG(DEBUG, EAL,
+			" match function failed, skipping\n");
+		return ret;
+	}
+
+	dev->driver = drv;
+	RTE_VERIFY(drv->probe != NULL);
+	return drv->probe(drv, dev);
+}
+
+static int
+soc_probe_all_drivers(struct rte_soc_device *dev)
+{
+	struct rte_soc_driver *drv = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		rc = rte_eal_soc_probe_one_driver(drv, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+/* If the IDs match, call the remove() function of the driver. */
+static int
+rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
+		       struct rte_soc_device *dev)
+{
+	int ret;
+
+	if ((drv == NULL) || (dev == NULL))
+		return -EINVAL;
+
+	ret = drv->match_fn(drv, dev);
+	if (ret) {
+		RTE_LOG(DEBUG, EAL, " driver (%s) didn't match device (%s)\n",
+			drv->driver.name, dev->addr.name);
+		return ret;
+	}
+
+	RTE_LOG(DEBUG, EAL, "SoC device %s\n",
+		dev->addr.name);
+
+	RTE_LOG(DEBUG, EAL, "  remove driver: %s\n", drv->driver.name);
+
+	if (drv->remove && (drv->remove(dev) < 0))
+		return -1;	/* negative value is an error */
+
+	/* clear driver structure */
+	dev->driver = NULL;
+
+	return 0;
+}
+
+/*
+ * Call the remove() function of all registered drivers for the device.
+ *
+ * @param dev
+ *	Device for which detach is to be performed
+ * @return
+ *       0 when successful
+ *      -1 if deinitialization fails
+ *       1 if no driver is found for this device.
+ */
+static int
+soc_detach_all_drivers(struct rte_soc_device *dev)
+{
+	struct rte_soc_driver *dr = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dr, &soc_driver_list, next) {
+		rc = rte_eal_soc_detach_dev(dr, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+int
+rte_eal_soc_detach(const struct rte_soc_addr *addr)
+{
+	struct rte_soc_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		if (rte_eal_compare_soc_addr(&dev->addr, addr))
+			continue;
+
+		ret = soc_detach_all_drivers(dev);
+		if (ret < 0)
+			goto err_return;
+
+		TAILQ_REMOVE(&soc_device_list, dev, next);
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL, "Requested device %s cannot be used\n",
+		dev->addr.name);
+	return -1;
+}
+
+int
+rte_eal_soc_probe_one(const struct rte_soc_addr *addr)
+{
+	struct rte_soc_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		if (rte_eal_compare_soc_addr(&dev->addr, addr))
+			continue;
+
+		ret = soc_probe_all_drivers(dev);
+		if (ret < 0)
+			goto err_return;
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL,
+		"Requested device %s cannot be used\n", addr->name);
+	return -1;
+}
+
+int
+rte_eal_soc_probe(void)
+{
+	struct rte_soc_device *dev = NULL;
+	int ret = 0;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		ret = soc_probe_all_drivers(dev);
+		if (ret < 0) {
+			RTE_LOG(DEBUG, EAL, "Requested device %s"
+				 " cannot be used\n", dev->addr.name);
+			/* Failure for a particular device is logged and
+			 * ignored
+			 */
+		}
+	}
+
+	return ret;
+}
+
 /* dump one device */
 static int
 soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
@@ -61,7 +265,6 @@ soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
 	return 0;
 }
 
-/* dump devices on the bus to an output stream */
 void
 rte_eal_soc_dump(FILE *f)
 {
@@ -75,14 +278,18 @@ rte_eal_soc_dump(FILE *f)
 	}
 }
 
-/* register a driver */
 void
 rte_eal_soc_register(struct rte_soc_driver *driver)
 {
+	/* For a valid soc driver, match and scan function
+	 * should be provided.
+	 */
+	RTE_VERIFY(driver != NULL);
+	RTE_VERIFY(driver->match_fn != NULL);
+	RTE_VERIFY(driver->scan_fn != NULL);
 	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
 }
 
-/* unregister a driver */
 void
 rte_eal_soc_unregister(struct rte_soc_driver *driver)
 {
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 4a01af5..030df6f 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -62,7 +62,6 @@ extern struct soc_device_list soc_device_list;
 TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
 TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
 
-
 struct rte_soc_id {
 	const char *compatible; /**< OF compatible specification */
 	uint64_t priv_data;     /**< SoC Driver specific data */
@@ -89,12 +88,29 @@ struct rte_soc_driver;
 /**
  * Initialization function for the driver called during SoC probing.
  */
-typedef int (soc_devinit_t)(struct rte_soc_driver *, struct rte_soc_device *);
+typedef int (soc_probe_t)(struct rte_soc_driver *, struct rte_soc_device *);
 
 /**
  * Uninitialization function for the driver called during hotplugging.
  */
-typedef int (soc_devuninit_t)(struct rte_soc_device *);
+typedef int (soc_remove_t)(struct rte_soc_device *);
+
+/**
+ * SoC device scan callback, called from rte_eal_soc_init.
+ * For various SoC, the bus on which devices are attached maynot be compliant
+ * to a standard platform (or platform bus itself). In which case, extra
+ * steps are implemented by PMD to scan over the bus and add devices to SoC
+ * device list.
+ */
+typedef void (soc_scan_t)(void);
+
+/**
+ * Custom device<=>driver match callback for SoC
+ * Unlike PCI, SoC devices don't have a fixed definition of device
+ * identification. PMDs can implement a specific matching function in which
+ * driver and device objects are provided to perform custom match.
+ */
+typedef int (soc_match_t)(struct rte_soc_driver *, struct rte_soc_device *);
 
 /**
  * A structure describing a SoC driver.
@@ -102,8 +118,10 @@ typedef int (soc_devuninit_t)(struct rte_soc_device *);
 struct rte_soc_driver {
 	TAILQ_ENTRY(rte_soc_driver) next;  /**< Next in list */
 	struct rte_driver driver;          /**< Inherit core driver. */
-	soc_devinit_t *devinit;            /**< Device initialization */
-	soc_devuninit_t *devuninit;        /**< Device uninitialization */
+	soc_probe_t *probe;                 /**< Device probe */
+	soc_remove_t *remove;               /**< Device remove */
+	soc_scan_t *scan_fn;                /**< Callback for scanning SoC bus*/
+	soc_match_t *match_fn;              /**< Callback to match dev<->drv */
 	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
 };
 
@@ -146,12 +164,63 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 }
 
 /**
+ * Default function for matching the Soc driver with device. Each driver can
+ * either use this function or define their own soc matching function.
+ * This function relies on the compatible string extracted from sysfs. But,
+ * a SoC might have different way of identifying its devices. Such SoC can
+ * override match_fn.
+ *
+ * @return
+ *	 0 on success
+ *	-1 when no match found
+  */
+int
+rte_eal_soc_match_compat(struct rte_soc_driver *drv,
+			 struct rte_soc_device *dev);
+
+/**
+ * Probe SoC devices for registered drivers.
+ *
+ * @return
+ *	0 on success
+ *	!0 in case of any failure in probe
+ */
+int rte_eal_soc_probe(void);
+
+/**
+ * Probe the single SoC device.
+ */
+int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
+
+/**
+ * Close the single SoC device.
+ *
+ * Scan the SoC devices and find the SoC device specified by the SoC
+ * address, then call the remove() function for registered driver
+ * that has a matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The SoC address to close.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_eal_soc_detach(const struct rte_soc_addr *addr);
+
+/**
  * Dump discovered SoC devices.
+ *
+ * @param f
+ *	File to dump device info in.
  */
 void rte_eal_soc_dump(FILE *f);
 
 /**
  * Register a SoC driver.
+ *
+ * @param driver
+ *	Object for SoC driver to register
+ * @return void
  */
 void rte_eal_soc_register(struct rte_soc_driver *driver);
 
@@ -167,6 +236,10 @@ RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
 
 /**
  * Unregister a SoC driver.
+ *
+ * @param driver
+ *	Object for SoC driver to unregister
+ * @return void
  */
 void rte_eal_soc_unregister(struct rte_soc_driver *driver);
 
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 098ba02..bd775f3 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -70,6 +70,7 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_common.h>
@@ -890,6 +891,10 @@ rte_eal_init(int argc, char **argv)
 	if (rte_eal_pci_probe())
 		rte_panic("Cannot probe PCI\n");
 
+	/* Probe & Initialize SoC devices */
+	if (rte_eal_soc_probe())
+		rte_panic("Cannot probe SoC\n");
+
 	rte_eal_mcfg_complete();
 
 	return fctret;
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index 04848b9..3929a76 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -44,13 +44,28 @@
 #include <rte_log.h>
 #include <rte_soc.h>
 
-#include "eal_internal_cfg.h"
-#include "eal_filesystem.h"
-#include "eal_private.h"
+#include <eal_internal_cfg.h>
+#include <eal_filesystem.h>
+#include <eal_private.h>
 
 /* Init the SoC EAL subsystem */
 int
 rte_eal_soc_init(void)
 {
+	struct rte_soc_driver *drv;
+
+	/* SoC is disabled by default */
+	if (!internal_config.enable_soc)
+		return 0;
+
+	/* For each registered driver, call their scan routine to perform any
+	 * custom scan for devices (for example, custom buses)
+	 */
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		RTE_VERIFY(drv->scan_fn);
+		drv->scan_fn();
+		/* Ignore all errors from this */
+	}
+
 	return 0;
 }
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 0155025..c28e093 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -175,7 +175,11 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_detach;
 	rte_eal_soc_dump;
+	rte_eal_soc_match;
+	rte_eal_soc_probe;
+	rte_eal_soc_probe_one;
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
-- 
2.7.4

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

* [PATCH v4 08/17] eal/soc: extend and utilize devargs
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
                       ` (6 preceding siblings ...)
  2016-10-15 13:44     ` [PATCH v4 07/17] eal/soc: implement probing of drivers Shreyansh Jain
@ 2016-10-15 13:44     ` Shreyansh Jain
  2016-10-15 13:45     ` [PATCH v4 09/17] eal/soc: add drv_flags Shreyansh Jain
                       ` (10 subsequent siblings)
  18 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-15 13:44 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

It is assumed that SoC Devices provided on command line are prefixed with
"soc:". This patch adds parse and attach support for such devices.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/common/eal_common_dev.c      | 27 +++++++++----
 lib/librte_eal/common/eal_common_devargs.c  | 17 ++++++++
 lib/librte_eal/common/eal_common_soc.c      | 61 ++++++++++++++++++++++++-----
 lib/librte_eal/common/include/rte_devargs.h |  8 ++++
 lib/librte_eal/common/include/rte_soc.h     | 24 ++++++++++++
 5 files changed, 120 insertions(+), 17 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 457d227..ebbcf47 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -107,17 +107,23 @@ rte_eal_dev_init(void)
 
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
-	struct rte_pci_addr addr;
+	struct rte_soc_addr soc_addr;
+	struct rte_pci_addr pci_addr;
 
 	if (name == NULL || devargs == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
 		return -EINVAL;
 	}
 
-	if (eal_parse_pci_DomBDF(name, &addr) == 0) {
-		if (rte_eal_pci_probe_one(&addr) < 0)
+	memset(&soc_addr, 0, sizeof(soc_addr));
+	if (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+		if (rte_eal_soc_probe_one(&soc_addr) < 0) {
+			free(soc_addr.name);
+			goto err;
+		}
+	} else if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+		if (rte_eal_pci_probe_one(&pci_addr) < 0)
 			goto err;
-
 	} else {
 		if (rte_eal_vdev_init(name, devargs))
 			goto err;
@@ -132,15 +138,22 @@ err:
 
 int rte_eal_dev_detach(const char *name)
 {
-	struct rte_pci_addr addr;
+	struct rte_soc_addr soc_addr;
+	struct rte_pci_addr pci_addr;
 
 	if (name == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device provided.\n");
 		return -EINVAL;
 	}
 
-	if (eal_parse_pci_DomBDF(name, &addr) == 0) {
-		if (rte_eal_pci_detach(&addr) < 0)
+	memset(&soc_addr, 0, sizeof(soc_addr));
+	if (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+		if (rte_eal_soc_detach(&soc_addr) < 0) {
+			free(soc_addr.name);
+			goto err;
+		}
+	} else if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+		if (rte_eal_pci_detach(&pci_addr) < 0)
 			goto err;
 	} else {
 		if (rte_eal_vdev_uninit(name))
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index e403717..e1dae1a 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -41,6 +41,7 @@
 #include <string.h>
 
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_devargs.h>
 #include "eal_private.h"
 
@@ -105,6 +106,14 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
 			goto fail;
 
 		break;
+
+	case RTE_DEVTYPE_WHITELISTED_SOC:
+	case RTE_DEVTYPE_BLACKLISTED_SOC:
+		/* try to parse soc device with prefix "soc:" */
+		if (rte_eal_parse_soc_spec(buf, &devargs->soc.addr) != 0)
+			goto fail;
+		break;
+
 	case RTE_DEVTYPE_VIRTUAL:
 		/* save driver name */
 		ret = snprintf(devargs->virt.drv_name,
@@ -166,6 +175,14 @@ rte_eal_devargs_dump(FILE *f)
 			       devargs->pci.addr.devid,
 			       devargs->pci.addr.function,
 			       devargs->args);
+		else if (devargs->type == RTE_DEVTYPE_WHITELISTED_SOC)
+			fprintf(f, "  SoC whitelist %s %s\n",
+			       devargs->soc.addr.name,
+			       devargs->soc.addr.fdt_path);
+		else if (devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC)
+			fprintf(f, "  SoC blacklist %s %s\n",
+			       devargs->soc.addr.name,
+			       devargs->soc.addr.fdt_path);
 		else if (devargs->type == RTE_DEVTYPE_VIRTUAL)
 			fprintf(f, "  VIRTUAL %s %s\n",
 			       devargs->virt.drv_name,
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 256cef8..44f5559 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -37,6 +37,8 @@
 
 #include <rte_log.h>
 #include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_eal.h>
 #include <rte_soc.h>
 
 #include "eal_private.h"
@@ -70,6 +72,21 @@ rte_eal_soc_match_compat(struct rte_soc_driver *drv,
 	return 1;
 }
 
+static struct rte_devargs *soc_devargs_lookup(struct rte_soc_device *dev)
+{
+	struct rte_devargs *devargs;
+
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->type != RTE_DEVTYPE_BLACKLISTED_SOC &&
+			devargs->type != RTE_DEVTYPE_WHITELISTED_SOC)
+			continue;
+		if (!rte_eal_compare_soc_addr(&dev->addr, &devargs->soc.addr))
+			return devargs;
+	}
+
+	return NULL;
+}
+
 static int
 rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
 			     struct rte_soc_device *dev)
@@ -85,6 +102,18 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
 		return ret;
 	}
 
+	RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %d\n",
+			dev->addr.name, dev->device.numa_node);
+	RTE_LOG(DEBUG, EAL, "  probe driver %s\n", drv->driver.name);
+
+	/* no initialization when blacklisted, return without error */
+	if (dev->device.devargs != NULL
+		&& dev->device.devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC) {
+		RTE_LOG(DEBUG, EAL,
+			"  device is blacklisted, skipping\n");
+		return ret;
+	}
+
 	dev->driver = drv;
 	RTE_VERIFY(drv->probe != NULL);
 	return drv->probe(drv, dev);
@@ -129,8 +158,8 @@ rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
 		return ret;
 	}
 
-	RTE_LOG(DEBUG, EAL, "SoC device %s\n",
-		dev->addr.name);
+	RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %i\n",
+			dev->addr.name, dev->device.numa_node);
 
 	RTE_LOG(DEBUG, EAL, "  remove driver: %s\n", drv->driver.name);
 
@@ -233,17 +262,29 @@ int
 rte_eal_soc_probe(void)
 {
 	struct rte_soc_device *dev = NULL;
+	struct rte_devargs *devargs = NULL;
 	int ret = 0;
+	int probe_all = 0;
+
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_SOC) == 0)
+		probe_all = 1;
 
 	TAILQ_FOREACH(dev, &soc_device_list, next) {
-		ret = soc_probe_all_drivers(dev);
-		if (ret < 0) {
-			RTE_LOG(DEBUG, EAL, "Requested device %s"
-				 " cannot be used\n", dev->addr.name);
-			/* Failure for a particular device is logged and
-			 * ignored
-			 */
-		}
+
+		/* set devargs in SoC structure */
+		devargs = soc_devargs_lookup(dev);
+		if (devargs != NULL)
+			dev->device.devargs = devargs;
+
+		/* probe all or only whitelisted devices */
+		if (probe_all)
+			ret = soc_probe_all_drivers(dev);
+		else if (devargs != NULL &&
+			devargs->type == RTE_DEVTYPE_WHITELISTED_SOC)
+			ret = soc_probe_all_drivers(dev);
+		if (ret < 0)
+			rte_exit(EXIT_FAILURE, "Requested device %s "
+				 "cannot be used\n", dev->addr.name);
 	}
 
 	return ret;
diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h
index 88120a1..b5dd436 100644
--- a/lib/librte_eal/common/include/rte_devargs.h
+++ b/lib/librte_eal/common/include/rte_devargs.h
@@ -51,6 +51,7 @@ extern "C" {
 #include <stdio.h>
 #include <sys/queue.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 
 /**
  * Type of generic device
@@ -58,6 +59,8 @@ extern "C" {
 enum rte_devtype {
 	RTE_DEVTYPE_WHITELISTED_PCI,
 	RTE_DEVTYPE_BLACKLISTED_PCI,
+	RTE_DEVTYPE_WHITELISTED_SOC,
+	RTE_DEVTYPE_BLACKLISTED_SOC,
 	RTE_DEVTYPE_VIRTUAL,
 };
 
@@ -83,6 +86,11 @@ struct rte_devargs {
 			/** PCI location. */
 			struct rte_pci_addr addr;
 		} pci;
+		/** Used if type is RTE_DEVTYPE_*_SOC. */
+		struct {
+			/** SoC location. */
+			struct rte_soc_addr addr;
+		} soc;
 		/** Used if type is RTE_DEVTYPE_VIRTUAL. */
 		struct {
 			/** Driver name. */
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 030df6f..90cd6aa 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -164,6 +164,30 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 }
 
 /**
+ * Parse a specification of a soc device. The specification must differentiate
+ * a SoC device specification from the PCI bus and virtual devices. We assume
+ * a SoC specification starts with "soc:". The function allocates the name
+ * entry of the given addr.
+ *
+ * @return
+ *      -  0 on success
+ *      -  1 when not a SoC spec
+ *      - -1 on failure
+ */
+static inline int
+rte_eal_parse_soc_spec(const char *spec, struct rte_soc_addr *addr)
+{
+	if (strstr(spec, "soc:") == spec) {
+		addr->name = strdup(spec + 4);
+		if (addr->name == NULL)
+			return -1;
+		return 0;
+	}
+
+	return 1;
+}
+
+/**
  * Default function for matching the Soc driver with device. Each driver can
  * either use this function or define their own soc matching function.
  * This function relies on the compatible string extracted from sysfs. But,
-- 
2.7.4

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

* [PATCH v4 09/17] eal/soc: add drv_flags
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
                       ` (7 preceding siblings ...)
  2016-10-15 13:44     ` [PATCH v4 08/17] eal/soc: extend and utilize devargs Shreyansh Jain
@ 2016-10-15 13:45     ` Shreyansh Jain
  2016-10-15 13:45     ` [PATCH v4 10/17] eal/soc: add intr_handle Shreyansh Jain
                       ` (9 subsequent siblings)
  18 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-15 13:45 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

The flags are copied from the PCI ones. They should be refactorized into a
general set of flags in the future.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/common/include/rte_soc.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 90cd6aa..415d409 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -123,8 +123,18 @@ struct rte_soc_driver {
 	soc_scan_t *scan_fn;                /**< Callback for scanning SoC bus*/
 	soc_match_t *match_fn;              /**< Callback to match dev<->drv */
 	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
+	uint32_t drv_flags;                /**< Control handling of device */
 };
 
+/** Device needs to map its resources by EAL */
+#define RTE_SOC_DRV_NEED_MAPPING 0x0001
+/** Device needs to be unbound even if no module is provieded */
+#define RTE_SOC_DRV_FORCE_UNBIND 0x0004
+/** Device driver supports link state interrupt */
+#define RTE_SOC_DRV_INTR_LSC	 0x0008
+/** Device driver supports detaching capability */
+#define RTE_SOC_DRV_DETACHABLE	 0x0010
+
 /**
  * Utility function to write a SoC device name, this device name can later be
  * used to retrieve the corresponding rte_soc_addr using above functions.
-- 
2.7.4

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

* [PATCH v4 10/17] eal/soc: add intr_handle
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
                       ` (8 preceding siblings ...)
  2016-10-15 13:45     ` [PATCH v4 09/17] eal/soc: add drv_flags Shreyansh Jain
@ 2016-10-15 13:45     ` Shreyansh Jain
  2016-10-15 13:45     ` [PATCH v4 11/17] eal/soc: add default scan for Soc devices Shreyansh Jain
                       ` (8 subsequent siblings)
  18 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-15 13:45 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/common/include/rte_soc.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 415d409..1f5f81b 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -53,6 +53,7 @@ extern "C" {
 #include <rte_dev.h>
 #include <rte_eal.h>
 #include <rte_debug.h>
+#include <rte_interrupts.h>
 
 extern struct soc_driver_list soc_driver_list;
 /**< Global list of SoC Drivers */
@@ -80,6 +81,7 @@ struct rte_soc_device {
 	struct rte_device device;           /**< Inherit code device */
 	struct rte_soc_addr addr;           /**< SoC device Location */
 	struct rte_soc_id *id;              /**< SoC device ID list */
+	struct rte_intr_handle intr_handle; /**< Interrupt handle */
 	struct rte_soc_driver *driver;      /**< Associated driver */
 };
 
-- 
2.7.4

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

* [PATCH v4 11/17] eal/soc: add default scan for Soc devices
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
                       ` (9 preceding siblings ...)
  2016-10-15 13:45     ` [PATCH v4 10/17] eal/soc: add intr_handle Shreyansh Jain
@ 2016-10-15 13:45     ` Shreyansh Jain
  2016-10-16  0:56       ` Jan Viktorin
  2016-10-15 13:45     ` [PATCH v4 12/17] eal/soc: additional features for SoC Shreyansh Jain
                       ` (7 subsequent siblings)
  18 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-15 13:45 UTC (permalink / raw)
  To: dev; +Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain

From: Jan Viktorin <viktorin@rehivetech.com>

Default implementation which scans the sysfs platform devices hierarchy.
For each device, extract the ueven and convert into rte_soc_device.

The information populated can then be used in probe to match against
the drivers registered.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: restructure commit to be an optional implementation]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_eal/common/include/rte_soc.h |  10 +-
 lib/librte_eal/linuxapp/eal/eal_soc.c   | 315 ++++++++++++++++++++++++++++++++
 2 files changed, 324 insertions(+), 1 deletion(-)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 1f5f81b..1865be5 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -64,7 +64,10 @@ TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
 TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
 
 struct rte_soc_id {
-	const char *compatible; /**< OF compatible specification */
+	union {
+		const char *compatible; /**< OF compatible specification */
+		char *_compatible;
+	};
 	uint64_t priv_data;     /**< SoC Driver specific data */
 };
 
@@ -200,6 +203,11 @@ rte_eal_parse_soc_spec(const char *spec, struct rte_soc_addr *addr)
 }
 
 /**
+ * Scan for new SoC devices.
+ */
+int rte_eal_soc_scan(void);
+
+/**
  * Default function for matching the Soc driver with device. Each driver can
  * either use this function or define their own soc matching function.
  * This function relies on the compatible string extracted from sysfs. But,
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index 3929a76..d8286bb 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -48,6 +48,321 @@
 #include <eal_filesystem.h>
 #include <eal_private.h>
 
+/** Pathname of SoC devices directory. */
+#define SYSFS_SOC_DEVICES "/sys/bus/platform/devices"
+
+static const char *
+soc_get_sysfs_path(void)
+{
+	const char *path = NULL;
+
+	path = getenv("SYSFS_SOC_DEVICES");
+	if (path == NULL)
+		return SYSFS_SOC_DEVICES;
+
+	return path;
+}
+
+static char *
+dev_read_uevent(const char *dirname)
+{
+	char filename[PATH_MAX];
+	struct stat st;
+	char *buf;
+	ssize_t total = 0;
+	int fd;
+
+	snprintf(filename, sizeof(filename), "%s/uevent", dirname);
+	fd = open(filename, O_RDONLY);
+	if (fd < 0) {
+		RTE_LOG(WARNING, EAL, "Failed to open file %s\n", filename);
+		return strdup("");
+	}
+
+	if (fstat(fd, &st) < 0) {
+		RTE_LOG(ERR, EAL, "Failed to stat file %s\n", filename);
+		close(fd);
+		return NULL;
+	}
+
+	if (st.st_size == 0) {
+		close(fd);
+		return strdup("");
+	}
+
+	buf = malloc(st.st_size + 1);
+	if (buf == NULL) {
+		RTE_LOG(ERR, EAL, "Failed to alloc memory to read %s\n",
+			filename);
+		close(fd);
+		return NULL;
+	}
+
+	while (total < st.st_size) {
+		ssize_t rlen = read(fd, buf + total, st.st_size - total);
+		if (rlen < 0) {
+			if (errno == EINTR)
+				continue;
+
+			RTE_LOG(ERR, EAL, "Failed to read file %s\n", filename);
+
+			free(buf);
+			close(fd);
+			return NULL;
+		}
+		if (rlen == 0) /* EOF */
+			break;
+
+		total += rlen;
+	}
+
+	buf[total] = '\0';
+	close(fd);
+
+	return buf;
+}
+
+static const char *
+dev_uevent_find(const char *uevent, const char *key)
+{
+	const size_t keylen = strlen(key);
+	const size_t total = strlen(uevent);
+	const char *p = uevent;
+
+	/* check whether it is the first key */
+	if (!strncmp(uevent, key, keylen))
+		return uevent + keylen;
+
+	/* check 2nd key or further... */
+	do {
+		p = strstr(p, key);
+		if (p == NULL)
+			break;
+
+		if (p[-1] == '\n') /* check we are at a new line */
+			return p + keylen;
+
+		p += keylen; /* skip this one */
+	} while (p - uevent < (ptrdiff_t) total);
+
+	return NULL;
+}
+
+static char *
+strdup_until_nl(const char *p)
+{
+	const char *nl = strchr(p, '\n');
+	if (nl == NULL)
+		return strdup(p); /* no newline, copy until '\0' */
+
+	return strndup(p, nl - p);
+}
+
+static int
+dev_parse_uevent(struct rte_soc_device *dev, const char *uevent)
+{
+	const char *of;
+	const char *compat_n;
+	char *err;
+	long n;
+	char compat[strlen("OF_COMPATIBLE_NNNN=")];
+	long i;
+
+	of = dev_uevent_find(uevent, "OF_FULLNAME=");
+	if (of == NULL)
+		return 1; /* don't care about this device */
+
+	dev->addr.fdt_path = strdup_until_nl(of);
+	if (dev->addr.fdt_path == NULL) {
+		RTE_LOG(ERR, PMD,
+			"Failed to alloc memory for fdt_path\n");
+		return -1;
+	}
+
+	RTE_LOG(DEBUG, EAL, "Detected device %s (%s)\n",
+			dev->addr.name, dev->addr.fdt_path);
+
+	compat_n = dev_uevent_find(uevent, "OF_COMPATIBLE_N=");
+	if (compat_n == NULL) {
+		RTE_LOG(ERR, EAL, "No OF_COMPATIBLE_N found\n");
+		return -1;
+	}
+
+	n = strtoul(compat_n, &err, 0);
+	if (*err != '\n' && err != NULL) {
+		RTE_LOG(ERR, EAL, "Failed to parse OF_COMPATIBLE_N: %.10s\n",
+			err);
+		goto fail_fdt_path;
+	}
+
+	if (n == 0)
+		return 1; /* cannot match anything */
+	if (n > 9999) { /* match NNNN */
+		RTE_LOG(ERR, EAL, "OF_COMPATIBLE_N is invalid: %ld\n", n);
+		goto fail_fdt_path;
+	}
+
+	dev->id = calloc(n + 1, sizeof(*dev->id));
+	if (dev->id == NULL) {
+		RTE_LOG(ERR, PMD, "Failed to alloc memory for ID\n");
+		free(dev->addr.fdt_path);
+		return -1;
+	}
+
+	for (i = 0; i < n; ++i) {
+		snprintf(compat, sizeof(compat), "OF_COMPATIBLE_%lu=", i);
+		const char *val;
+
+		val = dev_uevent_find(uevent, compat);
+		if (val == NULL) {
+			RTE_LOG(ERR, EAL, "%s was not found\n", compat);
+			goto fail_id;
+		}
+
+		dev->id[i]._compatible = strdup_until_nl(val);
+		if (dev->id[i]._compatible == NULL) {
+			RTE_LOG(ERR, PMD,
+				"Failed to alloc memory for compatible\n");
+			goto fail_id;
+		}
+
+		RTE_LOG(DEBUG, EAL, "  compatible: %s\n",
+				dev->id[i].compatible);
+	}
+
+	dev->id[n]._compatible = NULL; /* mark last one */
+
+	return 0;
+
+fail_id:
+	while (i-- >= 0)
+		free(dev->id[i]._compatible);
+	free(dev->id);
+fail_fdt_path:
+	free(dev->addr.fdt_path);
+	return -1;
+}
+
+static void
+dev_content_free(struct rte_soc_device *dev)
+{
+	int i;
+
+	if (dev->addr.fdt_path)
+		free(dev->addr.fdt_path);
+
+	if (dev->id != NULL) {
+		for (i = 0; dev->id[i]._compatible; ++i)
+			free(dev->id[i]._compatible);
+
+		free(dev->id);
+		dev->id = NULL;
+	}
+}
+
+/**
+ * Scan one SoC sysfs entry, and fill the devices list from it.
+ * We require to have the uevent file with records: OF_FULLNAME and
+ * OF_COMPATIBLE array (with at least one entry). Otherwise, such device
+ * is skipped.
+ */
+static int
+soc_scan_one(const char *dirname, const char *name)
+{
+	struct rte_soc_device *dev;
+	char *uevent;
+	int ret;
+
+	uevent = dev_read_uevent(dirname);
+	if (uevent == NULL)
+		return -1;
+
+	if (uevent[0] == '\0') {
+		/* ignore directory without uevent file */
+		free(uevent);
+		return 1;
+	}
+
+	dev = malloc(sizeof(*dev) + strlen(name) + 1);
+	if (dev == NULL) {
+		RTE_LOG(ERR, PMD, "Failed to alloc memory for %s\n", name);
+		free(uevent);
+		return -1;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	dev->addr.name = (char *) (dev + 1);
+	strcpy(dev->addr.name, name);
+
+	ret = dev_parse_uevent(dev, uevent);
+	if (ret)
+		goto fail;
+	free(uevent); /* not needed anymore */
+
+	/* device is valid, add in list (sorted) */
+	if (TAILQ_EMPTY(&soc_device_list)) {
+		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+	} else {
+		struct rte_soc_device *dev2;
+
+		TAILQ_FOREACH(dev2, &soc_device_list, next) {
+			ret = rte_eal_compare_soc_addr(&dev->addr, &dev2->addr);
+			if (ret > 0)
+				continue;
+
+			if (ret < 0) {
+				TAILQ_INSERT_BEFORE(dev2, dev, next);
+			} else { /* already registered */
+				dev_content_free(dev2);
+				dev2->addr.fdt_path = dev->addr.fdt_path;
+				dev2->id = dev->id;
+				free(dev);
+			}
+			return 0;
+		}
+		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+	}
+
+	return 0;
+
+fail:
+	free(uevent);
+	dev_content_free(dev);
+	free(dev);
+	return ret;
+}
+
+int
+rte_eal_soc_scan(void)
+{
+	struct dirent *e;
+	DIR *dir;
+	char dirname[PATH_MAX];
+
+	dir = opendir(soc_get_sysfs_path());
+	if (dir == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
+			__func__, strerror(errno));
+		return -1;
+	}
+
+	while ((e = readdir(dir)) != NULL) {
+		if (e->d_name[0] == '.')
+			continue;
+
+		snprintf(dirname, sizeof(dirname), "%s/%s",
+				soc_get_sysfs_path(), e->d_name);
+		if (soc_scan_one(dirname, e->d_name) < 0)
+			goto error;
+	}
+	closedir(dir);
+	return 0;
+
+error:
+	closedir(dir);
+	return -1;
+}
+
 /* Init the SoC EAL subsystem */
 int
 rte_eal_soc_init(void)
-- 
2.7.4

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

* [PATCH v4 12/17] eal/soc: additional features for SoC
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
                       ` (10 preceding siblings ...)
  2016-10-15 13:45     ` [PATCH v4 11/17] eal/soc: add default scan for Soc devices Shreyansh Jain
@ 2016-10-15 13:45     ` Shreyansh Jain
  2016-10-15 13:45     ` [PATCH v4 13/17] ether: utilize container_of for pci_drv Shreyansh Jain
                       ` (6 subsequent siblings)
  18 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-15 13:45 UTC (permalink / raw)
  To: dev; +Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain

From: Jan Viktorin <viktorin@rehivetech.com>

Additional features introduced:
 - Find kernel driver through sysfs bindings
 - Dummy implementation for mapping to kernel driver
 - DMA coherency value from sysfs
 - Numa node number from sysfs
 - Support for updating device during probe if already registered

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: merge multiple patches into single set]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_eal/common/eal_common_soc.c  |  30 ++++++++
 lib/librte_eal/common/eal_private.h     |  23 ++++++
 lib/librte_eal/common/include/rte_soc.h |  28 +++++++
 lib/librte_eal/linuxapp/eal/eal_soc.c   | 129 ++++++++++++++++++++++++++++++++
 4 files changed, 210 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 44f5559..29c38e0 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -114,6 +114,26 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
 		return ret;
 	}
 
+	if (!dev->is_dma_coherent) {
+		if (!(drv->drv_flags & RTE_SOC_DRV_ACCEPT_NONCC)) {
+			RTE_LOG(DEBUG, EAL,
+				"  device is not DMA coherent, skipping\n");
+			return 1;
+		}
+	}
+
+	if (drv->drv_flags & RTE_SOC_DRV_NEED_MAPPING) {
+		/* map resources */
+		ret = rte_eal_soc_map_device(dev);
+		if (ret)
+			return ret;
+	} else if (drv->drv_flags & RTE_SOC_DRV_FORCE_UNBIND
+		&& rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		/* unbind */
+		if (soc_unbind_kernel_driver(dev) < 0)
+			return -1;
+	}
+
 	dev->driver = drv;
 	RTE_VERIFY(drv->probe != NULL);
 	return drv->probe(drv, dev);
@@ -166,6 +186,10 @@ rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
 	if (drv->remove && (drv->remove(dev) < 0))
 		return -1;	/* negative value is an error */
 
+	if (drv->drv_flags & RTE_SOC_DRV_NEED_MAPPING)
+		/* unmap resources for devices */
+		rte_eal_soc_unmap_device(dev);
+
 	/* clear driver structure */
 	dev->driver = NULL;
 
@@ -241,6 +265,12 @@ rte_eal_soc_probe_one(const struct rte_soc_addr *addr)
 	if (addr == NULL)
 		return -1;
 
+	/* update current SoC device in global list, kernel bindings might have
+	 * changed since last time we looked at it.
+	 */
+	if (soc_update_device(addr) < 0)
+		goto err_return;
+
 	TAILQ_FOREACH(dev, &soc_device_list, next) {
 		if (rte_eal_compare_soc_addr(&dev->addr, addr))
 			continue;
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index d810f9f..30c648d 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -159,6 +159,29 @@ int pci_update_device(const struct rte_pci_addr *addr);
 int pci_unbind_kernel_driver(struct rte_pci_device *dev);
 
 /**
+ * Update a soc device object by asking the kernel for the latest information.
+ *
+ * This function is private to EAL.
+ *
+ * @param addr
+ *      The SoC address to look for
+ * @return
+ *   - 0 on success.
+ *   - negative on error.
+ */
+int soc_update_device(const struct rte_soc_addr *addr);
+
+/**
+ * Unbind kernel driver for this device
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int soc_unbind_kernel_driver(struct rte_soc_device *dev);
+
+/**
  * Map the PCI resource of a PCI device in virtual memory
  *
  * This function is private to EAL.
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 1865be5..93205c9 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -46,9 +46,11 @@ extern "C" {
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/queue.h>
 #include <stdint.h>
 #include <inttypes.h>
 #include <string.h>
+#include <limits.h>
 
 #include <rte_dev.h>
 #include <rte_eal.h>
@@ -63,6 +65,14 @@ extern struct soc_device_list soc_device_list;
 TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
 TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
 
+#define SOC_MAX_RESOURCE 6
+
+struct rte_soc_resource {
+	uint64_t phys_addr;
+	uint64_t len;
+	void *addr;
+};
+
 struct rte_soc_id {
 	union {
 		const char *compatible; /**< OF compatible specification */
@@ -84,8 +94,12 @@ struct rte_soc_device {
 	struct rte_device device;           /**< Inherit code device */
 	struct rte_soc_addr addr;           /**< SoC device Location */
 	struct rte_soc_id *id;              /**< SoC device ID list */
+	struct rte_soc_resource mem_resource[SOC_MAX_RESOURCE];
 	struct rte_intr_handle intr_handle; /**< Interrupt handle */
 	struct rte_soc_driver *driver;      /**< Associated driver */
+	int numa_node;                      /**< NUMA node connection */
+	int is_dma_coherent;                /**< DMA coherent device */
+	enum rte_kernel_driver kdrv;        /**< Kernel driver */
 };
 
 struct rte_soc_driver;
@@ -139,6 +153,8 @@ struct rte_soc_driver {
 #define RTE_SOC_DRV_INTR_LSC	 0x0008
 /** Device driver supports detaching capability */
 #define RTE_SOC_DRV_DETACHABLE	 0x0010
+/** Device driver accepts DMA non-coherent devices */
+#define RTE_SOC_DRV_ACCEPT_NONCC 0x0020
 
 /**
  * Utility function to write a SoC device name, this device name can later be
@@ -252,6 +268,18 @@ int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
 int rte_eal_soc_detach(const struct rte_soc_addr *addr);
 
 /**
+ * Map SoC device resources into userspace.
+ *
+ * This is called by the EAL if (drv_flags & RTE_SOC_DRV_NEED_MAPPING).
+ */
+int rte_eal_soc_map_device(struct rte_soc_device *dev);
+
+/**
+ * Unmap the device resources.
+ */
+void rte_eal_soc_unmap_device(struct rte_soc_device *dev);
+
+/**
  * Dump discovered SoC devices.
  *
  * @param f
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index d8286bb..d07bb40 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -63,6 +63,45 @@ soc_get_sysfs_path(void)
 	return path;
 }
 
+int
+soc_unbind_kernel_driver(struct rte_soc_device *dev)
+{
+	char devpath[PATH_MAX];
+
+	snprintf(devpath, sizeof(devpath), "%s/%s",
+		 soc_get_sysfs_path(), dev->addr.name);
+
+	return rte_eal_unbind_kernel_driver(devpath, dev->addr.name);
+}
+
+int
+rte_eal_soc_map_device(struct rte_soc_device *dev)
+{
+	int ret = -1;
+
+	/* try mapping the NIC resources using VFIO if it exists */
+	switch (dev->kdrv) {
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		ret = 1;
+		break;
+	}
+
+	return ret;
+}
+
+void
+rte_eal_soc_unmap_device(struct rte_soc_device *dev)
+{
+	switch (dev->kdrv) {
+	default:
+	RTE_LOG(DEBUG, EAL,
+		"  Not managed by a supported kernel driver, skipped\n");
+		break;
+	}
+}
+
 static char *
 dev_read_uevent(const char *dirname)
 {
@@ -260,6 +299,68 @@ dev_content_free(struct rte_soc_device *dev)
 	}
 }
 
+static int
+dev_setup_associated_driver(struct rte_soc_device *dev, const char *dirname)
+{
+	char filename[PATH_MAX];
+	char driver[PATH_MAX];
+	int ret;
+
+	/* parse driver */
+	snprintf(filename, sizeof(filename), "%s/driver", dirname);
+	ret = rte_eal_get_kernel_driver_by_path(filename, driver);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "Fail to get kernel driver for %s\n",
+			dirname);
+		return 1;
+	}
+
+	if (!ret)
+		dev->kdrv = RTE_KDRV_UNKNOWN;
+	else
+		dev->kdrv = RTE_KDRV_NONE;
+
+	return 0;
+}
+
+static int
+dev_setup_numa_node(struct rte_soc_device *dev, const char *dirname)
+{
+	char filename[PATH_MAX];
+
+	/* if no NUMA support, set default to 0 */
+	unsigned long tmp = 0;
+	int ret = 0;
+
+	/* get numa node */
+	snprintf(filename, sizeof(filename), "%s/numa_node", dirname);
+
+	if (eal_parse_sysfs_value(filename, &tmp) < 0)
+		ret = 1;
+
+	dev->numa_node = tmp;
+	return ret;
+}
+
+static int
+dev_detect_is_coherent(struct rte_soc_device *dev)
+{
+	char filename[PATH_MAX];
+	FILE *f;
+
+	if (dev->addr.fdt_path == NULL)
+		return 0; /* no way to detect */
+
+	snprintf(filename, sizeof(filename), "%s%s/dma-coherent",
+			"/proc/device-tree", dev->addr.fdt_path);
+	f = fopen(filename, "r");
+	if (f == NULL)
+		return 0;
+
+	fclose(f);
+	return 1;
+}
+
 /**
  * Scan one SoC sysfs entry, and fill the devices list from it.
  * We require to have the uevent file with records: OF_FULLNAME and
@@ -299,6 +400,18 @@ soc_scan_one(const char *dirname, const char *name)
 		goto fail;
 	free(uevent); /* not needed anymore */
 
+	ret = dev_setup_associated_driver(dev, dirname);
+	if (ret)
+		goto fail;
+
+	ret = dev_setup_numa_node(dev, dirname);
+	if (ret < 0)
+		goto fail;
+
+	dev->is_dma_coherent = dev_detect_is_coherent(dev);
+	RTE_LOG(DEBUG, EAL, "  DMA %s\n",
+			dev->is_dma_coherent ? "coherent" : "non-coherent");
+
 	/* device is valid, add in list (sorted) */
 	if (TAILQ_EMPTY(&soc_device_list)) {
 		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
@@ -313,6 +426,11 @@ soc_scan_one(const char *dirname, const char *name)
 			if (ret < 0) {
 				TAILQ_INSERT_BEFORE(dev2, dev, next);
 			} else { /* already registered */
+				dev2->kdrv = dev->kdrv;
+				dev2->is_dma_coherent = dev->is_dma_coherent;
+				memmove(dev2->mem_resource, dev->mem_resource,
+					sizeof(dev->mem_resource));
+
 				dev_content_free(dev2);
 				dev2->addr.fdt_path = dev->addr.fdt_path;
 				dev2->id = dev->id;
@@ -333,6 +451,17 @@ fail:
 }
 
 int
+soc_update_device(const struct rte_soc_addr *addr)
+{
+	char filename[PATH_MAX];
+
+	snprintf(filename, sizeof(filename), "%s/%s",
+			soc_get_sysfs_path(), addr->name);
+
+	return soc_scan_one(filename, addr->name);
+}
+
+int
 rte_eal_soc_scan(void)
 {
 	struct dirent *e;
-- 
2.7.4

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

* [PATCH v4 13/17] ether: utilize container_of for pci_drv
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
                       ` (11 preceding siblings ...)
  2016-10-15 13:45     ` [PATCH v4 12/17] eal/soc: additional features for SoC Shreyansh Jain
@ 2016-10-15 13:45     ` Shreyansh Jain
  2016-10-15 13:45     ` [PATCH v4 14/17] ether: verify we copy info from a PCI device Shreyansh Jain
                       ` (5 subsequent siblings)
  18 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-15 13:45 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

It is not necessary to place the rte_pci_driver at the beginning
of the rte_eth_dev struct anymore as we use the container_of macro
to get the parent pointer.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 4 ++--
 lib/librte_ether/rte_ethdev.h | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 0d9d9c1..9aea048 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -241,7 +241,7 @@ rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
 
 	int diag;
 
-	eth_drv = (struct eth_driver *)pci_drv;
+	eth_drv = container_of(pci_drv, struct eth_driver, pci_drv);
 
 	rte_eal_pci_device_name(&pci_dev->addr, ethdev_name,
 			sizeof(ethdev_name));
@@ -302,7 +302,7 @@ rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
 	if (eth_dev == NULL)
 		return -ENODEV;
 
-	eth_drv = (const struct eth_driver *)pci_dev->driver;
+	eth_drv = container_of(pci_dev->driver, struct eth_driver, pci_drv);
 
 	/* Invoke PMD device uninit function */
 	if (*eth_drv->eth_dev_uninit) {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 38641e8..f893fe0 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1850,7 +1850,7 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *eth_dev);
  * Each Ethernet driver acts as a PCI driver and is represented by a generic
  * *eth_driver* structure that holds:
  *
- * - An *rte_pci_driver* structure (which must be the first field).
+ * - An *rte_pci_driver* structure.
  *
  * - The *eth_dev_init* function invoked for each matching PCI device.
  *
-- 
2.7.4

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

* [PATCH v4 14/17] ether: verify we copy info from a PCI device
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
                       ` (12 preceding siblings ...)
  2016-10-15 13:45     ` [PATCH v4 13/17] ether: utilize container_of for pci_drv Shreyansh Jain
@ 2016-10-15 13:45     ` Shreyansh Jain
  2016-10-15 13:45     ` [PATCH v4 15/17] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
                       ` (4 subsequent siblings)
  18 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-15 13:45 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

Now that different types of ethdev exist, check for presence of PCI dev
while copying out the info.
Similar would be done for SoC.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 9aea048..daa1285 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3205,6 +3205,8 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_de
 		return;
 	}
 
+	RTE_VERIFY(eth_dev->pci_dev != NULL);
+
 	eth_dev->data->dev_flags = 0;
 	if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC)
 		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
-- 
2.7.4

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

* [PATCH v4 15/17] ether: extract function eth_dev_get_intr_handle
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
                       ` (13 preceding siblings ...)
  2016-10-15 13:45     ` [PATCH v4 14/17] ether: verify we copy info from a PCI device Shreyansh Jain
@ 2016-10-15 13:45     ` Shreyansh Jain
  2016-10-15 13:45     ` [PATCH v4 16/17] ether: introduce ethernet dev probe remove Shreyansh Jain
                       ` (3 subsequent siblings)
  18 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-15 13:45 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

We abstract access to the intr_handle here as we want to get
it either from the pci_dev or soc_dev.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index daa1285..ba9ae1e 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2531,6 +2531,16 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
 	rte_spinlock_unlock(&rte_eth_dev_cb_lock);
 }
 
+static inline
+struct rte_intr_handle *eth_dev_get_intr_handle(struct rte_eth_dev *dev)
+{
+	if (dev->pci_dev)
+		return &dev->pci_dev->intr_handle;
+
+	RTE_ASSERT(0);
+	return NULL;
+}
+
 int
 rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 {
@@ -2543,7 +2553,7 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
-	intr_handle = &dev->pci_dev->intr_handle;
+	intr_handle = eth_dev_get_intr_handle(dev);
 	if (!intr_handle->intr_vec) {
 		RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
 		return -EPERM;
@@ -2603,7 +2613,7 @@ rte_eth_dev_rx_intr_ctl_q(uint8_t port_id, uint16_t queue_id,
 		return -EINVAL;
 	}
 
-	intr_handle = &dev->pci_dev->intr_handle;
+	intr_handle = eth_dev_get_intr_handle(dev);
 	if (!intr_handle->intr_vec) {
 		RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
 		return -EPERM;
-- 
2.7.4

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

* [PATCH v4 16/17] ether: introduce ethernet dev probe remove
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
                       ` (14 preceding siblings ...)
  2016-10-15 13:45     ` [PATCH v4 15/17] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
@ 2016-10-15 13:45     ` Shreyansh Jain
  2016-10-15 13:45     ` [PATCH v4 17/17] eal/crypto: Support rte_soc_driver/device for cryptodev Shreyansh Jain
                       ` (2 subsequent siblings)
  18 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-15 13:45 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 148 +++++++++++++++++++++++++++++++++++++++++-
 lib/librte_ether/rte_ethdev.h |  31 +++++++++
 2 files changed, 177 insertions(+), 2 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index ba9ae1e..78b3fb8 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -325,6 +325,101 @@ rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
 }
 
 int
+rte_eth_dev_soc_probe(struct rte_soc_driver *soc_drv,
+		      struct rte_soc_device *soc_dev)
+{
+	struct eth_driver    *eth_drv;
+	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
+	int diag;
+
+	eth_drv = container_of(soc_drv, struct eth_driver, soc_drv);
+
+	rte_eal_soc_device_name(&soc_dev->addr, ethdev_name,
+			sizeof(ethdev_name));
+
+	eth_dev = rte_eth_dev_allocate(ethdev_name);
+	if (eth_dev == NULL)
+		return -ENOMEM;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		eth_dev->data->dev_private = rte_zmalloc(
+				  "ethdev private structure",
+				  eth_drv->dev_private_size,
+				  RTE_CACHE_LINE_SIZE);
+		if (eth_dev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private port "
+				  "data\n");
+	}
+	eth_dev->soc_dev = soc_dev;
+	eth_dev->driver = eth_drv;
+	eth_dev->data->rx_mbuf_alloc_failed = 0;
+
+	/* init user callbacks */
+	TAILQ_INIT(&(eth_dev->link_intr_cbs));
+
+	/*
+	 * Set the default MTU.
+	 */
+	eth_dev->data->mtu = ETHER_MTU;
+
+	/* Invoke PMD device initialization function */
+	diag = (*eth_drv->eth_dev_init)(eth_dev);
+	if (diag == 0)
+		return 0;
+
+	RTE_PMD_DEBUG_TRACE("driver %s: eth_dev_init(%s) failed\n",
+			soc_drv->driver.name,
+			soc_dev->addr.name);
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(eth_dev->data->dev_private);
+	rte_eth_dev_release_port(eth_dev);
+	return diag;
+}
+
+int
+rte_eth_dev_soc_remove(struct rte_soc_device *soc_dev)
+{
+	const struct eth_driver *eth_drv;
+	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+	int ret;
+
+	if (soc_dev == NULL)
+		return -EINVAL;
+
+	rte_eal_soc_device_name(&soc_dev->addr, ethdev_name,
+			sizeof(ethdev_name));
+
+	eth_dev = rte_eth_dev_allocated(ethdev_name);
+	if (eth_dev == NULL)
+		return -ENODEV;
+
+	eth_drv = container_of(soc_dev->driver, struct eth_driver, soc_drv);
+
+	/* Invoke PMD device uninit function */
+	if (*eth_drv->eth_dev_uninit) {
+		ret = (*eth_drv->eth_dev_uninit)(eth_dev);
+		if (ret)
+			return ret;
+	}
+
+	/* free ether device */
+	rte_eth_dev_release_port(eth_dev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(eth_dev->data->dev_private);
+
+	eth_dev->soc_dev = NULL;
+	eth_dev->driver = NULL;
+	eth_dev->data = NULL;
+
+	return 0;
+}
+
+
+int
 rte_eth_dev_is_valid_port(uint8_t port_id)
 {
 	if (port_id >= RTE_MAX_ETHPORTS ||
@@ -1557,6 +1652,7 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
 	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
 	dev_info->pci_dev = dev->pci_dev;
+	dev_info->soc_dev = dev->soc_dev;
 	dev_info->driver_name = dev->data->drv_name;
 	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
 	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
@@ -2534,8 +2630,15 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
 static inline
 struct rte_intr_handle *eth_dev_get_intr_handle(struct rte_eth_dev *dev)
 {
-	if (dev->pci_dev)
+	if (dev->pci_dev) {
+		RTE_ASSERT(dev->soc_dev == NULL);
 		return &dev->pci_dev->intr_handle;
+	}
+
+	if (dev->soc_dev) {
+		RTE_ASSERT(dev->pci_dev == NULL);
+		return &dev->soc_dev->intr_handle;
+	}
 
 	RTE_ASSERT(0);
 	return NULL;
@@ -2572,6 +2675,23 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 	return 0;
 }
 
+static inline
+const char *eth_dev_get_driver_name(const struct rte_eth_dev *dev)
+{
+	if (dev->pci_dev) {
+		RTE_ASSERT(dev->soc_dev == NULL);
+		return dev->driver->pci_drv.driver.name;
+	}
+
+	if (dev->soc_dev) {
+		RTE_ASSERT(dev->pci_dev == NULL);
+		return dev->driver->soc_drv.driver.name;
+	}
+
+	RTE_ASSERT(0);
+	return NULL;
+}
+
 const struct rte_memzone *
 rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 			 uint16_t queue_id, size_t size, unsigned align,
@@ -2579,9 +2699,11 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 {
 	char z_name[RTE_MEMZONE_NAMESIZE];
 	const struct rte_memzone *mz;
+	const char *drv_name;
 
+	drv_name = eth_dev_get_driver_name(dev);
 	snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
-		 dev->driver->pci_drv.driver.name, ring_name,
+		 drv_name, ring_name,
 		 dev->data->port_id, queue_id);
 
 	mz = rte_memzone_lookup(z_name);
@@ -3228,6 +3350,28 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_de
 	eth_dev->data->drv_name = pci_dev->driver->driver.name;
 }
 
+void
+rte_eth_copy_soc_info(struct rte_eth_dev *eth_dev,
+		      struct rte_soc_device *soc_dev)
+{
+	if ((eth_dev == NULL) || (soc_dev == NULL)) {
+		RTE_PMD_DEBUG_TRACE("NULL pointer eth_dev=%p soc_dev=%p\n",
+				eth_dev, soc_dev);
+		return;
+	}
+
+	RTE_ASSERT(eth_dev->soc_dev != NULL);
+
+	eth_dev->data->dev_flags = 0;
+	if (soc_dev->driver->drv_flags & RTE_SOC_DRV_INTR_LSC)
+		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
+	if (soc_dev->driver->drv_flags & RTE_SOC_DRV_DETACHABLE)
+		eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
+
+	eth_dev->data->numa_node = soc_dev->device.numa_node;
+	eth_dev->data->drv_name = soc_dev->driver->driver.name;
+}
+
 int
 rte_eth_dev_l2_tunnel_eth_type_conf(uint8_t port_id,
 				    struct rte_eth_l2_tunnel_conf *l2_tunnel)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index f893fe0..ff7958f 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -180,6 +180,7 @@ extern "C" {
 #include <rte_log.h>
 #include <rte_interrupts.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include "rte_ether.h"
@@ -877,6 +878,7 @@ struct rte_eth_conf {
  */
 struct rte_eth_dev_info {
 	struct rte_pci_device *pci_dev; /**< Device PCI information. */
+	struct rte_soc_device *soc_dev; /**< Device SoC information. */
 	const char *driver_name; /**< Device Driver name. */
 	unsigned int if_index; /**< Index to bound host interface, or 0 if none.
 		Use if_indextoname() to translate into an interface name. */
@@ -1626,6 +1628,7 @@ struct rte_eth_dev {
 	const struct eth_driver *driver;/**< Driver for this device */
 	const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
 	struct rte_pci_device *pci_dev; /**< PCI info. supplied by probing */
+	struct rte_soc_device *soc_dev; /**< SoC info. supplied by probing */
 	/** User application callbacks for NIC interrupts */
 	struct rte_eth_dev_cb_list link_intr_cbs;
 	/**
@@ -1860,6 +1863,7 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *eth_dev);
  */
 struct eth_driver {
 	struct rte_pci_driver pci_drv;    /**< The PMD is also a PCI driver. */
+	struct rte_soc_driver soc_drv;    /**< The PMD is also a SoC driver. */
 	eth_dev_init_t eth_dev_init;      /**< Device init function. */
 	eth_dev_uninit_t eth_dev_uninit;  /**< Device uninit function. */
 	unsigned int dev_private_size;    /**< Size of device private data. */
@@ -4262,6 +4266,20 @@ void rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev,
 		struct rte_pci_device *pci_dev);
 
 /**
+ * Copy SoC device info to the Ethernet device data.
+ *
+ * @param eth_dev
+ * The *eth_dev* pointer is the address of the *rte_eth_dev* structure.
+ * @param soc_dev
+ * The *soc_dev* pointer is the address of the *rte_soc_device* structure.
+ *
+ * @return
+ *   - 0 on success, negative on error
+ */
+void rte_eth_copy_soc_info(struct rte_eth_dev *eth_dev,
+		struct rte_soc_device *soc_dev);
+
+/**
  * Create memzone for HW rings.
  * malloc can't be used as the physical address is needed.
  * If the memzone is already created, then this function returns a ptr
@@ -4376,6 +4394,19 @@ int rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
  */
 int rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev);
 
+/**
+ * Wrapper for use by SoC drivers as a .devinit function to attach to a ethdev
+ * interface.
+ */
+int rte_eth_dev_soc_probe(struct rte_soc_driver *soc_drv,
+			  struct rte_soc_device *soc_dev);
+
+/**
+ * Wrapper for use by SoC drivers as a .devuninit function to detach a ethdev
+ * interface.
+ */
+int rte_eth_dev_soc_remove(struct rte_soc_device *soc_dev);
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.7.4

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

* [PATCH v4 17/17] eal/crypto: Support rte_soc_driver/device for cryptodev
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
                       ` (15 preceding siblings ...)
  2016-10-15 13:45     ` [PATCH v4 16/17] ether: introduce ethernet dev probe remove Shreyansh Jain
@ 2016-10-15 13:45     ` Shreyansh Jain
  2016-10-15 13:53     ` [PATCH v4 00/17] Introduce SoC device/driver framework for EAL Shreyansh Jain
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
  18 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-15 13:45 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

- rte_cryptodev_driver/rte_cryptodev_dev embeds rte_soc_driver/device for
  linking SoC PMDs to crypto devices.
- Add probe and remove functions linked

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_cryptodev/rte_cryptodev.c           | 122 ++++++++++++++++++++++++-
 lib/librte_cryptodev/rte_cryptodev.h           |   3 +
 lib/librte_cryptodev/rte_cryptodev_pmd.h       |  18 +++-
 lib/librte_cryptodev/rte_cryptodev_version.map |   2 +
 4 files changed, 140 insertions(+), 5 deletions(-)

diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 127e8d0..77ec9fe 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -422,7 +422,8 @@ rte_cryptodev_pci_probe(struct rte_pci_driver *pci_drv,
 
 	int retval;
 
-	cryptodrv = (struct rte_cryptodev_driver *)pci_drv;
+	cryptodrv = container_of(pci_drv, struct rte_cryptodev_driver,
+				 pci_drv);
 	if (cryptodrv == NULL)
 		return -ENODEV;
 
@@ -489,7 +490,8 @@ rte_cryptodev_pci_remove(struct rte_pci_device *pci_dev)
 	if (cryptodev == NULL)
 		return -ENODEV;
 
-	cryptodrv = (const struct rte_cryptodev_driver *)pci_dev->driver;
+	cryptodrv = container_of(pci_dev->driver, struct rte_cryptodev_driver,
+				 pci_drv);
 	if (cryptodrv == NULL)
 		return -ENODEV;
 
@@ -513,6 +515,111 @@ rte_cryptodev_pci_remove(struct rte_pci_device *pci_dev)
 	return 0;
 }
 
+
+int
+rte_cryptodev_soc_probe(struct rte_soc_driver *soc_drv,
+		      struct rte_soc_device *soc_dev)
+{
+	struct rte_cryptodev_driver *cryptodrv;
+	struct rte_cryptodev *cryptodev;
+
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+
+	int retval;
+
+	cryptodrv = container_of(soc_drv, struct rte_cryptodev_driver,
+				 soc_drv);
+
+	rte_eal_soc_device_name(&soc_dev->addr, cryptodev_name,
+			sizeof(cryptodev_name));
+
+	cryptodev = rte_cryptodev_pmd_allocate(cryptodev_name,
+					       rte_socket_id());
+	if (cryptodev == NULL)
+		return -ENOMEM;
+
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		cryptodev->data->dev_private =
+				rte_zmalloc_socket(
+						"cryptodev private structure",
+						cryptodrv->dev_private_size,
+						RTE_CACHE_LINE_SIZE,
+						rte_socket_id());
+
+		if (cryptodev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private "
+					"device data");
+	}
+
+	cryptodev->soc_dev = soc_dev;
+	cryptodev->driver = cryptodrv;
+
+	/* init user callbacks */
+	TAILQ_INIT(&(cryptodev->link_intr_cbs));
+
+	/* Invoke PMD device initialization function */
+	retval = (*cryptodrv->cryptodev_init)(cryptodrv, cryptodev);
+	if (retval == 0)
+		return 0;
+
+	CDEV_LOG_ERR("driver %s: cryptodev_init(%s) failed\n",
+			soc_drv->driver.name,
+			soc_dev->addr.name);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	cryptodev->attached = RTE_CRYPTODEV_DETACHED;
+	cryptodev_globals.nb_devs--;
+
+	return -ENXIO;
+}
+
+int
+rte_cryptodev_soc_remove(struct rte_soc_device *soc_dev)
+{
+	const struct rte_cryptodev_driver *cryptodrv;
+	struct rte_cryptodev *cryptodev;
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+	int ret;
+
+	if (soc_dev == NULL)
+		return -EINVAL;
+
+	rte_eal_soc_device_name(&soc_dev->addr, cryptodev_name,
+			sizeof(cryptodev_name));
+
+	cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name);
+	if (cryptodev == NULL)
+		return -ENODEV;
+
+	cryptodrv = container_of(soc_dev->driver,
+		struct rte_cryptodev_driver, soc_drv);
+	if (cryptodrv == NULL)
+		return -ENODEV;
+
+	/* Invoke PMD device uninit function */
+	if (*cryptodrv->cryptodev_uninit) {
+		ret = (*cryptodrv->cryptodev_uninit)(cryptodrv, cryptodev);
+		if (ret)
+			return ret;
+	}
+
+	/* free crypto device */
+	rte_cryptodev_pmd_release_device(cryptodev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	cryptodev->pci_dev = NULL;
+	cryptodev->soc_dev = NULL;
+	cryptodev->driver = NULL;
+	cryptodev->data = NULL;
+
+	return 0;
+}
+
 uint16_t
 rte_cryptodev_queue_pair_count(uint8_t dev_id)
 {
@@ -868,8 +975,15 @@ rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
 
 	dev_info->pci_dev = dev->pci_dev;
-	if (dev->driver)
-		dev_info->driver_name = dev->driver->pci_drv.driver.name;
+	dev_info->soc_dev = dev->soc_dev;
+	if (dev->driver) {
+		if (dev->soc_dev)
+			dev_info->driver_name
+				= dev->driver->soc_drv.driver.name;
+		else
+			dev_info->driver_name
+				= dev->driver->pci_drv.driver.name;
+	}
 }
 
 
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 232f34a..b94188d 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -244,6 +244,7 @@ struct rte_cryptodev_info {
 	const char *driver_name;		/**< Driver name. */
 	enum rte_cryptodev_type dev_type;	/**< Device type */
 	struct rte_pci_device *pci_dev;		/**< PCI information. */
+	struct rte_soc_device *soc_dev;		/**< SoC information. */
 
 	uint64_t feature_flags;			/**< Feature flags */
 
@@ -623,6 +624,8 @@ struct rte_cryptodev {
 	/**< Supported features */
 	struct rte_pci_device *pci_dev;
 	/**< PCI info. supplied by probing */
+	struct rte_soc_device *soc_dev;
+	/**< SoC info. supplied by probing/Scanning */
 
 	enum rte_cryptodev_type dev_type;
 	/**< Crypto device type */
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index abfe2dc..a8af2ce 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -48,6 +48,7 @@ extern "C" {
 
 #include <rte_dev.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_malloc.h>
 #include <rte_mbuf.h>
 #include <rte_mempool.h>
@@ -131,7 +132,8 @@ typedef int (*cryptodev_uninit_t)(const struct rte_cryptodev_driver  *drv,
  * - The size of the private data to allocate for each matching device.
  */
 struct rte_cryptodev_driver {
-	struct rte_pci_driver pci_drv;	/**< The PMD is also a PCI driver. */
+	struct rte_pci_driver pci_drv;	/**< The PMD is PCI type driver. */
+	struct rte_soc_driver soc_drv;	/**< The PMD is SoC type driver. */
 	unsigned dev_private_size;	/**< Size of device private data. */
 
 	cryptodev_init_t cryptodev_init;	/**< Device init function. */
@@ -519,6 +521,20 @@ int rte_cryptodev_pci_probe(struct rte_pci_driver *pci_drv,
  */
 int rte_cryptodev_pci_remove(struct rte_pci_device *pci_dev);
 
+/**
+ * Wrapper for use by SoC drivers as a .devinit function to attach to a
+ * cryptodev interface.
+ */
+int rte_cryptodev_soc_probe(struct rte_soc_driver *soc_drv,
+			  struct rte_soc_device *soc_dev);
+
+/**
+ * Wrapper for use by SoC drivers as a .devuninit function to detach a
+ * cryptodev interface.
+ */
+int rte_cryptodev_soc_remove(struct rte_soc_device *soc_dev);
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index 9dde0e7..d81073e 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -44,5 +44,7 @@ DPDK_16.11 {
 
 	rte_cryptodev_pci_probe;
 	rte_cryptodev_pci_remove;
+	rte_cryptodev_soc_probe;
+	rte_cryptodev_soc_remove;
 
 } DPDK_16.07;
-- 
2.7.4

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

* Re: [PATCH v4 00/17] Introduce SoC device/driver framework for EAL
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
                       ` (16 preceding siblings ...)
  2016-10-15 13:45     ` [PATCH v4 17/17] eal/crypto: Support rte_soc_driver/device for cryptodev Shreyansh Jain
@ 2016-10-15 13:53     ` Shreyansh Jain
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
  18 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-15 13:53 UTC (permalink / raw)
  To: dev; +Cc: viktorin, thomas.monjalon, david.marchand

On Saturday 15 October 2016 07:14 PM, Shreyansh Jain wrote:
[...]
>
> 4) Design considerations that are same as PCI:
>  - SoC initialization is being done through rte_eal_init(), just after PCI
>    initialization is done.
>  - As in case of PCI, probe is done after rte_eal_pci_probe() to link the
>    devices detected with the drivers registered.
>  - Device attach/detach functions are available and have been designed on
>    the lines of PCI framework.
>  - PMDs register using DRIVER_REGISTER_SOC, very similar to
>    DRIVER_REGISTER_PCI for PCI devices.
>  - Linked list of SoC driver and devices exists independent of the other
>    driver/device list, but inheriting rte_driver/rte_driver, these are
>    also part of a global list.
>
[...]

Two points which I missed in the Cover letter:
1. DRIVER_REGISTER_* has been replaced with RTE_PMD_REGISTER_*.
2. This is an experimental series. Verification of this has been done 
using NXP's PMD (to be published on ML soon) without using default 
scan/match helpers.

-
Shreyansh

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

* Re: [PATCH v4 11/17] eal/soc: add default scan for Soc devices
  2016-10-15 13:45     ` [PATCH v4 11/17] eal/soc: add default scan for Soc devices Shreyansh Jain
@ 2016-10-16  0:56       ` Jan Viktorin
  2016-10-16  7:12         ` Shreyansh Jain
  0 siblings, 1 reply; 231+ messages in thread
From: Jan Viktorin @ 2016-10-16  0:56 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, thomas.monjalon, david.marchand

On Sat, 15 Oct 2016 19:15:02 +0530
Shreyansh Jain <shreyansh.jain@nxp.com> wrote:

> From: Jan Viktorin <viktorin@rehivetech.com>
> 
> Default implementation which scans the sysfs platform devices hierarchy.
> For each device, extract the ueven and convert into rte_soc_device.
> 
> The information populated can then be used in probe to match against
> the drivers registered.
> 
> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> [Shreyansh: restructure commit to be an optional implementation]
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>

[...]

> +
> +int
> +rte_eal_soc_scan(void)

What about naming it rte_eal_soc_scan_default? This would underline the
fact that this function can be replaced.

Second, this is for the 7/17 patch:
 
-/* register a driver */
 void
 rte_eal_soc_register(struct rte_soc_driver *driver)
 {
+	/* For a valid soc driver, match and scan function
+	 * should be provided.
+	 */
+	RTE_VERIFY(driver != NULL);
+	RTE_VERIFY(driver->match_fn != NULL);
+	RTE_VERIFY(driver->scan_fn != NULL);

What about setting the match_fn and scan_fn to default implementations if they
are NULL? This would make the standard/default approach easier to use.

 	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
 }
 

> +{
> +	struct dirent *e;
> +	DIR *dir;
> +	char dirname[PATH_MAX];
> +
> +	dir = opendir(soc_get_sysfs_path());
> +	if (dir == NULL) {
> +		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
> +			__func__, strerror(errno));
> +		return -1;
> +	}
> +
> +	while ((e = readdir(dir)) != NULL) {
> +		if (e->d_name[0] == '.')
> +			continue;
> +
> +		snprintf(dirname, sizeof(dirname), "%s/%s",
> +				soc_get_sysfs_path(), e->d_name);
> +		if (soc_scan_one(dirname, e->d_name) < 0)
> +			goto error;
> +	}
> +	closedir(dir);
> +	return 0;
> +
> +error:
> +	closedir(dir);
> +	return -1;
> +}
> +
>  /* Init the SoC EAL subsystem */
>  int
>  rte_eal_soc_init(void)



-- 
  Jan Viktorin                E-mail: Viktorin@RehiveTech.com
  System Architect            Web:    www.RehiveTech.com
  RehiveTech
  Brno, Czech Republic

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

* Re: [PATCH v4 11/17] eal/soc: add default scan for Soc devices
  2016-10-16  0:56       ` Jan Viktorin
@ 2016-10-16  7:12         ` Shreyansh Jain
  2016-10-24 12:08           ` Shreyansh Jain
  0 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-16  7:12 UTC (permalink / raw)
  To: Jan Viktorin; +Cc: dev, thomas.monjalon, david.marchand

Hi Jan,

> -----Original Message-----
> From: Jan Viktorin [mailto:viktorin@rehivetech.com]
> Sent: Sunday, October 16, 2016 6:27 AM
> To: Shreyansh Jain <shreyansh.jain@nxp.com>
> Cc: dev@dpdk.org; thomas.monjalon@6wind.com; david.marchand@6wind.com
> Subject: Re: [PATCH v4 11/17] eal/soc: add default scan for Soc devices
> 
> On Sat, 15 Oct 2016 19:15:02 +0530
> Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
> 
> > From: Jan Viktorin <viktorin@rehivetech.com>
> >
> > Default implementation which scans the sysfs platform devices hierarchy.
> > For each device, extract the ueven and convert into rte_soc_device.
> >
> > The information populated can then be used in probe to match against
> > the drivers registered.
> >
> > Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> > [Shreyansh: restructure commit to be an optional implementation]
> > Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> 
> [...]
> 
> > +
> > +int
> > +rte_eal_soc_scan(void)
> 
> What about naming it rte_eal_soc_scan_default? This would underline the
> fact that this function can be replaced.

Yes, that would be in sync with match default. I will do it.

> 
> Second, this is for the 7/17 patch:
> 
> -/* register a driver */
>  void
>  rte_eal_soc_register(struct rte_soc_driver *driver)
>  {
> +	/* For a valid soc driver, match and scan function
> +	 * should be provided.
> +	 */
> +	RTE_VERIFY(driver != NULL);
> +	RTE_VERIFY(driver->match_fn != NULL);
> +	RTE_VERIFY(driver->scan_fn != NULL);
> 
> What about setting the match_fn and scan_fn to default implementations if
> they
> are NULL? This would make the standard/default approach easier to use.
> 
>  	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
>  }

I am not in favor of a forced default. What if user never intended it - it would lead to wrong scan being used and only intimation which can provided to user is a log.
Selecting such functions should be a model of PMD - one which is enforced.

> 
> > +{
> > +	struct dirent *e;
> > +	DIR *dir;
> > +	char dirname[PATH_MAX];
> > +
> > +	dir = opendir(soc_get_sysfs_path());
> > +	if (dir == NULL) {
> > +		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
> > +			__func__, strerror(errno));
> > +		return -1;
> > +	}
> > +
> > +	while ((e = readdir(dir)) != NULL) {
> > +		if (e->d_name[0] == '.')
> > +			continue;
> > +
> > +		snprintf(dirname, sizeof(dirname), "%s/%s",
> > +				soc_get_sysfs_path(), e->d_name);
> > +		if (soc_scan_one(dirname, e->d_name) < 0)
> > +			goto error;
> > +	}
> > +	closedir(dir);
> > +	return 0;
> > +
> > +error:
> > +	closedir(dir);
> > +	return -1;
> > +}
> > +
> >  /* Init the SoC EAL subsystem */
> >  int
> >  rte_eal_soc_init(void)
> 
> 
> 
> --
>   Jan Viktorin                E-mail: Viktorin@RehiveTech.com
>   System Architect            Web:    www.RehiveTech.com
>   RehiveTech
>   Brno, Czech Republic

Thanks for your quick comments.

I have not yet taken all the inputs you had provided in review of v3 - I will be replying to those soon marking out what I have taken and what I have not.
 
-
Shreyansh

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

* [PATCH v5 00/21] Introduce SoC device/driver framework for EAL
  2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
                       ` (17 preceding siblings ...)
  2016-10-15 13:53     ` [PATCH v4 00/17] Introduce SoC device/driver framework for EAL Shreyansh Jain
@ 2016-10-24 11:59     ` Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 01/21] eal: generalize PCI kernel driver enum to EAL Shreyansh Jain
                         ` (21 more replies)
  18 siblings, 22 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev; +Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain

Introduction:
=============

This patch set is direct derivative of Jan's original series [1],[2].

 - This version is based on master HEAD (173511).
 
 - In this, I am merging the series [11] back. It was initially part
   of this set but I had split considering that those changes in PCI
   were good standalone as well. But, 1) not much feedback was avail-
   able and 2) this patchset is a use-case for those patches making
   it easier to review. Just like what Jan had intended in original
   series.

 - Hereafter, this series is not dependent on any other external patch
   series.

Aim:
====

As of now EAL is primarly focused on PCI initialization/probing.

 rte_eal_init()
  |- rte_eal_pci_init(): Find PCI devices from sysfs
  |- ...
  |- rte_eal_memzone_init()
  |- ...
  `- rte_eal_pci_probe(): Driver<=>Device initialization

This patchset introduces SoC framework which would enable SoC drivers and
drivers to be plugged into EAL, very similar to how PCI drivers/devices are
done today.

This is a stripped down version of PCI framework which allows the SoC PMDs
to implement their own routines for detecting devices and linking devices to
drivers.

1) Changes to EAL
 rte_eal_init()
  |- rte_eal_pci_init(): Find PCI devices from sysfs
  |- rte_eal_soc_init(): Calls PMDs->scan_fn
  |- ...
  |- rte_eal_memzone_init()
  |- ...
  |- rte_eal_pci_probe(): Driver<=>Device initialization, PMD->devinit()
  `- rte_eal_soc_probe(): Calls PMDs->match_fn and PMDs->devinit();

2) New device/driver structures:
  - rte_soc_driver (inheriting rte_driver)
  - rte_soc_device (inheriting rte_device)
  - rte_eth_dev and eth_driver embedded rte_soc_device and rte_soc_driver,
    respectively.

3) The SoC PMDs need to:
 - define rte_soc_driver with necessary scan and match callbacks
 - Register themselves using DRIVER_REGISTER_SOC()
 - Implement respective bus scanning in the scan callbacks to add necessary
   devices to SoC device list
 - Implement necessary eth_dev_init/uninint for ethernet instances

4) Design considerations that are same as PCI:
 - SoC initialization is being done through rte_eal_init(), just after PCI
   initialization is done.
 - As in case of PCI, probe is done after rte_eal_pci_probe() to link the
   devices detected with the drivers registered.
 - Device attach/detach functions are available and have been designed on
   the lines of PCI framework.
 - PMDs register using DRIVER_REGISTER_SOC, very similar to
   DRIVER_REGISTER_PCI for PCI devices.
 - Linked list of SoC driver and devices exists independent of the other
   driver/device list, but inheriting rte_driver/rte_driver, these are
   also part of a global list.

5) Design considerations that are different from PCI:
 - Each driver implements its own scan and match function. PCI uses the BDF
   format to read the device from sysfs, but this _may_not_ be a case for a
   SoC ethernet device.
   = This is an important change from initial proposal by Jan in [2].
   Unlike his attempt to use /sys/bus/platform, this patch relies on the
   PMD to detect the devices. This is because SoC may require specific or
   additional info for device detection. Further, SoC may have embedded
   devices/MACs which require initialization which cannot be covered
   through sysfs parsing.
   `-> Point (6) below is a side note to above.
   = PCI based PMDs rely on EAL's capability to detect devices. This
   proposal puts the onus on PMD to detect devices, add to soc_device_list
   and wait for Probe. Matching, of device<=>driver is again PMD's
   callback.

6) Adding default scan and match helpers for PMDs
 - The design warrrants the PMDs implement their own scan of devices
   on bus, and match routines for probe implementation.
   This patch introduces helpers which can be used by PMDs for scan of
   the platform bus and matching devices against the compatible string
   extracted from the scan.
 - Intention is to make it easier to integrate known SoC which expose
   platform bus compliant information (compat, sys/bus/platform...).
 - PMDs which have deviations from this standard model can implement and
   hook their bus scanning and probe match callbacks while registering
   driver.

Patchset Overview:
==================
 - Patches 0001~0004 are from [11] - moving some PCI specific functions
   and definitions to non-PCI area.
 - Patches 0005~0008 introduce the base infrastructure and test case
 - Patch 0009 is for command line support for no-soc, on lines of no-pci
 - Patch 0010 enables EAL to handle SoC type devices
 - Patch 0011 adds support for scan and probe callbacks and updates the test
   framework with relevant test case.
 - Patch 0012~0014 enable device argument, driver specific flags and
   interrupt handling related basic infra. Subsequent patches build up on
   them.
 - Patch 0015~0016 add support for default function which PMDs can use for
   scanning platform bus. These functions are optional and need to be hooked
   to by PMDs.
 - Patch 0017~0019 makes changes to PCI as well as ethdev code to remove
   assumption that eth_driver is a PCI driver.
 - Patch 0020 adds necessary ethdev probe/remove functions for PMDs to use
 - Patch 0021 adds support for SoC driver/devices, along with probe/remove
   functions for Cryptodev devices.

Future/Pending Changes:
=======================
- Device whitelisting/blacklist still relies on command line '-b' and '-c'
  which are internally implemented using OPT_PCI_BLACKLIST/OPT_PCI_WHITELIST.
  This needs to be changed to a generic form - OPT_DEV_*LIST - probably.
- No cryptodriver currently uses SoC framework - probably a example driver
  can be created to demonstrate usage.
- test case for enable-soc command line parameter

 [1] http://dpdk.org/ml/archives/dev/2016-January/030915.html
 [2] http://www.dpdk.org/ml/archives/dev/2016-May/038486.html
 [3] http://dpdk.org/ml/archives/dev/2016-August/045707.html
 [4] http://dpdk.org/ml/archives/dev/2016-May/038948.html
 [5] http://dpdk.org/ml/archives/dev/2016-May/038953.html
 [6] http://dpdk.org/ml/archives/dev/2016-May/038487.html
 [7] http://dpdk.org/ml/archives/dev/2016-May/038488.html
 [8] http://dpdk.org/ml/archives/dev/2016-May/038489.html
 [9] http://dpdk.org/ml/archives/dev/2016-May/038491.html
[10] http://dpdk.org/ml/archives/dev/2016-September/046256.html
[11] http://dpdk.org/ml/archives/dev/2016-October/048915.html

Changes since v4:
 - change name of rte_eal_soc_scan function name to
   rte_eal_soc_scan_platform_bus. This still remains a helper function.
 - Fix comments over scan and match functions

Changes since v3:
 - rebasing over HEAD (fed622df tag: v16.11-rc1)
 - Add support for default scan function; PMD can use this for
   scanning on platform bus.
 - Support for kernel driver bind/unbind, numa and DMA from
   Jan's original patches.
 - SoC is disabled by default. '--enable-soc' command line parameter
   enables it. doc updated.
 - Updated testcase function names and comments
 - Map file addition alphabetically ordered
 - Patch author corrected

Changes since v2:
 - Rebasing over rte_driver/device patchset v9 [10]
 - Added cryptodev support for SoC
 - Default match function for SoC device<=>Driver
 - Some variables renamed to reflect 'drv' rather than 'dr'

Change since v1 [2]:
 - Removed patch 1-5 which were for generalizing some PCI specific routines
   into EAL. These patches are good-to-have but not directly linked to SoC
   and hence would be proposed separately.
 - Removed support for sysfs parsing (patches 6~9)
 - Rebasing over the recent (v8) version of rte_driver/device patchset
 - Rebasing over master (16.07)
 - Changes to various map file to change API intro to 16.11 from 16.07

Jan Viktorin (19):
  eal: generalize PCI kernel driver enum to EAL
  eal: generalize PCI map/unmap resource to EAL
  eal/linux: generalize PCI kernel unbinding driver to EAL
  eal/linux: generalize PCI kernel driver extraction to EAL
  eal: define container macro
  eal/soc: introduce very essential SoC infra definitions
  eal/soc: add SoC PMD register/unregister logic
  eal/soc: implement SoC device list and dump
  eal: introduce command line enable SoC option
  eal/soc: init SoC infra from EAL
  eal/soc: extend and utilize devargs
  eal/soc: add drv_flags
  eal/soc: add intr_handle
  eal/soc: add default scan for Soc devices
  eal/soc: additional features for SoC
  ether: utilize container_of for pci_drv
  ether: verify we copy info from a PCI device
  ether: extract function eth_dev_get_intr_handle
  ether: introduce ethernet dev probe remove

Shreyansh Jain (2):
  eal/soc: implement probing of drivers
  eal/crypto: Support rte_soc_driver/device for cryptodev

 app/test/Makefile                               |   1 +
 app/test/test_soc.c                             | 404 +++++++++++++++++++
 doc/guides/testpmd_app_ug/run_app.rst           |   4 +
 lib/librte_cryptodev/rte_cryptodev.c            | 122 +++++-
 lib/librte_cryptodev/rte_cryptodev.h            |   3 +
 lib/librte_cryptodev/rte_cryptodev_pmd.h        |  18 +-
 lib/librte_cryptodev/rte_cryptodev_version.map  |   2 +
 lib/librte_eal/bsdapp/eal/Makefile              |   1 +
 lib/librte_eal/bsdapp/eal/eal.c                 |  18 +
 lib/librte_eal/bsdapp/eal/eal_pci.c             |   6 +-
 lib/librte_eal/bsdapp/eal/eal_soc.c             |  46 +++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  11 +
 lib/librte_eal/common/Makefile                  |   2 +-
 lib/librte_eal/common/eal_common_dev.c          |  66 ++-
 lib/librte_eal/common/eal_common_devargs.c      |  17 +
 lib/librte_eal/common/eal_common_options.c      |   5 +
 lib/librte_eal/common/eal_common_pci.c          |  39 --
 lib/librte_eal/common/eal_common_pci_uio.c      |  16 +-
 lib/librte_eal/common/eal_common_soc.c          | 368 +++++++++++++++++
 lib/librte_eal/common/eal_internal_cfg.h        |   1 +
 lib/librte_eal/common/eal_options.h             |   2 +
 lib/librte_eal/common/eal_private.h             |  64 +++
 lib/librte_eal/common/include/rte_common.h      |  18 +
 lib/librte_eal/common/include/rte_dev.h         |  44 ++
 lib/librte_eal/common/include/rte_devargs.h     |   8 +
 lib/librte_eal/common/include/rte_pci.h         |  41 --
 lib/librte_eal/common/include/rte_soc.h         | 322 +++++++++++++++
 lib/librte_eal/linuxapp/eal/Makefile            |   2 +
 lib/librte_eal/linuxapp/eal/eal.c               |  63 +++
 lib/librte_eal/linuxapp/eal/eal_pci.c           |  62 +--
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c       |   2 +-
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c      |   5 +-
 lib/librte_eal/linuxapp/eal/eal_soc.c           | 515 ++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  11 +
 lib/librte_ether/rte_ethdev.c                   | 166 +++++++-
 lib/librte_ether/rte_ethdev.h                   |  33 +-
 36 files changed, 2343 insertions(+), 165 deletions(-)
 create mode 100644 app/test/test_soc.c
 create mode 100644 lib/librte_eal/bsdapp/eal/eal_soc.c
 create mode 100644 lib/librte_eal/common/eal_common_soc.c
 create mode 100644 lib/librte_eal/common/include/rte_soc.h
 create mode 100644 lib/librte_eal/linuxapp/eal/eal_soc.c

-- 
2.7.4

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

* [PATCH v5 01/21] eal: generalize PCI kernel driver enum to EAL
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-24 16:13         ` Jan Viktorin
  2016-10-24 11:59       ` [PATCH v5 02/21] eal: generalize PCI map/unmap resource " Shreyansh Jain
                         ` (20 subsequent siblings)
  21 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev; +Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain

From: Jan Viktorin <viktorin@rehivetech.com>

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>

--
Changes since v0:
 - fix compilation error due to missing include
---
 lib/librte_eal/common/include/rte_dev.h | 12 ++++++++++++
 lib/librte_eal/common/include/rte_pci.h |  9 ---------
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index b3873bd..e73b0fa 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -109,6 +109,18 @@ struct rte_mem_resource {
 	void *addr;         /**< Virtual address, NULL when not mapped. */
 };
 
+/**
+ * Kernel driver passthrough type
+ */
+enum rte_kernel_driver {
+	RTE_KDRV_UNKNOWN = 0,
+	RTE_KDRV_IGB_UIO,
+	RTE_KDRV_VFIO,
+	RTE_KDRV_UIO_GENERIC,
+	RTE_KDRV_NIC_UIO,
+	RTE_KDRV_NONE,
+};
+
 /** Double linked list of device drivers. */
 TAILQ_HEAD(rte_driver_list, rte_driver);
 /** Double linked list of devices. */
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 9ce8847..2c7046f 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -135,15 +135,6 @@ struct rte_pci_addr {
 
 struct rte_devargs;
 
-enum rte_kernel_driver {
-	RTE_KDRV_UNKNOWN = 0,
-	RTE_KDRV_IGB_UIO,
-	RTE_KDRV_VFIO,
-	RTE_KDRV_UIO_GENERIC,
-	RTE_KDRV_NIC_UIO,
-	RTE_KDRV_NONE,
-};
-
 /**
  * A structure describing a PCI device.
  */
-- 
2.7.4

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

* [PATCH v5 02/21] eal: generalize PCI map/unmap resource to EAL
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 01/21] eal: generalize PCI kernel driver enum to EAL Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 03/21] eal/linux: generalize PCI kernel unbinding driver " Shreyansh Jain
                         ` (19 subsequent siblings)
  21 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev; +Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain

From: Jan Viktorin <viktorin@rehivetech.com>

The functions pci_map_resource, pci_unmap_resource are generic so the
pci_* prefix can be omitted. The functions are moved to the
eal_common_dev.c so they can be reused by other infrastructure.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_eal/bsdapp/eal/eal_pci.c             |  2 +-
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  2 ++
 lib/librte_eal/common/eal_common_dev.c          | 39 +++++++++++++++++++++++++
 lib/librte_eal/common/eal_common_pci.c          | 39 -------------------------
 lib/librte_eal/common/eal_common_pci_uio.c      | 16 +++++-----
 lib/librte_eal/common/include/rte_dev.h         | 32 ++++++++++++++++++++
 lib/librte_eal/common/include/rte_pci.h         | 32 --------------------
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c       |  2 +-
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c      |  5 ++--
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  2 ++
 10 files changed, 89 insertions(+), 82 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 8b3ed88..7ed0115 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -228,7 +228,7 @@ pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
 
 	/* if matching map is found, then use it */
 	offset = res_idx * pagesz;
-	mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
+	mapaddr = rte_eal_map_resource(NULL, fd, (off_t)offset,
 			(size_t)dev->mem_resource[res_idx].len, 0);
 	close(fd);
 	if (mapaddr == MAP_FAILED)
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 2f81f7c..11d9f59 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -170,6 +170,8 @@ DPDK_16.11 {
 	rte_delay_us_callback_register;
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
+	rte_eal_map_resource;
+	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
 
diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 4f3b493..457d227 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -36,6 +36,7 @@
 #include <string.h>
 #include <inttypes.h>
 #include <sys/queue.h>
+#include <sys/mman.h>
 
 #include <rte_dev.h>
 #include <rte_devargs.h>
@@ -151,3 +152,41 @@ err:
 	RTE_LOG(ERR, EAL, "Driver cannot detach the device (%s)\n", name);
 	return -EINVAL;
 }
+
+/* map a particular resource from a file */
+void *
+rte_eal_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
+		 int additional_flags)
+{
+	void *mapaddr;
+
+	/* Map the Memory resource of device */
+	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
+			MAP_SHARED | additional_flags, fd, offset);
+	if (mapaddr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s"
+			" (%p)\n", __func__, fd, requested_addr,
+			(unsigned long)size, (unsigned long)offset,
+			strerror(errno), mapaddr);
+	} else
+		RTE_LOG(DEBUG, EAL, "  Device memory mapped at %p\n", mapaddr);
+
+	return mapaddr;
+}
+
+/* unmap a particular resource */
+void
+rte_eal_unmap_resource(void *requested_addr, size_t size)
+{
+	if (requested_addr == NULL)
+		return;
+
+	/* Unmap the Memory resource of device */
+	if (munmap(requested_addr, size)) {
+		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
+			__func__, requested_addr, (unsigned long)size,
+			strerror(errno));
+	} else
+		RTE_LOG(DEBUG, EAL, "  Device memory unmapped at %p\n",
+				requested_addr);
+}
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 638cd86..464acc1 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -67,7 +67,6 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/queue.h>
-#include <sys/mman.h>
 
 #include <rte_interrupts.h>
 #include <rte_log.h>
@@ -114,44 +113,6 @@ static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
 	return NULL;
 }
 
-/* map a particular resource from a file */
-void *
-pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
-		 int additional_flags)
-{
-	void *mapaddr;
-
-	/* Map the PCI memory resource of device */
-	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
-			MAP_SHARED | additional_flags, fd, offset);
-	if (mapaddr == MAP_FAILED) {
-		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
-			__func__, fd, requested_addr,
-			(unsigned long)size, (unsigned long)offset,
-			strerror(errno), mapaddr);
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
-
-	return mapaddr;
-}
-
-/* unmap a particular resource */
-void
-pci_unmap_resource(void *requested_addr, size_t size)
-{
-	if (requested_addr == NULL)
-		return;
-
-	/* Unmap the PCI memory resource of device */
-	if (munmap(requested_addr, size)) {
-		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
-			__func__, requested_addr, (unsigned long)size,
-			strerror(errno));
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
-				requested_addr);
-}
-
 /*
  * If vendor/device ID match, call the probe() function of the
  * driver.
diff --git a/lib/librte_eal/common/eal_common_pci_uio.c b/lib/librte_eal/common/eal_common_pci_uio.c
index 367a681..3402518 100644
--- a/lib/librte_eal/common/eal_common_pci_uio.c
+++ b/lib/librte_eal/common/eal_common_pci_uio.c
@@ -75,9 +75,11 @@ pci_uio_map_secondary(struct rte_pci_device *dev)
 				return -1;
 			}
 
-			void *mapaddr = pci_map_resource(uio_res->maps[i].addr,
-					fd, (off_t)uio_res->maps[i].offset,
-					(size_t)uio_res->maps[i].size, 0);
+			void *mapaddr = rte_eal_map_resource(
+						uio_res->maps[i].addr, fd,
+						(off_t)uio_res->maps[i].offset,
+						(size_t)uio_res->maps[i].size,
+						0);
 			/* fd is not needed in slave process, close it */
 			close(fd);
 			if (mapaddr != uio_res->maps[i].addr) {
@@ -88,11 +90,11 @@ pci_uio_map_secondary(struct rte_pci_device *dev)
 				if (mapaddr != MAP_FAILED) {
 					/* unmap addrs correctly mapped */
 					for (j = 0; j < i; j++)
-						pci_unmap_resource(
+						rte_eal_unmap_resource(
 							uio_res->maps[j].addr,
 							(size_t)uio_res->maps[j].size);
 					/* unmap addr wrongly mapped */
-					pci_unmap_resource(mapaddr,
+					rte_eal_unmap_resource(mapaddr,
 						(size_t)uio_res->maps[i].size);
 				}
 				return -1;
@@ -150,7 +152,7 @@ pci_uio_map_resource(struct rte_pci_device *dev)
 	return 0;
 error:
 	for (i = 0; i < map_idx; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
+		rte_eal_unmap_resource(uio_res->maps[i].addr,
 				(size_t)uio_res->maps[i].size);
 		rte_free(uio_res->maps[i].path);
 	}
@@ -167,7 +169,7 @@ pci_uio_unmap(struct mapped_pci_resource *uio_res)
 		return;
 
 	for (i = 0; i != uio_res->nb_maps; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
+		rte_eal_unmap_resource(uio_res->maps[i].addr,
 				(size_t)uio_res->maps[i].size);
 		if (rte_eal_process_type() == RTE_PROC_PRIMARY)
 			rte_free(uio_res->maps[i].path);
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index e73b0fa..277c07b 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -234,6 +234,38 @@ int rte_eal_dev_attach(const char *name, const char *devargs);
  */
 int rte_eal_dev_detach(const char *name);
 
+/*
+ * @internal
+ * Map a particular resource from a file.
+ *
+ * @param requested_addr
+ *      The starting address for the new mapping range.
+ * @param fd
+ *      The file descriptor.
+ * @param offset
+ *      The offset for the mapping range.
+ * @param size
+ *      The size for the mapping range.
+ * @param additional_flags
+ *      The additional flags for the mapping range.
+ * @return
+ *   - On success, the function returns a pointer to the mapped area.
+ *   - On error, the value MAP_FAILED is returned.
+ */
+void *rte_eal_map_resource(void *requested_addr, int fd, off_t offset,
+			   size_t size, int additional_flags);
+
+/**
+ * @internal
+ * Unmap a particular resource.
+ *
+ * @param requested_addr
+ *      The address for the unmapping range.
+ * @param size
+ *      The size for the unmapping range.
+ */
+void rte_eal_unmap_resource(void *requested_addr, size_t size);
+
 #define RTE_PMD_EXPORT_NAME_ARRAY(n, idx) n##idx[]
 
 #define RTE_PMD_EXPORT_NAME(name, idx) \
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 2c7046f..7d6eef5 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -399,38 +399,6 @@ int rte_eal_pci_map_device(struct rte_pci_device *dev);
 void rte_eal_pci_unmap_device(struct rte_pci_device *dev);
 
 /**
- * @internal
- * Map a particular resource from a file.
- *
- * @param requested_addr
- *      The starting address for the new mapping range.
- * @param fd
- *      The file descriptor.
- * @param offset
- *      The offset for the mapping range.
- * @param size
- *      The size for the mapping range.
- * @param additional_flags
- *      The additional flags for the mapping range.
- * @return
- *   - On success, the function returns a pointer to the mapped area.
- *   - On error, the value MAP_FAILED is returned.
- */
-void *pci_map_resource(void *requested_addr, int fd, off_t offset,
-		size_t size, int additional_flags);
-
-/**
- * @internal
- * Unmap a particular resource.
- *
- * @param requested_addr
- *      The address for the unmapping range.
- * @param size
- *      The size for the unmapping range.
- */
-void pci_unmap_resource(void *requested_addr, size_t size);
-
-/**
  * Probe the single PCI device.
  *
  * Scan the content of the PCI bus, and find the pci device specified by pci
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
index 1786b75..5c34421 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
@@ -347,7 +347,7 @@ pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
 	if (pci_map_addr == NULL)
 		pci_map_addr = pci_find_max_end_va();
 
-	mapaddr = pci_map_resource(pci_map_addr, fd, 0,
+	mapaddr = rte_eal_map_resource(pci_map_addr, fd, 0,
 			(size_t)dev->mem_resource[res_idx].len, 0);
 	close(fd);
 	if (mapaddr == MAP_FAILED)
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
index 5f478c5..5ad8cbe 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
@@ -465,7 +465,8 @@ pci_vfio_map_resource(struct rte_pci_device *dev)
 			void *map_addr = NULL;
 			if (memreg[0].size) {
 				/* actual map of first part */
-				map_addr = pci_map_resource(bar_addr, vfio_dev_fd,
+				map_addr = rte_eal_map_resource(bar_addr,
+							    vfio_dev_fd,
 							    memreg[0].offset,
 							    memreg[0].size,
 							    MAP_FIXED);
@@ -477,7 +478,7 @@ pci_vfio_map_resource(struct rte_pci_device *dev)
 				void *second_addr = RTE_PTR_ADD(bar_addr,
 								memreg[1].offset -
 								(uintptr_t)reg.offset);
-				map_addr = pci_map_resource(second_addr,
+				map_addr = rte_eal_map_resource(second_addr,
 							    vfio_dev_fd, memreg[1].offset,
 							    memreg[1].size,
 							    MAP_FIXED);
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 83721ba..22b5b59 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -174,6 +174,8 @@ DPDK_16.11 {
 	rte_delay_us_callback_register;
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
+	rte_eal_map_resource;
+	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
 
-- 
2.7.4

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

* [PATCH v5 03/21] eal/linux: generalize PCI kernel unbinding driver to EAL
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 01/21] eal: generalize PCI kernel driver enum to EAL Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 02/21] eal: generalize PCI map/unmap resource " Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 04/21] eal/linux: generalize PCI kernel driver extraction " Shreyansh Jain
                         ` (18 subsequent siblings)
  21 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev; +Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain

From: Jan Viktorin <viktorin@rehivetech.com>

Generalize the PCI-specific pci_unbind_kernel_driver. It is now divided
into two parts. First, determination of the path and string identification
of the device to be unbound. Second, the actual unbind operation which is
generic.

BSD implementation updated as ENOTSUP

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
--
Changes since v2:
 - update BSD support for unbind kernel driver
---
 lib/librte_eal/bsdapp/eal/eal.c       |  7 +++++++
 lib/librte_eal/bsdapp/eal/eal_pci.c   |  4 ++--
 lib/librte_eal/common/eal_private.h   | 13 +++++++++++++
 lib/librte_eal/linuxapp/eal/eal.c     | 26 ++++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/eal_pci.c | 33 +++++++++------------------------
 5 files changed, 57 insertions(+), 26 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 35e3117..5271fc2 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -633,3 +633,10 @@ rte_eal_process_type(void)
 {
 	return rte_config.process_type;
 }
+
+int
+rte_eal_unbind_kernel_driver(const char *devpath __rte_unused,
+			     const char *devid __rte_unused)
+{
+	return -ENOTSUP;
+}
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 7ed0115..703f034 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -89,11 +89,11 @@
 
 /* unbind kernel driver for this device */
 int
-pci_unbind_kernel_driver(struct rte_pci_device *dev __rte_unused)
+pci_unbind_kernel_driver(struct rte_pci_device *dev)
 {
 	RTE_LOG(ERR, EAL, "RTE_PCI_DRV_FORCE_UNBIND flag is not implemented "
 		"for BSD\n");
-	return -ENOTSUP;
+	return rte_eal_unbind_kernel_driver(dev);
 }
 
 /* Map pci device */
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 9e7d8f6..b0c208a 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -256,6 +256,19 @@ int rte_eal_alarm_init(void);
 int rte_eal_check_module(const char *module_name);
 
 /**
+ * Unbind kernel driver bound to the device specified by the given devpath,
+ * and its string identification.
+ *
+ * @param devpath  path to the device directory ("/sys/.../devices/<name>")
+ * @param devid    identification of the device (<name>)
+ *
+ * @return
+ *      -1  unbind has failed
+ *       0  module has been unbound
+ */
+int rte_eal_unbind_kernel_driver(const char *devpath, const char *devid);
+
+/**
  * Get cpu core_id.
  *
  * This function is private to the EAL.
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 2075282..5f6676d 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -943,3 +943,29 @@ rte_eal_check_module(const char *module_name)
 	/* Module has been found */
 	return 1;
 }
+
+int
+rte_eal_unbind_kernel_driver(const char *devpath, const char *devid)
+{
+	char filename[PATH_MAX];
+	FILE *f;
+
+	snprintf(filename, sizeof(filename),
+		 "%s/driver/unbind", devpath);
+
+	f = fopen(filename, "w");
+	if (f == NULL) /* device was not bound */
+		return 0;
+
+	if (fwrite(devid, strlen(devid), 1, f) == 0) {
+		RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
+				filename);
+		goto error;
+	}
+
+	fclose(f);
+	return 0;
+error:
+	fclose(f);
+	return -1;
+}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index 876ba38..a03553f 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -59,38 +59,23 @@ int
 pci_unbind_kernel_driver(struct rte_pci_device *dev)
 {
 	int n;
-	FILE *f;
-	char filename[PATH_MAX];
-	char buf[BUFSIZ];
+	char devpath[PATH_MAX];
+	char devid[BUFSIZ];
 	struct rte_pci_addr *loc = &dev->addr;
 
-	/* open /sys/bus/pci/devices/AAAA:BB:CC.D/driver */
-	snprintf(filename, sizeof(filename),
-		"%s/" PCI_PRI_FMT "/driver/unbind", pci_get_sysfs_path(),
+	/* devpath /sys/bus/pci/devices/AAAA:BB:CC.D */
+	snprintf(devpath, sizeof(devpath),
+		"%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
 		loc->domain, loc->bus, loc->devid, loc->function);
 
-	f = fopen(filename, "w");
-	if (f == NULL) /* device was not bound */
-		return 0;
-
-	n = snprintf(buf, sizeof(buf), PCI_PRI_FMT "\n",
+	n = snprintf(devid, sizeof(devid), PCI_PRI_FMT "\n",
 	             loc->domain, loc->bus, loc->devid, loc->function);
-	if ((n < 0) || (n >= (int)sizeof(buf))) {
+	if ((n < 0) || (n >= (int)sizeof(devid))) {
 		RTE_LOG(ERR, EAL, "%s(): snprintf failed\n", __func__);
-		goto error;
-	}
-	if (fwrite(buf, n, 1, f) == 0) {
-		RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
-				filename);
-		goto error;
+		return -1;
 	}
 
-	fclose(f);
-	return 0;
-
-error:
-	fclose(f);
-	return -1;
+	return rte_eal_unbind_kernel_driver(devpath, devid);
 }
 
 static int
-- 
2.7.4

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

* [PATCH v5 04/21] eal/linux: generalize PCI kernel driver extraction to EAL
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
                         ` (2 preceding siblings ...)
  2016-10-24 11:59       ` [PATCH v5 03/21] eal/linux: generalize PCI kernel unbinding driver " Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 05/21] eal: define container macro Shreyansh Jain
                         ` (17 subsequent siblings)
  21 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev; +Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain

From: Jan Viktorin <viktorin@rehivetech.com>

Generalize the PCI-specific pci_get_kernel_driver_by_path. The function
is general enough, we have just moved it to eal.c, changed the prefix to
rte_eal and provided it privately to other parts of EAL.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_eal/bsdapp/eal/eal.c       |  7 +++++++
 lib/librte_eal/common/eal_private.h   | 14 ++++++++++++++
 lib/librte_eal/linuxapp/eal/eal.c     | 29 +++++++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/eal_pci.c | 31 +------------------------------
 4 files changed, 51 insertions(+), 30 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 5271fc2..9b93da3 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -640,3 +640,10 @@ rte_eal_unbind_kernel_driver(const char *devpath __rte_unused,
 {
 	return -ENOTSUP;
 }
+
+int
+rte_eal_get_kernel_driver_by_path(const char *filename __rte_unused,
+				  char *dri_name __rte_unused)
+{
+	return -ENOTSUP;
+}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index b0c208a..c8c2131 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -269,6 +269,20 @@ int rte_eal_check_module(const char *module_name);
 int rte_eal_unbind_kernel_driver(const char *devpath, const char *devid);
 
 /**
+ * Extract the kernel driver name from the absolute path to the driver.
+ *
+ * @param filename  path to the driver ("<path-to-device>/driver")
+ * @path  dri_name  target buffer where to place the driver name
+ *                  (should be at least PATH_MAX long)
+ *
+ * @return
+ *      -1   on failure
+ *       0   when successful
+ *       1   when there is no such driver
+ */
+int rte_eal_get_kernel_driver_by_path(const char *filename, char *dri_name);
+
+/**
  * Get cpu core_id.
  *
  * This function is private to the EAL.
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 5f6676d..00af21c 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -969,3 +969,32 @@ error:
 	fclose(f);
 	return -1;
 }
+
+int
+rte_eal_get_kernel_driver_by_path(const char *filename, char *dri_name)
+{
+	int count;
+	char path[PATH_MAX];
+	char *name;
+
+	if (!filename || !dri_name)
+		return -1;
+
+	count = readlink(filename, path, PATH_MAX);
+	if (count >= PATH_MAX)
+		return -1;
+
+	/* For device does not have a driver */
+	if (count < 0)
+		return 1;
+
+	path[count] = '\0';
+
+	name = strrchr(path, '/');
+	if (name) {
+		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
+		return 0;
+	}
+
+	return -1;
+}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index a03553f..e1cf9e8 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -78,35 +78,6 @@ pci_unbind_kernel_driver(struct rte_pci_device *dev)
 	return rte_eal_unbind_kernel_driver(devpath, devid);
 }
 
-static int
-pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
-{
-	int count;
-	char path[PATH_MAX];
-	char *name;
-
-	if (!filename || !dri_name)
-		return -1;
-
-	count = readlink(filename, path, PATH_MAX);
-	if (count >= PATH_MAX)
-		return -1;
-
-	/* For device does not have a driver */
-	if (count < 0)
-		return 1;
-
-	path[count] = '\0';
-
-	name = strrchr(path, '/');
-	if (name) {
-		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
-		return 0;
-	}
-
-	return -1;
-}
-
 /* Map pci device */
 int
 rte_eal_pci_map_device(struct rte_pci_device *dev)
@@ -354,7 +325,7 @@ pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus,
 
 	/* parse driver */
 	snprintf(filename, sizeof(filename), "%s/driver", dirname);
-	ret = pci_get_kernel_driver_by_path(filename, driver);
+	ret = rte_eal_get_kernel_driver_by_path(filename, driver);
 	if (ret < 0) {
 		RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
 		free(dev);
-- 
2.7.4

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

* [PATCH v5 05/21] eal: define container macro
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
                         ` (3 preceding siblings ...)
  2016-10-24 11:59       ` [PATCH v5 04/21] eal/linux: generalize PCI kernel driver extraction " Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 06/21] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
                         ` (16 subsequent siblings)
  21 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev; +Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain

From: Jan Viktorin <viktorin@rehivetech.com>

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_eal/common/include/rte_common.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h
index db5ac91..8152bd9 100644
--- a/lib/librte_eal/common/include/rte_common.h
+++ b/lib/librte_eal/common/include/rte_common.h
@@ -331,6 +331,24 @@ rte_bsf32(uint32_t v)
 #define offsetof(TYPE, MEMBER)  __builtin_offsetof (TYPE, MEMBER)
 #endif
 
+/**
+ * Return pointer to the wrapping struct instance.
+ * Example:
+ *
+ *  struct wrapper {
+ *      ...
+ *      struct child c;
+ *      ...
+ *  };
+ *
+ *  struct child *x = obtain(...);
+ *  struct wrapper *w = container_of(x, struct wrapper, c);
+ */
+#ifndef container_of
+#define container_of(p, type, member) \
+	((type *) (((char *) (p)) - offsetof(type, member)))
+#endif
+
 #define _RTE_STR(x) #x
 /** Take a macro value and get a string version of it */
 #define RTE_STR(x) _RTE_STR(x)
-- 
2.7.4

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

* [PATCH v5 06/21] eal/soc: introduce very essential SoC infra definitions
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
                         ` (4 preceding siblings ...)
  2016-10-24 11:59       ` [PATCH v5 05/21] eal: define container macro Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-24 16:21         ` Jan Viktorin
  2016-10-24 11:59       ` [PATCH v5 07/21] eal/soc: add SoC PMD register/unregister logic Shreyansh Jain
                         ` (15 subsequent siblings)
  21 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

Define initial structures and functions for the SoC infrastructure.
This patch supports only a very minimal functions for now.
More features will be added in the following commits.

Includes rte_device/rte_driver inheritance of
rte_soc_device/rte_soc_driver.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 app/test/Makefile                       |   1 +
 app/test/test_soc.c                     |  90 +++++++++++++++++++++
 lib/librte_eal/common/Makefile          |   2 +-
 lib/librte_eal/common/eal_private.h     |   4 +
 lib/librte_eal/common/include/rte_soc.h | 138 ++++++++++++++++++++++++++++++++
 5 files changed, 234 insertions(+), 1 deletion(-)
 create mode 100644 app/test/test_soc.c
 create mode 100644 lib/librte_eal/common/include/rte_soc.h

diff --git a/app/test/Makefile b/app/test/Makefile
index 5be023a..30295af 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -77,6 +77,7 @@ APP = test
 #
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) := commands.c
 SRCS-y += test.c
+SRCS-y += test_soc.c
 SRCS-y += resource.c
 SRCS-y += test_resource.c
 test_resource.res: test_resource.c
diff --git a/app/test/test_soc.c b/app/test/test_soc.c
new file mode 100644
index 0000000..916a863
--- /dev/null
+++ b/app/test/test_soc.c
@@ -0,0 +1,90 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <sys/queue.h>
+
+#include <rte_soc.h>
+#include <rte_devargs.h>
+#include <rte_debug.h>
+
+#include "test.h"
+
+static char *safe_strdup(const char *s)
+{
+	char *c = strdup(s);
+
+	if (c == NULL)
+		rte_panic("failed to strdup '%s'\n", s);
+
+	return c;
+}
+
+static int test_compare_addr(void)
+{
+	struct rte_soc_addr a0;
+	struct rte_soc_addr a1;
+	struct rte_soc_addr a2;
+
+	a0.name = safe_strdup("ethernet0");
+	a0.fdt_path = NULL;
+
+	a1.name = safe_strdup("ethernet0");
+	a1.fdt_path = NULL;
+
+	a2.name = safe_strdup("ethernet1");
+	a2.fdt_path = NULL;
+
+	TEST_ASSERT(!rte_eal_compare_soc_addr(&a0, &a1),
+		    "Failed to compare two soc addresses that equal");
+	TEST_ASSERT(rte_eal_compare_soc_addr(&a0, &a2),
+		    "Failed to compare two soc addresses that differs");
+
+	free(a2.name);
+	free(a1.name);
+	free(a0.name);
+	return 0;
+}
+
+static int
+test_soc(void)
+{
+	if (test_compare_addr())
+		return -1;
+
+	return 0;
+}
+
+REGISTER_TEST_COMMAND(soc_autotest, test_soc);
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index dfd64aa..b414008 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 INC := rte_branch_prediction.h rte_common.h
 INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
-INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
+INC += rte_log.h rte_memory.h rte_memzone.h rte_soc.h rte_pci.h
 INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index c8c2131..0e8d6f7 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -36,6 +36,7 @@
 
 #include <stdio.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 
 /**
  * Initialize the memzone subsystem (private to eal).
@@ -118,6 +119,9 @@ int rte_eal_log_init(const char *id, int facility);
  */
 int rte_eal_pci_init(void);
 
+struct rte_soc_driver;
+struct rte_soc_device;
+
 struct rte_pci_driver;
 struct rte_pci_device;
 
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
new file mode 100644
index 0000000..bc0a43b
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -0,0 +1,138 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_SOC_H_
+#define _RTE_SOC_H_
+
+/**
+ * @file
+ *
+ * RTE SoC Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include <rte_dev.h>
+#include <rte_debug.h>
+
+struct rte_soc_id {
+	const char *compatible; /**< OF compatible specification */
+	uint64_t priv_data;     /**< SoC Driver specific data */
+};
+
+struct rte_soc_addr {
+	char *name;     /**< name used in sysfs */
+	char *fdt_path; /**< path to the associated node in FDT */
+};
+
+/**
+ * A structure describing a SoC device.
+ */
+struct rte_soc_device {
+	TAILQ_ENTRY(rte_soc_device) next;   /**< Next probed SoC device */
+	struct rte_device device;           /**< Inherit code device */
+	struct rte_soc_addr addr;           /**< SoC device Location */
+	struct rte_soc_id *id;              /**< SoC device ID list */
+	struct rte_soc_driver *driver;      /**< Associated driver */
+};
+
+struct rte_soc_driver;
+
+/**
+ * Initialization function for the driver called during SoC probing.
+ */
+typedef int (soc_devinit_t)(struct rte_soc_driver *, struct rte_soc_device *);
+
+/**
+ * Uninitialization function for the driver called during hotplugging.
+ */
+typedef int (soc_devuninit_t)(struct rte_soc_device *);
+
+/**
+ * A structure describing a SoC driver.
+ */
+struct rte_soc_driver {
+	TAILQ_ENTRY(rte_soc_driver) next;  /**< Next in list */
+	struct rte_driver driver;          /**< Inherit core driver. */
+	soc_devinit_t *devinit;            /**< Device initialization */
+	soc_devuninit_t *devuninit;        /**< Device uninitialization */
+	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
+};
+
+/**
+ * Utility function to write a SoC device name, this device name can later be
+ * used to retrieve the corresponding rte_soc_addr using above functions.
+ *
+ * @param addr
+ *	The SoC address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ * @return
+ *  0 on success, negative on error.
+ */
+static inline void
+rte_eal_soc_device_name(const struct rte_soc_addr *addr,
+			char *output, size_t size)
+{
+	int ret;
+
+	RTE_VERIFY(addr != NULL);
+	RTE_VERIFY(size >= strlen(addr->name));
+	ret = snprintf(output, size, "%s", addr->name);
+	RTE_VERIFY(ret >= 0);
+}
+
+static inline int
+rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
+			 const struct rte_soc_addr *a1)
+{
+	if (a0 == NULL || a1 == NULL)
+		return -1;
+
+	RTE_VERIFY(a0->name != NULL);
+	RTE_VERIFY(a1->name != NULL);
+
+	return strcmp(a0->name, a1->name);
+}
+
+#endif
-- 
2.7.4

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

* [PATCH v5 07/21] eal/soc: add SoC PMD register/unregister logic
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
                         ` (5 preceding siblings ...)
  2016-10-24 11:59       ` [PATCH v5 06/21] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 08/21] eal/soc: implement SoC device list and dump Shreyansh Jain
                         ` (14 subsequent siblings)
  21 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

Registeration of a SoC driver through a helper RTE_PMD_REGISTER_SOC
(on the lines of RTE_PMD_REGISTER_PCI). soc_driver_list stores all the
registered drivers.

Test case has been introduced to verify the registration and
deregistration.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: update PMD registration method]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 app/test/test_soc.c                             | 111 ++++++++++++++++++++++++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   3 +
 lib/librte_eal/common/eal_common_soc.c          |  56 ++++++++++++
 lib/librte_eal/common/include/rte_soc.h         |  26 ++++++
 lib/librte_eal/linuxapp/eal/Makefile            |   1 +
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   3 +
 6 files changed, 200 insertions(+)
 create mode 100644 lib/librte_eal/common/eal_common_soc.c

diff --git a/app/test/test_soc.c b/app/test/test_soc.c
index 916a863..ac03e64 100644
--- a/app/test/test_soc.c
+++ b/app/test/test_soc.c
@@ -75,6 +75,108 @@ static int test_compare_addr(void)
 	free(a2.name);
 	free(a1.name);
 	free(a0.name);
+
+	return 0;
+}
+
+/**
+ * Empty PMD driver based on the SoC infra.
+ *
+ * The rte_soc_device is usually wrapped in some higher-level struct
+ * (eth_driver). We simulate such a wrapper with an anonymous struct here.
+ */
+struct test_wrapper {
+	struct rte_soc_driver soc_drv;
+};
+
+struct test_wrapper empty_pmd0 = {
+	.soc_drv = {
+		.driver = {
+			.name = "empty_pmd0"
+		},
+	},
+};
+
+struct test_wrapper empty_pmd1 = {
+	.soc_drv = {
+		.driver = {
+			.name = "empty_pmd1"
+		},
+	},
+};
+
+static int
+count_registered_socdrvs(void)
+{
+	int i;
+	struct rte_soc_driver *drv;
+
+	i = 0;
+	TAILQ_FOREACH(drv, &soc_driver_list, next)
+		i += 1;
+
+	return i;
+}
+
+static int
+test_register_unregister(void)
+{
+	struct rte_soc_driver *drv;
+	int count;
+
+	rte_eal_soc_register(&empty_pmd0.soc_drv);
+
+	TEST_ASSERT(!TAILQ_EMPTY(&soc_driver_list),
+		    "No PMD is present but the empty_pmd0 should be there");
+	drv = TAILQ_FIRST(&soc_driver_list);
+	TEST_ASSERT(!strcmp(drv->driver.name, "empty_pmd0"),
+		    "The registered PMD is not empty_pmd0 but '%s'",
+		drv->driver.name);
+
+	rte_eal_soc_register(&empty_pmd1.soc_drv);
+
+	count = count_registered_socdrvs();
+	TEST_ASSERT_EQUAL(count, 2, "Expected 2 PMDs but detected %d", count);
+
+	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
+	count = count_registered_socdrvs();
+	TEST_ASSERT_EQUAL(count, 1, "Expected 1 PMDs but detected %d", count);
+
+	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
+
+	printf("%s has been successful\n", __func__);
+	return 0;
+}
+
+/* save real devices and drivers until the tests finishes */
+struct soc_driver_list real_soc_driver_list =
+	TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
+
+static int test_soc_setup(void)
+{
+	struct rte_soc_driver *drv;
+
+	/* no real drivers for the test */
+	while (!TAILQ_EMPTY(&soc_driver_list)) {
+		drv = TAILQ_FIRST(&soc_driver_list);
+		rte_eal_soc_unregister(drv);
+		TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
+	}
+
+	return 0;
+}
+
+static int test_soc_cleanup(void)
+{
+	struct rte_soc_driver *drv;
+
+	/* bring back real drivers after the test */
+	while (!TAILQ_EMPTY(&real_soc_driver_list)) {
+		drv = TAILQ_FIRST(&real_soc_driver_list);
+		TAILQ_REMOVE(&real_soc_driver_list, drv, next);
+		rte_eal_soc_register(drv);
+	}
+
 	return 0;
 }
 
@@ -84,6 +186,15 @@ test_soc(void)
 	if (test_compare_addr())
 		return -1;
 
+	if (test_soc_setup())
+		return -1;
+
+	if (test_register_unregister())
+		return -1;
+
+	if (test_soc_cleanup())
+		return -1;
+
 	return 0;
 }
 
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 11d9f59..cf6fb8e 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -171,8 +171,11 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_register;
+	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
+	soc_driver_list;
 
 } DPDK_16.07;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
new file mode 100644
index 0000000..56135ed
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -0,0 +1,56 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/queue.h>
+
+#include <rte_log.h>
+
+#include "eal_private.h"
+
+/* Global SoC driver list */
+struct soc_driver_list soc_driver_list =
+	TAILQ_HEAD_INITIALIZER(soc_driver_list);
+
+/* register a driver */
+void
+rte_eal_soc_register(struct rte_soc_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_eal_soc_unregister(struct rte_soc_driver *driver)
+{
+	TAILQ_REMOVE(&soc_driver_list, driver, next);
+}
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index bc0a43b..d17b20f 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -51,8 +51,14 @@ extern "C" {
 #include <string.h>
 
 #include <rte_dev.h>
+#include <rte_eal.h>
 #include <rte_debug.h>
 
+extern struct soc_driver_list soc_driver_list;
+/**< Global list of SoC Drivers */
+
+TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
+
 struct rte_soc_id {
 	const char *compatible; /**< OF compatible specification */
 	uint64_t priv_data;     /**< SoC Driver specific data */
@@ -135,4 +141,24 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 	return strcmp(a0->name, a1->name);
 }
 
+/**
+ * Register a SoC driver.
+ */
+void rte_eal_soc_register(struct rte_soc_driver *driver);
+
+/** Helper for SoC device registeration from PMD Drivers */
+#define RTE_PMD_REGISTER_SOC(nm, soc_drv) \
+RTE_INIT(socinitfn_ ##name); \
+static void socinitfn_ ##name(void) \
+{\
+	(soc_drv).driver.name = RTE_STR(nm);\
+	rte_eal_soc_register(&soc_drv); \
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+/**
+ * Unregister a SoC driver.
+ */
+void rte_eal_soc_unregister(struct rte_soc_driver *driver);
+
 #endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 4e206f0..a520477 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -77,6 +77,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 22b5b59..ab6b985 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -175,8 +175,11 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_register;
+	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
+	soc_driver_list;
 
 } DPDK_16.07;
-- 
2.7.4

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

* [PATCH v5 08/21] eal/soc: implement SoC device list and dump
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
                         ` (6 preceding siblings ...)
  2016-10-24 11:59       ` [PATCH v5 07/21] eal/soc: add SoC PMD register/unregister logic Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 09/21] eal: introduce command line enable SoC option Shreyansh Jain
                         ` (13 subsequent siblings)
  21 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

SoC devices would be linked in a separate list (from PCI). This is used for
probe function.
A helper for dumping the device list is added.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  2 ++
 lib/librte_eal/common/eal_common_soc.c          | 34 +++++++++++++++++++++++++
 lib/librte_eal/common/include/rte_soc.h         |  9 +++++++
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  2 ++
 4 files changed, 47 insertions(+)

diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index cf6fb8e..86e3cfd 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -171,11 +171,13 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_dump;
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
+	soc_device_list;
 	soc_driver_list;
 
 } DPDK_16.07;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 56135ed..5dcddc5 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -31,6 +31,8 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <stddef.h>
+#include <stdio.h>
 #include <sys/queue.h>
 
 #include <rte_log.h>
@@ -40,6 +42,38 @@
 /* Global SoC driver list */
 struct soc_driver_list soc_driver_list =
 	TAILQ_HEAD_INITIALIZER(soc_driver_list);
+struct soc_device_list soc_device_list =
+	TAILQ_HEAD_INITIALIZER(soc_device_list);
+
+/* dump one device */
+static int
+soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
+{
+	int i;
+
+	fprintf(f, "%s", dev->addr.name);
+	fprintf(f, " - fdt_path: %s\n",
+			dev->addr.fdt_path ? dev->addr.fdt_path : "(none)");
+
+	for (i = 0; dev->id && dev->id[i].compatible; ++i)
+		fprintf(f, "   %s\n", dev->id[i].compatible);
+
+	return 0;
+}
+
+/* dump devices on the bus to an output stream */
+void
+rte_eal_soc_dump(FILE *f)
+{
+	struct rte_soc_device *dev = NULL;
+
+	if (!f)
+		return;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		soc_dump_one_device(f, dev);
+	}
+}
 
 /* register a driver */
 void
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index d17b20f..4a01af5 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -56,8 +56,12 @@ extern "C" {
 
 extern struct soc_driver_list soc_driver_list;
 /**< Global list of SoC Drivers */
+extern struct soc_device_list soc_device_list;
+/**< Global list of SoC Devices */
 
 TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
+TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
+
 
 struct rte_soc_id {
 	const char *compatible; /**< OF compatible specification */
@@ -142,6 +146,11 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 }
 
 /**
+ * Dump discovered SoC devices.
+ */
+void rte_eal_soc_dump(FILE *f);
+
+/**
  * Register a SoC driver.
  */
 void rte_eal_soc_register(struct rte_soc_driver *driver);
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index ab6b985..0155025 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -175,11 +175,13 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_dump;
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
+	soc_device_list;
 	soc_driver_list;
 
 } DPDK_16.07;
-- 
2.7.4

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

* [PATCH v5 09/21] eal: introduce command line enable SoC option
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
                         ` (7 preceding siblings ...)
  2016-10-24 11:59       ` [PATCH v5 08/21] eal/soc: implement SoC device list and dump Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 10/21] eal/soc: init SoC infra from EAL Shreyansh Jain
                         ` (12 subsequent siblings)
  21 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

Support --enable-soc. SoC support is disabled by default.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: Change --no-soc to --enable-soc; disabled by default]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 doc/guides/testpmd_app_ug/run_app.rst      | 4 ++++
 lib/librte_eal/common/eal_common_options.c | 5 +++++
 lib/librte_eal/common/eal_internal_cfg.h   | 1 +
 lib/librte_eal/common/eal_options.h        | 2 ++
 4 files changed, 12 insertions(+)

diff --git a/doc/guides/testpmd_app_ug/run_app.rst b/doc/guides/testpmd_app_ug/run_app.rst
index d7c5120..4dafe5f 100644
--- a/doc/guides/testpmd_app_ug/run_app.rst
+++ b/doc/guides/testpmd_app_ug/run_app.rst
@@ -156,6 +156,10 @@ See the DPDK Getting Started Guides for more information on these options.
 
     Use malloc instead of hugetlbfs.
 
+*   ``--enable-soc``
+
+    Enable SoC framework support
+
 
 Testpmd Command-line Options
 ----------------------------
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 6ca8af1..2156ab3 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -75,6 +75,7 @@ const struct option
 eal_long_options[] = {
 	{OPT_BASE_VIRTADDR,     1, NULL, OPT_BASE_VIRTADDR_NUM    },
 	{OPT_CREATE_UIO_DEV,    0, NULL, OPT_CREATE_UIO_DEV_NUM   },
+	{OPT_ENABLE_SOC,        0, NULL, OPT_ENABLE_SOC_NUM       },
 	{OPT_FILE_PREFIX,       1, NULL, OPT_FILE_PREFIX_NUM      },
 	{OPT_HELP,              0, NULL, OPT_HELP_NUM             },
 	{OPT_HUGE_DIR,          1, NULL, OPT_HUGE_DIR_NUM         },
@@ -843,6 +844,10 @@ eal_parse_common_option(int opt, const char *optarg,
 		break;
 
 	/* long options */
+	case OPT_ENABLE_SOC_NUM:
+		conf->enable_soc = 1;
+		break;
+
 	case OPT_HUGE_UNLINK_NUM:
 		conf->hugepage_unlink = 1;
 		break;
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 5f1367e..2a6e3ea 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -67,6 +67,7 @@ struct internal_config {
 	unsigned hugepage_unlink;         /**< true to unlink backing files */
 	volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
 	volatile unsigned no_pci;         /**< true to disable PCI */
+	volatile unsigned enable_soc;     /**< true to enable SoC */
 	volatile unsigned no_hpet;        /**< true to disable HPET */
 	volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
 										* instead of native TSC */
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index a881c62..6e679c3 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -49,6 +49,8 @@ enum {
 	OPT_BASE_VIRTADDR_NUM,
 #define OPT_CREATE_UIO_DEV    "create-uio-dev"
 	OPT_CREATE_UIO_DEV_NUM,
+#define OPT_ENABLE_SOC        "enable-soc"
+	OPT_ENABLE_SOC_NUM,
 #define OPT_FILE_PREFIX       "file-prefix"
 	OPT_FILE_PREFIX_NUM,
 #define OPT_HUGE_DIR          "huge-dir"
-- 
2.7.4

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

* [PATCH v5 10/21] eal/soc: init SoC infra from EAL
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
                         ` (8 preceding siblings ...)
  2016-10-24 11:59       ` [PATCH v5 09/21] eal: introduce command line enable SoC option Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 11/21] eal/soc: implement probing of drivers Shreyansh Jain
                         ` (11 subsequent siblings)
  21 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/bsdapp/eal/Makefile    |  1 +
 lib/librte_eal/bsdapp/eal/eal.c       |  4 +++
 lib/librte_eal/bsdapp/eal/eal_soc.c   | 46 ++++++++++++++++++++++++++++
 lib/librte_eal/common/eal_private.h   | 10 +++++++
 lib/librte_eal/linuxapp/eal/Makefile  |  1 +
 lib/librte_eal/linuxapp/eal/eal.c     |  3 ++
 lib/librte_eal/linuxapp/eal/eal_soc.c | 56 +++++++++++++++++++++++++++++++++++
 7 files changed, 121 insertions(+)
 create mode 100644 lib/librte_eal/bsdapp/eal/eal_soc.c
 create mode 100644 lib/librte_eal/linuxapp/eal/eal_soc.c

diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index a15b762..42b3a2b 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -56,6 +56,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_hugepage_info.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_pci.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_timer.c
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 9b93da3..2d62b9d 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -64,6 +64,7 @@
 #include <rte_string_fns.h>
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
+#include <rte_soc.h>
 #include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
@@ -564,6 +565,9 @@ rte_eal_init(int argc, char **argv)
 	if (rte_eal_pci_init() < 0)
 		rte_panic("Cannot init PCI\n");
 
+	if (rte_eal_soc_init() < 0)
+		rte_panic("Cannot init SoC\n");
+
 	eal_check_mem_on_local_socket();
 
 	if (eal_plugins_init() < 0)
diff --git a/lib/librte_eal/bsdapp/eal/eal_soc.c b/lib/librte_eal/bsdapp/eal/eal_soc.c
new file mode 100644
index 0000000..cb297ff
--- /dev/null
+++ b/lib/librte_eal/bsdapp/eal/eal_soc.c
@@ -0,0 +1,46 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <rte_common.h>
+#include <rte_log.h>
+
+#include <eal_private.h>
+
+/* Init the SoC EAL subsystem */
+int
+rte_eal_soc_init(void)
+{
+	return 0;
+}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 0e8d6f7..d810f9f 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -122,6 +122,16 @@ int rte_eal_pci_init(void);
 struct rte_soc_driver;
 struct rte_soc_device;
 
+/**
+ * Init the SoC infra.
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int rte_eal_soc_init(void);
+
 struct rte_pci_driver;
 struct rte_pci_device;
 
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index a520477..59e30fa 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -65,6 +65,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio_mp_sync.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_vfio.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 00af21c..098ba02 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -810,6 +810,9 @@ rte_eal_init(int argc, char **argv)
 		rte_panic("Cannot init VFIO\n");
 #endif
 
+	if (rte_eal_soc_init() < 0)
+		rte_panic("Cannot init SoC\n");
+
 	if (rte_eal_memory_init() < 0)
 		rte_panic("Cannot init memory\n");
 
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
new file mode 100644
index 0000000..04848b9
--- /dev/null
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -0,0 +1,56 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <rte_log.h>
+#include <rte_soc.h>
+
+#include "eal_internal_cfg.h"
+#include "eal_filesystem.h"
+#include "eal_private.h"
+
+/* Init the SoC EAL subsystem */
+int
+rte_eal_soc_init(void)
+{
+	return 0;
+}
-- 
2.7.4

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

* [PATCH v5 11/21] eal/soc: implement probing of drivers
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
                         ` (9 preceding siblings ...)
  2016-10-24 11:59       ` [PATCH v5 10/21] eal/soc: init SoC infra from EAL Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 12/21] eal/soc: extend and utilize devargs Shreyansh Jain
                         ` (10 subsequent siblings)
  21 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

Each SoC PMD registers a set of callback for scanning its own bus/infra and
matching devices to drivers when probe is called.
This patch introduces the infra for calls to SoC scan on rte_eal_soc_init()
and match on rte_eal_soc_probe().

Patch also adds test case for scan and probe.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
--
v4:
 - Update test_soc for descriptive test function names
 - Comments over test functions
 - devinit and devuninint --> probe/remove
 - RTE_VERIFY at some places
---
 app/test/test_soc.c                             | 205 ++++++++++++++++++++++-
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   4 +
 lib/librte_eal/common/eal_common_soc.c          | 213 +++++++++++++++++++++++-
 lib/librte_eal/common/include/rte_soc.h         |  83 ++++++++-
 lib/librte_eal/linuxapp/eal/eal.c               |   5 +
 lib/librte_eal/linuxapp/eal/eal_soc.c           |  21 ++-
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   4 +
 7 files changed, 523 insertions(+), 12 deletions(-)

diff --git a/app/test/test_soc.c b/app/test/test_soc.c
index ac03e64..b587d5e 100644
--- a/app/test/test_soc.c
+++ b/app/test/test_soc.c
@@ -87,14 +87,65 @@ static int test_compare_addr(void)
  */
 struct test_wrapper {
 	struct rte_soc_driver soc_drv;
+	struct rte_soc_device soc_dev;
 };
 
+static int empty_pmd0_probe(struct rte_soc_driver *drv,
+			      struct rte_soc_device *dev);
+static int empty_pmd0_remove(struct rte_soc_device *dev);
+
+static void always_find_dev0_cb(void);
+static int match_dev0_by_name(struct rte_soc_driver *drv,
+				  struct rte_soc_device *dev);
+
+static void always_find_dev1_cb(void);
+static int match_dev1_by_name(struct rte_soc_driver *drv,
+				  struct rte_soc_device *dev);
+
+/**
+ * Dummy probe handler for PMD driver 'pmd0'.
+ *
+ * @param drv
+ *	driver object
+ * @param dev
+ *	device object
+ * @return
+ *	0 on success
+ */
+static int
+empty_pmd0_probe(struct rte_soc_driver *drv __rte_unused,
+		   struct rte_soc_device *dev __rte_unused)
+{
+	return 0;
+}
+
+/**
+ * Remove handler for PMD driver 'pmd0'.
+ *
+ * @param dev
+ *	device to remove
+ * @return
+ *	0 on success
+ */
+static int
+empty_pmd0_remove(struct rte_soc_device *dev)
+{
+	/* Release the memory associated with dev->addr.name */
+	free(dev->addr.name);
+
+	return 0;
+}
+
 struct test_wrapper empty_pmd0 = {
 	.soc_drv = {
 		.driver = {
 			.name = "empty_pmd0"
 		},
-	},
+		.probe = empty_pmd0_probe,
+		.remove = empty_pmd0_remove,
+		.scan_fn = always_find_dev0_cb,
+		.match_fn = match_dev0_by_name,
+	}
 };
 
 struct test_wrapper empty_pmd1 = {
@@ -102,9 +153,87 @@ struct test_wrapper empty_pmd1 = {
 		.driver = {
 			.name = "empty_pmd1"
 		},
+		.scan_fn = always_find_dev1_cb,
+		.match_fn = match_dev1_by_name,
 	},
 };
 
+/**
+ * Bus scan by PMD 'pmd0' for adding device 'dev0'
+ *
+ * @param void
+ * @return void
+ */
+static void
+always_find_dev0_cb(void)
+{
+	/* SoC's scan would scan devices on its bus and add to
+	 * soc_device_list
+	 */
+	empty_pmd0.soc_dev.addr.name = strdup("empty_pmd0_dev");
+
+	TAILQ_INSERT_TAIL(&soc_device_list, &empty_pmd0.soc_dev, next);
+}
+
+/**
+ * Match device 'dev0' with driver PMD pmd0
+ *
+ * @param drv
+ *	Driver with this matching needs to be done; unused here
+ * @param dev
+ *	device to be matched against driver
+ * @return
+ *	0 on successful matched
+ *	1 if driver<=>device don't match
+ */
+static int
+match_dev0_by_name(struct rte_soc_driver *drv __rte_unused,
+		       struct rte_soc_device *dev)
+{
+	if (!dev->addr.name || strcmp(dev->addr.name, "empty_pmd0_dev"))
+		return 0;
+
+	return 1;
+}
+
+/**
+ * Bus scan by PMD 'pmd0' for adding device 'dev1'
+ *
+ * @param void
+ * @return void
+ */
+static void
+always_find_dev1_cb(void)
+{
+	/* SoC's scan would scan devices on its bus and add to
+	 * soc_device_list
+	 */
+	empty_pmd0.soc_dev.addr.name = strdup("empty_pmd1_dev");
+
+	TAILQ_INSERT_TAIL(&soc_device_list, &empty_pmd1.soc_dev, next);
+}
+
+/**
+ * Match device 'dev1' with driver PMD pmd0
+ *
+ * @param drv
+ *	Driver with this matching needs to be done; unused here
+ * @param dev
+ *	device to be matched against driver
+ * @return
+ *	0 on successful matched
+ *	1 if driver<=>device don't match
+ */
+static int
+match_dev1_by_name(struct rte_soc_driver *drv __rte_unused,
+		       struct rte_soc_device *dev)
+{
+	if (!dev->addr.name || strcmp(dev->addr.name, "empty_pmd1_dev"))
+		return 0;
+
+	return 1;
+}
+
 static int
 count_registered_socdrvs(void)
 {
@@ -148,13 +277,68 @@ test_register_unregister(void)
 	return 0;
 }
 
+/* Test Probe (scan and match) functionality */
+static int
+test_soc_scan_and_match(void)
+{
+	int drv_count = 0;
+	struct rte_soc_driver *drv;
+
+	/* Registering dummy drivers */
+	rte_eal_soc_register(&empty_pmd0.soc_drv);
+	rte_eal_soc_register(&empty_pmd1.soc_drv);
+	/* Assuming that test_register_unregister is working, not verifying
+	 * that drivers are indeed registered
+	*/
+
+	/* rte_eal_soc_init is called by rte_eal_init, which in turn calls the
+	 * scan_fn of each driver.
+	 */
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		if (drv && drv->scan_fn)
+			drv->scan_fn();
+		drv_count++;
+	}
+
+	/* rte_eal_init() would perform other inits here */
+
+	/* Probe would link the SoC devices<=>drivers */
+	rte_eal_soc_probe();
+
+	/* Unregistering dummy drivers */
+	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
+	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
+
+	/* Verify the Unregistering has removed the driver from list */
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		if (drv)
+			drv_count--;
+	}
+
+	free(empty_pmd0.soc_dev.addr.name);
+
+	/* If drv_count is anything other than 0, Unregistering failed */
+	if (drv_count) {
+		printf("%s has failed\n", __func__);
+		return 1;
+	}
+
+	printf("%s has been successful\n", __func__);
+	return 0;
+}
+
 /* save real devices and drivers until the tests finishes */
 struct soc_driver_list real_soc_driver_list =
 	TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
 
+/* save real devices and drivers until the tests finishes */
+struct soc_device_list real_soc_device_list =
+	TAILQ_HEAD_INITIALIZER(real_soc_device_list);
+
 static int test_soc_setup(void)
 {
 	struct rte_soc_driver *drv;
+	struct rte_soc_device *dev;
 
 	/* no real drivers for the test */
 	while (!TAILQ_EMPTY(&soc_driver_list)) {
@@ -163,12 +347,20 @@ static int test_soc_setup(void)
 		TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
 	}
 
+	/* And, no real devices for the test */
+	while (!TAILQ_EMPTY(&soc_device_list)) {
+		dev = TAILQ_FIRST(&soc_device_list);
+		TAILQ_REMOVE(&soc_device_list, dev, next);
+		TAILQ_INSERT_TAIL(&real_soc_device_list, dev, next);
+	}
+
 	return 0;
 }
 
 static int test_soc_cleanup(void)
 {
 	struct rte_soc_driver *drv;
+	struct rte_soc_device *dev;
 
 	/* bring back real drivers after the test */
 	while (!TAILQ_EMPTY(&real_soc_driver_list)) {
@@ -177,6 +369,13 @@ static int test_soc_cleanup(void)
 		rte_eal_soc_register(drv);
 	}
 
+	/* And, bring back real devices after the test */
+	while (!TAILQ_EMPTY(&real_soc_device_list)) {
+		dev = TAILQ_FIRST(&real_soc_device_list);
+		TAILQ_REMOVE(&real_soc_device_list, dev, next);
+		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+	}
+
 	return 0;
 }
 
@@ -192,6 +391,10 @@ test_soc(void)
 	if (test_register_unregister())
 		return -1;
 
+	/* Assuming test_register_unregister has succeeded */
+	if (test_soc_scan_and_match())
+		return -1;
+
 	if (test_soc_cleanup())
 		return -1;
 
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 86e3cfd..dfbb1ac 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -171,7 +171,11 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_detach;
 	rte_eal_soc_dump;
+	rte_eal_soc_match;
+	rte_eal_soc_probe;
+	rte_eal_soc_probe_one;
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 5dcddc5..256cef8 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -36,6 +36,8 @@
 #include <sys/queue.h>
 
 #include <rte_log.h>
+#include <rte_common.h>
+#include <rte_soc.h>
 
 #include "eal_private.h"
 
@@ -45,6 +47,208 @@ struct soc_driver_list soc_driver_list =
 struct soc_device_list soc_device_list =
 	TAILQ_HEAD_INITIALIZER(soc_device_list);
 
+int
+rte_eal_soc_match_compat(struct rte_soc_driver *drv,
+			 struct rte_soc_device *dev)
+{
+	int i, j;
+
+	RTE_VERIFY(drv != NULL && drv->id_table != NULL);
+	RTE_VERIFY(dev != NULL && dev->id != NULL);
+
+	for (i = 0; drv->id_table[i].compatible; ++i) {
+		const char *drv_compat = drv->id_table[i].compatible;
+
+		for (j = 0; dev->id[j].compatible; ++j) {
+			const char *dev_compat = dev->id[j].compatible;
+
+			if (!strcmp(drv_compat, dev_compat))
+				return 0;
+		}
+	}
+
+	return 1;
+}
+
+static int
+rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
+			     struct rte_soc_device *dev)
+{
+	int ret = 1;
+
+	RTE_VERIFY(drv->match_fn);
+
+	ret = drv->match_fn(drv, dev);
+	if (ret) {
+		RTE_LOG(DEBUG, EAL,
+			" match function failed, skipping\n");
+		return ret;
+	}
+
+	dev->driver = drv;
+	RTE_VERIFY(drv->probe != NULL);
+	return drv->probe(drv, dev);
+}
+
+static int
+soc_probe_all_drivers(struct rte_soc_device *dev)
+{
+	struct rte_soc_driver *drv = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		rc = rte_eal_soc_probe_one_driver(drv, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+/* If the IDs match, call the remove() function of the driver. */
+static int
+rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
+		       struct rte_soc_device *dev)
+{
+	int ret;
+
+	if ((drv == NULL) || (dev == NULL))
+		return -EINVAL;
+
+	ret = drv->match_fn(drv, dev);
+	if (ret) {
+		RTE_LOG(DEBUG, EAL, " driver (%s) didn't match device (%s)\n",
+			drv->driver.name, dev->addr.name);
+		return ret;
+	}
+
+	RTE_LOG(DEBUG, EAL, "SoC device %s\n",
+		dev->addr.name);
+
+	RTE_LOG(DEBUG, EAL, "  remove driver: %s\n", drv->driver.name);
+
+	if (drv->remove && (drv->remove(dev) < 0))
+		return -1;	/* negative value is an error */
+
+	/* clear driver structure */
+	dev->driver = NULL;
+
+	return 0;
+}
+
+/*
+ * Call the remove() function of all registered drivers for the device.
+ *
+ * @param dev
+ *	Device for which detach is to be performed
+ * @return
+ *       0 when successful
+ *      -1 if deinitialization fails
+ *       1 if no driver is found for this device.
+ */
+static int
+soc_detach_all_drivers(struct rte_soc_device *dev)
+{
+	struct rte_soc_driver *dr = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dr, &soc_driver_list, next) {
+		rc = rte_eal_soc_detach_dev(dr, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+int
+rte_eal_soc_detach(const struct rte_soc_addr *addr)
+{
+	struct rte_soc_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		if (rte_eal_compare_soc_addr(&dev->addr, addr))
+			continue;
+
+		ret = soc_detach_all_drivers(dev);
+		if (ret < 0)
+			goto err_return;
+
+		TAILQ_REMOVE(&soc_device_list, dev, next);
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL, "Requested device %s cannot be used\n",
+		dev->addr.name);
+	return -1;
+}
+
+int
+rte_eal_soc_probe_one(const struct rte_soc_addr *addr)
+{
+	struct rte_soc_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		if (rte_eal_compare_soc_addr(&dev->addr, addr))
+			continue;
+
+		ret = soc_probe_all_drivers(dev);
+		if (ret < 0)
+			goto err_return;
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL,
+		"Requested device %s cannot be used\n", addr->name);
+	return -1;
+}
+
+int
+rte_eal_soc_probe(void)
+{
+	struct rte_soc_device *dev = NULL;
+	int ret = 0;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		ret = soc_probe_all_drivers(dev);
+		if (ret < 0) {
+			RTE_LOG(DEBUG, EAL, "Requested device %s"
+				 " cannot be used\n", dev->addr.name);
+			/* Failure for a particular device is logged and
+			 * ignored
+			 */
+		}
+	}
+
+	return ret;
+}
+
 /* dump one device */
 static int
 soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
@@ -61,7 +265,6 @@ soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
 	return 0;
 }
 
-/* dump devices on the bus to an output stream */
 void
 rte_eal_soc_dump(FILE *f)
 {
@@ -75,14 +278,18 @@ rte_eal_soc_dump(FILE *f)
 	}
 }
 
-/* register a driver */
 void
 rte_eal_soc_register(struct rte_soc_driver *driver)
 {
+	/* For a valid soc driver, match and scan function
+	 * should be provided.
+	 */
+	RTE_VERIFY(driver != NULL);
+	RTE_VERIFY(driver->match_fn != NULL);
+	RTE_VERIFY(driver->scan_fn != NULL);
 	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
 }
 
-/* unregister a driver */
 void
 rte_eal_soc_unregister(struct rte_soc_driver *driver)
 {
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 4a01af5..030df6f 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -62,7 +62,6 @@ extern struct soc_device_list soc_device_list;
 TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
 TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
 
-
 struct rte_soc_id {
 	const char *compatible; /**< OF compatible specification */
 	uint64_t priv_data;     /**< SoC Driver specific data */
@@ -89,12 +88,29 @@ struct rte_soc_driver;
 /**
  * Initialization function for the driver called during SoC probing.
  */
-typedef int (soc_devinit_t)(struct rte_soc_driver *, struct rte_soc_device *);
+typedef int (soc_probe_t)(struct rte_soc_driver *, struct rte_soc_device *);
 
 /**
  * Uninitialization function for the driver called during hotplugging.
  */
-typedef int (soc_devuninit_t)(struct rte_soc_device *);
+typedef int (soc_remove_t)(struct rte_soc_device *);
+
+/**
+ * SoC device scan callback, called from rte_eal_soc_init.
+ * For various SoC, the bus on which devices are attached maynot be compliant
+ * to a standard platform (or platform bus itself). In which case, extra
+ * steps are implemented by PMD to scan over the bus and add devices to SoC
+ * device list.
+ */
+typedef void (soc_scan_t)(void);
+
+/**
+ * Custom device<=>driver match callback for SoC
+ * Unlike PCI, SoC devices don't have a fixed definition of device
+ * identification. PMDs can implement a specific matching function in which
+ * driver and device objects are provided to perform custom match.
+ */
+typedef int (soc_match_t)(struct rte_soc_driver *, struct rte_soc_device *);
 
 /**
  * A structure describing a SoC driver.
@@ -102,8 +118,10 @@ typedef int (soc_devuninit_t)(struct rte_soc_device *);
 struct rte_soc_driver {
 	TAILQ_ENTRY(rte_soc_driver) next;  /**< Next in list */
 	struct rte_driver driver;          /**< Inherit core driver. */
-	soc_devinit_t *devinit;            /**< Device initialization */
-	soc_devuninit_t *devuninit;        /**< Device uninitialization */
+	soc_probe_t *probe;                 /**< Device probe */
+	soc_remove_t *remove;               /**< Device remove */
+	soc_scan_t *scan_fn;                /**< Callback for scanning SoC bus*/
+	soc_match_t *match_fn;              /**< Callback to match dev<->drv */
 	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
 };
 
@@ -146,12 +164,63 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 }
 
 /**
+ * Default function for matching the Soc driver with device. Each driver can
+ * either use this function or define their own soc matching function.
+ * This function relies on the compatible string extracted from sysfs. But,
+ * a SoC might have different way of identifying its devices. Such SoC can
+ * override match_fn.
+ *
+ * @return
+ *	 0 on success
+ *	-1 when no match found
+  */
+int
+rte_eal_soc_match_compat(struct rte_soc_driver *drv,
+			 struct rte_soc_device *dev);
+
+/**
+ * Probe SoC devices for registered drivers.
+ *
+ * @return
+ *	0 on success
+ *	!0 in case of any failure in probe
+ */
+int rte_eal_soc_probe(void);
+
+/**
+ * Probe the single SoC device.
+ */
+int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
+
+/**
+ * Close the single SoC device.
+ *
+ * Scan the SoC devices and find the SoC device specified by the SoC
+ * address, then call the remove() function for registered driver
+ * that has a matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The SoC address to close.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_eal_soc_detach(const struct rte_soc_addr *addr);
+
+/**
  * Dump discovered SoC devices.
+ *
+ * @param f
+ *	File to dump device info in.
  */
 void rte_eal_soc_dump(FILE *f);
 
 /**
  * Register a SoC driver.
+ *
+ * @param driver
+ *	Object for SoC driver to register
+ * @return void
  */
 void rte_eal_soc_register(struct rte_soc_driver *driver);
 
@@ -167,6 +236,10 @@ RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
 
 /**
  * Unregister a SoC driver.
+ *
+ * @param driver
+ *	Object for SoC driver to unregister
+ * @return void
  */
 void rte_eal_soc_unregister(struct rte_soc_driver *driver);
 
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 098ba02..bd775f3 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -70,6 +70,7 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_common.h>
@@ -890,6 +891,10 @@ rte_eal_init(int argc, char **argv)
 	if (rte_eal_pci_probe())
 		rte_panic("Cannot probe PCI\n");
 
+	/* Probe & Initialize SoC devices */
+	if (rte_eal_soc_probe())
+		rte_panic("Cannot probe SoC\n");
+
 	rte_eal_mcfg_complete();
 
 	return fctret;
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index 04848b9..3929a76 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -44,13 +44,28 @@
 #include <rte_log.h>
 #include <rte_soc.h>
 
-#include "eal_internal_cfg.h"
-#include "eal_filesystem.h"
-#include "eal_private.h"
+#include <eal_internal_cfg.h>
+#include <eal_filesystem.h>
+#include <eal_private.h>
 
 /* Init the SoC EAL subsystem */
 int
 rte_eal_soc_init(void)
 {
+	struct rte_soc_driver *drv;
+
+	/* SoC is disabled by default */
+	if (!internal_config.enable_soc)
+		return 0;
+
+	/* For each registered driver, call their scan routine to perform any
+	 * custom scan for devices (for example, custom buses)
+	 */
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		RTE_VERIFY(drv->scan_fn);
+		drv->scan_fn();
+		/* Ignore all errors from this */
+	}
+
 	return 0;
 }
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 0155025..c28e093 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -175,7 +175,11 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_detach;
 	rte_eal_soc_dump;
+	rte_eal_soc_match;
+	rte_eal_soc_probe;
+	rte_eal_soc_probe_one;
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
-- 
2.7.4

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

* [PATCH v5 12/21] eal/soc: extend and utilize devargs
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
                         ` (10 preceding siblings ...)
  2016-10-24 11:59       ` [PATCH v5 11/21] eal/soc: implement probing of drivers Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 13/21] eal/soc: add drv_flags Shreyansh Jain
                         ` (9 subsequent siblings)
  21 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

It is assumed that SoC Devices provided on command line are prefixed with
"soc:". This patch adds parse and attach support for such devices.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/common/eal_common_dev.c      | 27 +++++++++----
 lib/librte_eal/common/eal_common_devargs.c  | 17 ++++++++
 lib/librte_eal/common/eal_common_soc.c      | 61 ++++++++++++++++++++++++-----
 lib/librte_eal/common/include/rte_devargs.h |  8 ++++
 lib/librte_eal/common/include/rte_soc.h     | 24 ++++++++++++
 5 files changed, 120 insertions(+), 17 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 457d227..ebbcf47 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -107,17 +107,23 @@ rte_eal_dev_init(void)
 
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
-	struct rte_pci_addr addr;
+	struct rte_soc_addr soc_addr;
+	struct rte_pci_addr pci_addr;
 
 	if (name == NULL || devargs == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
 		return -EINVAL;
 	}
 
-	if (eal_parse_pci_DomBDF(name, &addr) == 0) {
-		if (rte_eal_pci_probe_one(&addr) < 0)
+	memset(&soc_addr, 0, sizeof(soc_addr));
+	if (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+		if (rte_eal_soc_probe_one(&soc_addr) < 0) {
+			free(soc_addr.name);
+			goto err;
+		}
+	} else if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+		if (rte_eal_pci_probe_one(&pci_addr) < 0)
 			goto err;
-
 	} else {
 		if (rte_eal_vdev_init(name, devargs))
 			goto err;
@@ -132,15 +138,22 @@ err:
 
 int rte_eal_dev_detach(const char *name)
 {
-	struct rte_pci_addr addr;
+	struct rte_soc_addr soc_addr;
+	struct rte_pci_addr pci_addr;
 
 	if (name == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device provided.\n");
 		return -EINVAL;
 	}
 
-	if (eal_parse_pci_DomBDF(name, &addr) == 0) {
-		if (rte_eal_pci_detach(&addr) < 0)
+	memset(&soc_addr, 0, sizeof(soc_addr));
+	if (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+		if (rte_eal_soc_detach(&soc_addr) < 0) {
+			free(soc_addr.name);
+			goto err;
+		}
+	} else if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+		if (rte_eal_pci_detach(&pci_addr) < 0)
 			goto err;
 	} else {
 		if (rte_eal_vdev_uninit(name))
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index e403717..e1dae1a 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -41,6 +41,7 @@
 #include <string.h>
 
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_devargs.h>
 #include "eal_private.h"
 
@@ -105,6 +106,14 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
 			goto fail;
 
 		break;
+
+	case RTE_DEVTYPE_WHITELISTED_SOC:
+	case RTE_DEVTYPE_BLACKLISTED_SOC:
+		/* try to parse soc device with prefix "soc:" */
+		if (rte_eal_parse_soc_spec(buf, &devargs->soc.addr) != 0)
+			goto fail;
+		break;
+
 	case RTE_DEVTYPE_VIRTUAL:
 		/* save driver name */
 		ret = snprintf(devargs->virt.drv_name,
@@ -166,6 +175,14 @@ rte_eal_devargs_dump(FILE *f)
 			       devargs->pci.addr.devid,
 			       devargs->pci.addr.function,
 			       devargs->args);
+		else if (devargs->type == RTE_DEVTYPE_WHITELISTED_SOC)
+			fprintf(f, "  SoC whitelist %s %s\n",
+			       devargs->soc.addr.name,
+			       devargs->soc.addr.fdt_path);
+		else if (devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC)
+			fprintf(f, "  SoC blacklist %s %s\n",
+			       devargs->soc.addr.name,
+			       devargs->soc.addr.fdt_path);
 		else if (devargs->type == RTE_DEVTYPE_VIRTUAL)
 			fprintf(f, "  VIRTUAL %s %s\n",
 			       devargs->virt.drv_name,
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 256cef8..44f5559 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -37,6 +37,8 @@
 
 #include <rte_log.h>
 #include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_eal.h>
 #include <rte_soc.h>
 
 #include "eal_private.h"
@@ -70,6 +72,21 @@ rte_eal_soc_match_compat(struct rte_soc_driver *drv,
 	return 1;
 }
 
+static struct rte_devargs *soc_devargs_lookup(struct rte_soc_device *dev)
+{
+	struct rte_devargs *devargs;
+
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->type != RTE_DEVTYPE_BLACKLISTED_SOC &&
+			devargs->type != RTE_DEVTYPE_WHITELISTED_SOC)
+			continue;
+		if (!rte_eal_compare_soc_addr(&dev->addr, &devargs->soc.addr))
+			return devargs;
+	}
+
+	return NULL;
+}
+
 static int
 rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
 			     struct rte_soc_device *dev)
@@ -85,6 +102,18 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
 		return ret;
 	}
 
+	RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %d\n",
+			dev->addr.name, dev->device.numa_node);
+	RTE_LOG(DEBUG, EAL, "  probe driver %s\n", drv->driver.name);
+
+	/* no initialization when blacklisted, return without error */
+	if (dev->device.devargs != NULL
+		&& dev->device.devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC) {
+		RTE_LOG(DEBUG, EAL,
+			"  device is blacklisted, skipping\n");
+		return ret;
+	}
+
 	dev->driver = drv;
 	RTE_VERIFY(drv->probe != NULL);
 	return drv->probe(drv, dev);
@@ -129,8 +158,8 @@ rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
 		return ret;
 	}
 
-	RTE_LOG(DEBUG, EAL, "SoC device %s\n",
-		dev->addr.name);
+	RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %i\n",
+			dev->addr.name, dev->device.numa_node);
 
 	RTE_LOG(DEBUG, EAL, "  remove driver: %s\n", drv->driver.name);
 
@@ -233,17 +262,29 @@ int
 rte_eal_soc_probe(void)
 {
 	struct rte_soc_device *dev = NULL;
+	struct rte_devargs *devargs = NULL;
 	int ret = 0;
+	int probe_all = 0;
+
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_SOC) == 0)
+		probe_all = 1;
 
 	TAILQ_FOREACH(dev, &soc_device_list, next) {
-		ret = soc_probe_all_drivers(dev);
-		if (ret < 0) {
-			RTE_LOG(DEBUG, EAL, "Requested device %s"
-				 " cannot be used\n", dev->addr.name);
-			/* Failure for a particular device is logged and
-			 * ignored
-			 */
-		}
+
+		/* set devargs in SoC structure */
+		devargs = soc_devargs_lookup(dev);
+		if (devargs != NULL)
+			dev->device.devargs = devargs;
+
+		/* probe all or only whitelisted devices */
+		if (probe_all)
+			ret = soc_probe_all_drivers(dev);
+		else if (devargs != NULL &&
+			devargs->type == RTE_DEVTYPE_WHITELISTED_SOC)
+			ret = soc_probe_all_drivers(dev);
+		if (ret < 0)
+			rte_exit(EXIT_FAILURE, "Requested device %s "
+				 "cannot be used\n", dev->addr.name);
 	}
 
 	return ret;
diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h
index 88120a1..b5dd436 100644
--- a/lib/librte_eal/common/include/rte_devargs.h
+++ b/lib/librte_eal/common/include/rte_devargs.h
@@ -51,6 +51,7 @@ extern "C" {
 #include <stdio.h>
 #include <sys/queue.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 
 /**
  * Type of generic device
@@ -58,6 +59,8 @@ extern "C" {
 enum rte_devtype {
 	RTE_DEVTYPE_WHITELISTED_PCI,
 	RTE_DEVTYPE_BLACKLISTED_PCI,
+	RTE_DEVTYPE_WHITELISTED_SOC,
+	RTE_DEVTYPE_BLACKLISTED_SOC,
 	RTE_DEVTYPE_VIRTUAL,
 };
 
@@ -83,6 +86,11 @@ struct rte_devargs {
 			/** PCI location. */
 			struct rte_pci_addr addr;
 		} pci;
+		/** Used if type is RTE_DEVTYPE_*_SOC. */
+		struct {
+			/** SoC location. */
+			struct rte_soc_addr addr;
+		} soc;
 		/** Used if type is RTE_DEVTYPE_VIRTUAL. */
 		struct {
 			/** Driver name. */
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 030df6f..90cd6aa 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -164,6 +164,30 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 }
 
 /**
+ * Parse a specification of a soc device. The specification must differentiate
+ * a SoC device specification from the PCI bus and virtual devices. We assume
+ * a SoC specification starts with "soc:". The function allocates the name
+ * entry of the given addr.
+ *
+ * @return
+ *      -  0 on success
+ *      -  1 when not a SoC spec
+ *      - -1 on failure
+ */
+static inline int
+rte_eal_parse_soc_spec(const char *spec, struct rte_soc_addr *addr)
+{
+	if (strstr(spec, "soc:") == spec) {
+		addr->name = strdup(spec + 4);
+		if (addr->name == NULL)
+			return -1;
+		return 0;
+	}
+
+	return 1;
+}
+
+/**
  * Default function for matching the Soc driver with device. Each driver can
  * either use this function or define their own soc matching function.
  * This function relies on the compatible string extracted from sysfs. But,
-- 
2.7.4

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

* [PATCH v5 13/21] eal/soc: add drv_flags
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
                         ` (11 preceding siblings ...)
  2016-10-24 11:59       ` [PATCH v5 12/21] eal/soc: extend and utilize devargs Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 14/21] eal/soc: add intr_handle Shreyansh Jain
                         ` (8 subsequent siblings)
  21 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

The flags are copied from the PCI ones. They should be refactorized into a
general set of flags in the future.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/common/include/rte_soc.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 90cd6aa..415d409 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -123,8 +123,18 @@ struct rte_soc_driver {
 	soc_scan_t *scan_fn;                /**< Callback for scanning SoC bus*/
 	soc_match_t *match_fn;              /**< Callback to match dev<->drv */
 	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
+	uint32_t drv_flags;                /**< Control handling of device */
 };
 
+/** Device needs to map its resources by EAL */
+#define RTE_SOC_DRV_NEED_MAPPING 0x0001
+/** Device needs to be unbound even if no module is provieded */
+#define RTE_SOC_DRV_FORCE_UNBIND 0x0004
+/** Device driver supports link state interrupt */
+#define RTE_SOC_DRV_INTR_LSC	 0x0008
+/** Device driver supports detaching capability */
+#define RTE_SOC_DRV_DETACHABLE	 0x0010
+
 /**
  * Utility function to write a SoC device name, this device name can later be
  * used to retrieve the corresponding rte_soc_addr using above functions.
-- 
2.7.4

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

* [PATCH v5 14/21] eal/soc: add intr_handle
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
                         ` (12 preceding siblings ...)
  2016-10-24 11:59       ` [PATCH v5 13/21] eal/soc: add drv_flags Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 15/21] eal/soc: add default scan for Soc devices Shreyansh Jain
                         ` (7 subsequent siblings)
  21 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/common/include/rte_soc.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 415d409..1f5f81b 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -53,6 +53,7 @@ extern "C" {
 #include <rte_dev.h>
 #include <rte_eal.h>
 #include <rte_debug.h>
+#include <rte_interrupts.h>
 
 extern struct soc_driver_list soc_driver_list;
 /**< Global list of SoC Drivers */
@@ -80,6 +81,7 @@ struct rte_soc_device {
 	struct rte_device device;           /**< Inherit code device */
 	struct rte_soc_addr addr;           /**< SoC device Location */
 	struct rte_soc_id *id;              /**< SoC device ID list */
+	struct rte_intr_handle intr_handle; /**< Interrupt handle */
 	struct rte_soc_driver *driver;      /**< Associated driver */
 };
 
-- 
2.7.4

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

* [PATCH v5 15/21] eal/soc: add default scan for Soc devices
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
                         ` (13 preceding siblings ...)
  2016-10-24 11:59       ` [PATCH v5 14/21] eal/soc: add intr_handle Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 16/21] eal/soc: additional features for SoC Shreyansh Jain
                         ` (6 subsequent siblings)
  21 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev; +Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain

From: Jan Viktorin <viktorin@rehivetech.com>

Default implementation which scans the sysfs platform devices hierarchy.
For each device, extract the ueven and convert into rte_soc_device.

The information populated can then be used in probe to match against
the drivers registered.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: restructure commit to be an optional implementation]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>

--
 v5:
 - Update rte_eal_soc_scan to rte_eal_soc_scan_platform_bus
 - Fix comments over scan and match functions
---
 lib/librte_eal/common/include/rte_soc.h |  16 +-
 lib/librte_eal/linuxapp/eal/eal_soc.c   | 315 ++++++++++++++++++++++++++++++++
 2 files changed, 329 insertions(+), 2 deletions(-)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 1f5f81b..a9b3129 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -64,7 +64,10 @@ TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
 TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
 
 struct rte_soc_id {
-	const char *compatible; /**< OF compatible specification */
+	union {
+		const char *compatible; /**< OF compatible specification */
+		char *_compatible;
+	};
 	uint64_t priv_data;     /**< SoC Driver specific data */
 };
 
@@ -200,7 +203,16 @@ rte_eal_parse_soc_spec(const char *spec, struct rte_soc_addr *addr)
 }
 
 /**
- * Default function for matching the Soc driver with device. Each driver can
+ * Helper function for scanning for new SoC devices on platform bus.
+ *
+ * @return
+ * 	0 on success
+ *	!0 on failure to scan
+ */
+int rte_eal_soc_scan_platform_bus(void);
+
+/**
+ * Helper function for matching the Soc driver with device. Each driver can
  * either use this function or define their own soc matching function.
  * This function relies on the compatible string extracted from sysfs. But,
  * a SoC might have different way of identifying its devices. Such SoC can
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index 3929a76..d8dfe97 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -48,6 +48,321 @@
 #include <eal_filesystem.h>
 #include <eal_private.h>
 
+/** Pathname of SoC devices directory. */
+#define SYSFS_SOC_DEVICES "/sys/bus/platform/devices"
+
+static const char *
+soc_get_sysfs_path(void)
+{
+	const char *path = NULL;
+
+	path = getenv("SYSFS_SOC_DEVICES");
+	if (path == NULL)
+		return SYSFS_SOC_DEVICES;
+
+	return path;
+}
+
+static char *
+dev_read_uevent(const char *dirname)
+{
+	char filename[PATH_MAX];
+	struct stat st;
+	char *buf;
+	ssize_t total = 0;
+	int fd;
+
+	snprintf(filename, sizeof(filename), "%s/uevent", dirname);
+	fd = open(filename, O_RDONLY);
+	if (fd < 0) {
+		RTE_LOG(WARNING, EAL, "Failed to open file %s\n", filename);
+		return strdup("");
+	}
+
+	if (fstat(fd, &st) < 0) {
+		RTE_LOG(ERR, EAL, "Failed to stat file %s\n", filename);
+		close(fd);
+		return NULL;
+	}
+
+	if (st.st_size == 0) {
+		close(fd);
+		return strdup("");
+	}
+
+	buf = malloc(st.st_size + 1);
+	if (buf == NULL) {
+		RTE_LOG(ERR, EAL, "Failed to alloc memory to read %s\n",
+			filename);
+		close(fd);
+		return NULL;
+	}
+
+	while (total < st.st_size) {
+		ssize_t rlen = read(fd, buf + total, st.st_size - total);
+		if (rlen < 0) {
+			if (errno == EINTR)
+				continue;
+
+			RTE_LOG(ERR, EAL, "Failed to read file %s\n", filename);
+
+			free(buf);
+			close(fd);
+			return NULL;
+		}
+		if (rlen == 0) /* EOF */
+			break;
+
+		total += rlen;
+	}
+
+	buf[total] = '\0';
+	close(fd);
+
+	return buf;
+}
+
+static const char *
+dev_uevent_find(const char *uevent, const char *key)
+{
+	const size_t keylen = strlen(key);
+	const size_t total = strlen(uevent);
+	const char *p = uevent;
+
+	/* check whether it is the first key */
+	if (!strncmp(uevent, key, keylen))
+		return uevent + keylen;
+
+	/* check 2nd key or further... */
+	do {
+		p = strstr(p, key);
+		if (p == NULL)
+			break;
+
+		if (p[-1] == '\n') /* check we are at a new line */
+			return p + keylen;
+
+		p += keylen; /* skip this one */
+	} while (p - uevent < (ptrdiff_t) total);
+
+	return NULL;
+}
+
+static char *
+strdup_until_nl(const char *p)
+{
+	const char *nl = strchr(p, '\n');
+	if (nl == NULL)
+		return strdup(p); /* no newline, copy until '\0' */
+
+	return strndup(p, nl - p);
+}
+
+static int
+dev_parse_uevent(struct rte_soc_device *dev, const char *uevent)
+{
+	const char *of;
+	const char *compat_n;
+	char *err;
+	long n;
+	char compat[strlen("OF_COMPATIBLE_NNNN=")];
+	long i;
+
+	of = dev_uevent_find(uevent, "OF_FULLNAME=");
+	if (of == NULL)
+		return 1; /* don't care about this device */
+
+	dev->addr.fdt_path = strdup_until_nl(of);
+	if (dev->addr.fdt_path == NULL) {
+		RTE_LOG(ERR, PMD,
+			"Failed to alloc memory for fdt_path\n");
+		return -1;
+	}
+
+	RTE_LOG(DEBUG, EAL, "Detected device %s (%s)\n",
+			dev->addr.name, dev->addr.fdt_path);
+
+	compat_n = dev_uevent_find(uevent, "OF_COMPATIBLE_N=");
+	if (compat_n == NULL) {
+		RTE_LOG(ERR, EAL, "No OF_COMPATIBLE_N found\n");
+		return -1;
+	}
+
+	n = strtoul(compat_n, &err, 0);
+	if (*err != '\n' && err != NULL) {
+		RTE_LOG(ERR, EAL, "Failed to parse OF_COMPATIBLE_N: %.10s\n",
+			err);
+		goto fail_fdt_path;
+	}
+
+	if (n == 0)
+		return 1; /* cannot match anything */
+	if (n > 9999) { /* match NNNN */
+		RTE_LOG(ERR, EAL, "OF_COMPATIBLE_N is invalid: %ld\n", n);
+		goto fail_fdt_path;
+	}
+
+	dev->id = calloc(n + 1, sizeof(*dev->id));
+	if (dev->id == NULL) {
+		RTE_LOG(ERR, PMD, "Failed to alloc memory for ID\n");
+		free(dev->addr.fdt_path);
+		return -1;
+	}
+
+	for (i = 0; i < n; ++i) {
+		snprintf(compat, sizeof(compat), "OF_COMPATIBLE_%lu=", i);
+		const char *val;
+
+		val = dev_uevent_find(uevent, compat);
+		if (val == NULL) {
+			RTE_LOG(ERR, EAL, "%s was not found\n", compat);
+			goto fail_id;
+		}
+
+		dev->id[i]._compatible = strdup_until_nl(val);
+		if (dev->id[i]._compatible == NULL) {
+			RTE_LOG(ERR, PMD,
+				"Failed to alloc memory for compatible\n");
+			goto fail_id;
+		}
+
+		RTE_LOG(DEBUG, EAL, "  compatible: %s\n",
+				dev->id[i].compatible);
+	}
+
+	dev->id[n]._compatible = NULL; /* mark last one */
+
+	return 0;
+
+fail_id:
+	while (i-- >= 0)
+		free(dev->id[i]._compatible);
+	free(dev->id);
+fail_fdt_path:
+	free(dev->addr.fdt_path);
+	return -1;
+}
+
+static void
+dev_content_free(struct rte_soc_device *dev)
+{
+	int i;
+
+	if (dev->addr.fdt_path)
+		free(dev->addr.fdt_path);
+
+	if (dev->id != NULL) {
+		for (i = 0; dev->id[i]._compatible; ++i)
+			free(dev->id[i]._compatible);
+
+		free(dev->id);
+		dev->id = NULL;
+	}
+}
+
+/**
+ * Scan one SoC sysfs entry, and fill the devices list from it.
+ * We require to have the uevent file with records: OF_FULLNAME and
+ * OF_COMPATIBLE array (with at least one entry). Otherwise, such device
+ * is skipped.
+ */
+static int
+soc_scan_one(const char *dirname, const char *name)
+{
+	struct rte_soc_device *dev;
+	char *uevent;
+	int ret;
+
+	uevent = dev_read_uevent(dirname);
+	if (uevent == NULL)
+		return -1;
+
+	if (uevent[0] == '\0') {
+		/* ignore directory without uevent file */
+		free(uevent);
+		return 1;
+	}
+
+	dev = malloc(sizeof(*dev) + strlen(name) + 1);
+	if (dev == NULL) {
+		RTE_LOG(ERR, PMD, "Failed to alloc memory for %s\n", name);
+		free(uevent);
+		return -1;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	dev->addr.name = (char *) (dev + 1);
+	strcpy(dev->addr.name, name);
+
+	ret = dev_parse_uevent(dev, uevent);
+	if (ret)
+		goto fail;
+	free(uevent); /* not needed anymore */
+
+	/* device is valid, add in list (sorted) */
+	if (TAILQ_EMPTY(&soc_device_list)) {
+		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+	} else {
+		struct rte_soc_device *dev2;
+
+		TAILQ_FOREACH(dev2, &soc_device_list, next) {
+			ret = rte_eal_compare_soc_addr(&dev->addr, &dev2->addr);
+			if (ret > 0)
+				continue;
+
+			if (ret < 0) {
+				TAILQ_INSERT_BEFORE(dev2, dev, next);
+			} else { /* already registered */
+				dev_content_free(dev2);
+				dev2->addr.fdt_path = dev->addr.fdt_path;
+				dev2->id = dev->id;
+				free(dev);
+			}
+			return 0;
+		}
+		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+	}
+
+	return 0;
+
+fail:
+	free(uevent);
+	dev_content_free(dev);
+	free(dev);
+	return ret;
+}
+
+int
+rte_eal_soc_scan_platform_bus(void)
+{
+	struct dirent *e;
+	DIR *dir;
+	char dirname[PATH_MAX];
+
+	dir = opendir(soc_get_sysfs_path());
+	if (dir == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
+			__func__, strerror(errno));
+		return -1;
+	}
+
+	while ((e = readdir(dir)) != NULL) {
+		if (e->d_name[0] == '.')
+			continue;
+
+		snprintf(dirname, sizeof(dirname), "%s/%s",
+				soc_get_sysfs_path(), e->d_name);
+		if (soc_scan_one(dirname, e->d_name) < 0)
+			goto error;
+	}
+	closedir(dir);
+	return 0;
+
+error:
+	closedir(dir);
+	return -1;
+}
+
 /* Init the SoC EAL subsystem */
 int
 rte_eal_soc_init(void)
-- 
2.7.4

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

* [PATCH v5 16/21] eal/soc: additional features for SoC
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
                         ` (14 preceding siblings ...)
  2016-10-24 11:59       ` [PATCH v5 15/21] eal/soc: add default scan for Soc devices Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 17/21] ether: utilize container_of for pci_drv Shreyansh Jain
                         ` (5 subsequent siblings)
  21 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev; +Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain

From: Jan Viktorin <viktorin@rehivetech.com>

Additional features introduced:
 - Find kernel driver through sysfs bindings
 - Dummy implementation for mapping to kernel driver
 - DMA coherency value from sysfs
 - Numa node number from sysfs
 - Support for updating device during probe if already registered

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: merge multiple patches into single set]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_eal/common/eal_common_soc.c  |  30 ++++++++
 lib/librte_eal/common/eal_private.h     |  23 ++++++
 lib/librte_eal/common/include/rte_soc.h |  28 +++++++
 lib/librte_eal/linuxapp/eal/eal_soc.c   | 129 ++++++++++++++++++++++++++++++++
 4 files changed, 210 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 44f5559..29c38e0 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -114,6 +114,26 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
 		return ret;
 	}
 
+	if (!dev->is_dma_coherent) {
+		if (!(drv->drv_flags & RTE_SOC_DRV_ACCEPT_NONCC)) {
+			RTE_LOG(DEBUG, EAL,
+				"  device is not DMA coherent, skipping\n");
+			return 1;
+		}
+	}
+
+	if (drv->drv_flags & RTE_SOC_DRV_NEED_MAPPING) {
+		/* map resources */
+		ret = rte_eal_soc_map_device(dev);
+		if (ret)
+			return ret;
+	} else if (drv->drv_flags & RTE_SOC_DRV_FORCE_UNBIND
+		&& rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		/* unbind */
+		if (soc_unbind_kernel_driver(dev) < 0)
+			return -1;
+	}
+
 	dev->driver = drv;
 	RTE_VERIFY(drv->probe != NULL);
 	return drv->probe(drv, dev);
@@ -166,6 +186,10 @@ rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
 	if (drv->remove && (drv->remove(dev) < 0))
 		return -1;	/* negative value is an error */
 
+	if (drv->drv_flags & RTE_SOC_DRV_NEED_MAPPING)
+		/* unmap resources for devices */
+		rte_eal_soc_unmap_device(dev);
+
 	/* clear driver structure */
 	dev->driver = NULL;
 
@@ -241,6 +265,12 @@ rte_eal_soc_probe_one(const struct rte_soc_addr *addr)
 	if (addr == NULL)
 		return -1;
 
+	/* update current SoC device in global list, kernel bindings might have
+	 * changed since last time we looked at it.
+	 */
+	if (soc_update_device(addr) < 0)
+		goto err_return;
+
 	TAILQ_FOREACH(dev, &soc_device_list, next) {
 		if (rte_eal_compare_soc_addr(&dev->addr, addr))
 			continue;
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index d810f9f..30c648d 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -159,6 +159,29 @@ int pci_update_device(const struct rte_pci_addr *addr);
 int pci_unbind_kernel_driver(struct rte_pci_device *dev);
 
 /**
+ * Update a soc device object by asking the kernel for the latest information.
+ *
+ * This function is private to EAL.
+ *
+ * @param addr
+ *      The SoC address to look for
+ * @return
+ *   - 0 on success.
+ *   - negative on error.
+ */
+int soc_update_device(const struct rte_soc_addr *addr);
+
+/**
+ * Unbind kernel driver for this device
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int soc_unbind_kernel_driver(struct rte_soc_device *dev);
+
+/**
  * Map the PCI resource of a PCI device in virtual memory
  *
  * This function is private to EAL.
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index a9b3129..3b8b03f 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -46,9 +46,11 @@ extern "C" {
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/queue.h>
 #include <stdint.h>
 #include <inttypes.h>
 #include <string.h>
+#include <limits.h>
 
 #include <rte_dev.h>
 #include <rte_eal.h>
@@ -63,6 +65,14 @@ extern struct soc_device_list soc_device_list;
 TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
 TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
 
+#define SOC_MAX_RESOURCE 6
+
+struct rte_soc_resource {
+	uint64_t phys_addr;
+	uint64_t len;
+	void *addr;
+};
+
 struct rte_soc_id {
 	union {
 		const char *compatible; /**< OF compatible specification */
@@ -84,8 +94,12 @@ struct rte_soc_device {
 	struct rte_device device;           /**< Inherit code device */
 	struct rte_soc_addr addr;           /**< SoC device Location */
 	struct rte_soc_id *id;              /**< SoC device ID list */
+	struct rte_soc_resource mem_resource[SOC_MAX_RESOURCE];
 	struct rte_intr_handle intr_handle; /**< Interrupt handle */
 	struct rte_soc_driver *driver;      /**< Associated driver */
+	int numa_node;                      /**< NUMA node connection */
+	int is_dma_coherent;                /**< DMA coherent device */
+	enum rte_kernel_driver kdrv;        /**< Kernel driver */
 };
 
 struct rte_soc_driver;
@@ -139,6 +153,8 @@ struct rte_soc_driver {
 #define RTE_SOC_DRV_INTR_LSC	 0x0008
 /** Device driver supports detaching capability */
 #define RTE_SOC_DRV_DETACHABLE	 0x0010
+/** Device driver accepts DMA non-coherent devices */
+#define RTE_SOC_DRV_ACCEPT_NONCC 0x0020
 
 /**
  * Utility function to write a SoC device name, this device name can later be
@@ -256,6 +272,18 @@ int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
 int rte_eal_soc_detach(const struct rte_soc_addr *addr);
 
 /**
+ * Map SoC device resources into userspace.
+ *
+ * This is called by the EAL if (drv_flags & RTE_SOC_DRV_NEED_MAPPING).
+ */
+int rte_eal_soc_map_device(struct rte_soc_device *dev);
+
+/**
+ * Unmap the device resources.
+ */
+void rte_eal_soc_unmap_device(struct rte_soc_device *dev);
+
+/**
  * Dump discovered SoC devices.
  *
  * @param f
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index d8dfe97..95f7565 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -63,6 +63,45 @@ soc_get_sysfs_path(void)
 	return path;
 }
 
+int
+soc_unbind_kernel_driver(struct rte_soc_device *dev)
+{
+	char devpath[PATH_MAX];
+
+	snprintf(devpath, sizeof(devpath), "%s/%s",
+		 soc_get_sysfs_path(), dev->addr.name);
+
+	return rte_eal_unbind_kernel_driver(devpath, dev->addr.name);
+}
+
+int
+rte_eal_soc_map_device(struct rte_soc_device *dev)
+{
+	int ret = -1;
+
+	/* try mapping the NIC resources using VFIO if it exists */
+	switch (dev->kdrv) {
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		ret = 1;
+		break;
+	}
+
+	return ret;
+}
+
+void
+rte_eal_soc_unmap_device(struct rte_soc_device *dev)
+{
+	switch (dev->kdrv) {
+	default:
+	RTE_LOG(DEBUG, EAL,
+		"  Not managed by a supported kernel driver, skipped\n");
+		break;
+	}
+}
+
 static char *
 dev_read_uevent(const char *dirname)
 {
@@ -260,6 +299,68 @@ dev_content_free(struct rte_soc_device *dev)
 	}
 }
 
+static int
+dev_setup_associated_driver(struct rte_soc_device *dev, const char *dirname)
+{
+	char filename[PATH_MAX];
+	char driver[PATH_MAX];
+	int ret;
+
+	/* parse driver */
+	snprintf(filename, sizeof(filename), "%s/driver", dirname);
+	ret = rte_eal_get_kernel_driver_by_path(filename, driver);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "Fail to get kernel driver for %s\n",
+			dirname);
+		return 1;
+	}
+
+	if (!ret)
+		dev->kdrv = RTE_KDRV_UNKNOWN;
+	else
+		dev->kdrv = RTE_KDRV_NONE;
+
+	return 0;
+}
+
+static int
+dev_setup_numa_node(struct rte_soc_device *dev, const char *dirname)
+{
+	char filename[PATH_MAX];
+
+	/* if no NUMA support, set default to 0 */
+	unsigned long tmp = 0;
+	int ret = 0;
+
+	/* get numa node */
+	snprintf(filename, sizeof(filename), "%s/numa_node", dirname);
+
+	if (eal_parse_sysfs_value(filename, &tmp) < 0)
+		ret = 1;
+
+	dev->numa_node = tmp;
+	return ret;
+}
+
+static int
+dev_detect_is_coherent(struct rte_soc_device *dev)
+{
+	char filename[PATH_MAX];
+	FILE *f;
+
+	if (dev->addr.fdt_path == NULL)
+		return 0; /* no way to detect */
+
+	snprintf(filename, sizeof(filename), "%s%s/dma-coherent",
+			"/proc/device-tree", dev->addr.fdt_path);
+	f = fopen(filename, "r");
+	if (f == NULL)
+		return 0;
+
+	fclose(f);
+	return 1;
+}
+
 /**
  * Scan one SoC sysfs entry, and fill the devices list from it.
  * We require to have the uevent file with records: OF_FULLNAME and
@@ -299,6 +400,18 @@ soc_scan_one(const char *dirname, const char *name)
 		goto fail;
 	free(uevent); /* not needed anymore */
 
+	ret = dev_setup_associated_driver(dev, dirname);
+	if (ret)
+		goto fail;
+
+	ret = dev_setup_numa_node(dev, dirname);
+	if (ret < 0)
+		goto fail;
+
+	dev->is_dma_coherent = dev_detect_is_coherent(dev);
+	RTE_LOG(DEBUG, EAL, "  DMA %s\n",
+			dev->is_dma_coherent ? "coherent" : "non-coherent");
+
 	/* device is valid, add in list (sorted) */
 	if (TAILQ_EMPTY(&soc_device_list)) {
 		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
@@ -313,6 +426,11 @@ soc_scan_one(const char *dirname, const char *name)
 			if (ret < 0) {
 				TAILQ_INSERT_BEFORE(dev2, dev, next);
 			} else { /* already registered */
+				dev2->kdrv = dev->kdrv;
+				dev2->is_dma_coherent = dev->is_dma_coherent;
+				memmove(dev2->mem_resource, dev->mem_resource,
+					sizeof(dev->mem_resource));
+
 				dev_content_free(dev2);
 				dev2->addr.fdt_path = dev->addr.fdt_path;
 				dev2->id = dev->id;
@@ -333,6 +451,17 @@ fail:
 }
 
 int
+soc_update_device(const struct rte_soc_addr *addr)
+{
+	char filename[PATH_MAX];
+
+	snprintf(filename, sizeof(filename), "%s/%s",
+			soc_get_sysfs_path(), addr->name);
+
+	return soc_scan_one(filename, addr->name);
+}
+
+int
 rte_eal_soc_scan_platform_bus(void)
 {
 	struct dirent *e;
-- 
2.7.4

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

* [PATCH v5 17/21] ether: utilize container_of for pci_drv
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
                         ` (15 preceding siblings ...)
  2016-10-24 11:59       ` [PATCH v5 16/21] eal/soc: additional features for SoC Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 18/21] ether: verify we copy info from a PCI device Shreyansh Jain
                         ` (4 subsequent siblings)
  21 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

It is not necessary to place the rte_pci_driver at the beginning
of the rte_eth_dev struct anymore as we use the container_of macro
to get the parent pointer.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 4 ++--
 lib/librte_ether/rte_ethdev.h | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 0d9d9c1..9aea048 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -241,7 +241,7 @@ rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
 
 	int diag;
 
-	eth_drv = (struct eth_driver *)pci_drv;
+	eth_drv = container_of(pci_drv, struct eth_driver, pci_drv);
 
 	rte_eal_pci_device_name(&pci_dev->addr, ethdev_name,
 			sizeof(ethdev_name));
@@ -302,7 +302,7 @@ rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
 	if (eth_dev == NULL)
 		return -ENODEV;
 
-	eth_drv = (const struct eth_driver *)pci_dev->driver;
+	eth_drv = container_of(pci_dev->driver, struct eth_driver, pci_drv);
 
 	/* Invoke PMD device uninit function */
 	if (*eth_drv->eth_dev_uninit) {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 38641e8..f893fe0 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1850,7 +1850,7 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *eth_dev);
  * Each Ethernet driver acts as a PCI driver and is represented by a generic
  * *eth_driver* structure that holds:
  *
- * - An *rte_pci_driver* structure (which must be the first field).
+ * - An *rte_pci_driver* structure.
  *
  * - The *eth_dev_init* function invoked for each matching PCI device.
  *
-- 
2.7.4

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

* [PATCH v5 18/21] ether: verify we copy info from a PCI device
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
                         ` (16 preceding siblings ...)
  2016-10-24 11:59       ` [PATCH v5 17/21] ether: utilize container_of for pci_drv Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 19/21] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
                         ` (3 subsequent siblings)
  21 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

Now that different types of ethdev exist, check for presence of PCI dev
while copying out the info.
Similar would be done for SoC.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 9aea048..daa1285 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3205,6 +3205,8 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_de
 		return;
 	}
 
+	RTE_VERIFY(eth_dev->pci_dev != NULL);
+
 	eth_dev->data->dev_flags = 0;
 	if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC)
 		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
-- 
2.7.4

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

* [PATCH v5 19/21] ether: extract function eth_dev_get_intr_handle
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
                         ` (17 preceding siblings ...)
  2016-10-24 11:59       ` [PATCH v5 18/21] ether: verify we copy info from a PCI device Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 20/21] ether: introduce ethernet dev probe remove Shreyansh Jain
                         ` (2 subsequent siblings)
  21 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

We abstract access to the intr_handle here as we want to get
it either from the pci_dev or soc_dev.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index daa1285..ba9ae1e 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2531,6 +2531,16 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
 	rte_spinlock_unlock(&rte_eth_dev_cb_lock);
 }
 
+static inline
+struct rte_intr_handle *eth_dev_get_intr_handle(struct rte_eth_dev *dev)
+{
+	if (dev->pci_dev)
+		return &dev->pci_dev->intr_handle;
+
+	RTE_ASSERT(0);
+	return NULL;
+}
+
 int
 rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 {
@@ -2543,7 +2553,7 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
-	intr_handle = &dev->pci_dev->intr_handle;
+	intr_handle = eth_dev_get_intr_handle(dev);
 	if (!intr_handle->intr_vec) {
 		RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
 		return -EPERM;
@@ -2603,7 +2613,7 @@ rte_eth_dev_rx_intr_ctl_q(uint8_t port_id, uint16_t queue_id,
 		return -EINVAL;
 	}
 
-	intr_handle = &dev->pci_dev->intr_handle;
+	intr_handle = eth_dev_get_intr_handle(dev);
 	if (!intr_handle->intr_vec) {
 		RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
 		return -EPERM;
-- 
2.7.4

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

* [PATCH v5 20/21] ether: introduce ethernet dev probe remove
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
                         ` (18 preceding siblings ...)
  2016-10-24 11:59       ` [PATCH v5 19/21] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-24 11:59       ` [PATCH v5 21/21] eal/crypto: Support rte_soc_driver/device for cryptodev Shreyansh Jain
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
  21 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

From: Jan Viktorin <viktorin@rehivetech.com>

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 148 +++++++++++++++++++++++++++++++++++++++++-
 lib/librte_ether/rte_ethdev.h |  31 +++++++++
 2 files changed, 177 insertions(+), 2 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index ba9ae1e..78b3fb8 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -325,6 +325,101 @@ rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
 }
 
 int
+rte_eth_dev_soc_probe(struct rte_soc_driver *soc_drv,
+		      struct rte_soc_device *soc_dev)
+{
+	struct eth_driver    *eth_drv;
+	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
+	int diag;
+
+	eth_drv = container_of(soc_drv, struct eth_driver, soc_drv);
+
+	rte_eal_soc_device_name(&soc_dev->addr, ethdev_name,
+			sizeof(ethdev_name));
+
+	eth_dev = rte_eth_dev_allocate(ethdev_name);
+	if (eth_dev == NULL)
+		return -ENOMEM;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		eth_dev->data->dev_private = rte_zmalloc(
+				  "ethdev private structure",
+				  eth_drv->dev_private_size,
+				  RTE_CACHE_LINE_SIZE);
+		if (eth_dev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private port "
+				  "data\n");
+	}
+	eth_dev->soc_dev = soc_dev;
+	eth_dev->driver = eth_drv;
+	eth_dev->data->rx_mbuf_alloc_failed = 0;
+
+	/* init user callbacks */
+	TAILQ_INIT(&(eth_dev->link_intr_cbs));
+
+	/*
+	 * Set the default MTU.
+	 */
+	eth_dev->data->mtu = ETHER_MTU;
+
+	/* Invoke PMD device initialization function */
+	diag = (*eth_drv->eth_dev_init)(eth_dev);
+	if (diag == 0)
+		return 0;
+
+	RTE_PMD_DEBUG_TRACE("driver %s: eth_dev_init(%s) failed\n",
+			soc_drv->driver.name,
+			soc_dev->addr.name);
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(eth_dev->data->dev_private);
+	rte_eth_dev_release_port(eth_dev);
+	return diag;
+}
+
+int
+rte_eth_dev_soc_remove(struct rte_soc_device *soc_dev)
+{
+	const struct eth_driver *eth_drv;
+	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+	int ret;
+
+	if (soc_dev == NULL)
+		return -EINVAL;
+
+	rte_eal_soc_device_name(&soc_dev->addr, ethdev_name,
+			sizeof(ethdev_name));
+
+	eth_dev = rte_eth_dev_allocated(ethdev_name);
+	if (eth_dev == NULL)
+		return -ENODEV;
+
+	eth_drv = container_of(soc_dev->driver, struct eth_driver, soc_drv);
+
+	/* Invoke PMD device uninit function */
+	if (*eth_drv->eth_dev_uninit) {
+		ret = (*eth_drv->eth_dev_uninit)(eth_dev);
+		if (ret)
+			return ret;
+	}
+
+	/* free ether device */
+	rte_eth_dev_release_port(eth_dev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(eth_dev->data->dev_private);
+
+	eth_dev->soc_dev = NULL;
+	eth_dev->driver = NULL;
+	eth_dev->data = NULL;
+
+	return 0;
+}
+
+
+int
 rte_eth_dev_is_valid_port(uint8_t port_id)
 {
 	if (port_id >= RTE_MAX_ETHPORTS ||
@@ -1557,6 +1652,7 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
 	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
 	dev_info->pci_dev = dev->pci_dev;
+	dev_info->soc_dev = dev->soc_dev;
 	dev_info->driver_name = dev->data->drv_name;
 	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
 	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
@@ -2534,8 +2630,15 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
 static inline
 struct rte_intr_handle *eth_dev_get_intr_handle(struct rte_eth_dev *dev)
 {
-	if (dev->pci_dev)
+	if (dev->pci_dev) {
+		RTE_ASSERT(dev->soc_dev == NULL);
 		return &dev->pci_dev->intr_handle;
+	}
+
+	if (dev->soc_dev) {
+		RTE_ASSERT(dev->pci_dev == NULL);
+		return &dev->soc_dev->intr_handle;
+	}
 
 	RTE_ASSERT(0);
 	return NULL;
@@ -2572,6 +2675,23 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 	return 0;
 }
 
+static inline
+const char *eth_dev_get_driver_name(const struct rte_eth_dev *dev)
+{
+	if (dev->pci_dev) {
+		RTE_ASSERT(dev->soc_dev == NULL);
+		return dev->driver->pci_drv.driver.name;
+	}
+
+	if (dev->soc_dev) {
+		RTE_ASSERT(dev->pci_dev == NULL);
+		return dev->driver->soc_drv.driver.name;
+	}
+
+	RTE_ASSERT(0);
+	return NULL;
+}
+
 const struct rte_memzone *
 rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 			 uint16_t queue_id, size_t size, unsigned align,
@@ -2579,9 +2699,11 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 {
 	char z_name[RTE_MEMZONE_NAMESIZE];
 	const struct rte_memzone *mz;
+	const char *drv_name;
 
+	drv_name = eth_dev_get_driver_name(dev);
 	snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
-		 dev->driver->pci_drv.driver.name, ring_name,
+		 drv_name, ring_name,
 		 dev->data->port_id, queue_id);
 
 	mz = rte_memzone_lookup(z_name);
@@ -3228,6 +3350,28 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_de
 	eth_dev->data->drv_name = pci_dev->driver->driver.name;
 }
 
+void
+rte_eth_copy_soc_info(struct rte_eth_dev *eth_dev,
+		      struct rte_soc_device *soc_dev)
+{
+	if ((eth_dev == NULL) || (soc_dev == NULL)) {
+		RTE_PMD_DEBUG_TRACE("NULL pointer eth_dev=%p soc_dev=%p\n",
+				eth_dev, soc_dev);
+		return;
+	}
+
+	RTE_ASSERT(eth_dev->soc_dev != NULL);
+
+	eth_dev->data->dev_flags = 0;
+	if (soc_dev->driver->drv_flags & RTE_SOC_DRV_INTR_LSC)
+		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
+	if (soc_dev->driver->drv_flags & RTE_SOC_DRV_DETACHABLE)
+		eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
+
+	eth_dev->data->numa_node = soc_dev->device.numa_node;
+	eth_dev->data->drv_name = soc_dev->driver->driver.name;
+}
+
 int
 rte_eth_dev_l2_tunnel_eth_type_conf(uint8_t port_id,
 				    struct rte_eth_l2_tunnel_conf *l2_tunnel)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index f893fe0..ff7958f 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -180,6 +180,7 @@ extern "C" {
 #include <rte_log.h>
 #include <rte_interrupts.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include "rte_ether.h"
@@ -877,6 +878,7 @@ struct rte_eth_conf {
  */
 struct rte_eth_dev_info {
 	struct rte_pci_device *pci_dev; /**< Device PCI information. */
+	struct rte_soc_device *soc_dev; /**< Device SoC information. */
 	const char *driver_name; /**< Device Driver name. */
 	unsigned int if_index; /**< Index to bound host interface, or 0 if none.
 		Use if_indextoname() to translate into an interface name. */
@@ -1626,6 +1628,7 @@ struct rte_eth_dev {
 	const struct eth_driver *driver;/**< Driver for this device */
 	const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
 	struct rte_pci_device *pci_dev; /**< PCI info. supplied by probing */
+	struct rte_soc_device *soc_dev; /**< SoC info. supplied by probing */
 	/** User application callbacks for NIC interrupts */
 	struct rte_eth_dev_cb_list link_intr_cbs;
 	/**
@@ -1860,6 +1863,7 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *eth_dev);
  */
 struct eth_driver {
 	struct rte_pci_driver pci_drv;    /**< The PMD is also a PCI driver. */
+	struct rte_soc_driver soc_drv;    /**< The PMD is also a SoC driver. */
 	eth_dev_init_t eth_dev_init;      /**< Device init function. */
 	eth_dev_uninit_t eth_dev_uninit;  /**< Device uninit function. */
 	unsigned int dev_private_size;    /**< Size of device private data. */
@@ -4262,6 +4266,20 @@ void rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev,
 		struct rte_pci_device *pci_dev);
 
 /**
+ * Copy SoC device info to the Ethernet device data.
+ *
+ * @param eth_dev
+ * The *eth_dev* pointer is the address of the *rte_eth_dev* structure.
+ * @param soc_dev
+ * The *soc_dev* pointer is the address of the *rte_soc_device* structure.
+ *
+ * @return
+ *   - 0 on success, negative on error
+ */
+void rte_eth_copy_soc_info(struct rte_eth_dev *eth_dev,
+		struct rte_soc_device *soc_dev);
+
+/**
  * Create memzone for HW rings.
  * malloc can't be used as the physical address is needed.
  * If the memzone is already created, then this function returns a ptr
@@ -4376,6 +4394,19 @@ int rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
  */
 int rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev);
 
+/**
+ * Wrapper for use by SoC drivers as a .devinit function to attach to a ethdev
+ * interface.
+ */
+int rte_eth_dev_soc_probe(struct rte_soc_driver *soc_drv,
+			  struct rte_soc_device *soc_dev);
+
+/**
+ * Wrapper for use by SoC drivers as a .devuninit function to detach a ethdev
+ * interface.
+ */
+int rte_eth_dev_soc_remove(struct rte_soc_device *soc_dev);
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.7.4

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

* [PATCH v5 21/21] eal/crypto: Support rte_soc_driver/device for cryptodev
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
                         ` (19 preceding siblings ...)
  2016-10-24 11:59       ` [PATCH v5 20/21] ether: introduce ethernet dev probe remove Shreyansh Jain
@ 2016-10-24 11:59       ` Shreyansh Jain
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
  21 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 11:59 UTC (permalink / raw)
  To: dev
  Cc: viktorin, thomas.monjalon, david.marchand, Shreyansh Jain,
	Hemant Agrawal

- rte_cryptodev_driver/rte_cryptodev_dev embeds rte_soc_driver/device for
  linking SoC PMDs to crypto devices.
- Add probe and remove functions linked

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_cryptodev/rte_cryptodev.c           | 122 ++++++++++++++++++++++++-
 lib/librte_cryptodev/rte_cryptodev.h           |   3 +
 lib/librte_cryptodev/rte_cryptodev_pmd.h       |  18 +++-
 lib/librte_cryptodev/rte_cryptodev_version.map |   2 +
 4 files changed, 140 insertions(+), 5 deletions(-)

diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 127e8d0..77ec9fe 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -422,7 +422,8 @@ rte_cryptodev_pci_probe(struct rte_pci_driver *pci_drv,
 
 	int retval;
 
-	cryptodrv = (struct rte_cryptodev_driver *)pci_drv;
+	cryptodrv = container_of(pci_drv, struct rte_cryptodev_driver,
+				 pci_drv);
 	if (cryptodrv == NULL)
 		return -ENODEV;
 
@@ -489,7 +490,8 @@ rte_cryptodev_pci_remove(struct rte_pci_device *pci_dev)
 	if (cryptodev == NULL)
 		return -ENODEV;
 
-	cryptodrv = (const struct rte_cryptodev_driver *)pci_dev->driver;
+	cryptodrv = container_of(pci_dev->driver, struct rte_cryptodev_driver,
+				 pci_drv);
 	if (cryptodrv == NULL)
 		return -ENODEV;
 
@@ -513,6 +515,111 @@ rte_cryptodev_pci_remove(struct rte_pci_device *pci_dev)
 	return 0;
 }
 
+
+int
+rte_cryptodev_soc_probe(struct rte_soc_driver *soc_drv,
+		      struct rte_soc_device *soc_dev)
+{
+	struct rte_cryptodev_driver *cryptodrv;
+	struct rte_cryptodev *cryptodev;
+
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+
+	int retval;
+
+	cryptodrv = container_of(soc_drv, struct rte_cryptodev_driver,
+				 soc_drv);
+
+	rte_eal_soc_device_name(&soc_dev->addr, cryptodev_name,
+			sizeof(cryptodev_name));
+
+	cryptodev = rte_cryptodev_pmd_allocate(cryptodev_name,
+					       rte_socket_id());
+	if (cryptodev == NULL)
+		return -ENOMEM;
+
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		cryptodev->data->dev_private =
+				rte_zmalloc_socket(
+						"cryptodev private structure",
+						cryptodrv->dev_private_size,
+						RTE_CACHE_LINE_SIZE,
+						rte_socket_id());
+
+		if (cryptodev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private "
+					"device data");
+	}
+
+	cryptodev->soc_dev = soc_dev;
+	cryptodev->driver = cryptodrv;
+
+	/* init user callbacks */
+	TAILQ_INIT(&(cryptodev->link_intr_cbs));
+
+	/* Invoke PMD device initialization function */
+	retval = (*cryptodrv->cryptodev_init)(cryptodrv, cryptodev);
+	if (retval == 0)
+		return 0;
+
+	CDEV_LOG_ERR("driver %s: cryptodev_init(%s) failed\n",
+			soc_drv->driver.name,
+			soc_dev->addr.name);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	cryptodev->attached = RTE_CRYPTODEV_DETACHED;
+	cryptodev_globals.nb_devs--;
+
+	return -ENXIO;
+}
+
+int
+rte_cryptodev_soc_remove(struct rte_soc_device *soc_dev)
+{
+	const struct rte_cryptodev_driver *cryptodrv;
+	struct rte_cryptodev *cryptodev;
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+	int ret;
+
+	if (soc_dev == NULL)
+		return -EINVAL;
+
+	rte_eal_soc_device_name(&soc_dev->addr, cryptodev_name,
+			sizeof(cryptodev_name));
+
+	cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name);
+	if (cryptodev == NULL)
+		return -ENODEV;
+
+	cryptodrv = container_of(soc_dev->driver,
+		struct rte_cryptodev_driver, soc_drv);
+	if (cryptodrv == NULL)
+		return -ENODEV;
+
+	/* Invoke PMD device uninit function */
+	if (*cryptodrv->cryptodev_uninit) {
+		ret = (*cryptodrv->cryptodev_uninit)(cryptodrv, cryptodev);
+		if (ret)
+			return ret;
+	}
+
+	/* free crypto device */
+	rte_cryptodev_pmd_release_device(cryptodev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	cryptodev->pci_dev = NULL;
+	cryptodev->soc_dev = NULL;
+	cryptodev->driver = NULL;
+	cryptodev->data = NULL;
+
+	return 0;
+}
+
 uint16_t
 rte_cryptodev_queue_pair_count(uint8_t dev_id)
 {
@@ -868,8 +975,15 @@ rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
 
 	dev_info->pci_dev = dev->pci_dev;
-	if (dev->driver)
-		dev_info->driver_name = dev->driver->pci_drv.driver.name;
+	dev_info->soc_dev = dev->soc_dev;
+	if (dev->driver) {
+		if (dev->soc_dev)
+			dev_info->driver_name
+				= dev->driver->soc_drv.driver.name;
+		else
+			dev_info->driver_name
+				= dev->driver->pci_drv.driver.name;
+	}
 }
 
 
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 232f34a..b94188d 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -244,6 +244,7 @@ struct rte_cryptodev_info {
 	const char *driver_name;		/**< Driver name. */
 	enum rte_cryptodev_type dev_type;	/**< Device type */
 	struct rte_pci_device *pci_dev;		/**< PCI information. */
+	struct rte_soc_device *soc_dev;		/**< SoC information. */
 
 	uint64_t feature_flags;			/**< Feature flags */
 
@@ -623,6 +624,8 @@ struct rte_cryptodev {
 	/**< Supported features */
 	struct rte_pci_device *pci_dev;
 	/**< PCI info. supplied by probing */
+	struct rte_soc_device *soc_dev;
+	/**< SoC info. supplied by probing/Scanning */
 
 	enum rte_cryptodev_type dev_type;
 	/**< Crypto device type */
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index abfe2dc..a8af2ce 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -48,6 +48,7 @@ extern "C" {
 
 #include <rte_dev.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_malloc.h>
 #include <rte_mbuf.h>
 #include <rte_mempool.h>
@@ -131,7 +132,8 @@ typedef int (*cryptodev_uninit_t)(const struct rte_cryptodev_driver  *drv,
  * - The size of the private data to allocate for each matching device.
  */
 struct rte_cryptodev_driver {
-	struct rte_pci_driver pci_drv;	/**< The PMD is also a PCI driver. */
+	struct rte_pci_driver pci_drv;	/**< The PMD is PCI type driver. */
+	struct rte_soc_driver soc_drv;	/**< The PMD is SoC type driver. */
 	unsigned dev_private_size;	/**< Size of device private data. */
 
 	cryptodev_init_t cryptodev_init;	/**< Device init function. */
@@ -519,6 +521,20 @@ int rte_cryptodev_pci_probe(struct rte_pci_driver *pci_drv,
  */
 int rte_cryptodev_pci_remove(struct rte_pci_device *pci_dev);
 
+/**
+ * Wrapper for use by SoC drivers as a .devinit function to attach to a
+ * cryptodev interface.
+ */
+int rte_cryptodev_soc_probe(struct rte_soc_driver *soc_drv,
+			  struct rte_soc_device *soc_dev);
+
+/**
+ * Wrapper for use by SoC drivers as a .devuninit function to detach a
+ * cryptodev interface.
+ */
+int rte_cryptodev_soc_remove(struct rte_soc_device *soc_dev);
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index 9dde0e7..d81073e 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -44,5 +44,7 @@ DPDK_16.11 {
 
 	rte_cryptodev_pci_probe;
 	rte_cryptodev_pci_remove;
+	rte_cryptodev_soc_probe;
+	rte_cryptodev_soc_remove;
 
 } DPDK_16.07;
-- 
2.7.4

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

* Re: [PATCH v4 11/17] eal/soc: add default scan for Soc devices
  2016-10-16  7:12         ` Shreyansh Jain
@ 2016-10-24 12:08           ` Shreyansh Jain
  2016-10-24 16:11             ` Jan Viktorin
  0 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-24 12:08 UTC (permalink / raw)
  To: Jan Viktorin; +Cc: dev, thomas.monjalon, david.marchand

Hi Jan,

On Sunday 16 October 2016 12:42 PM, Shreyansh Jain wrote:
> Hi Jan,
>
>> -----Original Message-----
>> From: Jan Viktorin [mailto:viktorin@rehivetech.com]
>> Sent: Sunday, October 16, 2016 6:27 AM
>> To: Shreyansh Jain <shreyansh.jain@nxp.com>
>> Cc: dev@dpdk.org; thomas.monjalon@6wind.com; david.marchand@6wind.com
>> Subject: Re: [PATCH v4 11/17] eal/soc: add default scan for Soc devices
>>
>> On Sat, 15 Oct 2016 19:15:02 +0530
>> Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
>>
>>> From: Jan Viktorin <viktorin@rehivetech.com>
>>>
>>> Default implementation which scans the sysfs platform devices hierarchy..
>>> For each device, extract the ueven and convert into rte_soc_device.
>>>
>>> The information populated can then be used in probe to match against
>>> the drivers registered.
>>>
>>> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
>>> [Shreyansh: restructure commit to be an optional implementation]
>>> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
>>
>> [...]
>>
>>> +
>>> +int
>>> +rte_eal_soc_scan(void)
>>
>> What about naming it rte_eal_soc_scan_default? This would underline the
>> fact that this function can be replaced.
>
> Yes, that would be in sync with match default. I will do it.

In v5 I have replaced the name with rte_eal_soc_platform_bus(). This is 
long but it does exactly what the name states - scan for platform bus. 
This is still a helper.

>
>>
>> Second, this is for the 7/17 patch:
>>
>> -/* register a driver */
>>  void
>>  rte_eal_soc_register(struct rte_soc_driver *driver)
>>  {
>> +	/* For a valid soc driver, match and scan function
>> +	 * should be provided.
>> +	 */
>> +	RTE_VERIFY(driver != NULL);
>> +	RTE_VERIFY(driver->match_fn != NULL);
>> +	RTE_VERIFY(driver->scan_fn != NULL);
>>
>> What about setting the match_fn and scan_fn to default implementations if
>> they
>> are NULL? This would make the standard/default approach easier to use.
>>
>>  	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
>>  }
>
> I am not in favor of a forced default. What if user never intended it - it would lead to wrong scan being used and only intimation which can provided to user is a log.
> Selecting such functions should be a model of PMD - one which is enforced.

As mentioned before, I am not in favor of a 'default' implementation. 
Thus, I would rather call these functions as 'helpers' rather than defaults.

[...]

-
Shreyansh

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

* Re: [PATCH v4 11/17] eal/soc: add default scan for Soc devices
  2016-10-24 12:08           ` Shreyansh Jain
@ 2016-10-24 16:11             ` Jan Viktorin
  0 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-10-24 16:11 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, thomas.monjalon, david.marchand

On Mon, 24 Oct 2016 17:38:29 +0530
Shreyansh Jain <shreyansh.jain@nxp.com> wrote:

> Hi Jan,
> 
> On Sunday 16 October 2016 12:42 PM, Shreyansh Jain wrote:
> > Hi Jan,
> >  

[...]

> >>  
> >>> +
> >>> +int
> >>> +rte_eal_soc_scan(void)  
> >>
> >> What about naming it rte_eal_soc_scan_default? This would underline the
> >> fact that this function can be replaced.  
> >
> > Yes, that would be in sync with match default. I will do it.  
> 
> In v5 I have replaced the name with rte_eal_soc_platform_bus(). This is 
> long but it does exactly what the name states - scan for platform bus. 
> This is still a helper.

OK.

> 
> >  
> >>
> >> Second, this is for the 7/17 patch:
> >>
> >> -/* register a driver */
> >>  void
> >>  rte_eal_soc_register(struct rte_soc_driver *driver)
> >>  {
> >> +	/* For a valid soc driver, match and scan function
> >> +	 * should be provided.
> >> +	 */
> >> +	RTE_VERIFY(driver != NULL);
> >> +	RTE_VERIFY(driver->match_fn != NULL);
> >> +	RTE_VERIFY(driver->scan_fn != NULL);
> >>
> >> What about setting the match_fn and scan_fn to default implementations if
> >> they
> >> are NULL? This would make the standard/default approach easier to use.
> >>
> >>  	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
> >>  }  
> >
> > I am not in favor of a forced default. What if user never intended it - it would lead to wrong scan being used and only intimation which can provided to user is a log.
> > Selecting such functions should be a model of PMD - one which is enforced.  
> 
> As mentioned before, I am not in favor of a 'default' implementation. 
> Thus, I would rather call these functions as 'helpers' rather than defaults.

Hmm, OK.

Jan

> 
> [...]
> 
> -
> Shreyansh



-- 
   Jan Viktorin                  E-mail: Viktorin@RehiveTech.com
   System Architect              Web:    www.RehiveTech.com
   RehiveTech
   Brno, Czech Republic

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

* Re: [PATCH v5 01/21] eal: generalize PCI kernel driver enum to EAL
  2016-10-24 11:59       ` [PATCH v5 01/21] eal: generalize PCI kernel driver enum to EAL Shreyansh Jain
@ 2016-10-24 16:13         ` Jan Viktorin
  0 siblings, 0 replies; 231+ messages in thread
From: Jan Viktorin @ 2016-10-24 16:13 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, thomas.monjalon, david.marchand

On Mon, 24 Oct 2016 17:29:20 +0530
Shreyansh Jain <shreyansh.jain@nxp.com> wrote:

> From: Jan Viktorin <viktorin@rehivetech.com>
> 
> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>

I think, there is no reason to prevent merging this. Feel free to add:

Acked-by: Jan Viktorin <viktorin@rehivetech.com>

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

* Re: [PATCH v5 06/21] eal/soc: introduce very essential SoC infra definitions
  2016-10-24 11:59       ` [PATCH v5 06/21] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
@ 2016-10-24 16:21         ` Jan Viktorin
  2016-10-25  5:36           ` Shreyansh Jain
  0 siblings, 1 reply; 231+ messages in thread
From: Jan Viktorin @ 2016-10-24 16:21 UTC (permalink / raw)
  To: Shreyansh Jain, david.marchand; +Cc: dev, thomas.monjalon, Hemant Agrawal

On Mon, 24 Oct 2016 17:29:25 +0530
Shreyansh Jain <shreyansh.jain@nxp.com> wrote:

> From: Jan Viktorin <viktorin@rehivetech.com>
> 
> Define initial structures and functions for the SoC infrastructure.
> This patch supports only a very minimal functions for now.
> More features will be added in the following commits.
> 
> Includes rte_device/rte_driver inheritance of
> rte_soc_device/rte_soc_driver.
> 
> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
>  app/test/Makefile                       |   1 +
>  app/test/test_soc.c                     |  90 +++++++++++++++++++++
>  lib/librte_eal/common/Makefile          |   2 +-
>  lib/librte_eal/common/eal_private.h     |   4 +
>  lib/librte_eal/common/include/rte_soc.h | 138 ++++++++++++++++++++++++++++++++
>  5 files changed, 234 insertions(+), 1 deletion(-)
>  create mode 100644 app/test/test_soc.c
>  create mode 100644 lib/librte_eal/common/include/rte_soc.h
> 
> diff --git a/app/test/Makefile b/app/test/Makefile

[...]

> +++ b/lib/librte_eal/common/include/rte_soc.h
> @@ -0,0 +1,138 @@

[...]

> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <stdint.h>
> +#include <inttypes.h>
> +#include <string.h>
> +
> +#include <rte_dev.h>
> +#include <rte_debug.h>
> +
> +struct rte_soc_id {
> +	const char *compatible; /**< OF compatible specification */
> +	uint64_t priv_data;     /**< SoC Driver specific data */

Do you expect this to be a pointer?

> +};
> +

[...]

> +
> +/**
> + * Initialization function for the driver called during SoC probing.
> + */
> +typedef int (soc_devinit_t)(struct rte_soc_driver *, struct rte_soc_device *);
> +
> +/**
> + * Uninitialization function for the driver called during hotplugging.
> + */
> +typedef int (soc_devuninit_t)(struct rte_soc_device *);
> +
> +/**
> + * A structure describing a SoC driver.
> + */
> +struct rte_soc_driver {
> +	TAILQ_ENTRY(rte_soc_driver) next;  /**< Next in list */
> +	struct rte_driver driver;          /**< Inherit core driver. */
> +	soc_devinit_t *devinit;            /**< Device initialization */
> +	soc_devuninit_t *devuninit;        /**< Device uninitialization */

Shouldn't those functions be named probe/remove?

> +	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
> +};
> +

[...]

> +#endif



-- 
   Jan Viktorin                  E-mail: Viktorin@RehiveTech.com
   System Architect              Web:    www.RehiveTech.com
   RehiveTech
   Brno, Czech Republic

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

* Re: [PATCH v5 06/21] eal/soc: introduce very essential SoC infra definitions
  2016-10-24 16:21         ` Jan Viktorin
@ 2016-10-25  5:36           ` Shreyansh Jain
  2016-10-25 12:38             ` Shreyansh Jain
  0 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-25  5:36 UTC (permalink / raw)
  To: Jan Viktorin; +Cc: david.marchand, dev, thomas.monjalon, Hemant Agrawal

Hello Jan,

On Monday 24 October 2016 09:51 PM, Jan Viktorin wrote:
> On Mon, 24 Oct 2016 17:29:25 +0530
> Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
>
>> From: Jan Viktorin <viktorin@rehivetech.com>
>>
>> Define initial structures and functions for the SoC infrastructure.
>> This patch supports only a very minimal functions for now.
>> More features will be added in the following commits.
>>
>> Includes rte_device/rte_driver inheritance of
>> rte_soc_device/rte_soc_driver.
>>
>> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
>> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>> ---
>>  app/test/Makefile                       |   1 +
>>  app/test/test_soc.c                     |  90 +++++++++++++++++++++
>>  lib/librte_eal/common/Makefile          |   2 +-
>>  lib/librte_eal/common/eal_private.h     |   4 +
>>  lib/librte_eal/common/include/rte_soc.h | 138 ++++++++++++++++++++++++++++++++
>>  5 files changed, 234 insertions(+), 1 deletion(-)
>>  create mode 100644 app/test/test_soc.c
>>  create mode 100644 lib/librte_eal/common/include/rte_soc.h
>>
>> diff --git a/app/test/Makefile b/app/test/Makefile
>
> [...]
>
>> +++ b/lib/librte_eal/common/include/rte_soc.h
>> @@ -0,0 +1,138 @@
>
> [...]
>
>> +
>> +#include <stdio.h>
>> +#include <stdlib.h>
>> +#include <stdint.h>
>> +#include <inttypes.h>
>> +#include <string.h>
>> +
>> +#include <rte_dev.h>
>> +#include <rte_debug.h>
>> +
>> +struct rte_soc_id {
>> +	const char *compatible; /**< OF compatible specification */
>> +	uint64_t priv_data;     /**< SoC Driver specific data */
>
> Do you expect this to be a pointer?

A 64 bit entry, which can be typecasted to pointer by implementations, 
if required. Or, it might as well remain as a 64bit entry as ID.

>
>> +};
>> +
>
> [...]
>
>> +
>> +/**
>> + * Initialization function for the driver called during SoC probing.
>> + */
>> +typedef int (soc_devinit_t)(struct rte_soc_driver *, struct rte_soc_device *);
>> +
>> +/**
>> + * Uninitialization function for the driver called during hotplugging.
>> + */
>> +typedef int (soc_devuninit_t)(struct rte_soc_device *);
>> +
>> +/**
>> + * A structure describing a SoC driver.
>> + */
>> +struct rte_soc_driver {
>> +	TAILQ_ENTRY(rte_soc_driver) next;  /**< Next in list */
>> +	struct rte_driver driver;          /**< Inherit core driver. */
>> +	soc_devinit_t *devinit;            /**< Device initialization */
>> +	soc_devuninit_t *devuninit;        /**< Device uninitialization */
>
> Shouldn't those functions be named probe/remove?

Indeed. I think there was a comment on v4 as well - I thought I had 
fixed it but it seems I have mixed up my patches. I will send v6 
immediately with this fixed. Thanks for pointing out.

>
>> +	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
>> +};
>> +
>
> [...]
>
>> +#endif
>
>
>

-
Shreyansh

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

* Re: [PATCH v5 06/21] eal/soc: introduce very essential SoC infra definitions
  2016-10-25  5:36           ` Shreyansh Jain
@ 2016-10-25 12:38             ` Shreyansh Jain
  0 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-25 12:38 UTC (permalink / raw)
  To: Jan Viktorin; +Cc: david.marchand, dev, thomas.monjalon, Hemant Agrawal

On Tuesday 25 October 2016 11:06 AM, Shreyansh Jain wrote:
> Hello Jan,
>
> On Monday 24 October 2016 09:51 PM, Jan Viktorin wrote:
>> On Mon, 24 Oct 2016 17:29:25 +0530
>> Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
>>
>>> From: Jan Viktorin <viktorin@rehivetech.com>
>>>
>>> Define initial structures and functions for the SoC infrastructure.
>>> This patch supports only a very minimal functions for now.
>>> More features will be added in the following commits.
>>>
>>> Includes rte_device/rte_driver inheritance of
>>> rte_soc_device/rte_soc_driver.
>>>
>>> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
>>> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
>>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>>> ---
>>>  app/test/Makefile                       |   1 +
>>>  app/test/test_soc.c                     |  90 +++++++++++++++++++++
>>>  lib/librte_eal/common/Makefile          |   2 +-
>>>  lib/librte_eal/common/eal_private.h     |   4 +
>>>  lib/librte_eal/common/include/rte_soc.h | 138
>>> ++++++++++++++++++++++++++++++++
>>>  5 files changed, 234 insertions(+), 1 deletion(-)
>>>  create mode 100644 app/test/test_soc.c
>>>  create mode 100644 lib/librte_eal/common/include/rte_soc.h
>>>
>>> diff --git a/app/test/Makefile b/app/test/Makefile
>>
>> [...]
>>
>>> +++ b/lib/librte_eal/common/include/rte_soc.h
>>> @@ -0,0 +1,138 @@
>>
>> [...]
>>
>>> +
>>> +#include <stdio.h>
>>> +#include <stdlib.h>
>>> +#include <stdint.h>
>>> +#include <inttypes.h>
>>> +#include <string.h>
>>> +
>>> +#include <rte_dev.h>
>>> +#include <rte_debug.h>
>>> +
>>> +struct rte_soc_id {
>>> +    const char *compatible; /**< OF compatible specification */
>>> +    uint64_t priv_data;     /**< SoC Driver specific data */
>>
>> Do you expect this to be a pointer?
>
> A 64 bit entry, which can be typecasted to pointer by implementations,
> if required. Or, it might as well remain as a 64bit entry as ID.
>
>>
>>> +};
>>> +
>>
>> [...]
>>
>>> +
>>> +/**
>>> + * Initialization function for the driver called during SoC probing.
>>> + */
>>> +typedef int (soc_devinit_t)(struct rte_soc_driver *, struct
>>> rte_soc_device *);
>>> +
>>> +/**
>>> + * Uninitialization function for the driver called during hotplugging.
>>> + */
>>> +typedef int (soc_devuninit_t)(struct rte_soc_device *);
>>> +
>>> +/**
>>> + * A structure describing a SoC driver.
>>> + */
>>> +struct rte_soc_driver {
>>> +    TAILQ_ENTRY(rte_soc_driver) next;  /**< Next in list */
>>> +    struct rte_driver driver;          /**< Inherit core driver. */
>>> +    soc_devinit_t *devinit;            /**< Device initialization */
>>> +    soc_devuninit_t *devuninit;        /**< Device uninitialization */
>>
>> Shouldn't those functions be named probe/remove?
>
> Indeed. I think there was a comment on v4 as well - I thought I had
> fixed it but it seems I have mixed up my patches. I will send v6
> immediately with this fixed. Thanks for pointing out.

Ah, I just noticed that I did change it - but in Patch 11. Ideally, it 
should have been done here itself. My bad.

>
>>
>>> +    const struct rte_soc_id *id_table; /**< ID table, NULL
>>> terminated */
>>> +};
>>> +
>>
>> [...]
>>
>>> +#endif
>>
>>
>>
>
> -
> Shreyansh
>

-
Shreyansh

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

* [PATCH v6 00/21] Introduce SoC device/driver framework for EAL
  2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
                         ` (20 preceding siblings ...)
  2016-10-24 11:59       ` [PATCH v5 21/21] eal/crypto: Support rte_soc_driver/device for cryptodev Shreyansh Jain
@ 2016-10-27 15:17       ` Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 01/21] eal: generalize PCI kernel driver enum to EAL Shreyansh Jain
                           ` (20 more replies)
  21 siblings, 21 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

Introduction:
=============

This patch set is direct derivative of Jan's original series [1],[2].

 - This version is based on master HEAD (ca41215)
 
 - In this, I am merging the series [11] back. It was initially part
   of this set but I had split considering that those changes in PCI
   were good standalone as well. But, 1) not much feedback was avail-
   able and 2) this patchset is a use-case for those patches making
   it easier to review. Just like what Jan had intended in original
   series.

 - SoC support is not enabled by default. It needs the 'enable-soc' toggle
   on command line. This is primarily because this patchset is still
   experimental and we would like to keep it isolated from non-SoC ops.
   Though, it does impact the ABI.

Aim:
====

As of now EAL is primarly focused on PCI initialization/probing.

 rte_eal_init()
  |- rte_eal_pci_init(): Find PCI devices from sysfs
  |- ...
  |- rte_eal_memzone_init()
  |- ...
  `- rte_eal_pci_probe(): Driver<=>Device initialization

This patchset introduces SoC framework which would enable SoC drivers and
drivers to be plugged into EAL, very similar to how PCI drivers/devices are
done today.

This is a stripped down version of PCI framework which allows the SoC PMDs
to implement their own routines for detecting devices and linking devices to
drivers.

1) Changes to EAL
 rte_eal_init()
  |- rte_eal_pci_init(): Find PCI devices from sysfs
  |- rte_eal_soc_init(): Calls PMDs->scan_fn
  |- ...
  |- rte_eal_memzone_init()
  |- ...
  |- rte_eal_pci_probe(): Driver<=>Device initialization, PMD->devinit()
  `- rte_eal_soc_probe(): Calls PMDs->match_fn and PMDs->devinit();

2) New device/driver structures:
  - rte_soc_driver (inheriting rte_driver)
  - rte_soc_device (inheriting rte_device)
  - rte_eth_dev and eth_driver embedded rte_soc_device and rte_soc_driver,
    respectively.

3) The SoC PMDs need to:
 - define rte_soc_driver with necessary scan and match callbacks
 - Register themselves using DRIVER_REGISTER_SOC()
 - Implement respective bus scanning in the scan callbacks to add necessary
   devices to SoC device list
 - Implement necessary eth_dev_init/uninint for ethernet instances

4) Design considerations that are same as PCI:
 - SoC initialization is being done through rte_eal_init(), just after PCI
   initialization is done.
 - As in case of PCI, probe is done after rte_eal_pci_probe() to link the
   devices detected with the drivers registered.
 - Device attach/detach functions are available and have been designed on
   the lines of PCI framework.
 - PMDs register using DRIVER_REGISTER_SOC, very similar to
   DRIVER_REGISTER_PCI for PCI devices.
 - Linked list of SoC driver and devices exists independent of the other
   driver/device list, but inheriting rte_driver/rte_driver, these are
   also part of a global list.

5) Design considerations that are different from PCI:
 - Each driver implements its own scan and match function. PCI uses the BDF
   format to read the device from sysfs, but this _may_not_ be a case for a
   SoC ethernet device.
   = This is an important change from initial proposal by Jan in [2].
   Unlike his attempt to use /sys/bus/platform, this patch relies on the
   PMD to detect the devices. This is because SoC may require specific or
   additional info for device detection. Further, SoC may have embedded
   devices/MACs which require initialization which cannot be covered
   through sysfs parsing.
   `-> Point (6) below is a side note to above.
   = PCI based PMDs rely on EAL's capability to detect devices. This
   proposal puts the onus on PMD to detect devices, add to soc_device_list
   and wait for Probe. Matching, of device<=>driver is again PMD's
   callback.

6) Adding default scan and match helpers for PMDs
 - The design warrrants the PMDs implement their own scan of devices
   on bus, and match routines for probe implementation.
   This patch introduces helpers which can be used by PMDs for scan of
   the platform bus and matching devices against the compatible string
   extracted from the scan.
 - Intention is to make it easier to integrate known SoC which expose
   platform bus compliant information (compat, sys/bus/platform...).
 - PMDs which have deviations from this standard model can implement and
   hook their bus scanning and probe match callbacks while registering
   driver.

Patchset Overview:
==================
 - Patches 0001~0004 are from [11] - moving some PCI specific functions
   and definitions to non-PCI area.
 - Patches 0005~0008 introduce the base infrastructure and test case
 - Patch 0009 is for command line support for no-soc, on lines of no-pci
 - Patch 0010 enables EAL to handle SoC type devices
 - Patch 0011 adds support for scan and probe callbacks and updates the test
   framework with relevant test case.
 - Patch 0012~0014 enable device argument, driver specific flags and
   interrupt handling related basic infra. Subsequent patches build up on
   them.
 - Patch 0015~0016 add support for default function which PMDs can use for
   scanning platform bus. These functions are optional and need to be hooked
   to by PMDs.
 - Patch 0017~0019 makes changes to PCI as well as ethdev code to remove
   assumption that eth_driver is a PCI driver.
 - Patch 0020 adds necessary ethdev probe/remove functions for PMDs to use
 - Patch 0021 adds support for SoC driver/devices, along with probe/remove
   functions for Cryptodev devices.

Future/Pending Changes:
=======================
- Device whitelisting/blacklist still relies on command line '-b' and '-c'
  which are internally implemented using OPT_PCI_BLACKLIST/OPT_PCI_WHITELIST.
  This needs to be changed to a generic form - OPT_DEV_*LIST - probably.
- No cryptodriver currently uses SoC framework - probably a example driver
  can be created to demonstrate usage.
- test case for enable-soc command line parameter
- This patch impacts a couple of ABIs (rte_device/driver) and thus require
  a patch for bump of libraries (if need be) and documentation.

 [1] http://dpdk.org/ml/archives/dev/2016-January/030915.html
 [2] http://www.dpdk.org/ml/archives/dev/2016-May/038486.html
 [3] http://dpdk.org/ml/archives/dev/2016-August/045707.html
 [4] http://dpdk.org/ml/archives/dev/2016-May/038948.html
 [5] http://dpdk.org/ml/archives/dev/2016-May/038953.html
 [6] http://dpdk.org/ml/archives/dev/2016-May/038487.html
 [7] http://dpdk.org/ml/archives/dev/2016-May/038488.html
 [8] http://dpdk.org/ml/archives/dev/2016-May/038489.html
 [9] http://dpdk.org/ml/archives/dev/2016-May/038491.html
[10] http://dpdk.org/ml/archives/dev/2016-September/046256.html
[11] http://dpdk.org/ml/archives/dev/2016-October/048915.html

Changes since v5:
 - fix devinit/devuninit name change; it was in wrong patch
 - rebased over HEAD (ca41215)
 - Update to pending section of coverletter

Changes since v4:
 - change name of rte_eal_soc_scan function name to
   rte_eal_soc_scan_platform_bus. This still remains a helper function.
 - Fix comments over scan and match functions

Changes since v3:
 - rebasing over HEAD (fed622df tag: v16.11-rc1)
 - Add support for default scan function; PMD can use this for
   scanning on platform bus.
 - Support for kernel driver bind/unbind, numa and DMA from
   Jan's original patches.
 - SoC is disabled by default. '--enable-soc' command line parameter
   enables it. doc updated.
 - Updated testcase function names and comments
 - Map file addition alphabetically ordered
 - Patch author corrected

Changes since v2:
 - Rebasing over rte_driver/device patchset v9 [10]
 - Added cryptodev support for SoC
 - Default match function for SoC device<=>Driver
 - Some variables renamed to reflect 'drv' rather than 'dr'

Change since v1 [2]:
 - Removed patch 1-5 which were for generalizing some PCI specific routines
   into EAL. These patches are good-to-have but not directly linked to SoC
   and hence would be proposed separately.
 - Removed support for sysfs parsing (patches 6~9)
 - Rebasing over the recent (v8) version of rte_driver/device patchset
 - Rebasing over master (16.07)
 - Changes to various map file to change API intro to 16.11 from 16.07

Jan Viktorin (19):
  eal: generalize PCI kernel driver enum to EAL
  eal: generalize PCI map/unmap resource to EAL
  eal/linux: generalize PCI kernel unbinding driver to EAL
  eal/linux: generalize PCI kernel driver extraction to EAL
  eal: define container macro
  eal/soc: introduce very essential SoC infra definitions
  eal/soc: add SoC PMD register/unregister logic
  eal/soc: implement SoC device list and dump
  eal: introduce command line enable SoC option
  eal/soc: init SoC infra from EAL
  eal/soc: extend and utilize devargs
  eal/soc: add drv_flags
  eal/soc: add intr_handle
  eal/soc: add default scan for Soc devices
  eal/soc: additional features for SoC
  ether: utilize container_of for pci_drv
  ether: verify we copy info from a PCI device
  ether: extract function eth_dev_get_intr_handle
  ether: introduce ethernet dev probe remove

Shreyansh Jain (2):
  eal/soc: implement probing of drivers
  eal/crypto: Support rte_soc_driver/device for cryptodev

 app/test/Makefile                               |   1 +
 app/test/test_soc.c                             | 404 +++++++++++++++++++
 doc/guides/testpmd_app_ug/run_app.rst           |   4 +
 lib/librte_cryptodev/rte_cryptodev.c            | 122 +++++-
 lib/librte_cryptodev/rte_cryptodev.h            |   3 +
 lib/librte_cryptodev/rte_cryptodev_pmd.h        |  18 +-
 lib/librte_cryptodev/rte_cryptodev_version.map  |   2 +
 lib/librte_eal/bsdapp/eal/Makefile              |   1 +
 lib/librte_eal/bsdapp/eal/eal.c                 |  18 +
 lib/librte_eal/bsdapp/eal/eal_pci.c             |   6 +-
 lib/librte_eal/bsdapp/eal/eal_soc.c             |  46 +++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  11 +
 lib/librte_eal/common/Makefile                  |   2 +-
 lib/librte_eal/common/eal_common_dev.c          |  66 ++-
 lib/librte_eal/common/eal_common_devargs.c      |  17 +
 lib/librte_eal/common/eal_common_options.c      |   5 +
 lib/librte_eal/common/eal_common_pci.c          |  39 --
 lib/librte_eal/common/eal_common_pci_uio.c      |  16 +-
 lib/librte_eal/common/eal_common_soc.c          | 368 +++++++++++++++++
 lib/librte_eal/common/eal_internal_cfg.h        |   1 +
 lib/librte_eal/common/eal_options.h             |   2 +
 lib/librte_eal/common/eal_private.h             |  64 +++
 lib/librte_eal/common/include/rte_common.h      |  18 +
 lib/librte_eal/common/include/rte_dev.h         |  44 ++
 lib/librte_eal/common/include/rte_devargs.h     |   8 +
 lib/librte_eal/common/include/rte_pci.h         |  41 --
 lib/librte_eal/common/include/rte_soc.h         | 322 +++++++++++++++
 lib/librte_eal/linuxapp/eal/Makefile            |   2 +
 lib/librte_eal/linuxapp/eal/eal.c               |  63 +++
 lib/librte_eal/linuxapp/eal/eal_pci.c           |  62 +--
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c       |   2 +-
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c      |   5 +-
 lib/librte_eal/linuxapp/eal/eal_soc.c           | 515 ++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  11 +
 lib/librte_ether/rte_ethdev.c                   | 166 +++++++-
 lib/librte_ether/rte_ethdev.h                   |  33 +-
 36 files changed, 2343 insertions(+), 165 deletions(-)
 create mode 100644 app/test/test_soc.c
 create mode 100644 lib/librte_eal/bsdapp/eal/eal_soc.c
 create mode 100644 lib/librte_eal/common/eal_common_soc.c
 create mode 100644 lib/librte_eal/common/include/rte_soc.h
 create mode 100644 lib/librte_eal/linuxapp/eal/eal_soc.c

-- 
2.7.4

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

* [PATCH v6 01/21] eal: generalize PCI kernel driver enum to EAL
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
@ 2016-10-27 15:17         ` Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 02/21] eal: generalize PCI map/unmap resource " Shreyansh Jain
                           ` (19 subsequent siblings)
  20 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>

--
Changes since v0:
 - fix compilation error due to missing include
---
 lib/librte_eal/common/include/rte_dev.h | 12 ++++++++++++
 lib/librte_eal/common/include/rte_pci.h |  9 ---------
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 8840380..6975b9f 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -109,6 +109,18 @@ struct rte_mem_resource {
 	void *addr;         /**< Virtual address, NULL when not mapped. */
 };
 
+/**
+ * Kernel driver passthrough type
+ */
+enum rte_kernel_driver {
+	RTE_KDRV_UNKNOWN = 0,
+	RTE_KDRV_IGB_UIO,
+	RTE_KDRV_VFIO,
+	RTE_KDRV_UIO_GENERIC,
+	RTE_KDRV_NIC_UIO,
+	RTE_KDRV_NONE,
+};
+
 /** Double linked list of device drivers. */
 TAILQ_HEAD(rte_driver_list, rte_driver);
 /** Double linked list of devices. */
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 9ce8847..2c7046f 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -135,15 +135,6 @@ struct rte_pci_addr {
 
 struct rte_devargs;
 
-enum rte_kernel_driver {
-	RTE_KDRV_UNKNOWN = 0,
-	RTE_KDRV_IGB_UIO,
-	RTE_KDRV_VFIO,
-	RTE_KDRV_UIO_GENERIC,
-	RTE_KDRV_NIC_UIO,
-	RTE_KDRV_NONE,
-};
-
 /**
  * A structure describing a PCI device.
  */
-- 
2.7.4

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

* [PATCH v6 02/21] eal: generalize PCI map/unmap resource to EAL
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 01/21] eal: generalize PCI kernel driver enum to EAL Shreyansh Jain
@ 2016-10-27 15:17         ` Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 03/21] eal/linux: generalize PCI kernel unbinding driver " Shreyansh Jain
                           ` (18 subsequent siblings)
  20 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

The functions pci_map_resource, pci_unmap_resource are generic so the
pci_* prefix can be omitted. The functions are moved to the
eal_common_dev.c so they can be reused by other infrastructure.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_eal/bsdapp/eal/eal_pci.c             |  2 +-
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  2 ++
 lib/librte_eal/common/eal_common_dev.c          | 39 +++++++++++++++++++++++++
 lib/librte_eal/common/eal_common_pci.c          | 39 -------------------------
 lib/librte_eal/common/eal_common_pci_uio.c      | 16 +++++-----
 lib/librte_eal/common/include/rte_dev.h         | 32 ++++++++++++++++++++
 lib/librte_eal/common/include/rte_pci.h         | 32 --------------------
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c       |  2 +-
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c      |  5 ++--
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  2 ++
 10 files changed, 89 insertions(+), 82 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 8b3ed88..7ed0115 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -228,7 +228,7 @@ pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
 
 	/* if matching map is found, then use it */
 	offset = res_idx * pagesz;
-	mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
+	mapaddr = rte_eal_map_resource(NULL, fd, (off_t)offset,
 			(size_t)dev->mem_resource[res_idx].len, 0);
 	close(fd);
 	if (mapaddr == MAP_FAILED)
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 2f81f7c..11d9f59 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -170,6 +170,8 @@ DPDK_16.11 {
 	rte_delay_us_callback_register;
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
+	rte_eal_map_resource;
+	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
 
diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 4f3b493..457d227 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -36,6 +36,7 @@
 #include <string.h>
 #include <inttypes.h>
 #include <sys/queue.h>
+#include <sys/mman.h>
 
 #include <rte_dev.h>
 #include <rte_devargs.h>
@@ -151,3 +152,41 @@ err:
 	RTE_LOG(ERR, EAL, "Driver cannot detach the device (%s)\n", name);
 	return -EINVAL;
 }
+
+/* map a particular resource from a file */
+void *
+rte_eal_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
+		 int additional_flags)
+{
+	void *mapaddr;
+
+	/* Map the Memory resource of device */
+	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
+			MAP_SHARED | additional_flags, fd, offset);
+	if (mapaddr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s"
+			" (%p)\n", __func__, fd, requested_addr,
+			(unsigned long)size, (unsigned long)offset,
+			strerror(errno), mapaddr);
+	} else
+		RTE_LOG(DEBUG, EAL, "  Device memory mapped at %p\n", mapaddr);
+
+	return mapaddr;
+}
+
+/* unmap a particular resource */
+void
+rte_eal_unmap_resource(void *requested_addr, size_t size)
+{
+	if (requested_addr == NULL)
+		return;
+
+	/* Unmap the Memory resource of device */
+	if (munmap(requested_addr, size)) {
+		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
+			__func__, requested_addr, (unsigned long)size,
+			strerror(errno));
+	} else
+		RTE_LOG(DEBUG, EAL, "  Device memory unmapped at %p\n",
+				requested_addr);
+}
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 638cd86..464acc1 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -67,7 +67,6 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/queue.h>
-#include <sys/mman.h>
 
 #include <rte_interrupts.h>
 #include <rte_log.h>
@@ -114,44 +113,6 @@ static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
 	return NULL;
 }
 
-/* map a particular resource from a file */
-void *
-pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
-		 int additional_flags)
-{
-	void *mapaddr;
-
-	/* Map the PCI memory resource of device */
-	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
-			MAP_SHARED | additional_flags, fd, offset);
-	if (mapaddr == MAP_FAILED) {
-		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
-			__func__, fd, requested_addr,
-			(unsigned long)size, (unsigned long)offset,
-			strerror(errno), mapaddr);
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
-
-	return mapaddr;
-}
-
-/* unmap a particular resource */
-void
-pci_unmap_resource(void *requested_addr, size_t size)
-{
-	if (requested_addr == NULL)
-		return;
-
-	/* Unmap the PCI memory resource of device */
-	if (munmap(requested_addr, size)) {
-		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
-			__func__, requested_addr, (unsigned long)size,
-			strerror(errno));
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
-				requested_addr);
-}
-
 /*
  * If vendor/device ID match, call the probe() function of the
  * driver.
diff --git a/lib/librte_eal/common/eal_common_pci_uio.c b/lib/librte_eal/common/eal_common_pci_uio.c
index 367a681..3402518 100644
--- a/lib/librte_eal/common/eal_common_pci_uio.c
+++ b/lib/librte_eal/common/eal_common_pci_uio.c
@@ -75,9 +75,11 @@ pci_uio_map_secondary(struct rte_pci_device *dev)
 				return -1;
 			}
 
-			void *mapaddr = pci_map_resource(uio_res->maps[i].addr,
-					fd, (off_t)uio_res->maps[i].offset,
-					(size_t)uio_res->maps[i].size, 0);
+			void *mapaddr = rte_eal_map_resource(
+						uio_res->maps[i].addr, fd,
+						(off_t)uio_res->maps[i].offset,
+						(size_t)uio_res->maps[i].size,
+						0);
 			/* fd is not needed in slave process, close it */
 			close(fd);
 			if (mapaddr != uio_res->maps[i].addr) {
@@ -88,11 +90,11 @@ pci_uio_map_secondary(struct rte_pci_device *dev)
 				if (mapaddr != MAP_FAILED) {
 					/* unmap addrs correctly mapped */
 					for (j = 0; j < i; j++)
-						pci_unmap_resource(
+						rte_eal_unmap_resource(
 							uio_res->maps[j].addr,
 							(size_t)uio_res->maps[j].size);
 					/* unmap addr wrongly mapped */
-					pci_unmap_resource(mapaddr,
+					rte_eal_unmap_resource(mapaddr,
 						(size_t)uio_res->maps[i].size);
 				}
 				return -1;
@@ -150,7 +152,7 @@ pci_uio_map_resource(struct rte_pci_device *dev)
 	return 0;
 error:
 	for (i = 0; i < map_idx; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
+		rte_eal_unmap_resource(uio_res->maps[i].addr,
 				(size_t)uio_res->maps[i].size);
 		rte_free(uio_res->maps[i].path);
 	}
@@ -167,7 +169,7 @@ pci_uio_unmap(struct mapped_pci_resource *uio_res)
 		return;
 
 	for (i = 0; i != uio_res->nb_maps; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
+		rte_eal_unmap_resource(uio_res->maps[i].addr,
 				(size_t)uio_res->maps[i].size);
 		if (rte_eal_process_type() == RTE_PROC_PRIMARY)
 			rte_free(uio_res->maps[i].path);
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 6975b9f..5be6326 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -235,6 +235,38 @@ int rte_eal_dev_attach(const char *name, const char *devargs);
  */
 int rte_eal_dev_detach(const char *name);
 
+/*
+ * @internal
+ * Map a particular resource from a file.
+ *
+ * @param requested_addr
+ *      The starting address for the new mapping range.
+ * @param fd
+ *      The file descriptor.
+ * @param offset
+ *      The offset for the mapping range.
+ * @param size
+ *      The size for the mapping range.
+ * @param additional_flags
+ *      The additional flags for the mapping range.
+ * @return
+ *   - On success, the function returns a pointer to the mapped area.
+ *   - On error, the value MAP_FAILED is returned.
+ */
+void *rte_eal_map_resource(void *requested_addr, int fd, off_t offset,
+			   size_t size, int additional_flags);
+
+/**
+ * @internal
+ * Unmap a particular resource.
+ *
+ * @param requested_addr
+ *      The address for the unmapping range.
+ * @param size
+ *      The size for the unmapping range.
+ */
+void rte_eal_unmap_resource(void *requested_addr, size_t size);
+
 #define RTE_PMD_EXPORT_NAME_ARRAY(n, idx) n##idx[]
 
 #define RTE_PMD_EXPORT_NAME(name, idx) \
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 2c7046f..7d6eef5 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -399,38 +399,6 @@ int rte_eal_pci_map_device(struct rte_pci_device *dev);
 void rte_eal_pci_unmap_device(struct rte_pci_device *dev);
 
 /**
- * @internal
- * Map a particular resource from a file.
- *
- * @param requested_addr
- *      The starting address for the new mapping range.
- * @param fd
- *      The file descriptor.
- * @param offset
- *      The offset for the mapping range.
- * @param size
- *      The size for the mapping range.
- * @param additional_flags
- *      The additional flags for the mapping range.
- * @return
- *   - On success, the function returns a pointer to the mapped area.
- *   - On error, the value MAP_FAILED is returned.
- */
-void *pci_map_resource(void *requested_addr, int fd, off_t offset,
-		size_t size, int additional_flags);
-
-/**
- * @internal
- * Unmap a particular resource.
- *
- * @param requested_addr
- *      The address for the unmapping range.
- * @param size
- *      The size for the unmapping range.
- */
-void pci_unmap_resource(void *requested_addr, size_t size);
-
-/**
  * Probe the single PCI device.
  *
  * Scan the content of the PCI bus, and find the pci device specified by pci
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
index 1786b75..5c34421 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
@@ -347,7 +347,7 @@ pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
 	if (pci_map_addr == NULL)
 		pci_map_addr = pci_find_max_end_va();
 
-	mapaddr = pci_map_resource(pci_map_addr, fd, 0,
+	mapaddr = rte_eal_map_resource(pci_map_addr, fd, 0,
 			(size_t)dev->mem_resource[res_idx].len, 0);
 	close(fd);
 	if (mapaddr == MAP_FAILED)
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
index 5f478c5..5ad8cbe 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
@@ -465,7 +465,8 @@ pci_vfio_map_resource(struct rte_pci_device *dev)
 			void *map_addr = NULL;
 			if (memreg[0].size) {
 				/* actual map of first part */
-				map_addr = pci_map_resource(bar_addr, vfio_dev_fd,
+				map_addr = rte_eal_map_resource(bar_addr,
+							    vfio_dev_fd,
 							    memreg[0].offset,
 							    memreg[0].size,
 							    MAP_FIXED);
@@ -477,7 +478,7 @@ pci_vfio_map_resource(struct rte_pci_device *dev)
 				void *second_addr = RTE_PTR_ADD(bar_addr,
 								memreg[1].offset -
 								(uintptr_t)reg.offset);
-				map_addr = pci_map_resource(second_addr,
+				map_addr = rte_eal_map_resource(second_addr,
 							    vfio_dev_fd, memreg[1].offset,
 							    memreg[1].size,
 							    MAP_FIXED);
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 83721ba..22b5b59 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -174,6 +174,8 @@ DPDK_16.11 {
 	rte_delay_us_callback_register;
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
+	rte_eal_map_resource;
+	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
 
-- 
2.7.4

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

* [PATCH v6 03/21] eal/linux: generalize PCI kernel unbinding driver to EAL
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 01/21] eal: generalize PCI kernel driver enum to EAL Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 02/21] eal: generalize PCI map/unmap resource " Shreyansh Jain
@ 2016-10-27 15:17         ` Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 04/21] eal/linux: generalize PCI kernel driver extraction " Shreyansh Jain
                           ` (17 subsequent siblings)
  20 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Generalize the PCI-specific pci_unbind_kernel_driver. It is now divided
into two parts. First, determination of the path and string identification
of the device to be unbound. Second, the actual unbind operation which is
generic.

BSD implementation updated as ENOTSUP

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
--
Changes since v2:
 - update BSD support for unbind kernel driver
---
 lib/librte_eal/bsdapp/eal/eal.c       |  7 +++++++
 lib/librte_eal/bsdapp/eal/eal_pci.c   |  4 ++--
 lib/librte_eal/common/eal_private.h   | 13 +++++++++++++
 lib/librte_eal/linuxapp/eal/eal.c     | 26 ++++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/eal_pci.c | 33 +++++++++------------------------
 5 files changed, 57 insertions(+), 26 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 35e3117..5271fc2 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -633,3 +633,10 @@ rte_eal_process_type(void)
 {
 	return rte_config.process_type;
 }
+
+int
+rte_eal_unbind_kernel_driver(const char *devpath __rte_unused,
+			     const char *devid __rte_unused)
+{
+	return -ENOTSUP;
+}
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 7ed0115..703f034 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -89,11 +89,11 @@
 
 /* unbind kernel driver for this device */
 int
-pci_unbind_kernel_driver(struct rte_pci_device *dev __rte_unused)
+pci_unbind_kernel_driver(struct rte_pci_device *dev)
 {
 	RTE_LOG(ERR, EAL, "RTE_PCI_DRV_FORCE_UNBIND flag is not implemented "
 		"for BSD\n");
-	return -ENOTSUP;
+	return rte_eal_unbind_kernel_driver(dev);
 }
 
 /* Map pci device */
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 9e7d8f6..b0c208a 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -256,6 +256,19 @@ int rte_eal_alarm_init(void);
 int rte_eal_check_module(const char *module_name);
 
 /**
+ * Unbind kernel driver bound to the device specified by the given devpath,
+ * and its string identification.
+ *
+ * @param devpath  path to the device directory ("/sys/.../devices/<name>")
+ * @param devid    identification of the device (<name>)
+ *
+ * @return
+ *      -1  unbind has failed
+ *       0  module has been unbound
+ */
+int rte_eal_unbind_kernel_driver(const char *devpath, const char *devid);
+
+/**
  * Get cpu core_id.
  *
  * This function is private to the EAL.
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 2075282..5f6676d 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -943,3 +943,29 @@ rte_eal_check_module(const char *module_name)
 	/* Module has been found */
 	return 1;
 }
+
+int
+rte_eal_unbind_kernel_driver(const char *devpath, const char *devid)
+{
+	char filename[PATH_MAX];
+	FILE *f;
+
+	snprintf(filename, sizeof(filename),
+		 "%s/driver/unbind", devpath);
+
+	f = fopen(filename, "w");
+	if (f == NULL) /* device was not bound */
+		return 0;
+
+	if (fwrite(devid, strlen(devid), 1, f) == 0) {
+		RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
+				filename);
+		goto error;
+	}
+
+	fclose(f);
+	return 0;
+error:
+	fclose(f);
+	return -1;
+}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index 876ba38..a03553f 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -59,38 +59,23 @@ int
 pci_unbind_kernel_driver(struct rte_pci_device *dev)
 {
 	int n;
-	FILE *f;
-	char filename[PATH_MAX];
-	char buf[BUFSIZ];
+	char devpath[PATH_MAX];
+	char devid[BUFSIZ];
 	struct rte_pci_addr *loc = &dev->addr;
 
-	/* open /sys/bus/pci/devices/AAAA:BB:CC.D/driver */
-	snprintf(filename, sizeof(filename),
-		"%s/" PCI_PRI_FMT "/driver/unbind", pci_get_sysfs_path(),
+	/* devpath /sys/bus/pci/devices/AAAA:BB:CC.D */
+	snprintf(devpath, sizeof(devpath),
+		"%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
 		loc->domain, loc->bus, loc->devid, loc->function);
 
-	f = fopen(filename, "w");
-	if (f == NULL) /* device was not bound */
-		return 0;
-
-	n = snprintf(buf, sizeof(buf), PCI_PRI_FMT "\n",
+	n = snprintf(devid, sizeof(devid), PCI_PRI_FMT "\n",
 	             loc->domain, loc->bus, loc->devid, loc->function);
-	if ((n < 0) || (n >= (int)sizeof(buf))) {
+	if ((n < 0) || (n >= (int)sizeof(devid))) {
 		RTE_LOG(ERR, EAL, "%s(): snprintf failed\n", __func__);
-		goto error;
-	}
-	if (fwrite(buf, n, 1, f) == 0) {
-		RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
-				filename);
-		goto error;
+		return -1;
 	}
 
-	fclose(f);
-	return 0;
-
-error:
-	fclose(f);
-	return -1;
+	return rte_eal_unbind_kernel_driver(devpath, devid);
 }
 
 static int
-- 
2.7.4

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

* [PATCH v6 04/21] eal/linux: generalize PCI kernel driver extraction to EAL
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                           ` (2 preceding siblings ...)
  2016-10-27 15:17         ` [PATCH v6 03/21] eal/linux: generalize PCI kernel unbinding driver " Shreyansh Jain
@ 2016-10-27 15:17         ` Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 05/21] eal: define container macro Shreyansh Jain
                           ` (16 subsequent siblings)
  20 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Generalize the PCI-specific pci_get_kernel_driver_by_path. The function
is general enough, we have just moved it to eal.c, changed the prefix to
rte_eal and provided it privately to other parts of EAL.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_eal/bsdapp/eal/eal.c       |  7 +++++++
 lib/librte_eal/common/eal_private.h   | 14 ++++++++++++++
 lib/librte_eal/linuxapp/eal/eal.c     | 29 +++++++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/eal_pci.c | 31 +------------------------------
 4 files changed, 51 insertions(+), 30 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 5271fc2..9b93da3 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -640,3 +640,10 @@ rte_eal_unbind_kernel_driver(const char *devpath __rte_unused,
 {
 	return -ENOTSUP;
 }
+
+int
+rte_eal_get_kernel_driver_by_path(const char *filename __rte_unused,
+				  char *dri_name __rte_unused)
+{
+	return -ENOTSUP;
+}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index b0c208a..c8c2131 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -269,6 +269,20 @@ int rte_eal_check_module(const char *module_name);
 int rte_eal_unbind_kernel_driver(const char *devpath, const char *devid);
 
 /**
+ * Extract the kernel driver name from the absolute path to the driver.
+ *
+ * @param filename  path to the driver ("<path-to-device>/driver")
+ * @path  dri_name  target buffer where to place the driver name
+ *                  (should be at least PATH_MAX long)
+ *
+ * @return
+ *      -1   on failure
+ *       0   when successful
+ *       1   when there is no such driver
+ */
+int rte_eal_get_kernel_driver_by_path(const char *filename, char *dri_name);
+
+/**
  * Get cpu core_id.
  *
  * This function is private to the EAL.
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 5f6676d..00af21c 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -969,3 +969,32 @@ error:
 	fclose(f);
 	return -1;
 }
+
+int
+rte_eal_get_kernel_driver_by_path(const char *filename, char *dri_name)
+{
+	int count;
+	char path[PATH_MAX];
+	char *name;
+
+	if (!filename || !dri_name)
+		return -1;
+
+	count = readlink(filename, path, PATH_MAX);
+	if (count >= PATH_MAX)
+		return -1;
+
+	/* For device does not have a driver */
+	if (count < 0)
+		return 1;
+
+	path[count] = '\0';
+
+	name = strrchr(path, '/');
+	if (name) {
+		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
+		return 0;
+	}
+
+	return -1;
+}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index a03553f..e1cf9e8 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -78,35 +78,6 @@ pci_unbind_kernel_driver(struct rte_pci_device *dev)
 	return rte_eal_unbind_kernel_driver(devpath, devid);
 }
 
-static int
-pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
-{
-	int count;
-	char path[PATH_MAX];
-	char *name;
-
-	if (!filename || !dri_name)
-		return -1;
-
-	count = readlink(filename, path, PATH_MAX);
-	if (count >= PATH_MAX)
-		return -1;
-
-	/* For device does not have a driver */
-	if (count < 0)
-		return 1;
-
-	path[count] = '\0';
-
-	name = strrchr(path, '/');
-	if (name) {
-		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
-		return 0;
-	}
-
-	return -1;
-}
-
 /* Map pci device */
 int
 rte_eal_pci_map_device(struct rte_pci_device *dev)
@@ -354,7 +325,7 @@ pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus,
 
 	/* parse driver */
 	snprintf(filename, sizeof(filename), "%s/driver", dirname);
-	ret = pci_get_kernel_driver_by_path(filename, driver);
+	ret = rte_eal_get_kernel_driver_by_path(filename, driver);
 	if (ret < 0) {
 		RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
 		free(dev);
-- 
2.7.4

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

* [PATCH v6 05/21] eal: define container macro
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                           ` (3 preceding siblings ...)
  2016-10-27 15:17         ` [PATCH v6 04/21] eal/linux: generalize PCI kernel driver extraction " Shreyansh Jain
@ 2016-10-27 15:17         ` Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 06/21] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
                           ` (15 subsequent siblings)
  20 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_eal/common/include/rte_common.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h
index db5ac91..8152bd9 100644
--- a/lib/librte_eal/common/include/rte_common.h
+++ b/lib/librte_eal/common/include/rte_common.h
@@ -331,6 +331,24 @@ rte_bsf32(uint32_t v)
 #define offsetof(TYPE, MEMBER)  __builtin_offsetof (TYPE, MEMBER)
 #endif
 
+/**
+ * Return pointer to the wrapping struct instance.
+ * Example:
+ *
+ *  struct wrapper {
+ *      ...
+ *      struct child c;
+ *      ...
+ *  };
+ *
+ *  struct child *x = obtain(...);
+ *  struct wrapper *w = container_of(x, struct wrapper, c);
+ */
+#ifndef container_of
+#define container_of(p, type, member) \
+	((type *) (((char *) (p)) - offsetof(type, member)))
+#endif
+
 #define _RTE_STR(x) #x
 /** Take a macro value and get a string version of it */
 #define RTE_STR(x) _RTE_STR(x)
-- 
2.7.4

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

* [PATCH v6 06/21] eal/soc: introduce very essential SoC infra definitions
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                           ` (4 preceding siblings ...)
  2016-10-27 15:17         ` [PATCH v6 05/21] eal: define container macro Shreyansh Jain
@ 2016-10-27 15:17         ` Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 07/21] eal/soc: add SoC PMD register/unregister logic Shreyansh Jain
                           ` (14 subsequent siblings)
  20 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Define initial structures and functions for the SoC infrastructure.
This patch supports only a very minimal functions for now.
More features will be added in the following commits.

Includes rte_device/rte_driver inheritance of
rte_soc_device/rte_soc_driver.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 app/test/Makefile                       |   1 +
 app/test/test_soc.c                     |  90 +++++++++++++++++++++
 lib/librte_eal/common/Makefile          |   2 +-
 lib/librte_eal/common/eal_private.h     |   4 +
 lib/librte_eal/common/include/rte_soc.h | 138 ++++++++++++++++++++++++++++++++
 5 files changed, 234 insertions(+), 1 deletion(-)
 create mode 100644 app/test/test_soc.c
 create mode 100644 lib/librte_eal/common/include/rte_soc.h

diff --git a/app/test/Makefile b/app/test/Makefile
index 5be023a..30295af 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -77,6 +77,7 @@ APP = test
 #
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) := commands.c
 SRCS-y += test.c
+SRCS-y += test_soc.c
 SRCS-y += resource.c
 SRCS-y += test_resource.c
 test_resource.res: test_resource.c
diff --git a/app/test/test_soc.c b/app/test/test_soc.c
new file mode 100644
index 0000000..916a863
--- /dev/null
+++ b/app/test/test_soc.c
@@ -0,0 +1,90 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <sys/queue.h>
+
+#include <rte_soc.h>
+#include <rte_devargs.h>
+#include <rte_debug.h>
+
+#include "test.h"
+
+static char *safe_strdup(const char *s)
+{
+	char *c = strdup(s);
+
+	if (c == NULL)
+		rte_panic("failed to strdup '%s'\n", s);
+
+	return c;
+}
+
+static int test_compare_addr(void)
+{
+	struct rte_soc_addr a0;
+	struct rte_soc_addr a1;
+	struct rte_soc_addr a2;
+
+	a0.name = safe_strdup("ethernet0");
+	a0.fdt_path = NULL;
+
+	a1.name = safe_strdup("ethernet0");
+	a1.fdt_path = NULL;
+
+	a2.name = safe_strdup("ethernet1");
+	a2.fdt_path = NULL;
+
+	TEST_ASSERT(!rte_eal_compare_soc_addr(&a0, &a1),
+		    "Failed to compare two soc addresses that equal");
+	TEST_ASSERT(rte_eal_compare_soc_addr(&a0, &a2),
+		    "Failed to compare two soc addresses that differs");
+
+	free(a2.name);
+	free(a1.name);
+	free(a0.name);
+	return 0;
+}
+
+static int
+test_soc(void)
+{
+	if (test_compare_addr())
+		return -1;
+
+	return 0;
+}
+
+REGISTER_TEST_COMMAND(soc_autotest, test_soc);
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index dfd64aa..b414008 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 INC := rte_branch_prediction.h rte_common.h
 INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
-INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
+INC += rte_log.h rte_memory.h rte_memzone.h rte_soc.h rte_pci.h
 INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index c8c2131..0e8d6f7 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -36,6 +36,7 @@
 
 #include <stdio.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 
 /**
  * Initialize the memzone subsystem (private to eal).
@@ -118,6 +119,9 @@ int rte_eal_log_init(const char *id, int facility);
  */
 int rte_eal_pci_init(void);
 
+struct rte_soc_driver;
+struct rte_soc_device;
+
 struct rte_pci_driver;
 struct rte_pci_device;
 
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
new file mode 100644
index 0000000..5c32737
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -0,0 +1,138 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_SOC_H_
+#define _RTE_SOC_H_
+
+/**
+ * @file
+ *
+ * RTE SoC Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include <rte_dev.h>
+#include <rte_debug.h>
+
+struct rte_soc_id {
+	const char *compatible; /**< OF compatible specification */
+	uint64_t priv_data;     /**< SoC Driver specific data */
+};
+
+struct rte_soc_addr {
+	char *name;     /**< name used in sysfs */
+	char *fdt_path; /**< path to the associated node in FDT */
+};
+
+/**
+ * A structure describing a SoC device.
+ */
+struct rte_soc_device {
+	TAILQ_ENTRY(rte_soc_device) next;   /**< Next probed SoC device */
+	struct rte_device device;           /**< Inherit code device */
+	struct rte_soc_addr addr;           /**< SoC device Location */
+	struct rte_soc_id *id;              /**< SoC device ID list */
+	struct rte_soc_driver *driver;      /**< Associated driver */
+};
+
+struct rte_soc_driver;
+
+/**
+ * Probe function for the driver called during SoC probing.
+ */
+typedef int (soc_probe_t)(struct rte_soc_driver *, struct rte_soc_device *);
+
+/**
+ * Remove function for the driver called during hotplugging.
+ */
+typedef int (soc_remove_t)(struct rte_soc_device *);
+
+/**
+ * A structure describing a SoC driver.
+ */
+struct rte_soc_driver {
+	TAILQ_ENTRY(rte_soc_driver) next;  /**< Next in list */
+	struct rte_driver driver;          /**< Inherit core driver. */
+	soc_probe_t *probe;                /**< Device probe */
+	soc_remove_t *remove;              /**< Device remove */
+	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
+};
+
+/**
+ * Utility function to write a SoC device name, this device name can later be
+ * used to retrieve the corresponding rte_soc_addr using above functions.
+ *
+ * @param addr
+ *	The SoC address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ * @return
+ *  0 on success, negative on error.
+ */
+static inline void
+rte_eal_soc_device_name(const struct rte_soc_addr *addr,
+			char *output, size_t size)
+{
+	int ret;
+
+	RTE_VERIFY(addr != NULL);
+	RTE_VERIFY(size >= strlen(addr->name));
+	ret = snprintf(output, size, "%s", addr->name);
+	RTE_VERIFY(ret >= 0);
+}
+
+static inline int
+rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
+			 const struct rte_soc_addr *a1)
+{
+	if (a0 == NULL || a1 == NULL)
+		return -1;
+
+	RTE_VERIFY(a0->name != NULL);
+	RTE_VERIFY(a1->name != NULL);
+
+	return strcmp(a0->name, a1->name);
+}
+
+#endif
-- 
2.7.4

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

* [PATCH v6 07/21] eal/soc: add SoC PMD register/unregister logic
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                           ` (5 preceding siblings ...)
  2016-10-27 15:17         ` [PATCH v6 06/21] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
@ 2016-10-27 15:17         ` Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 08/21] eal/soc: implement SoC device list and dump Shreyansh Jain
                           ` (13 subsequent siblings)
  20 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Registeration of a SoC driver through a helper RTE_PMD_REGISTER_SOC
(on the lines of RTE_PMD_REGISTER_PCI). soc_driver_list stores all the
registered drivers.

Test case has been introduced to verify the registration and
deregistration.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: update PMD registration method]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 app/test/test_soc.c                             | 111 ++++++++++++++++++++++++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   3 +
 lib/librte_eal/common/eal_common_soc.c          |  56 ++++++++++++
 lib/librte_eal/common/include/rte_soc.h         |  26 ++++++
 lib/librte_eal/linuxapp/eal/Makefile            |   1 +
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   3 +
 6 files changed, 200 insertions(+)
 create mode 100644 lib/librte_eal/common/eal_common_soc.c

diff --git a/app/test/test_soc.c b/app/test/test_soc.c
index 916a863..ac03e64 100644
--- a/app/test/test_soc.c
+++ b/app/test/test_soc.c
@@ -75,6 +75,108 @@ static int test_compare_addr(void)
 	free(a2.name);
 	free(a1.name);
 	free(a0.name);
+
+	return 0;
+}
+
+/**
+ * Empty PMD driver based on the SoC infra.
+ *
+ * The rte_soc_device is usually wrapped in some higher-level struct
+ * (eth_driver). We simulate such a wrapper with an anonymous struct here.
+ */
+struct test_wrapper {
+	struct rte_soc_driver soc_drv;
+};
+
+struct test_wrapper empty_pmd0 = {
+	.soc_drv = {
+		.driver = {
+			.name = "empty_pmd0"
+		},
+	},
+};
+
+struct test_wrapper empty_pmd1 = {
+	.soc_drv = {
+		.driver = {
+			.name = "empty_pmd1"
+		},
+	},
+};
+
+static int
+count_registered_socdrvs(void)
+{
+	int i;
+	struct rte_soc_driver *drv;
+
+	i = 0;
+	TAILQ_FOREACH(drv, &soc_driver_list, next)
+		i += 1;
+
+	return i;
+}
+
+static int
+test_register_unregister(void)
+{
+	struct rte_soc_driver *drv;
+	int count;
+
+	rte_eal_soc_register(&empty_pmd0.soc_drv);
+
+	TEST_ASSERT(!TAILQ_EMPTY(&soc_driver_list),
+		    "No PMD is present but the empty_pmd0 should be there");
+	drv = TAILQ_FIRST(&soc_driver_list);
+	TEST_ASSERT(!strcmp(drv->driver.name, "empty_pmd0"),
+		    "The registered PMD is not empty_pmd0 but '%s'",
+		drv->driver.name);
+
+	rte_eal_soc_register(&empty_pmd1.soc_drv);
+
+	count = count_registered_socdrvs();
+	TEST_ASSERT_EQUAL(count, 2, "Expected 2 PMDs but detected %d", count);
+
+	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
+	count = count_registered_socdrvs();
+	TEST_ASSERT_EQUAL(count, 1, "Expected 1 PMDs but detected %d", count);
+
+	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
+
+	printf("%s has been successful\n", __func__);
+	return 0;
+}
+
+/* save real devices and drivers until the tests finishes */
+struct soc_driver_list real_soc_driver_list =
+	TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
+
+static int test_soc_setup(void)
+{
+	struct rte_soc_driver *drv;
+
+	/* no real drivers for the test */
+	while (!TAILQ_EMPTY(&soc_driver_list)) {
+		drv = TAILQ_FIRST(&soc_driver_list);
+		rte_eal_soc_unregister(drv);
+		TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
+	}
+
+	return 0;
+}
+
+static int test_soc_cleanup(void)
+{
+	struct rte_soc_driver *drv;
+
+	/* bring back real drivers after the test */
+	while (!TAILQ_EMPTY(&real_soc_driver_list)) {
+		drv = TAILQ_FIRST(&real_soc_driver_list);
+		TAILQ_REMOVE(&real_soc_driver_list, drv, next);
+		rte_eal_soc_register(drv);
+	}
+
 	return 0;
 }
 
@@ -84,6 +186,15 @@ test_soc(void)
 	if (test_compare_addr())
 		return -1;
 
+	if (test_soc_setup())
+		return -1;
+
+	if (test_register_unregister())
+		return -1;
+
+	if (test_soc_cleanup())
+		return -1;
+
 	return 0;
 }
 
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 11d9f59..cf6fb8e 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -171,8 +171,11 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_register;
+	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
+	soc_driver_list;
 
 } DPDK_16.07;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
new file mode 100644
index 0000000..56135ed
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -0,0 +1,56 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/queue.h>
+
+#include <rte_log.h>
+
+#include "eal_private.h"
+
+/* Global SoC driver list */
+struct soc_driver_list soc_driver_list =
+	TAILQ_HEAD_INITIALIZER(soc_driver_list);
+
+/* register a driver */
+void
+rte_eal_soc_register(struct rte_soc_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_eal_soc_unregister(struct rte_soc_driver *driver)
+{
+	TAILQ_REMOVE(&soc_driver_list, driver, next);
+}
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 5c32737..23b06a9 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -51,8 +51,14 @@ extern "C" {
 #include <string.h>
 
 #include <rte_dev.h>
+#include <rte_eal.h>
 #include <rte_debug.h>
 
+extern struct soc_driver_list soc_driver_list;
+/**< Global list of SoC Drivers */
+
+TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
+
 struct rte_soc_id {
 	const char *compatible; /**< OF compatible specification */
 	uint64_t priv_data;     /**< SoC Driver specific data */
@@ -135,4 +141,24 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 	return strcmp(a0->name, a1->name);
 }
 
+/**
+ * Register a SoC driver.
+ */
+void rte_eal_soc_register(struct rte_soc_driver *driver);
+
+/** Helper for SoC device registeration from PMD Drivers */
+#define RTE_PMD_REGISTER_SOC(nm, soc_drv) \
+RTE_INIT(socinitfn_ ##name); \
+static void socinitfn_ ##name(void) \
+{\
+	(soc_drv).driver.name = RTE_STR(nm);\
+	rte_eal_soc_register(&soc_drv); \
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+/**
+ * Unregister a SoC driver.
+ */
+void rte_eal_soc_unregister(struct rte_soc_driver *driver);
+
 #endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 4e206f0..a520477 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -77,6 +77,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 22b5b59..ab6b985 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -175,8 +175,11 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_register;
+	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
+	soc_driver_list;
 
 } DPDK_16.07;
-- 
2.7.4

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

* [PATCH v6 08/21] eal/soc: implement SoC device list and dump
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                           ` (6 preceding siblings ...)
  2016-10-27 15:17         ` [PATCH v6 07/21] eal/soc: add SoC PMD register/unregister logic Shreyansh Jain
@ 2016-10-27 15:17         ` Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 09/21] eal: introduce command line enable SoC option Shreyansh Jain
                           ` (12 subsequent siblings)
  20 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

SoC devices would be linked in a separate list (from PCI). This is used for
probe function.
A helper for dumping the device list is added.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  2 ++
 lib/librte_eal/common/eal_common_soc.c          | 34 +++++++++++++++++++++++++
 lib/librte_eal/common/include/rte_soc.h         |  9 +++++++
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  2 ++
 4 files changed, 47 insertions(+)

diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index cf6fb8e..86e3cfd 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -171,11 +171,13 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_dump;
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
+	soc_device_list;
 	soc_driver_list;
 
 } DPDK_16.07;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 56135ed..5dcddc5 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -31,6 +31,8 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <stddef.h>
+#include <stdio.h>
 #include <sys/queue.h>
 
 #include <rte_log.h>
@@ -40,6 +42,38 @@
 /* Global SoC driver list */
 struct soc_driver_list soc_driver_list =
 	TAILQ_HEAD_INITIALIZER(soc_driver_list);
+struct soc_device_list soc_device_list =
+	TAILQ_HEAD_INITIALIZER(soc_device_list);
+
+/* dump one device */
+static int
+soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
+{
+	int i;
+
+	fprintf(f, "%s", dev->addr.name);
+	fprintf(f, " - fdt_path: %s\n",
+			dev->addr.fdt_path ? dev->addr.fdt_path : "(none)");
+
+	for (i = 0; dev->id && dev->id[i].compatible; ++i)
+		fprintf(f, "   %s\n", dev->id[i].compatible);
+
+	return 0;
+}
+
+/* dump devices on the bus to an output stream */
+void
+rte_eal_soc_dump(FILE *f)
+{
+	struct rte_soc_device *dev = NULL;
+
+	if (!f)
+		return;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		soc_dump_one_device(f, dev);
+	}
+}
 
 /* register a driver */
 void
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 23b06a9..347e611 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -56,8 +56,12 @@ extern "C" {
 
 extern struct soc_driver_list soc_driver_list;
 /**< Global list of SoC Drivers */
+extern struct soc_device_list soc_device_list;
+/**< Global list of SoC Devices */
 
 TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
+TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
+
 
 struct rte_soc_id {
 	const char *compatible; /**< OF compatible specification */
@@ -142,6 +146,11 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 }
 
 /**
+ * Dump discovered SoC devices.
+ */
+void rte_eal_soc_dump(FILE *f);
+
+/**
  * Register a SoC driver.
  */
 void rte_eal_soc_register(struct rte_soc_driver *driver);
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index ab6b985..0155025 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -175,11 +175,13 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_dump;
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
+	soc_device_list;
 	soc_driver_list;
 
 } DPDK_16.07;
-- 
2.7.4

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

* [PATCH v6 09/21] eal: introduce command line enable SoC option
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                           ` (7 preceding siblings ...)
  2016-10-27 15:17         ` [PATCH v6 08/21] eal/soc: implement SoC device list and dump Shreyansh Jain
@ 2016-10-27 15:17         ` Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 10/21] eal/soc: init SoC infra from EAL Shreyansh Jain
                           ` (11 subsequent siblings)
  20 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Support --enable-soc. SoC support is disabled by default.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: Change --no-soc to --enable-soc; disabled by default]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 doc/guides/testpmd_app_ug/run_app.rst      | 4 ++++
 lib/librte_eal/common/eal_common_options.c | 5 +++++
 lib/librte_eal/common/eal_internal_cfg.h   | 1 +
 lib/librte_eal/common/eal_options.h        | 2 ++
 4 files changed, 12 insertions(+)

diff --git a/doc/guides/testpmd_app_ug/run_app.rst b/doc/guides/testpmd_app_ug/run_app.rst
index d7c5120..4dafe5f 100644
--- a/doc/guides/testpmd_app_ug/run_app.rst
+++ b/doc/guides/testpmd_app_ug/run_app.rst
@@ -156,6 +156,10 @@ See the DPDK Getting Started Guides for more information on these options.
 
     Use malloc instead of hugetlbfs.
 
+*   ``--enable-soc``
+
+    Enable SoC framework support
+
 
 Testpmd Command-line Options
 ----------------------------
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 6ca8af1..2156ab3 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -75,6 +75,7 @@ const struct option
 eal_long_options[] = {
 	{OPT_BASE_VIRTADDR,     1, NULL, OPT_BASE_VIRTADDR_NUM    },
 	{OPT_CREATE_UIO_DEV,    0, NULL, OPT_CREATE_UIO_DEV_NUM   },
+	{OPT_ENABLE_SOC,        0, NULL, OPT_ENABLE_SOC_NUM       },
 	{OPT_FILE_PREFIX,       1, NULL, OPT_FILE_PREFIX_NUM      },
 	{OPT_HELP,              0, NULL, OPT_HELP_NUM             },
 	{OPT_HUGE_DIR,          1, NULL, OPT_HUGE_DIR_NUM         },
@@ -843,6 +844,10 @@ eal_parse_common_option(int opt, const char *optarg,
 		break;
 
 	/* long options */
+	case OPT_ENABLE_SOC_NUM:
+		conf->enable_soc = 1;
+		break;
+
 	case OPT_HUGE_UNLINK_NUM:
 		conf->hugepage_unlink = 1;
 		break;
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 5f1367e..2a6e3ea 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -67,6 +67,7 @@ struct internal_config {
 	unsigned hugepage_unlink;         /**< true to unlink backing files */
 	volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
 	volatile unsigned no_pci;         /**< true to disable PCI */
+	volatile unsigned enable_soc;     /**< true to enable SoC */
 	volatile unsigned no_hpet;        /**< true to disable HPET */
 	volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
 										* instead of native TSC */
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index a881c62..6e679c3 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -49,6 +49,8 @@ enum {
 	OPT_BASE_VIRTADDR_NUM,
 #define OPT_CREATE_UIO_DEV    "create-uio-dev"
 	OPT_CREATE_UIO_DEV_NUM,
+#define OPT_ENABLE_SOC        "enable-soc"
+	OPT_ENABLE_SOC_NUM,
 #define OPT_FILE_PREFIX       "file-prefix"
 	OPT_FILE_PREFIX_NUM,
 #define OPT_HUGE_DIR          "huge-dir"
-- 
2.7.4

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

* [PATCH v6 10/21] eal/soc: init SoC infra from EAL
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                           ` (8 preceding siblings ...)
  2016-10-27 15:17         ` [PATCH v6 09/21] eal: introduce command line enable SoC option Shreyansh Jain
@ 2016-10-27 15:17         ` Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 12/21] eal/soc: extend and utilize devargs Shreyansh Jain
                           ` (10 subsequent siblings)
  20 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/bsdapp/eal/Makefile    |  1 +
 lib/librte_eal/bsdapp/eal/eal.c       |  4 +++
 lib/librte_eal/bsdapp/eal/eal_soc.c   | 46 ++++++++++++++++++++++++++++
 lib/librte_eal/common/eal_private.h   | 10 +++++++
 lib/librte_eal/linuxapp/eal/Makefile  |  1 +
 lib/librte_eal/linuxapp/eal/eal.c     |  3 ++
 lib/librte_eal/linuxapp/eal/eal_soc.c | 56 +++++++++++++++++++++++++++++++++++
 7 files changed, 121 insertions(+)
 create mode 100644 lib/librte_eal/bsdapp/eal/eal_soc.c
 create mode 100644 lib/librte_eal/linuxapp/eal/eal_soc.c

diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index a15b762..42b3a2b 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -56,6 +56,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_hugepage_info.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_pci.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_timer.c
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 9b93da3..2d62b9d 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -64,6 +64,7 @@
 #include <rte_string_fns.h>
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
+#include <rte_soc.h>
 #include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
@@ -564,6 +565,9 @@ rte_eal_init(int argc, char **argv)
 	if (rte_eal_pci_init() < 0)
 		rte_panic("Cannot init PCI\n");
 
+	if (rte_eal_soc_init() < 0)
+		rte_panic("Cannot init SoC\n");
+
 	eal_check_mem_on_local_socket();
 
 	if (eal_plugins_init() < 0)
diff --git a/lib/librte_eal/bsdapp/eal/eal_soc.c b/lib/librte_eal/bsdapp/eal/eal_soc.c
new file mode 100644
index 0000000..cb297ff
--- /dev/null
+++ b/lib/librte_eal/bsdapp/eal/eal_soc.c
@@ -0,0 +1,46 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <rte_common.h>
+#include <rte_log.h>
+
+#include <eal_private.h>
+
+/* Init the SoC EAL subsystem */
+int
+rte_eal_soc_init(void)
+{
+	return 0;
+}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 0e8d6f7..d810f9f 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -122,6 +122,16 @@ int rte_eal_pci_init(void);
 struct rte_soc_driver;
 struct rte_soc_device;
 
+/**
+ * Init the SoC infra.
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int rte_eal_soc_init(void);
+
 struct rte_pci_driver;
 struct rte_pci_device;
 
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index a520477..59e30fa 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -65,6 +65,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio_mp_sync.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_vfio.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 00af21c..098ba02 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -810,6 +810,9 @@ rte_eal_init(int argc, char **argv)
 		rte_panic("Cannot init VFIO\n");
 #endif
 
+	if (rte_eal_soc_init() < 0)
+		rte_panic("Cannot init SoC\n");
+
 	if (rte_eal_memory_init() < 0)
 		rte_panic("Cannot init memory\n");
 
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
new file mode 100644
index 0000000..04848b9
--- /dev/null
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -0,0 +1,56 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <rte_log.h>
+#include <rte_soc.h>
+
+#include "eal_internal_cfg.h"
+#include "eal_filesystem.h"
+#include "eal_private.h"
+
+/* Init the SoC EAL subsystem */
+int
+rte_eal_soc_init(void)
+{
+	return 0;
+}
-- 
2.7.4

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

* [PATCH v6 12/21] eal/soc: extend and utilize devargs
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                           ` (9 preceding siblings ...)
  2016-10-27 15:17         ` [PATCH v6 10/21] eal/soc: init SoC infra from EAL Shreyansh Jain
@ 2016-10-27 15:17         ` Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 13/21] eal/soc: add drv_flags Shreyansh Jain
                           ` (9 subsequent siblings)
  20 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

It is assumed that SoC Devices provided on command line are prefixed with
"soc:". This patch adds parse and attach support for such devices.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/common/eal_common_dev.c      | 27 +++++++++----
 lib/librte_eal/common/eal_common_devargs.c  | 17 ++++++++
 lib/librte_eal/common/eal_common_soc.c      | 61 ++++++++++++++++++++++++-----
 lib/librte_eal/common/include/rte_devargs.h |  8 ++++
 lib/librte_eal/common/include/rte_soc.h     | 24 ++++++++++++
 5 files changed, 120 insertions(+), 17 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 457d227..ebbcf47 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -107,17 +107,23 @@ rte_eal_dev_init(void)
 
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
-	struct rte_pci_addr addr;
+	struct rte_soc_addr soc_addr;
+	struct rte_pci_addr pci_addr;
 
 	if (name == NULL || devargs == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
 		return -EINVAL;
 	}
 
-	if (eal_parse_pci_DomBDF(name, &addr) == 0) {
-		if (rte_eal_pci_probe_one(&addr) < 0)
+	memset(&soc_addr, 0, sizeof(soc_addr));
+	if (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+		if (rte_eal_soc_probe_one(&soc_addr) < 0) {
+			free(soc_addr.name);
+			goto err;
+		}
+	} else if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+		if (rte_eal_pci_probe_one(&pci_addr) < 0)
 			goto err;
-
 	} else {
 		if (rte_eal_vdev_init(name, devargs))
 			goto err;
@@ -132,15 +138,22 @@ err:
 
 int rte_eal_dev_detach(const char *name)
 {
-	struct rte_pci_addr addr;
+	struct rte_soc_addr soc_addr;
+	struct rte_pci_addr pci_addr;
 
 	if (name == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device provided.\n");
 		return -EINVAL;
 	}
 
-	if (eal_parse_pci_DomBDF(name, &addr) == 0) {
-		if (rte_eal_pci_detach(&addr) < 0)
+	memset(&soc_addr, 0, sizeof(soc_addr));
+	if (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+		if (rte_eal_soc_detach(&soc_addr) < 0) {
+			free(soc_addr.name);
+			goto err;
+		}
+	} else if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+		if (rte_eal_pci_detach(&pci_addr) < 0)
 			goto err;
 	} else {
 		if (rte_eal_vdev_uninit(name))
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index e403717..e1dae1a 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -41,6 +41,7 @@
 #include <string.h>
 
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_devargs.h>
 #include "eal_private.h"
 
@@ -105,6 +106,14 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
 			goto fail;
 
 		break;
+
+	case RTE_DEVTYPE_WHITELISTED_SOC:
+	case RTE_DEVTYPE_BLACKLISTED_SOC:
+		/* try to parse soc device with prefix "soc:" */
+		if (rte_eal_parse_soc_spec(buf, &devargs->soc.addr) != 0)
+			goto fail;
+		break;
+
 	case RTE_DEVTYPE_VIRTUAL:
 		/* save driver name */
 		ret = snprintf(devargs->virt.drv_name,
@@ -166,6 +175,14 @@ rte_eal_devargs_dump(FILE *f)
 			       devargs->pci.addr.devid,
 			       devargs->pci.addr.function,
 			       devargs->args);
+		else if (devargs->type == RTE_DEVTYPE_WHITELISTED_SOC)
+			fprintf(f, "  SoC whitelist %s %s\n",
+			       devargs->soc.addr.name,
+			       devargs->soc.addr.fdt_path);
+		else if (devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC)
+			fprintf(f, "  SoC blacklist %s %s\n",
+			       devargs->soc.addr.name,
+			       devargs->soc.addr.fdt_path);
 		else if (devargs->type == RTE_DEVTYPE_VIRTUAL)
 			fprintf(f, "  VIRTUAL %s %s\n",
 			       devargs->virt.drv_name,
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 256cef8..44f5559 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -37,6 +37,8 @@
 
 #include <rte_log.h>
 #include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_eal.h>
 #include <rte_soc.h>
 
 #include "eal_private.h"
@@ -70,6 +72,21 @@ rte_eal_soc_match_compat(struct rte_soc_driver *drv,
 	return 1;
 }
 
+static struct rte_devargs *soc_devargs_lookup(struct rte_soc_device *dev)
+{
+	struct rte_devargs *devargs;
+
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->type != RTE_DEVTYPE_BLACKLISTED_SOC &&
+			devargs->type != RTE_DEVTYPE_WHITELISTED_SOC)
+			continue;
+		if (!rte_eal_compare_soc_addr(&dev->addr, &devargs->soc.addr))
+			return devargs;
+	}
+
+	return NULL;
+}
+
 static int
 rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
 			     struct rte_soc_device *dev)
@@ -85,6 +102,18 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
 		return ret;
 	}
 
+	RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %d\n",
+			dev->addr.name, dev->device.numa_node);
+	RTE_LOG(DEBUG, EAL, "  probe driver %s\n", drv->driver.name);
+
+	/* no initialization when blacklisted, return without error */
+	if (dev->device.devargs != NULL
+		&& dev->device.devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC) {
+		RTE_LOG(DEBUG, EAL,
+			"  device is blacklisted, skipping\n");
+		return ret;
+	}
+
 	dev->driver = drv;
 	RTE_VERIFY(drv->probe != NULL);
 	return drv->probe(drv, dev);
@@ -129,8 +158,8 @@ rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
 		return ret;
 	}
 
-	RTE_LOG(DEBUG, EAL, "SoC device %s\n",
-		dev->addr.name);
+	RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %i\n",
+			dev->addr.name, dev->device.numa_node);
 
 	RTE_LOG(DEBUG, EAL, "  remove driver: %s\n", drv->driver.name);
 
@@ -233,17 +262,29 @@ int
 rte_eal_soc_probe(void)
 {
 	struct rte_soc_device *dev = NULL;
+	struct rte_devargs *devargs = NULL;
 	int ret = 0;
+	int probe_all = 0;
+
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_SOC) == 0)
+		probe_all = 1;
 
 	TAILQ_FOREACH(dev, &soc_device_list, next) {
-		ret = soc_probe_all_drivers(dev);
-		if (ret < 0) {
-			RTE_LOG(DEBUG, EAL, "Requested device %s"
-				 " cannot be used\n", dev->addr.name);
-			/* Failure for a particular device is logged and
-			 * ignored
-			 */
-		}
+
+		/* set devargs in SoC structure */
+		devargs = soc_devargs_lookup(dev);
+		if (devargs != NULL)
+			dev->device.devargs = devargs;
+
+		/* probe all or only whitelisted devices */
+		if (probe_all)
+			ret = soc_probe_all_drivers(dev);
+		else if (devargs != NULL &&
+			devargs->type == RTE_DEVTYPE_WHITELISTED_SOC)
+			ret = soc_probe_all_drivers(dev);
+		if (ret < 0)
+			rte_exit(EXIT_FAILURE, "Requested device %s "
+				 "cannot be used\n", dev->addr.name);
 	}
 
 	return ret;
diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h
index 88120a1..b5dd436 100644
--- a/lib/librte_eal/common/include/rte_devargs.h
+++ b/lib/librte_eal/common/include/rte_devargs.h
@@ -51,6 +51,7 @@ extern "C" {
 #include <stdio.h>
 #include <sys/queue.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 
 /**
  * Type of generic device
@@ -58,6 +59,8 @@ extern "C" {
 enum rte_devtype {
 	RTE_DEVTYPE_WHITELISTED_PCI,
 	RTE_DEVTYPE_BLACKLISTED_PCI,
+	RTE_DEVTYPE_WHITELISTED_SOC,
+	RTE_DEVTYPE_BLACKLISTED_SOC,
 	RTE_DEVTYPE_VIRTUAL,
 };
 
@@ -83,6 +86,11 @@ struct rte_devargs {
 			/** PCI location. */
 			struct rte_pci_addr addr;
 		} pci;
+		/** Used if type is RTE_DEVTYPE_*_SOC. */
+		struct {
+			/** SoC location. */
+			struct rte_soc_addr addr;
+		} soc;
 		/** Used if type is RTE_DEVTYPE_VIRTUAL. */
 		struct {
 			/** Driver name. */
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 53a321b..fb5ea7b 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -164,6 +164,30 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 }
 
 /**
+ * Parse a specification of a soc device. The specification must differentiate
+ * a SoC device specification from the PCI bus and virtual devices. We assume
+ * a SoC specification starts with "soc:". The function allocates the name
+ * entry of the given addr.
+ *
+ * @return
+ *      -  0 on success
+ *      -  1 when not a SoC spec
+ *      - -1 on failure
+ */
+static inline int
+rte_eal_parse_soc_spec(const char *spec, struct rte_soc_addr *addr)
+{
+	if (strstr(spec, "soc:") == spec) {
+		addr->name = strdup(spec + 4);
+		if (addr->name == NULL)
+			return -1;
+		return 0;
+	}
+
+	return 1;
+}
+
+/**
  * Default function for matching the Soc driver with device. Each driver can
  * either use this function or define their own soc matching function.
  * This function relies on the compatible string extracted from sysfs. But,
-- 
2.7.4

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

* [PATCH v6 13/21] eal/soc: add drv_flags
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                           ` (10 preceding siblings ...)
  2016-10-27 15:17         ` [PATCH v6 12/21] eal/soc: extend and utilize devargs Shreyansh Jain
@ 2016-10-27 15:17         ` Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 14/21] eal/soc: add intr_handle Shreyansh Jain
                           ` (8 subsequent siblings)
  20 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

The flags are copied from the PCI ones. They should be refactorized into a
general set of flags in the future.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/common/include/rte_soc.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index fb5ea7b..40490b9 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -123,8 +123,18 @@ struct rte_soc_driver {
 	soc_scan_t *scan_fn;               /**< Callback for scanning SoC bus*/
 	soc_match_t *match_fn;             /**< Callback to match dev<->drv */
 	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
+	uint32_t drv_flags;                /**< Control handling of device */
 };
 
+/** Device needs to map its resources by EAL */
+#define RTE_SOC_DRV_NEED_MAPPING 0x0001
+/** Device needs to be unbound even if no module is provieded */
+#define RTE_SOC_DRV_FORCE_UNBIND 0x0004
+/** Device driver supports link state interrupt */
+#define RTE_SOC_DRV_INTR_LSC	 0x0008
+/** Device driver supports detaching capability */
+#define RTE_SOC_DRV_DETACHABLE	 0x0010
+
 /**
  * Utility function to write a SoC device name, this device name can later be
  * used to retrieve the corresponding rte_soc_addr using above functions.
-- 
2.7.4

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

* [PATCH v6 14/21] eal/soc: add intr_handle
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                           ` (11 preceding siblings ...)
  2016-10-27 15:17         ` [PATCH v6 13/21] eal/soc: add drv_flags Shreyansh Jain
@ 2016-10-27 15:17         ` Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 15/21] eal/soc: add default scan for Soc devices Shreyansh Jain
                           ` (7 subsequent siblings)
  20 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/common/include/rte_soc.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 40490b9..38f897d 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -53,6 +53,7 @@ extern "C" {
 #include <rte_dev.h>
 #include <rte_eal.h>
 #include <rte_debug.h>
+#include <rte_interrupts.h>
 
 extern struct soc_driver_list soc_driver_list;
 /**< Global list of SoC Drivers */
@@ -80,6 +81,7 @@ struct rte_soc_device {
 	struct rte_device device;           /**< Inherit code device */
 	struct rte_soc_addr addr;           /**< SoC device Location */
 	struct rte_soc_id *id;              /**< SoC device ID list */
+	struct rte_intr_handle intr_handle; /**< Interrupt handle */
 	struct rte_soc_driver *driver;      /**< Associated driver */
 };
 
-- 
2.7.4

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

* [PATCH v6 15/21] eal/soc: add default scan for Soc devices
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                           ` (12 preceding siblings ...)
  2016-10-27 15:17         ` [PATCH v6 14/21] eal/soc: add intr_handle Shreyansh Jain
@ 2016-10-27 15:17         ` Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 16/21] eal/soc: additional features for SoC Shreyansh Jain
                           ` (6 subsequent siblings)
  20 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Default implementation which scans the sysfs platform devices hierarchy.
For each device, extract the ueven and convert into rte_soc_device.

The information populated can then be used in probe to match against
the drivers registered.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: restructure commit to be an optional implementation]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>

--
 v5:
 - Update rte_eal_soc_scan to rte_eal_soc_scan_platform_bus
 - Fix comments over scan and match functions
---
 lib/librte_eal/common/include/rte_soc.h |  16 +-
 lib/librte_eal/linuxapp/eal/eal_soc.c   | 315 ++++++++++++++++++++++++++++++++
 2 files changed, 329 insertions(+), 2 deletions(-)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 38f897d..8be3db7 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -64,7 +64,10 @@ TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
 TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
 
 struct rte_soc_id {
-	const char *compatible; /**< OF compatible specification */
+	union {
+		const char *compatible; /**< OF compatible specification */
+		char *_compatible;
+	};
 	uint64_t priv_data;     /**< SoC Driver specific data */
 };
 
@@ -200,7 +203,16 @@ rte_eal_parse_soc_spec(const char *spec, struct rte_soc_addr *addr)
 }
 
 /**
- * Default function for matching the Soc driver with device. Each driver can
+ * Helper function for scanning for new SoC devices on platform bus.
+ *
+ * @return
+ * 	0 on success
+ *	!0 on failure to scan
+ */
+int rte_eal_soc_scan_platform_bus(void);
+
+/**
+ * Helper function for matching the Soc driver with device. Each driver can
  * either use this function or define their own soc matching function.
  * This function relies on the compatible string extracted from sysfs. But,
  * a SoC might have different way of identifying its devices. Such SoC can
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index 3929a76..d8dfe97 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -48,6 +48,321 @@
 #include <eal_filesystem.h>
 #include <eal_private.h>
 
+/** Pathname of SoC devices directory. */
+#define SYSFS_SOC_DEVICES "/sys/bus/platform/devices"
+
+static const char *
+soc_get_sysfs_path(void)
+{
+	const char *path = NULL;
+
+	path = getenv("SYSFS_SOC_DEVICES");
+	if (path == NULL)
+		return SYSFS_SOC_DEVICES;
+
+	return path;
+}
+
+static char *
+dev_read_uevent(const char *dirname)
+{
+	char filename[PATH_MAX];
+	struct stat st;
+	char *buf;
+	ssize_t total = 0;
+	int fd;
+
+	snprintf(filename, sizeof(filename), "%s/uevent", dirname);
+	fd = open(filename, O_RDONLY);
+	if (fd < 0) {
+		RTE_LOG(WARNING, EAL, "Failed to open file %s\n", filename);
+		return strdup("");
+	}
+
+	if (fstat(fd, &st) < 0) {
+		RTE_LOG(ERR, EAL, "Failed to stat file %s\n", filename);
+		close(fd);
+		return NULL;
+	}
+
+	if (st.st_size == 0) {
+		close(fd);
+		return strdup("");
+	}
+
+	buf = malloc(st.st_size + 1);
+	if (buf == NULL) {
+		RTE_LOG(ERR, EAL, "Failed to alloc memory to read %s\n",
+			filename);
+		close(fd);
+		return NULL;
+	}
+
+	while (total < st.st_size) {
+		ssize_t rlen = read(fd, buf + total, st.st_size - total);
+		if (rlen < 0) {
+			if (errno == EINTR)
+				continue;
+
+			RTE_LOG(ERR, EAL, "Failed to read file %s\n", filename);
+
+			free(buf);
+			close(fd);
+			return NULL;
+		}
+		if (rlen == 0) /* EOF */
+			break;
+
+		total += rlen;
+	}
+
+	buf[total] = '\0';
+	close(fd);
+
+	return buf;
+}
+
+static const char *
+dev_uevent_find(const char *uevent, const char *key)
+{
+	const size_t keylen = strlen(key);
+	const size_t total = strlen(uevent);
+	const char *p = uevent;
+
+	/* check whether it is the first key */
+	if (!strncmp(uevent, key, keylen))
+		return uevent + keylen;
+
+	/* check 2nd key or further... */
+	do {
+		p = strstr(p, key);
+		if (p == NULL)
+			break;
+
+		if (p[-1] == '\n') /* check we are at a new line */
+			return p + keylen;
+
+		p += keylen; /* skip this one */
+	} while (p - uevent < (ptrdiff_t) total);
+
+	return NULL;
+}
+
+static char *
+strdup_until_nl(const char *p)
+{
+	const char *nl = strchr(p, '\n');
+	if (nl == NULL)
+		return strdup(p); /* no newline, copy until '\0' */
+
+	return strndup(p, nl - p);
+}
+
+static int
+dev_parse_uevent(struct rte_soc_device *dev, const char *uevent)
+{
+	const char *of;
+	const char *compat_n;
+	char *err;
+	long n;
+	char compat[strlen("OF_COMPATIBLE_NNNN=")];
+	long i;
+
+	of = dev_uevent_find(uevent, "OF_FULLNAME=");
+	if (of == NULL)
+		return 1; /* don't care about this device */
+
+	dev->addr.fdt_path = strdup_until_nl(of);
+	if (dev->addr.fdt_path == NULL) {
+		RTE_LOG(ERR, PMD,
+			"Failed to alloc memory for fdt_path\n");
+		return -1;
+	}
+
+	RTE_LOG(DEBUG, EAL, "Detected device %s (%s)\n",
+			dev->addr.name, dev->addr.fdt_path);
+
+	compat_n = dev_uevent_find(uevent, "OF_COMPATIBLE_N=");
+	if (compat_n == NULL) {
+		RTE_LOG(ERR, EAL, "No OF_COMPATIBLE_N found\n");
+		return -1;
+	}
+
+	n = strtoul(compat_n, &err, 0);
+	if (*err != '\n' && err != NULL) {
+		RTE_LOG(ERR, EAL, "Failed to parse OF_COMPATIBLE_N: %.10s\n",
+			err);
+		goto fail_fdt_path;
+	}
+
+	if (n == 0)
+		return 1; /* cannot match anything */
+	if (n > 9999) { /* match NNNN */
+		RTE_LOG(ERR, EAL, "OF_COMPATIBLE_N is invalid: %ld\n", n);
+		goto fail_fdt_path;
+	}
+
+	dev->id = calloc(n + 1, sizeof(*dev->id));
+	if (dev->id == NULL) {
+		RTE_LOG(ERR, PMD, "Failed to alloc memory for ID\n");
+		free(dev->addr.fdt_path);
+		return -1;
+	}
+
+	for (i = 0; i < n; ++i) {
+		snprintf(compat, sizeof(compat), "OF_COMPATIBLE_%lu=", i);
+		const char *val;
+
+		val = dev_uevent_find(uevent, compat);
+		if (val == NULL) {
+			RTE_LOG(ERR, EAL, "%s was not found\n", compat);
+			goto fail_id;
+		}
+
+		dev->id[i]._compatible = strdup_until_nl(val);
+		if (dev->id[i]._compatible == NULL) {
+			RTE_LOG(ERR, PMD,
+				"Failed to alloc memory for compatible\n");
+			goto fail_id;
+		}
+
+		RTE_LOG(DEBUG, EAL, "  compatible: %s\n",
+				dev->id[i].compatible);
+	}
+
+	dev->id[n]._compatible = NULL; /* mark last one */
+
+	return 0;
+
+fail_id:
+	while (i-- >= 0)
+		free(dev->id[i]._compatible);
+	free(dev->id);
+fail_fdt_path:
+	free(dev->addr.fdt_path);
+	return -1;
+}
+
+static void
+dev_content_free(struct rte_soc_device *dev)
+{
+	int i;
+
+	if (dev->addr.fdt_path)
+		free(dev->addr.fdt_path);
+
+	if (dev->id != NULL) {
+		for (i = 0; dev->id[i]._compatible; ++i)
+			free(dev->id[i]._compatible);
+
+		free(dev->id);
+		dev->id = NULL;
+	}
+}
+
+/**
+ * Scan one SoC sysfs entry, and fill the devices list from it.
+ * We require to have the uevent file with records: OF_FULLNAME and
+ * OF_COMPATIBLE array (with at least one entry). Otherwise, such device
+ * is skipped.
+ */
+static int
+soc_scan_one(const char *dirname, const char *name)
+{
+	struct rte_soc_device *dev;
+	char *uevent;
+	int ret;
+
+	uevent = dev_read_uevent(dirname);
+	if (uevent == NULL)
+		return -1;
+
+	if (uevent[0] == '\0') {
+		/* ignore directory without uevent file */
+		free(uevent);
+		return 1;
+	}
+
+	dev = malloc(sizeof(*dev) + strlen(name) + 1);
+	if (dev == NULL) {
+		RTE_LOG(ERR, PMD, "Failed to alloc memory for %s\n", name);
+		free(uevent);
+		return -1;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	dev->addr.name = (char *) (dev + 1);
+	strcpy(dev->addr.name, name);
+
+	ret = dev_parse_uevent(dev, uevent);
+	if (ret)
+		goto fail;
+	free(uevent); /* not needed anymore */
+
+	/* device is valid, add in list (sorted) */
+	if (TAILQ_EMPTY(&soc_device_list)) {
+		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+	} else {
+		struct rte_soc_device *dev2;
+
+		TAILQ_FOREACH(dev2, &soc_device_list, next) {
+			ret = rte_eal_compare_soc_addr(&dev->addr, &dev2->addr);
+			if (ret > 0)
+				continue;
+
+			if (ret < 0) {
+				TAILQ_INSERT_BEFORE(dev2, dev, next);
+			} else { /* already registered */
+				dev_content_free(dev2);
+				dev2->addr.fdt_path = dev->addr.fdt_path;
+				dev2->id = dev->id;
+				free(dev);
+			}
+			return 0;
+		}
+		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+	}
+
+	return 0;
+
+fail:
+	free(uevent);
+	dev_content_free(dev);
+	free(dev);
+	return ret;
+}
+
+int
+rte_eal_soc_scan_platform_bus(void)
+{
+	struct dirent *e;
+	DIR *dir;
+	char dirname[PATH_MAX];
+
+	dir = opendir(soc_get_sysfs_path());
+	if (dir == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
+			__func__, strerror(errno));
+		return -1;
+	}
+
+	while ((e = readdir(dir)) != NULL) {
+		if (e->d_name[0] == '.')
+			continue;
+
+		snprintf(dirname, sizeof(dirname), "%s/%s",
+				soc_get_sysfs_path(), e->d_name);
+		if (soc_scan_one(dirname, e->d_name) < 0)
+			goto error;
+	}
+	closedir(dir);
+	return 0;
+
+error:
+	closedir(dir);
+	return -1;
+}
+
 /* Init the SoC EAL subsystem */
 int
 rte_eal_soc_init(void)
-- 
2.7.4

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

* [PATCH v6 16/21] eal/soc: additional features for SoC
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                           ` (13 preceding siblings ...)
  2016-10-27 15:17         ` [PATCH v6 15/21] eal/soc: add default scan for Soc devices Shreyansh Jain
@ 2016-10-27 15:17         ` Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 17/21] ether: utilize container_of for pci_drv Shreyansh Jain
                           ` (5 subsequent siblings)
  20 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Additional features introduced:
 - Find kernel driver through sysfs bindings
 - Dummy implementation for mapping to kernel driver
 - DMA coherency value from sysfs
 - Numa node number from sysfs
 - Support for updating device during probe if already registered

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: merge multiple patches into single set]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_eal/common/eal_common_soc.c  |  30 ++++++++
 lib/librte_eal/common/eal_private.h     |  23 ++++++
 lib/librte_eal/common/include/rte_soc.h |  28 +++++++
 lib/librte_eal/linuxapp/eal/eal_soc.c   | 129 ++++++++++++++++++++++++++++++++
 4 files changed, 210 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 44f5559..29c38e0 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -114,6 +114,26 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
 		return ret;
 	}
 
+	if (!dev->is_dma_coherent) {
+		if (!(drv->drv_flags & RTE_SOC_DRV_ACCEPT_NONCC)) {
+			RTE_LOG(DEBUG, EAL,
+				"  device is not DMA coherent, skipping\n");
+			return 1;
+		}
+	}
+
+	if (drv->drv_flags & RTE_SOC_DRV_NEED_MAPPING) {
+		/* map resources */
+		ret = rte_eal_soc_map_device(dev);
+		if (ret)
+			return ret;
+	} else if (drv->drv_flags & RTE_SOC_DRV_FORCE_UNBIND
+		&& rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		/* unbind */
+		if (soc_unbind_kernel_driver(dev) < 0)
+			return -1;
+	}
+
 	dev->driver = drv;
 	RTE_VERIFY(drv->probe != NULL);
 	return drv->probe(drv, dev);
@@ -166,6 +186,10 @@ rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
 	if (drv->remove && (drv->remove(dev) < 0))
 		return -1;	/* negative value is an error */
 
+	if (drv->drv_flags & RTE_SOC_DRV_NEED_MAPPING)
+		/* unmap resources for devices */
+		rte_eal_soc_unmap_device(dev);
+
 	/* clear driver structure */
 	dev->driver = NULL;
 
@@ -241,6 +265,12 @@ rte_eal_soc_probe_one(const struct rte_soc_addr *addr)
 	if (addr == NULL)
 		return -1;
 
+	/* update current SoC device in global list, kernel bindings might have
+	 * changed since last time we looked at it.
+	 */
+	if (soc_update_device(addr) < 0)
+		goto err_return;
+
 	TAILQ_FOREACH(dev, &soc_device_list, next) {
 		if (rte_eal_compare_soc_addr(&dev->addr, addr))
 			continue;
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index d810f9f..30c648d 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -159,6 +159,29 @@ int pci_update_device(const struct rte_pci_addr *addr);
 int pci_unbind_kernel_driver(struct rte_pci_device *dev);
 
 /**
+ * Update a soc device object by asking the kernel for the latest information.
+ *
+ * This function is private to EAL.
+ *
+ * @param addr
+ *      The SoC address to look for
+ * @return
+ *   - 0 on success.
+ *   - negative on error.
+ */
+int soc_update_device(const struct rte_soc_addr *addr);
+
+/**
+ * Unbind kernel driver for this device
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int soc_unbind_kernel_driver(struct rte_soc_device *dev);
+
+/**
  * Map the PCI resource of a PCI device in virtual memory
  *
  * This function is private to EAL.
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 8be3db7..d7f7ec8 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -46,9 +46,11 @@ extern "C" {
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/queue.h>
 #include <stdint.h>
 #include <inttypes.h>
 #include <string.h>
+#include <limits.h>
 
 #include <rte_dev.h>
 #include <rte_eal.h>
@@ -63,6 +65,14 @@ extern struct soc_device_list soc_device_list;
 TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
 TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
 
+#define SOC_MAX_RESOURCE 6
+
+struct rte_soc_resource {
+	uint64_t phys_addr;
+	uint64_t len;
+	void *addr;
+};
+
 struct rte_soc_id {
 	union {
 		const char *compatible; /**< OF compatible specification */
@@ -84,8 +94,12 @@ struct rte_soc_device {
 	struct rte_device device;           /**< Inherit code device */
 	struct rte_soc_addr addr;           /**< SoC device Location */
 	struct rte_soc_id *id;              /**< SoC device ID list */
+	struct rte_soc_resource mem_resource[SOC_MAX_RESOURCE];
 	struct rte_intr_handle intr_handle; /**< Interrupt handle */
 	struct rte_soc_driver *driver;      /**< Associated driver */
+	int numa_node;                      /**< NUMA node connection */
+	int is_dma_coherent;                /**< DMA coherent device */
+	enum rte_kernel_driver kdrv;        /**< Kernel driver */
 };
 
 struct rte_soc_driver;
@@ -139,6 +153,8 @@ struct rte_soc_driver {
 #define RTE_SOC_DRV_INTR_LSC	 0x0008
 /** Device driver supports detaching capability */
 #define RTE_SOC_DRV_DETACHABLE	 0x0010
+/** Device driver accepts DMA non-coherent devices */
+#define RTE_SOC_DRV_ACCEPT_NONCC 0x0020
 
 /**
  * Utility function to write a SoC device name, this device name can later be
@@ -256,6 +272,18 @@ int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
 int rte_eal_soc_detach(const struct rte_soc_addr *addr);
 
 /**
+ * Map SoC device resources into userspace.
+ *
+ * This is called by the EAL if (drv_flags & RTE_SOC_DRV_NEED_MAPPING).
+ */
+int rte_eal_soc_map_device(struct rte_soc_device *dev);
+
+/**
+ * Unmap the device resources.
+ */
+void rte_eal_soc_unmap_device(struct rte_soc_device *dev);
+
+/**
  * Dump discovered SoC devices.
  *
  * @param f
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index d8dfe97..95f7565 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -63,6 +63,45 @@ soc_get_sysfs_path(void)
 	return path;
 }
 
+int
+soc_unbind_kernel_driver(struct rte_soc_device *dev)
+{
+	char devpath[PATH_MAX];
+
+	snprintf(devpath, sizeof(devpath), "%s/%s",
+		 soc_get_sysfs_path(), dev->addr.name);
+
+	return rte_eal_unbind_kernel_driver(devpath, dev->addr.name);
+}
+
+int
+rte_eal_soc_map_device(struct rte_soc_device *dev)
+{
+	int ret = -1;
+
+	/* try mapping the NIC resources using VFIO if it exists */
+	switch (dev->kdrv) {
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		ret = 1;
+		break;
+	}
+
+	return ret;
+}
+
+void
+rte_eal_soc_unmap_device(struct rte_soc_device *dev)
+{
+	switch (dev->kdrv) {
+	default:
+	RTE_LOG(DEBUG, EAL,
+		"  Not managed by a supported kernel driver, skipped\n");
+		break;
+	}
+}
+
 static char *
 dev_read_uevent(const char *dirname)
 {
@@ -260,6 +299,68 @@ dev_content_free(struct rte_soc_device *dev)
 	}
 }
 
+static int
+dev_setup_associated_driver(struct rte_soc_device *dev, const char *dirname)
+{
+	char filename[PATH_MAX];
+	char driver[PATH_MAX];
+	int ret;
+
+	/* parse driver */
+	snprintf(filename, sizeof(filename), "%s/driver", dirname);
+	ret = rte_eal_get_kernel_driver_by_path(filename, driver);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "Fail to get kernel driver for %s\n",
+			dirname);
+		return 1;
+	}
+
+	if (!ret)
+		dev->kdrv = RTE_KDRV_UNKNOWN;
+	else
+		dev->kdrv = RTE_KDRV_NONE;
+
+	return 0;
+}
+
+static int
+dev_setup_numa_node(struct rte_soc_device *dev, const char *dirname)
+{
+	char filename[PATH_MAX];
+
+	/* if no NUMA support, set default to 0 */
+	unsigned long tmp = 0;
+	int ret = 0;
+
+	/* get numa node */
+	snprintf(filename, sizeof(filename), "%s/numa_node", dirname);
+
+	if (eal_parse_sysfs_value(filename, &tmp) < 0)
+		ret = 1;
+
+	dev->numa_node = tmp;
+	return ret;
+}
+
+static int
+dev_detect_is_coherent(struct rte_soc_device *dev)
+{
+	char filename[PATH_MAX];
+	FILE *f;
+
+	if (dev->addr.fdt_path == NULL)
+		return 0; /* no way to detect */
+
+	snprintf(filename, sizeof(filename), "%s%s/dma-coherent",
+			"/proc/device-tree", dev->addr.fdt_path);
+	f = fopen(filename, "r");
+	if (f == NULL)
+		return 0;
+
+	fclose(f);
+	return 1;
+}
+
 /**
  * Scan one SoC sysfs entry, and fill the devices list from it.
  * We require to have the uevent file with records: OF_FULLNAME and
@@ -299,6 +400,18 @@ soc_scan_one(const char *dirname, const char *name)
 		goto fail;
 	free(uevent); /* not needed anymore */
 
+	ret = dev_setup_associated_driver(dev, dirname);
+	if (ret)
+		goto fail;
+
+	ret = dev_setup_numa_node(dev, dirname);
+	if (ret < 0)
+		goto fail;
+
+	dev->is_dma_coherent = dev_detect_is_coherent(dev);
+	RTE_LOG(DEBUG, EAL, "  DMA %s\n",
+			dev->is_dma_coherent ? "coherent" : "non-coherent");
+
 	/* device is valid, add in list (sorted) */
 	if (TAILQ_EMPTY(&soc_device_list)) {
 		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
@@ -313,6 +426,11 @@ soc_scan_one(const char *dirname, const char *name)
 			if (ret < 0) {
 				TAILQ_INSERT_BEFORE(dev2, dev, next);
 			} else { /* already registered */
+				dev2->kdrv = dev->kdrv;
+				dev2->is_dma_coherent = dev->is_dma_coherent;
+				memmove(dev2->mem_resource, dev->mem_resource,
+					sizeof(dev->mem_resource));
+
 				dev_content_free(dev2);
 				dev2->addr.fdt_path = dev->addr.fdt_path;
 				dev2->id = dev->id;
@@ -333,6 +451,17 @@ fail:
 }
 
 int
+soc_update_device(const struct rte_soc_addr *addr)
+{
+	char filename[PATH_MAX];
+
+	snprintf(filename, sizeof(filename), "%s/%s",
+			soc_get_sysfs_path(), addr->name);
+
+	return soc_scan_one(filename, addr->name);
+}
+
+int
 rte_eal_soc_scan_platform_bus(void)
 {
 	struct dirent *e;
-- 
2.7.4

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

* [PATCH v6 17/21] ether: utilize container_of for pci_drv
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                           ` (14 preceding siblings ...)
  2016-10-27 15:17         ` [PATCH v6 16/21] eal/soc: additional features for SoC Shreyansh Jain
@ 2016-10-27 15:17         ` Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 18/21] ether: verify we copy info from a PCI device Shreyansh Jain
                           ` (4 subsequent siblings)
  20 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

It is not necessary to place the rte_pci_driver at the beginning
of the rte_eth_dev struct anymore as we use the container_of macro
to get the parent pointer.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 4 ++--
 lib/librte_ether/rte_ethdev.h | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index fde8112..347c230 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -241,7 +241,7 @@ rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
 
 	int diag;
 
-	eth_drv = (struct eth_driver *)pci_drv;
+	eth_drv = container_of(pci_drv, struct eth_driver, pci_drv);
 
 	rte_eal_pci_device_name(&pci_dev->addr, ethdev_name,
 			sizeof(ethdev_name));
@@ -302,7 +302,7 @@ rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
 	if (eth_dev == NULL)
 		return -ENODEV;
 
-	eth_drv = (const struct eth_driver *)pci_dev->driver;
+	eth_drv = container_of(pci_dev->driver, struct eth_driver, pci_drv);
 
 	/* Invoke PMD device uninit function */
 	if (*eth_drv->eth_dev_uninit) {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 38641e8..f893fe0 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1850,7 +1850,7 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *eth_dev);
  * Each Ethernet driver acts as a PCI driver and is represented by a generic
  * *eth_driver* structure that holds:
  *
- * - An *rte_pci_driver* structure (which must be the first field).
+ * - An *rte_pci_driver* structure.
  *
  * - The *eth_dev_init* function invoked for each matching PCI device.
  *
-- 
2.7.4

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

* [PATCH v6 18/21] ether: verify we copy info from a PCI device
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                           ` (15 preceding siblings ...)
  2016-10-27 15:17         ` [PATCH v6 17/21] ether: utilize container_of for pci_drv Shreyansh Jain
@ 2016-10-27 15:17         ` Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 19/21] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
                           ` (3 subsequent siblings)
  20 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Now that different types of ethdev exist, check for presence of PCI dev
while copying out the info.
Similar would be done for SoC.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 347c230..a1e3aaf 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3206,6 +3206,8 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_de
 		return;
 	}
 
+	RTE_VERIFY(eth_dev->pci_dev != NULL);
+
 	eth_dev->data->dev_flags = 0;
 	if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC)
 		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
-- 
2.7.4

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

* [PATCH v6 19/21] ether: extract function eth_dev_get_intr_handle
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                           ` (16 preceding siblings ...)
  2016-10-27 15:17         ` [PATCH v6 18/21] ether: verify we copy info from a PCI device Shreyansh Jain
@ 2016-10-27 15:17         ` Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 20/21] ether: introduce ethernet dev probe remove Shreyansh Jain
                           ` (2 subsequent siblings)
  20 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

We abstract access to the intr_handle here as we want to get
it either from the pci_dev or soc_dev.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index a1e3aaf..4c61246 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2532,6 +2532,16 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
 	rte_spinlock_unlock(&rte_eth_dev_cb_lock);
 }
 
+static inline
+struct rte_intr_handle *eth_dev_get_intr_handle(struct rte_eth_dev *dev)
+{
+	if (dev->pci_dev)
+		return &dev->pci_dev->intr_handle;
+
+	RTE_ASSERT(0);
+	return NULL;
+}
+
 int
 rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 {
@@ -2544,7 +2554,7 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
-	intr_handle = &dev->pci_dev->intr_handle;
+	intr_handle = eth_dev_get_intr_handle(dev);
 	if (!intr_handle->intr_vec) {
 		RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
 		return -EPERM;
@@ -2604,7 +2614,7 @@ rte_eth_dev_rx_intr_ctl_q(uint8_t port_id, uint16_t queue_id,
 		return -EINVAL;
 	}
 
-	intr_handle = &dev->pci_dev->intr_handle;
+	intr_handle = eth_dev_get_intr_handle(dev);
 	if (!intr_handle->intr_vec) {
 		RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
 		return -EPERM;
-- 
2.7.4

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

* [PATCH v6 20/21] ether: introduce ethernet dev probe remove
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                           ` (17 preceding siblings ...)
  2016-10-27 15:17         ` [PATCH v6 19/21] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
@ 2016-10-27 15:17         ` Shreyansh Jain
  2016-10-27 15:17         ` [PATCH v6 21/21] eal/crypto: Support rte_soc_driver/device for cryptodev Shreyansh Jain
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
  20 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 148 +++++++++++++++++++++++++++++++++++++++++-
 lib/librte_ether/rte_ethdev.h |  31 +++++++++
 2 files changed, 177 insertions(+), 2 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 4c61246..972e916 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -325,6 +325,101 @@ rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
 }
 
 int
+rte_eth_dev_soc_probe(struct rte_soc_driver *soc_drv,
+		      struct rte_soc_device *soc_dev)
+{
+	struct eth_driver    *eth_drv;
+	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
+	int diag;
+
+	eth_drv = container_of(soc_drv, struct eth_driver, soc_drv);
+
+	rte_eal_soc_device_name(&soc_dev->addr, ethdev_name,
+			sizeof(ethdev_name));
+
+	eth_dev = rte_eth_dev_allocate(ethdev_name);
+	if (eth_dev == NULL)
+		return -ENOMEM;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		eth_dev->data->dev_private = rte_zmalloc(
+				  "ethdev private structure",
+				  eth_drv->dev_private_size,
+				  RTE_CACHE_LINE_SIZE);
+		if (eth_dev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private port "
+				  "data\n");
+	}
+	eth_dev->soc_dev = soc_dev;
+	eth_dev->driver = eth_drv;
+	eth_dev->data->rx_mbuf_alloc_failed = 0;
+
+	/* init user callbacks */
+	TAILQ_INIT(&(eth_dev->link_intr_cbs));
+
+	/*
+	 * Set the default MTU.
+	 */
+	eth_dev->data->mtu = ETHER_MTU;
+
+	/* Invoke PMD device initialization function */
+	diag = (*eth_drv->eth_dev_init)(eth_dev);
+	if (diag == 0)
+		return 0;
+
+	RTE_PMD_DEBUG_TRACE("driver %s: eth_dev_init(%s) failed\n",
+			soc_drv->driver.name,
+			soc_dev->addr.name);
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(eth_dev->data->dev_private);
+	rte_eth_dev_release_port(eth_dev);
+	return diag;
+}
+
+int
+rte_eth_dev_soc_remove(struct rte_soc_device *soc_dev)
+{
+	const struct eth_driver *eth_drv;
+	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+	int ret;
+
+	if (soc_dev == NULL)
+		return -EINVAL;
+
+	rte_eal_soc_device_name(&soc_dev->addr, ethdev_name,
+			sizeof(ethdev_name));
+
+	eth_dev = rte_eth_dev_allocated(ethdev_name);
+	if (eth_dev == NULL)
+		return -ENODEV;
+
+	eth_drv = container_of(soc_dev->driver, struct eth_driver, soc_drv);
+
+	/* Invoke PMD device uninit function */
+	if (*eth_drv->eth_dev_uninit) {
+		ret = (*eth_drv->eth_dev_uninit)(eth_dev);
+		if (ret)
+			return ret;
+	}
+
+	/* free ether device */
+	rte_eth_dev_release_port(eth_dev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(eth_dev->data->dev_private);
+
+	eth_dev->soc_dev = NULL;
+	eth_dev->driver = NULL;
+	eth_dev->data = NULL;
+
+	return 0;
+}
+
+
+int
 rte_eth_dev_is_valid_port(uint8_t port_id)
 {
 	if (port_id >= RTE_MAX_ETHPORTS ||
@@ -1557,6 +1652,7 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
 	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
 	dev_info->pci_dev = dev->pci_dev;
+	dev_info->soc_dev = dev->soc_dev;
 	dev_info->driver_name = dev->data->drv_name;
 	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
 	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
@@ -2535,8 +2631,15 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
 static inline
 struct rte_intr_handle *eth_dev_get_intr_handle(struct rte_eth_dev *dev)
 {
-	if (dev->pci_dev)
+	if (dev->pci_dev) {
+		RTE_ASSERT(dev->soc_dev == NULL);
 		return &dev->pci_dev->intr_handle;
+	}
+
+	if (dev->soc_dev) {
+		RTE_ASSERT(dev->pci_dev == NULL);
+		return &dev->soc_dev->intr_handle;
+	}
 
 	RTE_ASSERT(0);
 	return NULL;
@@ -2573,6 +2676,23 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 	return 0;
 }
 
+static inline
+const char *eth_dev_get_driver_name(const struct rte_eth_dev *dev)
+{
+	if (dev->pci_dev) {
+		RTE_ASSERT(dev->soc_dev == NULL);
+		return dev->driver->pci_drv.driver.name;
+	}
+
+	if (dev->soc_dev) {
+		RTE_ASSERT(dev->pci_dev == NULL);
+		return dev->driver->soc_drv.driver.name;
+	}
+
+	RTE_ASSERT(0);
+	return NULL;
+}
+
 const struct rte_memzone *
 rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 			 uint16_t queue_id, size_t size, unsigned align,
@@ -2580,9 +2700,11 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 {
 	char z_name[RTE_MEMZONE_NAMESIZE];
 	const struct rte_memzone *mz;
+	const char *drv_name;
 
+	drv_name = eth_dev_get_driver_name(dev);
 	snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
-		 dev->driver->pci_drv.driver.name, ring_name,
+		 drv_name, ring_name,
 		 dev->data->port_id, queue_id);
 
 	mz = rte_memzone_lookup(z_name);
@@ -3229,6 +3351,28 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_de
 	eth_dev->data->drv_name = pci_dev->driver->driver.name;
 }
 
+void
+rte_eth_copy_soc_info(struct rte_eth_dev *eth_dev,
+		      struct rte_soc_device *soc_dev)
+{
+	if ((eth_dev == NULL) || (soc_dev == NULL)) {
+		RTE_PMD_DEBUG_TRACE("NULL pointer eth_dev=%p soc_dev=%p\n",
+				eth_dev, soc_dev);
+		return;
+	}
+
+	RTE_ASSERT(eth_dev->soc_dev != NULL);
+
+	eth_dev->data->dev_flags = 0;
+	if (soc_dev->driver->drv_flags & RTE_SOC_DRV_INTR_LSC)
+		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
+	if (soc_dev->driver->drv_flags & RTE_SOC_DRV_DETACHABLE)
+		eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
+
+	eth_dev->data->numa_node = soc_dev->device.numa_node;
+	eth_dev->data->drv_name = soc_dev->driver->driver.name;
+}
+
 int
 rte_eth_dev_l2_tunnel_eth_type_conf(uint8_t port_id,
 				    struct rte_eth_l2_tunnel_conf *l2_tunnel)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index f893fe0..ff7958f 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -180,6 +180,7 @@ extern "C" {
 #include <rte_log.h>
 #include <rte_interrupts.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include "rte_ether.h"
@@ -877,6 +878,7 @@ struct rte_eth_conf {
  */
 struct rte_eth_dev_info {
 	struct rte_pci_device *pci_dev; /**< Device PCI information. */
+	struct rte_soc_device *soc_dev; /**< Device SoC information. */
 	const char *driver_name; /**< Device Driver name. */
 	unsigned int if_index; /**< Index to bound host interface, or 0 if none.
 		Use if_indextoname() to translate into an interface name. */
@@ -1626,6 +1628,7 @@ struct rte_eth_dev {
 	const struct eth_driver *driver;/**< Driver for this device */
 	const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
 	struct rte_pci_device *pci_dev; /**< PCI info. supplied by probing */
+	struct rte_soc_device *soc_dev; /**< SoC info. supplied by probing */
 	/** User application callbacks for NIC interrupts */
 	struct rte_eth_dev_cb_list link_intr_cbs;
 	/**
@@ -1860,6 +1863,7 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *eth_dev);
  */
 struct eth_driver {
 	struct rte_pci_driver pci_drv;    /**< The PMD is also a PCI driver. */
+	struct rte_soc_driver soc_drv;    /**< The PMD is also a SoC driver. */
 	eth_dev_init_t eth_dev_init;      /**< Device init function. */
 	eth_dev_uninit_t eth_dev_uninit;  /**< Device uninit function. */
 	unsigned int dev_private_size;    /**< Size of device private data. */
@@ -4262,6 +4266,20 @@ void rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev,
 		struct rte_pci_device *pci_dev);
 
 /**
+ * Copy SoC device info to the Ethernet device data.
+ *
+ * @param eth_dev
+ * The *eth_dev* pointer is the address of the *rte_eth_dev* structure.
+ * @param soc_dev
+ * The *soc_dev* pointer is the address of the *rte_soc_device* structure.
+ *
+ * @return
+ *   - 0 on success, negative on error
+ */
+void rte_eth_copy_soc_info(struct rte_eth_dev *eth_dev,
+		struct rte_soc_device *soc_dev);
+
+/**
  * Create memzone for HW rings.
  * malloc can't be used as the physical address is needed.
  * If the memzone is already created, then this function returns a ptr
@@ -4376,6 +4394,19 @@ int rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
  */
 int rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev);
 
+/**
+ * Wrapper for use by SoC drivers as a .devinit function to attach to a ethdev
+ * interface.
+ */
+int rte_eth_dev_soc_probe(struct rte_soc_driver *soc_drv,
+			  struct rte_soc_device *soc_dev);
+
+/**
+ * Wrapper for use by SoC drivers as a .devuninit function to detach a ethdev
+ * interface.
+ */
+int rte_eth_dev_soc_remove(struct rte_soc_device *soc_dev);
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.7.4

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

* [PATCH v6 21/21] eal/crypto: Support rte_soc_driver/device for cryptodev
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                           ` (18 preceding siblings ...)
  2016-10-27 15:17         ` [PATCH v6 20/21] ether: introduce ethernet dev probe remove Shreyansh Jain
@ 2016-10-27 15:17         ` Shreyansh Jain
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
  20 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-27 15:17 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

- rte_cryptodev_driver/rte_cryptodev_dev embeds rte_soc_driver/device for
  linking SoC PMDs to crypto devices.
- Add probe and remove functions linked

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_cryptodev/rte_cryptodev.c           | 122 ++++++++++++++++++++++++-
 lib/librte_cryptodev/rte_cryptodev.h           |   3 +
 lib/librte_cryptodev/rte_cryptodev_pmd.h       |  18 +++-
 lib/librte_cryptodev/rte_cryptodev_version.map |   2 +
 4 files changed, 140 insertions(+), 5 deletions(-)

diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 127e8d0..77ec9fe 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -422,7 +422,8 @@ rte_cryptodev_pci_probe(struct rte_pci_driver *pci_drv,
 
 	int retval;
 
-	cryptodrv = (struct rte_cryptodev_driver *)pci_drv;
+	cryptodrv = container_of(pci_drv, struct rte_cryptodev_driver,
+				 pci_drv);
 	if (cryptodrv == NULL)
 		return -ENODEV;
 
@@ -489,7 +490,8 @@ rte_cryptodev_pci_remove(struct rte_pci_device *pci_dev)
 	if (cryptodev == NULL)
 		return -ENODEV;
 
-	cryptodrv = (const struct rte_cryptodev_driver *)pci_dev->driver;
+	cryptodrv = container_of(pci_dev->driver, struct rte_cryptodev_driver,
+				 pci_drv);
 	if (cryptodrv == NULL)
 		return -ENODEV;
 
@@ -513,6 +515,111 @@ rte_cryptodev_pci_remove(struct rte_pci_device *pci_dev)
 	return 0;
 }
 
+
+int
+rte_cryptodev_soc_probe(struct rte_soc_driver *soc_drv,
+		      struct rte_soc_device *soc_dev)
+{
+	struct rte_cryptodev_driver *cryptodrv;
+	struct rte_cryptodev *cryptodev;
+
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+
+	int retval;
+
+	cryptodrv = container_of(soc_drv, struct rte_cryptodev_driver,
+				 soc_drv);
+
+	rte_eal_soc_device_name(&soc_dev->addr, cryptodev_name,
+			sizeof(cryptodev_name));
+
+	cryptodev = rte_cryptodev_pmd_allocate(cryptodev_name,
+					       rte_socket_id());
+	if (cryptodev == NULL)
+		return -ENOMEM;
+
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		cryptodev->data->dev_private =
+				rte_zmalloc_socket(
+						"cryptodev private structure",
+						cryptodrv->dev_private_size,
+						RTE_CACHE_LINE_SIZE,
+						rte_socket_id());
+
+		if (cryptodev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private "
+					"device data");
+	}
+
+	cryptodev->soc_dev = soc_dev;
+	cryptodev->driver = cryptodrv;
+
+	/* init user callbacks */
+	TAILQ_INIT(&(cryptodev->link_intr_cbs));
+
+	/* Invoke PMD device initialization function */
+	retval = (*cryptodrv->cryptodev_init)(cryptodrv, cryptodev);
+	if (retval == 0)
+		return 0;
+
+	CDEV_LOG_ERR("driver %s: cryptodev_init(%s) failed\n",
+			soc_drv->driver.name,
+			soc_dev->addr.name);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	cryptodev->attached = RTE_CRYPTODEV_DETACHED;
+	cryptodev_globals.nb_devs--;
+
+	return -ENXIO;
+}
+
+int
+rte_cryptodev_soc_remove(struct rte_soc_device *soc_dev)
+{
+	const struct rte_cryptodev_driver *cryptodrv;
+	struct rte_cryptodev *cryptodev;
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+	int ret;
+
+	if (soc_dev == NULL)
+		return -EINVAL;
+
+	rte_eal_soc_device_name(&soc_dev->addr, cryptodev_name,
+			sizeof(cryptodev_name));
+
+	cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name);
+	if (cryptodev == NULL)
+		return -ENODEV;
+
+	cryptodrv = container_of(soc_dev->driver,
+		struct rte_cryptodev_driver, soc_drv);
+	if (cryptodrv == NULL)
+		return -ENODEV;
+
+	/* Invoke PMD device uninit function */
+	if (*cryptodrv->cryptodev_uninit) {
+		ret = (*cryptodrv->cryptodev_uninit)(cryptodrv, cryptodev);
+		if (ret)
+			return ret;
+	}
+
+	/* free crypto device */
+	rte_cryptodev_pmd_release_device(cryptodev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	cryptodev->pci_dev = NULL;
+	cryptodev->soc_dev = NULL;
+	cryptodev->driver = NULL;
+	cryptodev->data = NULL;
+
+	return 0;
+}
+
 uint16_t
 rte_cryptodev_queue_pair_count(uint8_t dev_id)
 {
@@ -868,8 +975,15 @@ rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
 
 	dev_info->pci_dev = dev->pci_dev;
-	if (dev->driver)
-		dev_info->driver_name = dev->driver->pci_drv.driver.name;
+	dev_info->soc_dev = dev->soc_dev;
+	if (dev->driver) {
+		if (dev->soc_dev)
+			dev_info->driver_name
+				= dev->driver->soc_drv.driver.name;
+		else
+			dev_info->driver_name
+				= dev->driver->pci_drv.driver.name;
+	}
 }
 
 
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 8f63e8f..85ce5cb 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -244,6 +244,7 @@ struct rte_cryptodev_info {
 	const char *driver_name;		/**< Driver name. */
 	enum rte_cryptodev_type dev_type;	/**< Device type */
 	struct rte_pci_device *pci_dev;		/**< PCI information. */
+	struct rte_soc_device *soc_dev;		/**< SoC information. */
 
 	uint64_t feature_flags;			/**< Feature flags */
 
@@ -623,6 +624,8 @@ struct rte_cryptodev {
 	/**< Supported features */
 	struct rte_pci_device *pci_dev;
 	/**< PCI info. supplied by probing */
+	struct rte_soc_device *soc_dev;
+	/**< SoC info. supplied by probing/Scanning */
 
 	enum rte_cryptodev_type dev_type;
 	/**< Crypto device type */
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index abfe2dc..a8af2ce 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -48,6 +48,7 @@ extern "C" {
 
 #include <rte_dev.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_malloc.h>
 #include <rte_mbuf.h>
 #include <rte_mempool.h>
@@ -131,7 +132,8 @@ typedef int (*cryptodev_uninit_t)(const struct rte_cryptodev_driver  *drv,
  * - The size of the private data to allocate for each matching device.
  */
 struct rte_cryptodev_driver {
-	struct rte_pci_driver pci_drv;	/**< The PMD is also a PCI driver. */
+	struct rte_pci_driver pci_drv;	/**< The PMD is PCI type driver. */
+	struct rte_soc_driver soc_drv;	/**< The PMD is SoC type driver. */
 	unsigned dev_private_size;	/**< Size of device private data. */
 
 	cryptodev_init_t cryptodev_init;	/**< Device init function. */
@@ -519,6 +521,20 @@ int rte_cryptodev_pci_probe(struct rte_pci_driver *pci_drv,
  */
 int rte_cryptodev_pci_remove(struct rte_pci_device *pci_dev);
 
+/**
+ * Wrapper for use by SoC drivers as a .devinit function to attach to a
+ * cryptodev interface.
+ */
+int rte_cryptodev_soc_probe(struct rte_soc_driver *soc_drv,
+			  struct rte_soc_device *soc_dev);
+
+/**
+ * Wrapper for use by SoC drivers as a .devuninit function to detach a
+ * cryptodev interface.
+ */
+int rte_cryptodev_soc_remove(struct rte_soc_device *soc_dev);
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index 9dde0e7..d81073e 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -44,5 +44,7 @@ DPDK_16.11 {
 
 	rte_cryptodev_pci_probe;
 	rte_cryptodev_pci_remove;
+	rte_cryptodev_soc_probe;
+	rte_cryptodev_soc_remove;
 
 } DPDK_16.07;
-- 
2.7.4

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

* [PATCH v7 00/21] Introduce SoC device/driver framework for EAL
  2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                           ` (19 preceding siblings ...)
  2016-10-27 15:17         ` [PATCH v6 21/21] eal/crypto: Support rte_soc_driver/device for cryptodev Shreyansh Jain
@ 2016-10-28 12:26         ` Shreyansh Jain
  2016-10-28 12:26           ` [PATCH v7 01/21] eal: generalize PCI kernel driver enum to EAL Shreyansh Jain
                             ` (22 more replies)
  20 siblings, 23 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

Introduction:
=============

This patch set is direct derivative of Jan's original series [1],[2].

 - This version is based on master HEAD (ca41215)
 
 - In this, I am merging the series [11] back. It was initially part
   of this set but I had split considering that those changes in PCI
   were good standalone as well. But, 1) not much feedback was avail-
   able and 2) this patchset is a use-case for those patches making
   it easier to review. Just like what Jan had intended in original
   series.

 - SoC support is not enabled by default. It needs the 'enable-soc' toggle
   on command line. This is primarily because this patchset is still
   experimental and we would like to keep it isolated from non-SoC ops.
   Though, it does impact the ABI.

Aim:
====

As of now EAL is primarly focused on PCI initialization/probing.

 rte_eal_init()
  |- rte_eal_pci_init(): Find PCI devices from sysfs
  |- ...
  |- rte_eal_memzone_init()
  |- ...
  `- rte_eal_pci_probe(): Driver<=>Device initialization

This patchset introduces SoC framework which would enable SoC drivers and
drivers to be plugged into EAL, very similar to how PCI drivers/devices are
done today.

This is a stripped down version of PCI framework which allows the SoC PMDs
to implement their own routines for detecting devices and linking devices to
drivers.

1) Changes to EAL
 rte_eal_init()
  |- rte_eal_pci_init(): Find PCI devices from sysfs
  |- rte_eal_soc_init(): Calls PMDs->scan_fn
  |- ...
  |- rte_eal_memzone_init()
  |- ...
  |- rte_eal_pci_probe(): Driver<=>Device initialization, PMD->devinit()
  `- rte_eal_soc_probe(): Calls PMDs->match_fn and PMDs->devinit();

2) New device/driver structures:
  - rte_soc_driver (inheriting rte_driver)
  - rte_soc_device (inheriting rte_device)
  - rte_eth_dev and eth_driver embedded rte_soc_device and rte_soc_driver,
    respectively.

3) The SoC PMDs need to:
 - define rte_soc_driver with necessary scan and match callbacks
 - Register themselves using DRIVER_REGISTER_SOC()
 - Implement respective bus scanning in the scan callbacks to add necessary
   devices to SoC device list
 - Implement necessary eth_dev_init/uninint for ethernet instances

4) Design considerations that are same as PCI:
 - SoC initialization is being done through rte_eal_init(), just after PCI
   initialization is done.
 - As in case of PCI, probe is done after rte_eal_pci_probe() to link the
   devices detected with the drivers registered.
 - Device attach/detach functions are available and have been designed on
   the lines of PCI framework.
 - PMDs register using DRIVER_REGISTER_SOC, very similar to
   DRIVER_REGISTER_PCI for PCI devices.
 - Linked list of SoC driver and devices exists independent of the other
   driver/device list, but inheriting rte_driver/rte_driver, these are
   also part of a global list.

5) Design considerations that are different from PCI:
 - Each driver implements its own scan and match function. PCI uses the BDF
   format to read the device from sysfs, but this _may_not_ be a case for a
   SoC ethernet device.
   = This is an important change from initial proposal by Jan in [2].
   Unlike his attempt to use /sys/bus/platform, this patch relies on the
   PMD to detect the devices. This is because SoC may require specific or
   additional info for device detection. Further, SoC may have embedded
   devices/MACs which require initialization which cannot be covered
   through sysfs parsing.
   `-> Point (6) below is a side note to above.
   = PCI based PMDs rely on EAL's capability to detect devices. This
   proposal puts the onus on PMD to detect devices, add to soc_device_list
   and wait for Probe. Matching, of device<=>driver is again PMD's
   callback.

6) Adding default scan and match helpers for PMDs
 - The design warrrants the PMDs implement their own scan of devices
   on bus, and match routines for probe implementation.
   This patch introduces helpers which can be used by PMDs for scan of
   the platform bus and matching devices against the compatible string
   extracted from the scan.
 - Intention is to make it easier to integrate known SoC which expose
   platform bus compliant information (compat, sys/bus/platform...).
 - PMDs which have deviations from this standard model can implement and
   hook their bus scanning and probe match callbacks while registering
   driver.

Patchset Overview:
==================
 - Patches 0001~0004 are from [11] - moving some PCI specific functions
   and definitions to non-PCI area.
 - Patches 0005~0008 introduce the base infrastructure and test case
 - Patch 0009 is for command line support for no-soc, on lines of no-pci
 - Patch 0010 enables EAL to handle SoC type devices
 - Patch 0011 adds support for scan and probe callbacks and updates the test
   framework with relevant test case.
 - Patch 0012~0014 enable device argument, driver specific flags and
   interrupt handling related basic infra. Subsequent patches build up on
   them.
 - Patch 0015~0016 add support for default function which PMDs can use for
   scanning platform bus. These functions are optional and need to be hooked
   to by PMDs.
 - Patch 0017~0019 makes changes to PCI as well as ethdev code to remove
   assumption that eth_driver is a PCI driver.
 - Patch 0020 adds necessary ethdev probe/remove functions for PMDs to use
 - Patch 0021 adds support for SoC driver/devices, along with probe/remove
   functions for Cryptodev devices.

Future/Pending Changes:
=======================
- Device whitelisting/blacklist still relies on command line '-b' and '-c'
  which are internally implemented using OPT_PCI_BLACKLIST/OPT_PCI_WHITELIST.
  This needs to be changed to a generic form - OPT_DEV_*LIST - probably.
- No cryptodriver currently uses SoC framework - probably a example driver
  can be created to demonstrate usage.
- test case for enable-soc command line parameter
- This patch impacts a couple of ABIs (rte_device/driver) and thus require
  a patch for bump of libraries (if need be) and documentation.

 [1] http://dpdk.org/ml/archives/dev/2016-January/030915.html
 [2] http://www.dpdk.org/ml/archives/dev/2016-May/038486.html
 [3] http://dpdk.org/ml/archives/dev/2016-August/045707.html
 [4] http://dpdk.org/ml/archives/dev/2016-May/038948.html
 [5] http://dpdk.org/ml/archives/dev/2016-May/038953.html
 [6] http://dpdk.org/ml/archives/dev/2016-May/038487.html
 [7] http://dpdk.org/ml/archives/dev/2016-May/038488.html
 [8] http://dpdk.org/ml/archives/dev/2016-May/038489.html
 [9] http://dpdk.org/ml/archives/dev/2016-May/038491.html
[10] http://dpdk.org/ml/archives/dev/2016-September/046256.html
[11] http://dpdk.org/ml/archives/dev/2016-October/048915.html

Changes since v6;
 - Fix patch rebase over HEAD (ca41215)

Changes since v5:
 - fix devinit/devuninit name change; it was in wrong patch
 - rebased over HEAD (ca41215)
 - Update to pending section of coverletter

Changes since v4:
 - change name of rte_eal_soc_scan function name to
   rte_eal_soc_scan_platform_bus. This still remains a helper function.
 - Fix comments over scan and match functions

Changes since v3:
 - rebasing over HEAD (fed622df tag: v16.11-rc1)
 - Add support for default scan function; PMD can use this for
   scanning on platform bus.
 - Support for kernel driver bind/unbind, numa and DMA from
   Jan's original patches.
 - SoC is disabled by default. '--enable-soc' command line parameter
   enables it. doc updated.
 - Updated testcase function names and comments
 - Map file addition alphabetically ordered
 - Patch author corrected

Changes since v2:
 - Rebasing over rte_driver/device patchset v9 [10]
 - Added cryptodev support for SoC
 - Default match function for SoC device<=>Driver
 - Some variables renamed to reflect 'drv' rather than 'dr'

Change since v1 [2]:
 - Removed patch 1-5 which were for generalizing some PCI specific routines
   into EAL. These patches are good-to-have but not directly linked to SoC
   and hence would be proposed separately.
 - Removed support for sysfs parsing (patches 6~9)
 - Rebasing over the recent (v8) version of rte_driver/device patchset
 - Rebasing over master (16.07)
 - Changes to various map file to change API intro to 16.11 from 16.07

Jan Viktorin (19):
  eal: generalize PCI kernel driver enum to EAL
  eal: generalize PCI map/unmap resource to EAL
  eal/linux: generalize PCI kernel unbinding driver to EAL
  eal/linux: generalize PCI kernel driver extraction to EAL
  eal: define container macro
  eal/soc: introduce very essential SoC infra definitions
  eal/soc: add SoC PMD register/unregister logic
  eal/soc: implement SoC device list and dump
  eal: introduce command line enable SoC option
  eal/soc: init SoC infra from EAL
  eal/soc: extend and utilize devargs
  eal/soc: add drv_flags
  eal/soc: add intr_handle
  eal/soc: add default scan for Soc devices
  eal/soc: additional features for SoC
  ether: utilize container_of for pci_drv
  ether: verify we copy info from a PCI device
  ether: extract function eth_dev_get_intr_handle
  ether: introduce ethernet dev probe remove

Shreyansh Jain (2):
  eal/soc: implement probing of drivers
  eal/crypto: Support rte_soc_driver/device for cryptodev

 app/test/Makefile                               |   1 +
 app/test/test_soc.c                             | 404 +++++++++++++++++++
 doc/guides/testpmd_app_ug/run_app.rst           |   4 +
 lib/librte_cryptodev/rte_cryptodev.c            | 122 +++++-
 lib/librte_cryptodev/rte_cryptodev.h            |   3 +
 lib/librte_cryptodev/rte_cryptodev_pmd.h        |  18 +-
 lib/librte_cryptodev/rte_cryptodev_version.map  |   2 +
 lib/librte_eal/bsdapp/eal/Makefile              |   1 +
 lib/librte_eal/bsdapp/eal/eal.c                 |  18 +
 lib/librte_eal/bsdapp/eal/eal_pci.c             |   6 +-
 lib/librte_eal/bsdapp/eal/eal_soc.c             |  46 +++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  11 +
 lib/librte_eal/common/Makefile                  |   2 +-
 lib/librte_eal/common/eal_common_dev.c          |  66 ++-
 lib/librte_eal/common/eal_common_devargs.c      |  17 +
 lib/librte_eal/common/eal_common_options.c      |   5 +
 lib/librte_eal/common/eal_common_pci.c          |  39 --
 lib/librte_eal/common/eal_common_pci_uio.c      |  16 +-
 lib/librte_eal/common/eal_common_soc.c          | 368 +++++++++++++++++
 lib/librte_eal/common/eal_internal_cfg.h        |   1 +
 lib/librte_eal/common/eal_options.h             |   2 +
 lib/librte_eal/common/eal_private.h             |  64 +++
 lib/librte_eal/common/include/rte_common.h      |  18 +
 lib/librte_eal/common/include/rte_dev.h         |  44 ++
 lib/librte_eal/common/include/rte_devargs.h     |   8 +
 lib/librte_eal/common/include/rte_pci.h         |  41 --
 lib/librte_eal/common/include/rte_soc.h         | 322 +++++++++++++++
 lib/librte_eal/linuxapp/eal/Makefile            |   2 +
 lib/librte_eal/linuxapp/eal/eal.c               |  63 +++
 lib/librte_eal/linuxapp/eal/eal_pci.c           |  62 +--
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c       |   2 +-
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c      |   5 +-
 lib/librte_eal/linuxapp/eal/eal_soc.c           | 515 ++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  11 +
 lib/librte_ether/rte_ethdev.c                   | 166 +++++++-
 lib/librte_ether/rte_ethdev.h                   |  33 +-
 36 files changed, 2343 insertions(+), 165 deletions(-)
 create mode 100644 app/test/test_soc.c
 create mode 100644 lib/librte_eal/bsdapp/eal/eal_soc.c
 create mode 100644 lib/librte_eal/common/eal_common_soc.c
 create mode 100644 lib/librte_eal/common/include/rte_soc.h
 create mode 100644 lib/librte_eal/linuxapp/eal/eal_soc.c

-- 
2.7.4

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

* [PATCH v7 01/21] eal: generalize PCI kernel driver enum to EAL
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-10-28 12:26           ` [PATCH v7 02/21] eal: generalize PCI map/unmap resource " Shreyansh Jain
                             ` (21 subsequent siblings)
  22 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>

--
Changes since v0:
 - fix compilation error due to missing include
---
 lib/librte_eal/common/include/rte_dev.h | 12 ++++++++++++
 lib/librte_eal/common/include/rte_pci.h |  9 ---------
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 8840380..6975b9f 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -109,6 +109,18 @@ struct rte_mem_resource {
 	void *addr;         /**< Virtual address, NULL when not mapped. */
 };
 
+/**
+ * Kernel driver passthrough type
+ */
+enum rte_kernel_driver {
+	RTE_KDRV_UNKNOWN = 0,
+	RTE_KDRV_IGB_UIO,
+	RTE_KDRV_VFIO,
+	RTE_KDRV_UIO_GENERIC,
+	RTE_KDRV_NIC_UIO,
+	RTE_KDRV_NONE,
+};
+
 /** Double linked list of device drivers. */
 TAILQ_HEAD(rte_driver_list, rte_driver);
 /** Double linked list of devices. */
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 9ce8847..2c7046f 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -135,15 +135,6 @@ struct rte_pci_addr {
 
 struct rte_devargs;
 
-enum rte_kernel_driver {
-	RTE_KDRV_UNKNOWN = 0,
-	RTE_KDRV_IGB_UIO,
-	RTE_KDRV_VFIO,
-	RTE_KDRV_UIO_GENERIC,
-	RTE_KDRV_NIC_UIO,
-	RTE_KDRV_NONE,
-};
-
 /**
  * A structure describing a PCI device.
  */
-- 
2.7.4

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

* [PATCH v7 02/21] eal: generalize PCI map/unmap resource to EAL
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
  2016-10-28 12:26           ` [PATCH v7 01/21] eal: generalize PCI kernel driver enum to EAL Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-10-28 12:26           ` [PATCH v7 03/21] eal/linux: generalize PCI kernel unbinding driver " Shreyansh Jain
                             ` (20 subsequent siblings)
  22 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

The functions pci_map_resource, pci_unmap_resource are generic so the
pci_* prefix can be omitted. The functions are moved to the
eal_common_dev.c so they can be reused by other infrastructure.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_eal/bsdapp/eal/eal_pci.c             |  2 +-
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  2 ++
 lib/librte_eal/common/eal_common_dev.c          | 39 +++++++++++++++++++++++++
 lib/librte_eal/common/eal_common_pci.c          | 39 -------------------------
 lib/librte_eal/common/eal_common_pci_uio.c      | 16 +++++-----
 lib/librte_eal/common/include/rte_dev.h         | 32 ++++++++++++++++++++
 lib/librte_eal/common/include/rte_pci.h         | 32 --------------------
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c       |  2 +-
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c      |  5 ++--
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  2 ++
 10 files changed, 89 insertions(+), 82 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 8b3ed88..7ed0115 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -228,7 +228,7 @@ pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
 
 	/* if matching map is found, then use it */
 	offset = res_idx * pagesz;
-	mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
+	mapaddr = rte_eal_map_resource(NULL, fd, (off_t)offset,
 			(size_t)dev->mem_resource[res_idx].len, 0);
 	close(fd);
 	if (mapaddr == MAP_FAILED)
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 2f81f7c..11d9f59 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -170,6 +170,8 @@ DPDK_16.11 {
 	rte_delay_us_callback_register;
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
+	rte_eal_map_resource;
+	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
 
diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 4f3b493..457d227 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -36,6 +36,7 @@
 #include <string.h>
 #include <inttypes.h>
 #include <sys/queue.h>
+#include <sys/mman.h>
 
 #include <rte_dev.h>
 #include <rte_devargs.h>
@@ -151,3 +152,41 @@ err:
 	RTE_LOG(ERR, EAL, "Driver cannot detach the device (%s)\n", name);
 	return -EINVAL;
 }
+
+/* map a particular resource from a file */
+void *
+rte_eal_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
+		 int additional_flags)
+{
+	void *mapaddr;
+
+	/* Map the Memory resource of device */
+	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
+			MAP_SHARED | additional_flags, fd, offset);
+	if (mapaddr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s"
+			" (%p)\n", __func__, fd, requested_addr,
+			(unsigned long)size, (unsigned long)offset,
+			strerror(errno), mapaddr);
+	} else
+		RTE_LOG(DEBUG, EAL, "  Device memory mapped at %p\n", mapaddr);
+
+	return mapaddr;
+}
+
+/* unmap a particular resource */
+void
+rte_eal_unmap_resource(void *requested_addr, size_t size)
+{
+	if (requested_addr == NULL)
+		return;
+
+	/* Unmap the Memory resource of device */
+	if (munmap(requested_addr, size)) {
+		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
+			__func__, requested_addr, (unsigned long)size,
+			strerror(errno));
+	} else
+		RTE_LOG(DEBUG, EAL, "  Device memory unmapped at %p\n",
+				requested_addr);
+}
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 638cd86..464acc1 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -67,7 +67,6 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/queue.h>
-#include <sys/mman.h>
 
 #include <rte_interrupts.h>
 #include <rte_log.h>
@@ -114,44 +113,6 @@ static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
 	return NULL;
 }
 
-/* map a particular resource from a file */
-void *
-pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
-		 int additional_flags)
-{
-	void *mapaddr;
-
-	/* Map the PCI memory resource of device */
-	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
-			MAP_SHARED | additional_flags, fd, offset);
-	if (mapaddr == MAP_FAILED) {
-		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
-			__func__, fd, requested_addr,
-			(unsigned long)size, (unsigned long)offset,
-			strerror(errno), mapaddr);
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
-
-	return mapaddr;
-}
-
-/* unmap a particular resource */
-void
-pci_unmap_resource(void *requested_addr, size_t size)
-{
-	if (requested_addr == NULL)
-		return;
-
-	/* Unmap the PCI memory resource of device */
-	if (munmap(requested_addr, size)) {
-		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
-			__func__, requested_addr, (unsigned long)size,
-			strerror(errno));
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
-				requested_addr);
-}
-
 /*
  * If vendor/device ID match, call the probe() function of the
  * driver.
diff --git a/lib/librte_eal/common/eal_common_pci_uio.c b/lib/librte_eal/common/eal_common_pci_uio.c
index 367a681..3402518 100644
--- a/lib/librte_eal/common/eal_common_pci_uio.c
+++ b/lib/librte_eal/common/eal_common_pci_uio.c
@@ -75,9 +75,11 @@ pci_uio_map_secondary(struct rte_pci_device *dev)
 				return -1;
 			}
 
-			void *mapaddr = pci_map_resource(uio_res->maps[i].addr,
-					fd, (off_t)uio_res->maps[i].offset,
-					(size_t)uio_res->maps[i].size, 0);
+			void *mapaddr = rte_eal_map_resource(
+						uio_res->maps[i].addr, fd,
+						(off_t)uio_res->maps[i].offset,
+						(size_t)uio_res->maps[i].size,
+						0);
 			/* fd is not needed in slave process, close it */
 			close(fd);
 			if (mapaddr != uio_res->maps[i].addr) {
@@ -88,11 +90,11 @@ pci_uio_map_secondary(struct rte_pci_device *dev)
 				if (mapaddr != MAP_FAILED) {
 					/* unmap addrs correctly mapped */
 					for (j = 0; j < i; j++)
-						pci_unmap_resource(
+						rte_eal_unmap_resource(
 							uio_res->maps[j].addr,
 							(size_t)uio_res->maps[j].size);
 					/* unmap addr wrongly mapped */
-					pci_unmap_resource(mapaddr,
+					rte_eal_unmap_resource(mapaddr,
 						(size_t)uio_res->maps[i].size);
 				}
 				return -1;
@@ -150,7 +152,7 @@ pci_uio_map_resource(struct rte_pci_device *dev)
 	return 0;
 error:
 	for (i = 0; i < map_idx; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
+		rte_eal_unmap_resource(uio_res->maps[i].addr,
 				(size_t)uio_res->maps[i].size);
 		rte_free(uio_res->maps[i].path);
 	}
@@ -167,7 +169,7 @@ pci_uio_unmap(struct mapped_pci_resource *uio_res)
 		return;
 
 	for (i = 0; i != uio_res->nb_maps; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
+		rte_eal_unmap_resource(uio_res->maps[i].addr,
 				(size_t)uio_res->maps[i].size);
 		if (rte_eal_process_type() == RTE_PROC_PRIMARY)
 			rte_free(uio_res->maps[i].path);
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 6975b9f..5be6326 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -235,6 +235,38 @@ int rte_eal_dev_attach(const char *name, const char *devargs);
  */
 int rte_eal_dev_detach(const char *name);
 
+/*
+ * @internal
+ * Map a particular resource from a file.
+ *
+ * @param requested_addr
+ *      The starting address for the new mapping range.
+ * @param fd
+ *      The file descriptor.
+ * @param offset
+ *      The offset for the mapping range.
+ * @param size
+ *      The size for the mapping range.
+ * @param additional_flags
+ *      The additional flags for the mapping range.
+ * @return
+ *   - On success, the function returns a pointer to the mapped area.
+ *   - On error, the value MAP_FAILED is returned.
+ */
+void *rte_eal_map_resource(void *requested_addr, int fd, off_t offset,
+			   size_t size, int additional_flags);
+
+/**
+ * @internal
+ * Unmap a particular resource.
+ *
+ * @param requested_addr
+ *      The address for the unmapping range.
+ * @param size
+ *      The size for the unmapping range.
+ */
+void rte_eal_unmap_resource(void *requested_addr, size_t size);
+
 #define RTE_PMD_EXPORT_NAME_ARRAY(n, idx) n##idx[]
 
 #define RTE_PMD_EXPORT_NAME(name, idx) \
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 2c7046f..7d6eef5 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -399,38 +399,6 @@ int rte_eal_pci_map_device(struct rte_pci_device *dev);
 void rte_eal_pci_unmap_device(struct rte_pci_device *dev);
 
 /**
- * @internal
- * Map a particular resource from a file.
- *
- * @param requested_addr
- *      The starting address for the new mapping range.
- * @param fd
- *      The file descriptor.
- * @param offset
- *      The offset for the mapping range.
- * @param size
- *      The size for the mapping range.
- * @param additional_flags
- *      The additional flags for the mapping range.
- * @return
- *   - On success, the function returns a pointer to the mapped area.
- *   - On error, the value MAP_FAILED is returned.
- */
-void *pci_map_resource(void *requested_addr, int fd, off_t offset,
-		size_t size, int additional_flags);
-
-/**
- * @internal
- * Unmap a particular resource.
- *
- * @param requested_addr
- *      The address for the unmapping range.
- * @param size
- *      The size for the unmapping range.
- */
-void pci_unmap_resource(void *requested_addr, size_t size);
-
-/**
  * Probe the single PCI device.
  *
  * Scan the content of the PCI bus, and find the pci device specified by pci
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
index 1786b75..5c34421 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
@@ -347,7 +347,7 @@ pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
 	if (pci_map_addr == NULL)
 		pci_map_addr = pci_find_max_end_va();
 
-	mapaddr = pci_map_resource(pci_map_addr, fd, 0,
+	mapaddr = rte_eal_map_resource(pci_map_addr, fd, 0,
 			(size_t)dev->mem_resource[res_idx].len, 0);
 	close(fd);
 	if (mapaddr == MAP_FAILED)
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
index 5f478c5..5ad8cbe 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
@@ -465,7 +465,8 @@ pci_vfio_map_resource(struct rte_pci_device *dev)
 			void *map_addr = NULL;
 			if (memreg[0].size) {
 				/* actual map of first part */
-				map_addr = pci_map_resource(bar_addr, vfio_dev_fd,
+				map_addr = rte_eal_map_resource(bar_addr,
+							    vfio_dev_fd,
 							    memreg[0].offset,
 							    memreg[0].size,
 							    MAP_FIXED);
@@ -477,7 +478,7 @@ pci_vfio_map_resource(struct rte_pci_device *dev)
 				void *second_addr = RTE_PTR_ADD(bar_addr,
 								memreg[1].offset -
 								(uintptr_t)reg.offset);
-				map_addr = pci_map_resource(second_addr,
+				map_addr = rte_eal_map_resource(second_addr,
 							    vfio_dev_fd, memreg[1].offset,
 							    memreg[1].size,
 							    MAP_FIXED);
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 83721ba..22b5b59 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -174,6 +174,8 @@ DPDK_16.11 {
 	rte_delay_us_callback_register;
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
+	rte_eal_map_resource;
+	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
 
-- 
2.7.4

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

* [PATCH v7 03/21] eal/linux: generalize PCI kernel unbinding driver to EAL
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
  2016-10-28 12:26           ` [PATCH v7 01/21] eal: generalize PCI kernel driver enum to EAL Shreyansh Jain
  2016-10-28 12:26           ` [PATCH v7 02/21] eal: generalize PCI map/unmap resource " Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-11-10  2:24             ` Jianbo Liu
  2016-10-28 12:26           ` [PATCH v7 04/21] eal/linux: generalize PCI kernel driver extraction " Shreyansh Jain
                             ` (19 subsequent siblings)
  22 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Generalize the PCI-specific pci_unbind_kernel_driver. It is now divided
into two parts. First, determination of the path and string identification
of the device to be unbound. Second, the actual unbind operation which is
generic.

BSD implementation updated as ENOTSUP

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
--
Changes since v2:
 - update BSD support for unbind kernel driver
---
 lib/librte_eal/bsdapp/eal/eal.c       |  7 +++++++
 lib/librte_eal/bsdapp/eal/eal_pci.c   |  4 ++--
 lib/librte_eal/common/eal_private.h   | 13 +++++++++++++
 lib/librte_eal/linuxapp/eal/eal.c     | 26 ++++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/eal_pci.c | 33 +++++++++------------------------
 5 files changed, 57 insertions(+), 26 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 35e3117..5271fc2 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -633,3 +633,10 @@ rte_eal_process_type(void)
 {
 	return rte_config.process_type;
 }
+
+int
+rte_eal_unbind_kernel_driver(const char *devpath __rte_unused,
+			     const char *devid __rte_unused)
+{
+	return -ENOTSUP;
+}
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 7ed0115..703f034 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -89,11 +89,11 @@
 
 /* unbind kernel driver for this device */
 int
-pci_unbind_kernel_driver(struct rte_pci_device *dev __rte_unused)
+pci_unbind_kernel_driver(struct rte_pci_device *dev)
 {
 	RTE_LOG(ERR, EAL, "RTE_PCI_DRV_FORCE_UNBIND flag is not implemented "
 		"for BSD\n");
-	return -ENOTSUP;
+	return rte_eal_unbind_kernel_driver(dev);
 }
 
 /* Map pci device */
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 9e7d8f6..b0c208a 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -256,6 +256,19 @@ int rte_eal_alarm_init(void);
 int rte_eal_check_module(const char *module_name);
 
 /**
+ * Unbind kernel driver bound to the device specified by the given devpath,
+ * and its string identification.
+ *
+ * @param devpath  path to the device directory ("/sys/.../devices/<name>")
+ * @param devid    identification of the device (<name>)
+ *
+ * @return
+ *      -1  unbind has failed
+ *       0  module has been unbound
+ */
+int rte_eal_unbind_kernel_driver(const char *devpath, const char *devid);
+
+/**
  * Get cpu core_id.
  *
  * This function is private to the EAL.
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 2075282..5f6676d 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -943,3 +943,29 @@ rte_eal_check_module(const char *module_name)
 	/* Module has been found */
 	return 1;
 }
+
+int
+rte_eal_unbind_kernel_driver(const char *devpath, const char *devid)
+{
+	char filename[PATH_MAX];
+	FILE *f;
+
+	snprintf(filename, sizeof(filename),
+		 "%s/driver/unbind", devpath);
+
+	f = fopen(filename, "w");
+	if (f == NULL) /* device was not bound */
+		return 0;
+
+	if (fwrite(devid, strlen(devid), 1, f) == 0) {
+		RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
+				filename);
+		goto error;
+	}
+
+	fclose(f);
+	return 0;
+error:
+	fclose(f);
+	return -1;
+}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index 876ba38..a03553f 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -59,38 +59,23 @@ int
 pci_unbind_kernel_driver(struct rte_pci_device *dev)
 {
 	int n;
-	FILE *f;
-	char filename[PATH_MAX];
-	char buf[BUFSIZ];
+	char devpath[PATH_MAX];
+	char devid[BUFSIZ];
 	struct rte_pci_addr *loc = &dev->addr;
 
-	/* open /sys/bus/pci/devices/AAAA:BB:CC.D/driver */
-	snprintf(filename, sizeof(filename),
-		"%s/" PCI_PRI_FMT "/driver/unbind", pci_get_sysfs_path(),
+	/* devpath /sys/bus/pci/devices/AAAA:BB:CC.D */
+	snprintf(devpath, sizeof(devpath),
+		"%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
 		loc->domain, loc->bus, loc->devid, loc->function);
 
-	f = fopen(filename, "w");
-	if (f == NULL) /* device was not bound */
-		return 0;
-
-	n = snprintf(buf, sizeof(buf), PCI_PRI_FMT "\n",
+	n = snprintf(devid, sizeof(devid), PCI_PRI_FMT "\n",
 	             loc->domain, loc->bus, loc->devid, loc->function);
-	if ((n < 0) || (n >= (int)sizeof(buf))) {
+	if ((n < 0) || (n >= (int)sizeof(devid))) {
 		RTE_LOG(ERR, EAL, "%s(): snprintf failed\n", __func__);
-		goto error;
-	}
-	if (fwrite(buf, n, 1, f) == 0) {
-		RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
-				filename);
-		goto error;
+		return -1;
 	}
 
-	fclose(f);
-	return 0;
-
-error:
-	fclose(f);
-	return -1;
+	return rte_eal_unbind_kernel_driver(devpath, devid);
 }
 
 static int
-- 
2.7.4

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

* [PATCH v7 04/21] eal/linux: generalize PCI kernel driver extraction to EAL
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                             ` (2 preceding siblings ...)
  2016-10-28 12:26           ` [PATCH v7 03/21] eal/linux: generalize PCI kernel unbinding driver " Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-10-28 12:26           ` [PATCH v7 05/21] eal: define container macro Shreyansh Jain
                             ` (18 subsequent siblings)
  22 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Generalize the PCI-specific pci_get_kernel_driver_by_path. The function
is general enough, we have just moved it to eal.c, changed the prefix to
rte_eal and provided it privately to other parts of EAL.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_eal/bsdapp/eal/eal.c       |  7 +++++++
 lib/librte_eal/common/eal_private.h   | 14 ++++++++++++++
 lib/librte_eal/linuxapp/eal/eal.c     | 29 +++++++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/eal_pci.c | 31 +------------------------------
 4 files changed, 51 insertions(+), 30 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 5271fc2..9b93da3 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -640,3 +640,10 @@ rte_eal_unbind_kernel_driver(const char *devpath __rte_unused,
 {
 	return -ENOTSUP;
 }
+
+int
+rte_eal_get_kernel_driver_by_path(const char *filename __rte_unused,
+				  char *dri_name __rte_unused)
+{
+	return -ENOTSUP;
+}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index b0c208a..c8c2131 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -269,6 +269,20 @@ int rte_eal_check_module(const char *module_name);
 int rte_eal_unbind_kernel_driver(const char *devpath, const char *devid);
 
 /**
+ * Extract the kernel driver name from the absolute path to the driver.
+ *
+ * @param filename  path to the driver ("<path-to-device>/driver")
+ * @path  dri_name  target buffer where to place the driver name
+ *                  (should be at least PATH_MAX long)
+ *
+ * @return
+ *      -1   on failure
+ *       0   when successful
+ *       1   when there is no such driver
+ */
+int rte_eal_get_kernel_driver_by_path(const char *filename, char *dri_name);
+
+/**
  * Get cpu core_id.
  *
  * This function is private to the EAL.
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 5f6676d..00af21c 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -969,3 +969,32 @@ error:
 	fclose(f);
 	return -1;
 }
+
+int
+rte_eal_get_kernel_driver_by_path(const char *filename, char *dri_name)
+{
+	int count;
+	char path[PATH_MAX];
+	char *name;
+
+	if (!filename || !dri_name)
+		return -1;
+
+	count = readlink(filename, path, PATH_MAX);
+	if (count >= PATH_MAX)
+		return -1;
+
+	/* For device does not have a driver */
+	if (count < 0)
+		return 1;
+
+	path[count] = '\0';
+
+	name = strrchr(path, '/');
+	if (name) {
+		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
+		return 0;
+	}
+
+	return -1;
+}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index a03553f..e1cf9e8 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -78,35 +78,6 @@ pci_unbind_kernel_driver(struct rte_pci_device *dev)
 	return rte_eal_unbind_kernel_driver(devpath, devid);
 }
 
-static int
-pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
-{
-	int count;
-	char path[PATH_MAX];
-	char *name;
-
-	if (!filename || !dri_name)
-		return -1;
-
-	count = readlink(filename, path, PATH_MAX);
-	if (count >= PATH_MAX)
-		return -1;
-
-	/* For device does not have a driver */
-	if (count < 0)
-		return 1;
-
-	path[count] = '\0';
-
-	name = strrchr(path, '/');
-	if (name) {
-		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
-		return 0;
-	}
-
-	return -1;
-}
-
 /* Map pci device */
 int
 rte_eal_pci_map_device(struct rte_pci_device *dev)
@@ -354,7 +325,7 @@ pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus,
 
 	/* parse driver */
 	snprintf(filename, sizeof(filename), "%s/driver", dirname);
-	ret = pci_get_kernel_driver_by_path(filename, driver);
+	ret = rte_eal_get_kernel_driver_by_path(filename, driver);
 	if (ret < 0) {
 		RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
 		free(dev);
-- 
2.7.4

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

* [PATCH v7 05/21] eal: define container macro
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                             ` (3 preceding siblings ...)
  2016-10-28 12:26           ` [PATCH v7 04/21] eal/linux: generalize PCI kernel driver extraction " Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-10-28 12:26           ` [PATCH v7 06/21] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
                             ` (17 subsequent siblings)
  22 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_eal/common/include/rte_common.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h
index db5ac91..8152bd9 100644
--- a/lib/librte_eal/common/include/rte_common.h
+++ b/lib/librte_eal/common/include/rte_common.h
@@ -331,6 +331,24 @@ rte_bsf32(uint32_t v)
 #define offsetof(TYPE, MEMBER)  __builtin_offsetof (TYPE, MEMBER)
 #endif
 
+/**
+ * Return pointer to the wrapping struct instance.
+ * Example:
+ *
+ *  struct wrapper {
+ *      ...
+ *      struct child c;
+ *      ...
+ *  };
+ *
+ *  struct child *x = obtain(...);
+ *  struct wrapper *w = container_of(x, struct wrapper, c);
+ */
+#ifndef container_of
+#define container_of(p, type, member) \
+	((type *) (((char *) (p)) - offsetof(type, member)))
+#endif
+
 #define _RTE_STR(x) #x
 /** Take a macro value and get a string version of it */
 #define RTE_STR(x) _RTE_STR(x)
-- 
2.7.4

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

* [PATCH v7 06/21] eal/soc: introduce very essential SoC infra definitions
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                             ` (4 preceding siblings ...)
  2016-10-28 12:26           ` [PATCH v7 05/21] eal: define container macro Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-11-10  4:09             ` Jianbo Liu
  2016-10-28 12:26           ` [PATCH v7 07/21] eal/soc: add SoC PMD register/unregister logic Shreyansh Jain
                             ` (16 subsequent siblings)
  22 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Define initial structures and functions for the SoC infrastructure.
This patch supports only a very minimal functions for now.
More features will be added in the following commits.

Includes rte_device/rte_driver inheritance of
rte_soc_device/rte_soc_driver.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 app/test/Makefile                       |   1 +
 app/test/test_soc.c                     |  90 +++++++++++++++++++++
 lib/librte_eal/common/Makefile          |   2 +-
 lib/librte_eal/common/eal_private.h     |   4 +
 lib/librte_eal/common/include/rte_soc.h | 138 ++++++++++++++++++++++++++++++++
 5 files changed, 234 insertions(+), 1 deletion(-)
 create mode 100644 app/test/test_soc.c
 create mode 100644 lib/librte_eal/common/include/rte_soc.h

diff --git a/app/test/Makefile b/app/test/Makefile
index 5be023a..30295af 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -77,6 +77,7 @@ APP = test
 #
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) := commands.c
 SRCS-y += test.c
+SRCS-y += test_soc.c
 SRCS-y += resource.c
 SRCS-y += test_resource.c
 test_resource.res: test_resource.c
diff --git a/app/test/test_soc.c b/app/test/test_soc.c
new file mode 100644
index 0000000..916a863
--- /dev/null
+++ b/app/test/test_soc.c
@@ -0,0 +1,90 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <sys/queue.h>
+
+#include <rte_soc.h>
+#include <rte_devargs.h>
+#include <rte_debug.h>
+
+#include "test.h"
+
+static char *safe_strdup(const char *s)
+{
+	char *c = strdup(s);
+
+	if (c == NULL)
+		rte_panic("failed to strdup '%s'\n", s);
+
+	return c;
+}
+
+static int test_compare_addr(void)
+{
+	struct rte_soc_addr a0;
+	struct rte_soc_addr a1;
+	struct rte_soc_addr a2;
+
+	a0.name = safe_strdup("ethernet0");
+	a0.fdt_path = NULL;
+
+	a1.name = safe_strdup("ethernet0");
+	a1.fdt_path = NULL;
+
+	a2.name = safe_strdup("ethernet1");
+	a2.fdt_path = NULL;
+
+	TEST_ASSERT(!rte_eal_compare_soc_addr(&a0, &a1),
+		    "Failed to compare two soc addresses that equal");
+	TEST_ASSERT(rte_eal_compare_soc_addr(&a0, &a2),
+		    "Failed to compare two soc addresses that differs");
+
+	free(a2.name);
+	free(a1.name);
+	free(a0.name);
+	return 0;
+}
+
+static int
+test_soc(void)
+{
+	if (test_compare_addr())
+		return -1;
+
+	return 0;
+}
+
+REGISTER_TEST_COMMAND(soc_autotest, test_soc);
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index dfd64aa..b414008 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 INC := rte_branch_prediction.h rte_common.h
 INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
-INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
+INC += rte_log.h rte_memory.h rte_memzone.h rte_soc.h rte_pci.h
 INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index c8c2131..0e8d6f7 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -36,6 +36,7 @@
 
 #include <stdio.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 
 /**
  * Initialize the memzone subsystem (private to eal).
@@ -118,6 +119,9 @@ int rte_eal_log_init(const char *id, int facility);
  */
 int rte_eal_pci_init(void);
 
+struct rte_soc_driver;
+struct rte_soc_device;
+
 struct rte_pci_driver;
 struct rte_pci_device;
 
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
new file mode 100644
index 0000000..5c32737
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -0,0 +1,138 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_SOC_H_
+#define _RTE_SOC_H_
+
+/**
+ * @file
+ *
+ * RTE SoC Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include <rte_dev.h>
+#include <rte_debug.h>
+
+struct rte_soc_id {
+	const char *compatible; /**< OF compatible specification */
+	uint64_t priv_data;     /**< SoC Driver specific data */
+};
+
+struct rte_soc_addr {
+	char *name;     /**< name used in sysfs */
+	char *fdt_path; /**< path to the associated node in FDT */
+};
+
+/**
+ * A structure describing a SoC device.
+ */
+struct rte_soc_device {
+	TAILQ_ENTRY(rte_soc_device) next;   /**< Next probed SoC device */
+	struct rte_device device;           /**< Inherit code device */
+	struct rte_soc_addr addr;           /**< SoC device Location */
+	struct rte_soc_id *id;              /**< SoC device ID list */
+	struct rte_soc_driver *driver;      /**< Associated driver */
+};
+
+struct rte_soc_driver;
+
+/**
+ * Probe function for the driver called during SoC probing.
+ */
+typedef int (soc_probe_t)(struct rte_soc_driver *, struct rte_soc_device *);
+
+/**
+ * Remove function for the driver called during hotplugging.
+ */
+typedef int (soc_remove_t)(struct rte_soc_device *);
+
+/**
+ * A structure describing a SoC driver.
+ */
+struct rte_soc_driver {
+	TAILQ_ENTRY(rte_soc_driver) next;  /**< Next in list */
+	struct rte_driver driver;          /**< Inherit core driver. */
+	soc_probe_t *probe;                /**< Device probe */
+	soc_remove_t *remove;              /**< Device remove */
+	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
+};
+
+/**
+ * Utility function to write a SoC device name, this device name can later be
+ * used to retrieve the corresponding rte_soc_addr using above functions.
+ *
+ * @param addr
+ *	The SoC address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ * @return
+ *  0 on success, negative on error.
+ */
+static inline void
+rte_eal_soc_device_name(const struct rte_soc_addr *addr,
+			char *output, size_t size)
+{
+	int ret;
+
+	RTE_VERIFY(addr != NULL);
+	RTE_VERIFY(size >= strlen(addr->name));
+	ret = snprintf(output, size, "%s", addr->name);
+	RTE_VERIFY(ret >= 0);
+}
+
+static inline int
+rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
+			 const struct rte_soc_addr *a1)
+{
+	if (a0 == NULL || a1 == NULL)
+		return -1;
+
+	RTE_VERIFY(a0->name != NULL);
+	RTE_VERIFY(a1->name != NULL);
+
+	return strcmp(a0->name, a1->name);
+}
+
+#endif
-- 
2.7.4

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

* [PATCH v7 07/21] eal/soc: add SoC PMD register/unregister logic
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                             ` (5 preceding siblings ...)
  2016-10-28 12:26           ` [PATCH v7 06/21] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-10-28 12:26           ` [PATCH v7 08/21] eal/soc: implement SoC device list and dump Shreyansh Jain
                             ` (15 subsequent siblings)
  22 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Registeration of a SoC driver through a helper RTE_PMD_REGISTER_SOC
(on the lines of RTE_PMD_REGISTER_PCI). soc_driver_list stores all the
registered drivers.

Test case has been introduced to verify the registration and
deregistration.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: update PMD registration method]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 app/test/test_soc.c                             | 111 ++++++++++++++++++++++++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   3 +
 lib/librte_eal/common/eal_common_soc.c          |  56 ++++++++++++
 lib/librte_eal/common/include/rte_soc.h         |  26 ++++++
 lib/librte_eal/linuxapp/eal/Makefile            |   1 +
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   3 +
 6 files changed, 200 insertions(+)
 create mode 100644 lib/librte_eal/common/eal_common_soc.c

diff --git a/app/test/test_soc.c b/app/test/test_soc.c
index 916a863..ac03e64 100644
--- a/app/test/test_soc.c
+++ b/app/test/test_soc.c
@@ -75,6 +75,108 @@ static int test_compare_addr(void)
 	free(a2.name);
 	free(a1.name);
 	free(a0.name);
+
+	return 0;
+}
+
+/**
+ * Empty PMD driver based on the SoC infra.
+ *
+ * The rte_soc_device is usually wrapped in some higher-level struct
+ * (eth_driver). We simulate such a wrapper with an anonymous struct here.
+ */
+struct test_wrapper {
+	struct rte_soc_driver soc_drv;
+};
+
+struct test_wrapper empty_pmd0 = {
+	.soc_drv = {
+		.driver = {
+			.name = "empty_pmd0"
+		},
+	},
+};
+
+struct test_wrapper empty_pmd1 = {
+	.soc_drv = {
+		.driver = {
+			.name = "empty_pmd1"
+		},
+	},
+};
+
+static int
+count_registered_socdrvs(void)
+{
+	int i;
+	struct rte_soc_driver *drv;
+
+	i = 0;
+	TAILQ_FOREACH(drv, &soc_driver_list, next)
+		i += 1;
+
+	return i;
+}
+
+static int
+test_register_unregister(void)
+{
+	struct rte_soc_driver *drv;
+	int count;
+
+	rte_eal_soc_register(&empty_pmd0.soc_drv);
+
+	TEST_ASSERT(!TAILQ_EMPTY(&soc_driver_list),
+		    "No PMD is present but the empty_pmd0 should be there");
+	drv = TAILQ_FIRST(&soc_driver_list);
+	TEST_ASSERT(!strcmp(drv->driver.name, "empty_pmd0"),
+		    "The registered PMD is not empty_pmd0 but '%s'",
+		drv->driver.name);
+
+	rte_eal_soc_register(&empty_pmd1.soc_drv);
+
+	count = count_registered_socdrvs();
+	TEST_ASSERT_EQUAL(count, 2, "Expected 2 PMDs but detected %d", count);
+
+	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
+	count = count_registered_socdrvs();
+	TEST_ASSERT_EQUAL(count, 1, "Expected 1 PMDs but detected %d", count);
+
+	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
+
+	printf("%s has been successful\n", __func__);
+	return 0;
+}
+
+/* save real devices and drivers until the tests finishes */
+struct soc_driver_list real_soc_driver_list =
+	TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
+
+static int test_soc_setup(void)
+{
+	struct rte_soc_driver *drv;
+
+	/* no real drivers for the test */
+	while (!TAILQ_EMPTY(&soc_driver_list)) {
+		drv = TAILQ_FIRST(&soc_driver_list);
+		rte_eal_soc_unregister(drv);
+		TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
+	}
+
+	return 0;
+}
+
+static int test_soc_cleanup(void)
+{
+	struct rte_soc_driver *drv;
+
+	/* bring back real drivers after the test */
+	while (!TAILQ_EMPTY(&real_soc_driver_list)) {
+		drv = TAILQ_FIRST(&real_soc_driver_list);
+		TAILQ_REMOVE(&real_soc_driver_list, drv, next);
+		rte_eal_soc_register(drv);
+	}
+
 	return 0;
 }
 
@@ -84,6 +186,15 @@ test_soc(void)
 	if (test_compare_addr())
 		return -1;
 
+	if (test_soc_setup())
+		return -1;
+
+	if (test_register_unregister())
+		return -1;
+
+	if (test_soc_cleanup())
+		return -1;
+
 	return 0;
 }
 
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 11d9f59..cf6fb8e 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -171,8 +171,11 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_register;
+	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
+	soc_driver_list;
 
 } DPDK_16.07;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
new file mode 100644
index 0000000..56135ed
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -0,0 +1,56 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/queue.h>
+
+#include <rte_log.h>
+
+#include "eal_private.h"
+
+/* Global SoC driver list */
+struct soc_driver_list soc_driver_list =
+	TAILQ_HEAD_INITIALIZER(soc_driver_list);
+
+/* register a driver */
+void
+rte_eal_soc_register(struct rte_soc_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_eal_soc_unregister(struct rte_soc_driver *driver)
+{
+	TAILQ_REMOVE(&soc_driver_list, driver, next);
+}
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 5c32737..23b06a9 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -51,8 +51,14 @@ extern "C" {
 #include <string.h>
 
 #include <rte_dev.h>
+#include <rte_eal.h>
 #include <rte_debug.h>
 
+extern struct soc_driver_list soc_driver_list;
+/**< Global list of SoC Drivers */
+
+TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
+
 struct rte_soc_id {
 	const char *compatible; /**< OF compatible specification */
 	uint64_t priv_data;     /**< SoC Driver specific data */
@@ -135,4 +141,24 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 	return strcmp(a0->name, a1->name);
 }
 
+/**
+ * Register a SoC driver.
+ */
+void rte_eal_soc_register(struct rte_soc_driver *driver);
+
+/** Helper for SoC device registeration from PMD Drivers */
+#define RTE_PMD_REGISTER_SOC(nm, soc_drv) \
+RTE_INIT(socinitfn_ ##name); \
+static void socinitfn_ ##name(void) \
+{\
+	(soc_drv).driver.name = RTE_STR(nm);\
+	rte_eal_soc_register(&soc_drv); \
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+/**
+ * Unregister a SoC driver.
+ */
+void rte_eal_soc_unregister(struct rte_soc_driver *driver);
+
 #endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 4e206f0..a520477 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -77,6 +77,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 22b5b59..ab6b985 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -175,8 +175,11 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_register;
+	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
+	soc_driver_list;
 
 } DPDK_16.07;
-- 
2.7.4

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

* [PATCH v7 08/21] eal/soc: implement SoC device list and dump
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                             ` (6 preceding siblings ...)
  2016-10-28 12:26           ` [PATCH v7 07/21] eal/soc: add SoC PMD register/unregister logic Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-11-10  3:06             ` Jianbo Liu
  2016-10-28 12:26           ` [PATCH v7 09/21] eal: introduce command line enable SoC option Shreyansh Jain
                             ` (14 subsequent siblings)
  22 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

SoC devices would be linked in a separate list (from PCI). This is used for
probe function.
A helper for dumping the device list is added.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  2 ++
 lib/librte_eal/common/eal_common_soc.c          | 34 +++++++++++++++++++++++++
 lib/librte_eal/common/include/rte_soc.h         |  9 +++++++
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  2 ++
 4 files changed, 47 insertions(+)

diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index cf6fb8e..86e3cfd 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -171,11 +171,13 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_dump;
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
+	soc_device_list;
 	soc_driver_list;
 
 } DPDK_16.07;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 56135ed..5dcddc5 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -31,6 +31,8 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <stddef.h>
+#include <stdio.h>
 #include <sys/queue.h>
 
 #include <rte_log.h>
@@ -40,6 +42,38 @@
 /* Global SoC driver list */
 struct soc_driver_list soc_driver_list =
 	TAILQ_HEAD_INITIALIZER(soc_driver_list);
+struct soc_device_list soc_device_list =
+	TAILQ_HEAD_INITIALIZER(soc_device_list);
+
+/* dump one device */
+static int
+soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
+{
+	int i;
+
+	fprintf(f, "%s", dev->addr.name);
+	fprintf(f, " - fdt_path: %s\n",
+			dev->addr.fdt_path ? dev->addr.fdt_path : "(none)");
+
+	for (i = 0; dev->id && dev->id[i].compatible; ++i)
+		fprintf(f, "   %s\n", dev->id[i].compatible);
+
+	return 0;
+}
+
+/* dump devices on the bus to an output stream */
+void
+rte_eal_soc_dump(FILE *f)
+{
+	struct rte_soc_device *dev = NULL;
+
+	if (!f)
+		return;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		soc_dump_one_device(f, dev);
+	}
+}
 
 /* register a driver */
 void
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 23b06a9..347e611 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -56,8 +56,12 @@ extern "C" {
 
 extern struct soc_driver_list soc_driver_list;
 /**< Global list of SoC Drivers */
+extern struct soc_device_list soc_device_list;
+/**< Global list of SoC Devices */
 
 TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
+TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
+
 
 struct rte_soc_id {
 	const char *compatible; /**< OF compatible specification */
@@ -142,6 +146,11 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 }
 
 /**
+ * Dump discovered SoC devices.
+ */
+void rte_eal_soc_dump(FILE *f);
+
+/**
  * Register a SoC driver.
  */
 void rte_eal_soc_register(struct rte_soc_driver *driver);
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index ab6b985..0155025 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -175,11 +175,13 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_dump;
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
 	rte_eal_vdrv_register;
 	rte_eal_vdrv_unregister;
+	soc_device_list;
 	soc_driver_list;
 
 } DPDK_16.07;
-- 
2.7.4

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

* [PATCH v7 09/21] eal: introduce command line enable SoC option
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                             ` (7 preceding siblings ...)
  2016-10-28 12:26           ` [PATCH v7 08/21] eal/soc: implement SoC device list and dump Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-10-28 12:26           ` [PATCH v7 10/21] eal/soc: init SoC infra from EAL Shreyansh Jain
                             ` (13 subsequent siblings)
  22 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Support --enable-soc. SoC support is disabled by default.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: Change --no-soc to --enable-soc; disabled by default]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 doc/guides/testpmd_app_ug/run_app.rst      | 4 ++++
 lib/librte_eal/common/eal_common_options.c | 5 +++++
 lib/librte_eal/common/eal_internal_cfg.h   | 1 +
 lib/librte_eal/common/eal_options.h        | 2 ++
 4 files changed, 12 insertions(+)

diff --git a/doc/guides/testpmd_app_ug/run_app.rst b/doc/guides/testpmd_app_ug/run_app.rst
index d7c5120..4dafe5f 100644
--- a/doc/guides/testpmd_app_ug/run_app.rst
+++ b/doc/guides/testpmd_app_ug/run_app.rst
@@ -156,6 +156,10 @@ See the DPDK Getting Started Guides for more information on these options.
 
     Use malloc instead of hugetlbfs.
 
+*   ``--enable-soc``
+
+    Enable SoC framework support
+
 
 Testpmd Command-line Options
 ----------------------------
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 6ca8af1..2156ab3 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -75,6 +75,7 @@ const struct option
 eal_long_options[] = {
 	{OPT_BASE_VIRTADDR,     1, NULL, OPT_BASE_VIRTADDR_NUM    },
 	{OPT_CREATE_UIO_DEV,    0, NULL, OPT_CREATE_UIO_DEV_NUM   },
+	{OPT_ENABLE_SOC,        0, NULL, OPT_ENABLE_SOC_NUM       },
 	{OPT_FILE_PREFIX,       1, NULL, OPT_FILE_PREFIX_NUM      },
 	{OPT_HELP,              0, NULL, OPT_HELP_NUM             },
 	{OPT_HUGE_DIR,          1, NULL, OPT_HUGE_DIR_NUM         },
@@ -843,6 +844,10 @@ eal_parse_common_option(int opt, const char *optarg,
 		break;
 
 	/* long options */
+	case OPT_ENABLE_SOC_NUM:
+		conf->enable_soc = 1;
+		break;
+
 	case OPT_HUGE_UNLINK_NUM:
 		conf->hugepage_unlink = 1;
 		break;
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 5f1367e..2a6e3ea 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -67,6 +67,7 @@ struct internal_config {
 	unsigned hugepage_unlink;         /**< true to unlink backing files */
 	volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
 	volatile unsigned no_pci;         /**< true to disable PCI */
+	volatile unsigned enable_soc;     /**< true to enable SoC */
 	volatile unsigned no_hpet;        /**< true to disable HPET */
 	volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
 										* instead of native TSC */
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index a881c62..6e679c3 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -49,6 +49,8 @@ enum {
 	OPT_BASE_VIRTADDR_NUM,
 #define OPT_CREATE_UIO_DEV    "create-uio-dev"
 	OPT_CREATE_UIO_DEV_NUM,
+#define OPT_ENABLE_SOC        "enable-soc"
+	OPT_ENABLE_SOC_NUM,
 #define OPT_FILE_PREFIX       "file-prefix"
 	OPT_FILE_PREFIX_NUM,
 #define OPT_HUGE_DIR          "huge-dir"
-- 
2.7.4

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

* [PATCH v7 10/21] eal/soc: init SoC infra from EAL
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                             ` (8 preceding siblings ...)
  2016-10-28 12:26           ` [PATCH v7 09/21] eal: introduce command line enable SoC option Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-10-28 12:26           ` [PATCH v7 11/21] eal/soc: implement probing of drivers Shreyansh Jain
                             ` (12 subsequent siblings)
  22 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/bsdapp/eal/Makefile    |  1 +
 lib/librte_eal/bsdapp/eal/eal.c       |  4 +++
 lib/librte_eal/bsdapp/eal/eal_soc.c   | 46 ++++++++++++++++++++++++++++
 lib/librte_eal/common/eal_private.h   | 10 +++++++
 lib/librte_eal/linuxapp/eal/Makefile  |  1 +
 lib/librte_eal/linuxapp/eal/eal.c     |  3 ++
 lib/librte_eal/linuxapp/eal/eal_soc.c | 56 +++++++++++++++++++++++++++++++++++
 7 files changed, 121 insertions(+)
 create mode 100644 lib/librte_eal/bsdapp/eal/eal_soc.c
 create mode 100644 lib/librte_eal/linuxapp/eal/eal_soc.c

diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index a15b762..42b3a2b 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -56,6 +56,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_hugepage_info.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_pci.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_timer.c
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 9b93da3..2d62b9d 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -64,6 +64,7 @@
 #include <rte_string_fns.h>
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
+#include <rte_soc.h>
 #include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
@@ -564,6 +565,9 @@ rte_eal_init(int argc, char **argv)
 	if (rte_eal_pci_init() < 0)
 		rte_panic("Cannot init PCI\n");
 
+	if (rte_eal_soc_init() < 0)
+		rte_panic("Cannot init SoC\n");
+
 	eal_check_mem_on_local_socket();
 
 	if (eal_plugins_init() < 0)
diff --git a/lib/librte_eal/bsdapp/eal/eal_soc.c b/lib/librte_eal/bsdapp/eal/eal_soc.c
new file mode 100644
index 0000000..cb297ff
--- /dev/null
+++ b/lib/librte_eal/bsdapp/eal/eal_soc.c
@@ -0,0 +1,46 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <rte_common.h>
+#include <rte_log.h>
+
+#include <eal_private.h>
+
+/* Init the SoC EAL subsystem */
+int
+rte_eal_soc_init(void)
+{
+	return 0;
+}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 0e8d6f7..d810f9f 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -122,6 +122,16 @@ int rte_eal_pci_init(void);
 struct rte_soc_driver;
 struct rte_soc_device;
 
+/**
+ * Init the SoC infra.
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int rte_eal_soc_init(void);
+
 struct rte_pci_driver;
 struct rte_pci_device;
 
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index a520477..59e30fa 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -65,6 +65,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio_mp_sync.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_vfio.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_soc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 00af21c..098ba02 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -810,6 +810,9 @@ rte_eal_init(int argc, char **argv)
 		rte_panic("Cannot init VFIO\n");
 #endif
 
+	if (rte_eal_soc_init() < 0)
+		rte_panic("Cannot init SoC\n");
+
 	if (rte_eal_memory_init() < 0)
 		rte_panic("Cannot init memory\n");
 
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
new file mode 100644
index 0000000..04848b9
--- /dev/null
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -0,0 +1,56 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of RehiveTech nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <rte_log.h>
+#include <rte_soc.h>
+
+#include "eal_internal_cfg.h"
+#include "eal_filesystem.h"
+#include "eal_private.h"
+
+/* Init the SoC EAL subsystem */
+int
+rte_eal_soc_init(void)
+{
+	return 0;
+}
-- 
2.7.4

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

* [PATCH v7 11/21] eal/soc: implement probing of drivers
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                             ` (9 preceding siblings ...)
  2016-10-28 12:26           ` [PATCH v7 10/21] eal/soc: init SoC infra from EAL Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-11-10  3:30             ` Jianbo Liu
  2016-10-28 12:26           ` [PATCH v7 12/21] eal/soc: extend and utilize devargs Shreyansh Jain
                             ` (11 subsequent siblings)
  22 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

Each SoC PMD registers a set of callback for scanning its own bus/infra and
matching devices to drivers when probe is called.
This patch introduces the infra for calls to SoC scan on rte_eal_soc_init()
and match on rte_eal_soc_probe().

Patch also adds test case for scan and probe.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
--
v4:
 - Update test_soc for descriptive test function names
 - Comments over test functions
 - devinit and devuninint --> probe/remove
 - RTE_VERIFY at some places
---
 app/test/test_soc.c                             | 205 ++++++++++++++++++++++-
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   4 +
 lib/librte_eal/common/eal_common_soc.c          | 213 +++++++++++++++++++++++-
 lib/librte_eal/common/include/rte_soc.h         |  75 ++++++++-
 lib/librte_eal/linuxapp/eal/eal.c               |   5 +
 lib/librte_eal/linuxapp/eal/eal_soc.c           |  21 ++-
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   4 +
 7 files changed, 519 insertions(+), 8 deletions(-)

diff --git a/app/test/test_soc.c b/app/test/test_soc.c
index ac03e64..b587d5e 100644
--- a/app/test/test_soc.c
+++ b/app/test/test_soc.c
@@ -87,14 +87,65 @@ static int test_compare_addr(void)
  */
 struct test_wrapper {
 	struct rte_soc_driver soc_drv;
+	struct rte_soc_device soc_dev;
 };
 
+static int empty_pmd0_probe(struct rte_soc_driver *drv,
+			      struct rte_soc_device *dev);
+static int empty_pmd0_remove(struct rte_soc_device *dev);
+
+static void always_find_dev0_cb(void);
+static int match_dev0_by_name(struct rte_soc_driver *drv,
+				  struct rte_soc_device *dev);
+
+static void always_find_dev1_cb(void);
+static int match_dev1_by_name(struct rte_soc_driver *drv,
+				  struct rte_soc_device *dev);
+
+/**
+ * Dummy probe handler for PMD driver 'pmd0'.
+ *
+ * @param drv
+ *	driver object
+ * @param dev
+ *	device object
+ * @return
+ *	0 on success
+ */
+static int
+empty_pmd0_probe(struct rte_soc_driver *drv __rte_unused,
+		   struct rte_soc_device *dev __rte_unused)
+{
+	return 0;
+}
+
+/**
+ * Remove handler for PMD driver 'pmd0'.
+ *
+ * @param dev
+ *	device to remove
+ * @return
+ *	0 on success
+ */
+static int
+empty_pmd0_remove(struct rte_soc_device *dev)
+{
+	/* Release the memory associated with dev->addr.name */
+	free(dev->addr.name);
+
+	return 0;
+}
+
 struct test_wrapper empty_pmd0 = {
 	.soc_drv = {
 		.driver = {
 			.name = "empty_pmd0"
 		},
-	},
+		.probe = empty_pmd0_probe,
+		.remove = empty_pmd0_remove,
+		.scan_fn = always_find_dev0_cb,
+		.match_fn = match_dev0_by_name,
+	}
 };
 
 struct test_wrapper empty_pmd1 = {
@@ -102,9 +153,87 @@ struct test_wrapper empty_pmd1 = {
 		.driver = {
 			.name = "empty_pmd1"
 		},
+		.scan_fn = always_find_dev1_cb,
+		.match_fn = match_dev1_by_name,
 	},
 };
 
+/**
+ * Bus scan by PMD 'pmd0' for adding device 'dev0'
+ *
+ * @param void
+ * @return void
+ */
+static void
+always_find_dev0_cb(void)
+{
+	/* SoC's scan would scan devices on its bus and add to
+	 * soc_device_list
+	 */
+	empty_pmd0.soc_dev.addr.name = strdup("empty_pmd0_dev");
+
+	TAILQ_INSERT_TAIL(&soc_device_list, &empty_pmd0.soc_dev, next);
+}
+
+/**
+ * Match device 'dev0' with driver PMD pmd0
+ *
+ * @param drv
+ *	Driver with this matching needs to be done; unused here
+ * @param dev
+ *	device to be matched against driver
+ * @return
+ *	0 on successful matched
+ *	1 if driver<=>device don't match
+ */
+static int
+match_dev0_by_name(struct rte_soc_driver *drv __rte_unused,
+		       struct rte_soc_device *dev)
+{
+	if (!dev->addr.name || strcmp(dev->addr.name, "empty_pmd0_dev"))
+		return 0;
+
+	return 1;
+}
+
+/**
+ * Bus scan by PMD 'pmd0' for adding device 'dev1'
+ *
+ * @param void
+ * @return void
+ */
+static void
+always_find_dev1_cb(void)
+{
+	/* SoC's scan would scan devices on its bus and add to
+	 * soc_device_list
+	 */
+	empty_pmd0.soc_dev.addr.name = strdup("empty_pmd1_dev");
+
+	TAILQ_INSERT_TAIL(&soc_device_list, &empty_pmd1.soc_dev, next);
+}
+
+/**
+ * Match device 'dev1' with driver PMD pmd0
+ *
+ * @param drv
+ *	Driver with this matching needs to be done; unused here
+ * @param dev
+ *	device to be matched against driver
+ * @return
+ *	0 on successful matched
+ *	1 if driver<=>device don't match
+ */
+static int
+match_dev1_by_name(struct rte_soc_driver *drv __rte_unused,
+		       struct rte_soc_device *dev)
+{
+	if (!dev->addr.name || strcmp(dev->addr.name, "empty_pmd1_dev"))
+		return 0;
+
+	return 1;
+}
+
 static int
 count_registered_socdrvs(void)
 {
@@ -148,13 +277,68 @@ test_register_unregister(void)
 	return 0;
 }
 
+/* Test Probe (scan and match) functionality */
+static int
+test_soc_scan_and_match(void)
+{
+	int drv_count = 0;
+	struct rte_soc_driver *drv;
+
+	/* Registering dummy drivers */
+	rte_eal_soc_register(&empty_pmd0.soc_drv);
+	rte_eal_soc_register(&empty_pmd1.soc_drv);
+	/* Assuming that test_register_unregister is working, not verifying
+	 * that drivers are indeed registered
+	*/
+
+	/* rte_eal_soc_init is called by rte_eal_init, which in turn calls the
+	 * scan_fn of each driver.
+	 */
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		if (drv && drv->scan_fn)
+			drv->scan_fn();
+		drv_count++;
+	}
+
+	/* rte_eal_init() would perform other inits here */
+
+	/* Probe would link the SoC devices<=>drivers */
+	rte_eal_soc_probe();
+
+	/* Unregistering dummy drivers */
+	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
+	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
+
+	/* Verify the Unregistering has removed the driver from list */
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		if (drv)
+			drv_count--;
+	}
+
+	free(empty_pmd0.soc_dev.addr.name);
+
+	/* If drv_count is anything other than 0, Unregistering failed */
+	if (drv_count) {
+		printf("%s has failed\n", __func__);
+		return 1;
+	}
+
+	printf("%s has been successful\n", __func__);
+	return 0;
+}
+
 /* save real devices and drivers until the tests finishes */
 struct soc_driver_list real_soc_driver_list =
 	TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
 
+/* save real devices and drivers until the tests finishes */
+struct soc_device_list real_soc_device_list =
+	TAILQ_HEAD_INITIALIZER(real_soc_device_list);
+
 static int test_soc_setup(void)
 {
 	struct rte_soc_driver *drv;
+	struct rte_soc_device *dev;
 
 	/* no real drivers for the test */
 	while (!TAILQ_EMPTY(&soc_driver_list)) {
@@ -163,12 +347,20 @@ static int test_soc_setup(void)
 		TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
 	}
 
+	/* And, no real devices for the test */
+	while (!TAILQ_EMPTY(&soc_device_list)) {
+		dev = TAILQ_FIRST(&soc_device_list);
+		TAILQ_REMOVE(&soc_device_list, dev, next);
+		TAILQ_INSERT_TAIL(&real_soc_device_list, dev, next);
+	}
+
 	return 0;
 }
 
 static int test_soc_cleanup(void)
 {
 	struct rte_soc_driver *drv;
+	struct rte_soc_device *dev;
 
 	/* bring back real drivers after the test */
 	while (!TAILQ_EMPTY(&real_soc_driver_list)) {
@@ -177,6 +369,13 @@ static int test_soc_cleanup(void)
 		rte_eal_soc_register(drv);
 	}
 
+	/* And, bring back real devices after the test */
+	while (!TAILQ_EMPTY(&real_soc_device_list)) {
+		dev = TAILQ_FIRST(&real_soc_device_list);
+		TAILQ_REMOVE(&real_soc_device_list, dev, next);
+		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+	}
+
 	return 0;
 }
 
@@ -192,6 +391,10 @@ test_soc(void)
 	if (test_register_unregister())
 		return -1;
 
+	/* Assuming test_register_unregister has succeeded */
+	if (test_soc_scan_and_match())
+		return -1;
+
 	if (test_soc_cleanup())
 		return -1;
 
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 86e3cfd..dfbb1ac 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -171,7 +171,11 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_detach;
 	rte_eal_soc_dump;
+	rte_eal_soc_match;
+	rte_eal_soc_probe;
+	rte_eal_soc_probe_one;
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 5dcddc5..256cef8 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -36,6 +36,8 @@
 #include <sys/queue.h>
 
 #include <rte_log.h>
+#include <rte_common.h>
+#include <rte_soc.h>
 
 #include "eal_private.h"
 
@@ -45,6 +47,208 @@ struct soc_driver_list soc_driver_list =
 struct soc_device_list soc_device_list =
 	TAILQ_HEAD_INITIALIZER(soc_device_list);
 
+int
+rte_eal_soc_match_compat(struct rte_soc_driver *drv,
+			 struct rte_soc_device *dev)
+{
+	int i, j;
+
+	RTE_VERIFY(drv != NULL && drv->id_table != NULL);
+	RTE_VERIFY(dev != NULL && dev->id != NULL);
+
+	for (i = 0; drv->id_table[i].compatible; ++i) {
+		const char *drv_compat = drv->id_table[i].compatible;
+
+		for (j = 0; dev->id[j].compatible; ++j) {
+			const char *dev_compat = dev->id[j].compatible;
+
+			if (!strcmp(drv_compat, dev_compat))
+				return 0;
+		}
+	}
+
+	return 1;
+}
+
+static int
+rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
+			     struct rte_soc_device *dev)
+{
+	int ret = 1;
+
+	RTE_VERIFY(drv->match_fn);
+
+	ret = drv->match_fn(drv, dev);
+	if (ret) {
+		RTE_LOG(DEBUG, EAL,
+			" match function failed, skipping\n");
+		return ret;
+	}
+
+	dev->driver = drv;
+	RTE_VERIFY(drv->probe != NULL);
+	return drv->probe(drv, dev);
+}
+
+static int
+soc_probe_all_drivers(struct rte_soc_device *dev)
+{
+	struct rte_soc_driver *drv = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		rc = rte_eal_soc_probe_one_driver(drv, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+/* If the IDs match, call the remove() function of the driver. */
+static int
+rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
+		       struct rte_soc_device *dev)
+{
+	int ret;
+
+	if ((drv == NULL) || (dev == NULL))
+		return -EINVAL;
+
+	ret = drv->match_fn(drv, dev);
+	if (ret) {
+		RTE_LOG(DEBUG, EAL, " driver (%s) didn't match device (%s)\n",
+			drv->driver.name, dev->addr.name);
+		return ret;
+	}
+
+	RTE_LOG(DEBUG, EAL, "SoC device %s\n",
+		dev->addr.name);
+
+	RTE_LOG(DEBUG, EAL, "  remove driver: %s\n", drv->driver.name);
+
+	if (drv->remove && (drv->remove(dev) < 0))
+		return -1;	/* negative value is an error */
+
+	/* clear driver structure */
+	dev->driver = NULL;
+
+	return 0;
+}
+
+/*
+ * Call the remove() function of all registered drivers for the device.
+ *
+ * @param dev
+ *	Device for which detach is to be performed
+ * @return
+ *       0 when successful
+ *      -1 if deinitialization fails
+ *       1 if no driver is found for this device.
+ */
+static int
+soc_detach_all_drivers(struct rte_soc_device *dev)
+{
+	struct rte_soc_driver *dr = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dr, &soc_driver_list, next) {
+		rc = rte_eal_soc_detach_dev(dr, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+int
+rte_eal_soc_detach(const struct rte_soc_addr *addr)
+{
+	struct rte_soc_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		if (rte_eal_compare_soc_addr(&dev->addr, addr))
+			continue;
+
+		ret = soc_detach_all_drivers(dev);
+		if (ret < 0)
+			goto err_return;
+
+		TAILQ_REMOVE(&soc_device_list, dev, next);
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL, "Requested device %s cannot be used\n",
+		dev->addr.name);
+	return -1;
+}
+
+int
+rte_eal_soc_probe_one(const struct rte_soc_addr *addr)
+{
+	struct rte_soc_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		if (rte_eal_compare_soc_addr(&dev->addr, addr))
+			continue;
+
+		ret = soc_probe_all_drivers(dev);
+		if (ret < 0)
+			goto err_return;
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL,
+		"Requested device %s cannot be used\n", addr->name);
+	return -1;
+}
+
+int
+rte_eal_soc_probe(void)
+{
+	struct rte_soc_device *dev = NULL;
+	int ret = 0;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		ret = soc_probe_all_drivers(dev);
+		if (ret < 0) {
+			RTE_LOG(DEBUG, EAL, "Requested device %s"
+				 " cannot be used\n", dev->addr.name);
+			/* Failure for a particular device is logged and
+			 * ignored
+			 */
+		}
+	}
+
+	return ret;
+}
+
 /* dump one device */
 static int
 soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
@@ -61,7 +265,6 @@ soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
 	return 0;
 }
 
-/* dump devices on the bus to an output stream */
 void
 rte_eal_soc_dump(FILE *f)
 {
@@ -75,14 +278,18 @@ rte_eal_soc_dump(FILE *f)
 	}
 }
 
-/* register a driver */
 void
 rte_eal_soc_register(struct rte_soc_driver *driver)
 {
+	/* For a valid soc driver, match and scan function
+	 * should be provided.
+	 */
+	RTE_VERIFY(driver != NULL);
+	RTE_VERIFY(driver->match_fn != NULL);
+	RTE_VERIFY(driver->scan_fn != NULL);
 	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
 }
 
-/* unregister a driver */
 void
 rte_eal_soc_unregister(struct rte_soc_driver *driver)
 {
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 347e611..53a321b 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -62,7 +62,6 @@ extern struct soc_device_list soc_device_list;
 TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
 TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
 
-
 struct rte_soc_id {
 	const char *compatible; /**< OF compatible specification */
 	uint64_t priv_data;     /**< SoC Driver specific data */
@@ -97,6 +96,23 @@ typedef int (soc_probe_t)(struct rte_soc_driver *, struct rte_soc_device *);
 typedef int (soc_remove_t)(struct rte_soc_device *);
 
 /**
+ * SoC device scan callback, called from rte_eal_soc_init.
+ * For various SoC, the bus on which devices are attached maynot be compliant
+ * to a standard platform (or platform bus itself). In which case, extra
+ * steps are implemented by PMD to scan over the bus and add devices to SoC
+ * device list.
+ */
+typedef void (soc_scan_t)(void);
+
+/**
+ * Custom device<=>driver match callback for SoC
+ * Unlike PCI, SoC devices don't have a fixed definition of device
+ * identification. PMDs can implement a specific matching function in which
+ * driver and device objects are provided to perform custom match.
+ */
+typedef int (soc_match_t)(struct rte_soc_driver *, struct rte_soc_device *);
+
+/**
  * A structure describing a SoC driver.
  */
 struct rte_soc_driver {
@@ -104,6 +120,8 @@ struct rte_soc_driver {
 	struct rte_driver driver;          /**< Inherit core driver. */
 	soc_probe_t *probe;                /**< Device probe */
 	soc_remove_t *remove;              /**< Device remove */
+	soc_scan_t *scan_fn;               /**< Callback for scanning SoC bus*/
+	soc_match_t *match_fn;             /**< Callback to match dev<->drv */
 	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
 };
 
@@ -146,12 +164,63 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 }
 
 /**
+ * Default function for matching the Soc driver with device. Each driver can
+ * either use this function or define their own soc matching function.
+ * This function relies on the compatible string extracted from sysfs. But,
+ * a SoC might have different way of identifying its devices. Such SoC can
+ * override match_fn.
+ *
+ * @return
+ *	 0 on success
+ *	-1 when no match found
+  */
+int
+rte_eal_soc_match_compat(struct rte_soc_driver *drv,
+			 struct rte_soc_device *dev);
+
+/**
+ * Probe SoC devices for registered drivers.
+ *
+ * @return
+ *	0 on success
+ *	!0 in case of any failure in probe
+ */
+int rte_eal_soc_probe(void);
+
+/**
+ * Probe the single SoC device.
+ */
+int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
+
+/**
+ * Close the single SoC device.
+ *
+ * Scan the SoC devices and find the SoC device specified by the SoC
+ * address, then call the remove() function for registered driver
+ * that has a matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The SoC address to close.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_eal_soc_detach(const struct rte_soc_addr *addr);
+
+/**
  * Dump discovered SoC devices.
+ *
+ * @param f
+ *	File to dump device info in.
  */
 void rte_eal_soc_dump(FILE *f);
 
 /**
  * Register a SoC driver.
+ *
+ * @param driver
+ *	Object for SoC driver to register
+ * @return void
  */
 void rte_eal_soc_register(struct rte_soc_driver *driver);
 
@@ -167,6 +236,10 @@ RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
 
 /**
  * Unregister a SoC driver.
+ *
+ * @param driver
+ *	Object for SoC driver to unregister
+ * @return void
  */
 void rte_eal_soc_unregister(struct rte_soc_driver *driver);
 
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 098ba02..bd775f3 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -70,6 +70,7 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_common.h>
@@ -890,6 +891,10 @@ rte_eal_init(int argc, char **argv)
 	if (rte_eal_pci_probe())
 		rte_panic("Cannot probe PCI\n");
 
+	/* Probe & Initialize SoC devices */
+	if (rte_eal_soc_probe())
+		rte_panic("Cannot probe SoC\n");
+
 	rte_eal_mcfg_complete();
 
 	return fctret;
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index 04848b9..3929a76 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -44,13 +44,28 @@
 #include <rte_log.h>
 #include <rte_soc.h>
 
-#include "eal_internal_cfg.h"
-#include "eal_filesystem.h"
-#include "eal_private.h"
+#include <eal_internal_cfg.h>
+#include <eal_filesystem.h>
+#include <eal_private.h>
 
 /* Init the SoC EAL subsystem */
 int
 rte_eal_soc_init(void)
 {
+	struct rte_soc_driver *drv;
+
+	/* SoC is disabled by default */
+	if (!internal_config.enable_soc)
+		return 0;
+
+	/* For each registered driver, call their scan routine to perform any
+	 * custom scan for devices (for example, custom buses)
+	 */
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		RTE_VERIFY(drv->scan_fn);
+		drv->scan_fn();
+		/* Ignore all errors from this */
+	}
+
 	return 0;
 }
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 0155025..c28e093 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -175,7 +175,11 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_detach;
 	rte_eal_soc_dump;
+	rte_eal_soc_match;
+	rte_eal_soc_probe;
+	rte_eal_soc_probe_one;
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
-- 
2.7.4

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

* [PATCH v7 12/21] eal/soc: extend and utilize devargs
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                             ` (10 preceding siblings ...)
  2016-10-28 12:26           ` [PATCH v7 11/21] eal/soc: implement probing of drivers Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-10-28 12:26           ` [PATCH v7 13/21] eal/soc: add drv_flags Shreyansh Jain
                             ` (10 subsequent siblings)
  22 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

It is assumed that SoC Devices provided on command line are prefixed with
"soc:". This patch adds parse and attach support for such devices.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/common/eal_common_dev.c      | 27 +++++++++----
 lib/librte_eal/common/eal_common_devargs.c  | 17 ++++++++
 lib/librte_eal/common/eal_common_soc.c      | 61 ++++++++++++++++++++++++-----
 lib/librte_eal/common/include/rte_devargs.h |  8 ++++
 lib/librte_eal/common/include/rte_soc.h     | 24 ++++++++++++
 5 files changed, 120 insertions(+), 17 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 457d227..ebbcf47 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -107,17 +107,23 @@ rte_eal_dev_init(void)
 
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
-	struct rte_pci_addr addr;
+	struct rte_soc_addr soc_addr;
+	struct rte_pci_addr pci_addr;
 
 	if (name == NULL || devargs == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
 		return -EINVAL;
 	}
 
-	if (eal_parse_pci_DomBDF(name, &addr) == 0) {
-		if (rte_eal_pci_probe_one(&addr) < 0)
+	memset(&soc_addr, 0, sizeof(soc_addr));
+	if (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+		if (rte_eal_soc_probe_one(&soc_addr) < 0) {
+			free(soc_addr.name);
+			goto err;
+		}
+	} else if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+		if (rte_eal_pci_probe_one(&pci_addr) < 0)
 			goto err;
-
 	} else {
 		if (rte_eal_vdev_init(name, devargs))
 			goto err;
@@ -132,15 +138,22 @@ err:
 
 int rte_eal_dev_detach(const char *name)
 {
-	struct rte_pci_addr addr;
+	struct rte_soc_addr soc_addr;
+	struct rte_pci_addr pci_addr;
 
 	if (name == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device provided.\n");
 		return -EINVAL;
 	}
 
-	if (eal_parse_pci_DomBDF(name, &addr) == 0) {
-		if (rte_eal_pci_detach(&addr) < 0)
+	memset(&soc_addr, 0, sizeof(soc_addr));
+	if (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+		if (rte_eal_soc_detach(&soc_addr) < 0) {
+			free(soc_addr.name);
+			goto err;
+		}
+	} else if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+		if (rte_eal_pci_detach(&pci_addr) < 0)
 			goto err;
 	} else {
 		if (rte_eal_vdev_uninit(name))
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index e403717..e1dae1a 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -41,6 +41,7 @@
 #include <string.h>
 
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_devargs.h>
 #include "eal_private.h"
 
@@ -105,6 +106,14 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
 			goto fail;
 
 		break;
+
+	case RTE_DEVTYPE_WHITELISTED_SOC:
+	case RTE_DEVTYPE_BLACKLISTED_SOC:
+		/* try to parse soc device with prefix "soc:" */
+		if (rte_eal_parse_soc_spec(buf, &devargs->soc.addr) != 0)
+			goto fail;
+		break;
+
 	case RTE_DEVTYPE_VIRTUAL:
 		/* save driver name */
 		ret = snprintf(devargs->virt.drv_name,
@@ -166,6 +175,14 @@ rte_eal_devargs_dump(FILE *f)
 			       devargs->pci.addr.devid,
 			       devargs->pci.addr.function,
 			       devargs->args);
+		else if (devargs->type == RTE_DEVTYPE_WHITELISTED_SOC)
+			fprintf(f, "  SoC whitelist %s %s\n",
+			       devargs->soc.addr.name,
+			       devargs->soc.addr.fdt_path);
+		else if (devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC)
+			fprintf(f, "  SoC blacklist %s %s\n",
+			       devargs->soc.addr.name,
+			       devargs->soc.addr.fdt_path);
 		else if (devargs->type == RTE_DEVTYPE_VIRTUAL)
 			fprintf(f, "  VIRTUAL %s %s\n",
 			       devargs->virt.drv_name,
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 256cef8..44f5559 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -37,6 +37,8 @@
 
 #include <rte_log.h>
 #include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_eal.h>
 #include <rte_soc.h>
 
 #include "eal_private.h"
@@ -70,6 +72,21 @@ rte_eal_soc_match_compat(struct rte_soc_driver *drv,
 	return 1;
 }
 
+static struct rte_devargs *soc_devargs_lookup(struct rte_soc_device *dev)
+{
+	struct rte_devargs *devargs;
+
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->type != RTE_DEVTYPE_BLACKLISTED_SOC &&
+			devargs->type != RTE_DEVTYPE_WHITELISTED_SOC)
+			continue;
+		if (!rte_eal_compare_soc_addr(&dev->addr, &devargs->soc.addr))
+			return devargs;
+	}
+
+	return NULL;
+}
+
 static int
 rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
 			     struct rte_soc_device *dev)
@@ -85,6 +102,18 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
 		return ret;
 	}
 
+	RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %d\n",
+			dev->addr.name, dev->device.numa_node);
+	RTE_LOG(DEBUG, EAL, "  probe driver %s\n", drv->driver.name);
+
+	/* no initialization when blacklisted, return without error */
+	if (dev->device.devargs != NULL
+		&& dev->device.devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC) {
+		RTE_LOG(DEBUG, EAL,
+			"  device is blacklisted, skipping\n");
+		return ret;
+	}
+
 	dev->driver = drv;
 	RTE_VERIFY(drv->probe != NULL);
 	return drv->probe(drv, dev);
@@ -129,8 +158,8 @@ rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
 		return ret;
 	}
 
-	RTE_LOG(DEBUG, EAL, "SoC device %s\n",
-		dev->addr.name);
+	RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %i\n",
+			dev->addr.name, dev->device.numa_node);
 
 	RTE_LOG(DEBUG, EAL, "  remove driver: %s\n", drv->driver.name);
 
@@ -233,17 +262,29 @@ int
 rte_eal_soc_probe(void)
 {
 	struct rte_soc_device *dev = NULL;
+	struct rte_devargs *devargs = NULL;
 	int ret = 0;
+	int probe_all = 0;
+
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_SOC) == 0)
+		probe_all = 1;
 
 	TAILQ_FOREACH(dev, &soc_device_list, next) {
-		ret = soc_probe_all_drivers(dev);
-		if (ret < 0) {
-			RTE_LOG(DEBUG, EAL, "Requested device %s"
-				 " cannot be used\n", dev->addr.name);
-			/* Failure for a particular device is logged and
-			 * ignored
-			 */
-		}
+
+		/* set devargs in SoC structure */
+		devargs = soc_devargs_lookup(dev);
+		if (devargs != NULL)
+			dev->device.devargs = devargs;
+
+		/* probe all or only whitelisted devices */
+		if (probe_all)
+			ret = soc_probe_all_drivers(dev);
+		else if (devargs != NULL &&
+			devargs->type == RTE_DEVTYPE_WHITELISTED_SOC)
+			ret = soc_probe_all_drivers(dev);
+		if (ret < 0)
+			rte_exit(EXIT_FAILURE, "Requested device %s "
+				 "cannot be used\n", dev->addr.name);
 	}
 
 	return ret;
diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h
index 88120a1..b5dd436 100644
--- a/lib/librte_eal/common/include/rte_devargs.h
+++ b/lib/librte_eal/common/include/rte_devargs.h
@@ -51,6 +51,7 @@ extern "C" {
 #include <stdio.h>
 #include <sys/queue.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 
 /**
  * Type of generic device
@@ -58,6 +59,8 @@ extern "C" {
 enum rte_devtype {
 	RTE_DEVTYPE_WHITELISTED_PCI,
 	RTE_DEVTYPE_BLACKLISTED_PCI,
+	RTE_DEVTYPE_WHITELISTED_SOC,
+	RTE_DEVTYPE_BLACKLISTED_SOC,
 	RTE_DEVTYPE_VIRTUAL,
 };
 
@@ -83,6 +86,11 @@ struct rte_devargs {
 			/** PCI location. */
 			struct rte_pci_addr addr;
 		} pci;
+		/** Used if type is RTE_DEVTYPE_*_SOC. */
+		struct {
+			/** SoC location. */
+			struct rte_soc_addr addr;
+		} soc;
 		/** Used if type is RTE_DEVTYPE_VIRTUAL. */
 		struct {
 			/** Driver name. */
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 53a321b..fb5ea7b 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -164,6 +164,30 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 }
 
 /**
+ * Parse a specification of a soc device. The specification must differentiate
+ * a SoC device specification from the PCI bus and virtual devices. We assume
+ * a SoC specification starts with "soc:". The function allocates the name
+ * entry of the given addr.
+ *
+ * @return
+ *      -  0 on success
+ *      -  1 when not a SoC spec
+ *      - -1 on failure
+ */
+static inline int
+rte_eal_parse_soc_spec(const char *spec, struct rte_soc_addr *addr)
+{
+	if (strstr(spec, "soc:") == spec) {
+		addr->name = strdup(spec + 4);
+		if (addr->name == NULL)
+			return -1;
+		return 0;
+	}
+
+	return 1;
+}
+
+/**
  * Default function for matching the Soc driver with device. Each driver can
  * either use this function or define their own soc matching function.
  * This function relies on the compatible string extracted from sysfs. But,
-- 
2.7.4

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

* [PATCH v7 13/21] eal/soc: add drv_flags
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                             ` (11 preceding siblings ...)
  2016-10-28 12:26           ` [PATCH v7 12/21] eal/soc: extend and utilize devargs Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-10-28 12:26           ` [PATCH v7 14/21] eal/soc: add intr_handle Shreyansh Jain
                             ` (9 subsequent siblings)
  22 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

The flags are copied from the PCI ones. They should be refactorized into a
general set of flags in the future.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/common/include/rte_soc.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index fb5ea7b..40490b9 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -123,8 +123,18 @@ struct rte_soc_driver {
 	soc_scan_t *scan_fn;               /**< Callback for scanning SoC bus*/
 	soc_match_t *match_fn;             /**< Callback to match dev<->drv */
 	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
+	uint32_t drv_flags;                /**< Control handling of device */
 };
 
+/** Device needs to map its resources by EAL */
+#define RTE_SOC_DRV_NEED_MAPPING 0x0001
+/** Device needs to be unbound even if no module is provieded */
+#define RTE_SOC_DRV_FORCE_UNBIND 0x0004
+/** Device driver supports link state interrupt */
+#define RTE_SOC_DRV_INTR_LSC	 0x0008
+/** Device driver supports detaching capability */
+#define RTE_SOC_DRV_DETACHABLE	 0x0010
+
 /**
  * Utility function to write a SoC device name, this device name can later be
  * used to retrieve the corresponding rte_soc_addr using above functions.
-- 
2.7.4

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

* [PATCH v7 14/21] eal/soc: add intr_handle
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                             ` (12 preceding siblings ...)
  2016-10-28 12:26           ` [PATCH v7 13/21] eal/soc: add drv_flags Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-10-28 12:26           ` [PATCH v7 15/21] eal/soc: add default scan for Soc devices Shreyansh Jain
                             ` (8 subsequent siblings)
  22 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_eal/common/include/rte_soc.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 40490b9..38f897d 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -53,6 +53,7 @@ extern "C" {
 #include <rte_dev.h>
 #include <rte_eal.h>
 #include <rte_debug.h>
+#include <rte_interrupts.h>
 
 extern struct soc_driver_list soc_driver_list;
 /**< Global list of SoC Drivers */
@@ -80,6 +81,7 @@ struct rte_soc_device {
 	struct rte_device device;           /**< Inherit code device */
 	struct rte_soc_addr addr;           /**< SoC device Location */
 	struct rte_soc_id *id;              /**< SoC device ID list */
+	struct rte_intr_handle intr_handle; /**< Interrupt handle */
 	struct rte_soc_driver *driver;      /**< Associated driver */
 };
 
-- 
2.7.4

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

* [PATCH v7 15/21] eal/soc: add default scan for Soc devices
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                             ` (13 preceding siblings ...)
  2016-10-28 12:26           ` [PATCH v7 14/21] eal/soc: add intr_handle Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-10-28 12:26           ` [PATCH v7 16/21] eal/soc: additional features for SoC Shreyansh Jain
                             ` (7 subsequent siblings)
  22 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Default implementation which scans the sysfs platform devices hierarchy.
For each device, extract the ueven and convert into rte_soc_device.

The information populated can then be used in probe to match against
the drivers registered.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: restructure commit to be an optional implementation]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>

--
 v5:
 - Update rte_eal_soc_scan to rte_eal_soc_scan_platform_bus
 - Fix comments over scan and match functions
---
 lib/librte_eal/common/include/rte_soc.h |  16 +-
 lib/librte_eal/linuxapp/eal/eal_soc.c   | 315 ++++++++++++++++++++++++++++++++
 2 files changed, 329 insertions(+), 2 deletions(-)

diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 38f897d..8be3db7 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -64,7 +64,10 @@ TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
 TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
 
 struct rte_soc_id {
-	const char *compatible; /**< OF compatible specification */
+	union {
+		const char *compatible; /**< OF compatible specification */
+		char *_compatible;
+	};
 	uint64_t priv_data;     /**< SoC Driver specific data */
 };
 
@@ -200,7 +203,16 @@ rte_eal_parse_soc_spec(const char *spec, struct rte_soc_addr *addr)
 }
 
 /**
- * Default function for matching the Soc driver with device. Each driver can
+ * Helper function for scanning for new SoC devices on platform bus.
+ *
+ * @return
+ * 	0 on success
+ *	!0 on failure to scan
+ */
+int rte_eal_soc_scan_platform_bus(void);
+
+/**
+ * Helper function for matching the Soc driver with device. Each driver can
  * either use this function or define their own soc matching function.
  * This function relies on the compatible string extracted from sysfs. But,
  * a SoC might have different way of identifying its devices. Such SoC can
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index 3929a76..d8dfe97 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -48,6 +48,321 @@
 #include <eal_filesystem.h>
 #include <eal_private.h>
 
+/** Pathname of SoC devices directory. */
+#define SYSFS_SOC_DEVICES "/sys/bus/platform/devices"
+
+static const char *
+soc_get_sysfs_path(void)
+{
+	const char *path = NULL;
+
+	path = getenv("SYSFS_SOC_DEVICES");
+	if (path == NULL)
+		return SYSFS_SOC_DEVICES;
+
+	return path;
+}
+
+static char *
+dev_read_uevent(const char *dirname)
+{
+	char filename[PATH_MAX];
+	struct stat st;
+	char *buf;
+	ssize_t total = 0;
+	int fd;
+
+	snprintf(filename, sizeof(filename), "%s/uevent", dirname);
+	fd = open(filename, O_RDONLY);
+	if (fd < 0) {
+		RTE_LOG(WARNING, EAL, "Failed to open file %s\n", filename);
+		return strdup("");
+	}
+
+	if (fstat(fd, &st) < 0) {
+		RTE_LOG(ERR, EAL, "Failed to stat file %s\n", filename);
+		close(fd);
+		return NULL;
+	}
+
+	if (st.st_size == 0) {
+		close(fd);
+		return strdup("");
+	}
+
+	buf = malloc(st.st_size + 1);
+	if (buf == NULL) {
+		RTE_LOG(ERR, EAL, "Failed to alloc memory to read %s\n",
+			filename);
+		close(fd);
+		return NULL;
+	}
+
+	while (total < st.st_size) {
+		ssize_t rlen = read(fd, buf + total, st.st_size - total);
+		if (rlen < 0) {
+			if (errno == EINTR)
+				continue;
+
+			RTE_LOG(ERR, EAL, "Failed to read file %s\n", filename);
+
+			free(buf);
+			close(fd);
+			return NULL;
+		}
+		if (rlen == 0) /* EOF */
+			break;
+
+		total += rlen;
+	}
+
+	buf[total] = '\0';
+	close(fd);
+
+	return buf;
+}
+
+static const char *
+dev_uevent_find(const char *uevent, const char *key)
+{
+	const size_t keylen = strlen(key);
+	const size_t total = strlen(uevent);
+	const char *p = uevent;
+
+	/* check whether it is the first key */
+	if (!strncmp(uevent, key, keylen))
+		return uevent + keylen;
+
+	/* check 2nd key or further... */
+	do {
+		p = strstr(p, key);
+		if (p == NULL)
+			break;
+
+		if (p[-1] == '\n') /* check we are at a new line */
+			return p + keylen;
+
+		p += keylen; /* skip this one */
+	} while (p - uevent < (ptrdiff_t) total);
+
+	return NULL;
+}
+
+static char *
+strdup_until_nl(const char *p)
+{
+	const char *nl = strchr(p, '\n');
+	if (nl == NULL)
+		return strdup(p); /* no newline, copy until '\0' */
+
+	return strndup(p, nl - p);
+}
+
+static int
+dev_parse_uevent(struct rte_soc_device *dev, const char *uevent)
+{
+	const char *of;
+	const char *compat_n;
+	char *err;
+	long n;
+	char compat[strlen("OF_COMPATIBLE_NNNN=")];
+	long i;
+
+	of = dev_uevent_find(uevent, "OF_FULLNAME=");
+	if (of == NULL)
+		return 1; /* don't care about this device */
+
+	dev->addr.fdt_path = strdup_until_nl(of);
+	if (dev->addr.fdt_path == NULL) {
+		RTE_LOG(ERR, PMD,
+			"Failed to alloc memory for fdt_path\n");
+		return -1;
+	}
+
+	RTE_LOG(DEBUG, EAL, "Detected device %s (%s)\n",
+			dev->addr.name, dev->addr.fdt_path);
+
+	compat_n = dev_uevent_find(uevent, "OF_COMPATIBLE_N=");
+	if (compat_n == NULL) {
+		RTE_LOG(ERR, EAL, "No OF_COMPATIBLE_N found\n");
+		return -1;
+	}
+
+	n = strtoul(compat_n, &err, 0);
+	if (*err != '\n' && err != NULL) {
+		RTE_LOG(ERR, EAL, "Failed to parse OF_COMPATIBLE_N: %.10s\n",
+			err);
+		goto fail_fdt_path;
+	}
+
+	if (n == 0)
+		return 1; /* cannot match anything */
+	if (n > 9999) { /* match NNNN */
+		RTE_LOG(ERR, EAL, "OF_COMPATIBLE_N is invalid: %ld\n", n);
+		goto fail_fdt_path;
+	}
+
+	dev->id = calloc(n + 1, sizeof(*dev->id));
+	if (dev->id == NULL) {
+		RTE_LOG(ERR, PMD, "Failed to alloc memory for ID\n");
+		free(dev->addr.fdt_path);
+		return -1;
+	}
+
+	for (i = 0; i < n; ++i) {
+		snprintf(compat, sizeof(compat), "OF_COMPATIBLE_%lu=", i);
+		const char *val;
+
+		val = dev_uevent_find(uevent, compat);
+		if (val == NULL) {
+			RTE_LOG(ERR, EAL, "%s was not found\n", compat);
+			goto fail_id;
+		}
+
+		dev->id[i]._compatible = strdup_until_nl(val);
+		if (dev->id[i]._compatible == NULL) {
+			RTE_LOG(ERR, PMD,
+				"Failed to alloc memory for compatible\n");
+			goto fail_id;
+		}
+
+		RTE_LOG(DEBUG, EAL, "  compatible: %s\n",
+				dev->id[i].compatible);
+	}
+
+	dev->id[n]._compatible = NULL; /* mark last one */
+
+	return 0;
+
+fail_id:
+	while (i-- >= 0)
+		free(dev->id[i]._compatible);
+	free(dev->id);
+fail_fdt_path:
+	free(dev->addr.fdt_path);
+	return -1;
+}
+
+static void
+dev_content_free(struct rte_soc_device *dev)
+{
+	int i;
+
+	if (dev->addr.fdt_path)
+		free(dev->addr.fdt_path);
+
+	if (dev->id != NULL) {
+		for (i = 0; dev->id[i]._compatible; ++i)
+			free(dev->id[i]._compatible);
+
+		free(dev->id);
+		dev->id = NULL;
+	}
+}
+
+/**
+ * Scan one SoC sysfs entry, and fill the devices list from it.
+ * We require to have the uevent file with records: OF_FULLNAME and
+ * OF_COMPATIBLE array (with at least one entry). Otherwise, such device
+ * is skipped.
+ */
+static int
+soc_scan_one(const char *dirname, const char *name)
+{
+	struct rte_soc_device *dev;
+	char *uevent;
+	int ret;
+
+	uevent = dev_read_uevent(dirname);
+	if (uevent == NULL)
+		return -1;
+
+	if (uevent[0] == '\0') {
+		/* ignore directory without uevent file */
+		free(uevent);
+		return 1;
+	}
+
+	dev = malloc(sizeof(*dev) + strlen(name) + 1);
+	if (dev == NULL) {
+		RTE_LOG(ERR, PMD, "Failed to alloc memory for %s\n", name);
+		free(uevent);
+		return -1;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	dev->addr.name = (char *) (dev + 1);
+	strcpy(dev->addr.name, name);
+
+	ret = dev_parse_uevent(dev, uevent);
+	if (ret)
+		goto fail;
+	free(uevent); /* not needed anymore */
+
+	/* device is valid, add in list (sorted) */
+	if (TAILQ_EMPTY(&soc_device_list)) {
+		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+	} else {
+		struct rte_soc_device *dev2;
+
+		TAILQ_FOREACH(dev2, &soc_device_list, next) {
+			ret = rte_eal_compare_soc_addr(&dev->addr, &dev2->addr);
+			if (ret > 0)
+				continue;
+
+			if (ret < 0) {
+				TAILQ_INSERT_BEFORE(dev2, dev, next);
+			} else { /* already registered */
+				dev_content_free(dev2);
+				dev2->addr.fdt_path = dev->addr.fdt_path;
+				dev2->id = dev->id;
+				free(dev);
+			}
+			return 0;
+		}
+		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+	}
+
+	return 0;
+
+fail:
+	free(uevent);
+	dev_content_free(dev);
+	free(dev);
+	return ret;
+}
+
+int
+rte_eal_soc_scan_platform_bus(void)
+{
+	struct dirent *e;
+	DIR *dir;
+	char dirname[PATH_MAX];
+
+	dir = opendir(soc_get_sysfs_path());
+	if (dir == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
+			__func__, strerror(errno));
+		return -1;
+	}
+
+	while ((e = readdir(dir)) != NULL) {
+		if (e->d_name[0] == '.')
+			continue;
+
+		snprintf(dirname, sizeof(dirname), "%s/%s",
+				soc_get_sysfs_path(), e->d_name);
+		if (soc_scan_one(dirname, e->d_name) < 0)
+			goto error;
+	}
+	closedir(dir);
+	return 0;
+
+error:
+	closedir(dir);
+	return -1;
+}
+
 /* Init the SoC EAL subsystem */
 int
 rte_eal_soc_init(void)
-- 
2.7.4

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

* [PATCH v7 16/21] eal/soc: additional features for SoC
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                             ` (14 preceding siblings ...)
  2016-10-28 12:26           ` [PATCH v7 15/21] eal/soc: add default scan for Soc devices Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-10-28 12:26           ` [PATCH v7 17/21] ether: utilize container_of for pci_drv Shreyansh Jain
                             ` (6 subsequent siblings)
  22 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Additional features introduced:
 - Find kernel driver through sysfs bindings
 - Dummy implementation for mapping to kernel driver
 - DMA coherency value from sysfs
 - Numa node number from sysfs
 - Support for updating device during probe if already registered

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: merge multiple patches into single set]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_eal/common/eal_common_soc.c  |  30 ++++++++
 lib/librte_eal/common/eal_private.h     |  23 ++++++
 lib/librte_eal/common/include/rte_soc.h |  28 +++++++
 lib/librte_eal/linuxapp/eal/eal_soc.c   | 129 ++++++++++++++++++++++++++++++++
 4 files changed, 210 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 44f5559..29c38e0 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -114,6 +114,26 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
 		return ret;
 	}
 
+	if (!dev->is_dma_coherent) {
+		if (!(drv->drv_flags & RTE_SOC_DRV_ACCEPT_NONCC)) {
+			RTE_LOG(DEBUG, EAL,
+				"  device is not DMA coherent, skipping\n");
+			return 1;
+		}
+	}
+
+	if (drv->drv_flags & RTE_SOC_DRV_NEED_MAPPING) {
+		/* map resources */
+		ret = rte_eal_soc_map_device(dev);
+		if (ret)
+			return ret;
+	} else if (drv->drv_flags & RTE_SOC_DRV_FORCE_UNBIND
+		&& rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		/* unbind */
+		if (soc_unbind_kernel_driver(dev) < 0)
+			return -1;
+	}
+
 	dev->driver = drv;
 	RTE_VERIFY(drv->probe != NULL);
 	return drv->probe(drv, dev);
@@ -166,6 +186,10 @@ rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
 	if (drv->remove && (drv->remove(dev) < 0))
 		return -1;	/* negative value is an error */
 
+	if (drv->drv_flags & RTE_SOC_DRV_NEED_MAPPING)
+		/* unmap resources for devices */
+		rte_eal_soc_unmap_device(dev);
+
 	/* clear driver structure */
 	dev->driver = NULL;
 
@@ -241,6 +265,12 @@ rte_eal_soc_probe_one(const struct rte_soc_addr *addr)
 	if (addr == NULL)
 		return -1;
 
+	/* update current SoC device in global list, kernel bindings might have
+	 * changed since last time we looked at it.
+	 */
+	if (soc_update_device(addr) < 0)
+		goto err_return;
+
 	TAILQ_FOREACH(dev, &soc_device_list, next) {
 		if (rte_eal_compare_soc_addr(&dev->addr, addr))
 			continue;
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index d810f9f..30c648d 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -159,6 +159,29 @@ int pci_update_device(const struct rte_pci_addr *addr);
 int pci_unbind_kernel_driver(struct rte_pci_device *dev);
 
 /**
+ * Update a soc device object by asking the kernel for the latest information.
+ *
+ * This function is private to EAL.
+ *
+ * @param addr
+ *      The SoC address to look for
+ * @return
+ *   - 0 on success.
+ *   - negative on error.
+ */
+int soc_update_device(const struct rte_soc_addr *addr);
+
+/**
+ * Unbind kernel driver for this device
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int soc_unbind_kernel_driver(struct rte_soc_device *dev);
+
+/**
  * Map the PCI resource of a PCI device in virtual memory
  *
  * This function is private to EAL.
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 8be3db7..d7f7ec8 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -46,9 +46,11 @@ extern "C" {
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/queue.h>
 #include <stdint.h>
 #include <inttypes.h>
 #include <string.h>
+#include <limits.h>
 
 #include <rte_dev.h>
 #include <rte_eal.h>
@@ -63,6 +65,14 @@ extern struct soc_device_list soc_device_list;
 TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
 TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
 
+#define SOC_MAX_RESOURCE 6
+
+struct rte_soc_resource {
+	uint64_t phys_addr;
+	uint64_t len;
+	void *addr;
+};
+
 struct rte_soc_id {
 	union {
 		const char *compatible; /**< OF compatible specification */
@@ -84,8 +94,12 @@ struct rte_soc_device {
 	struct rte_device device;           /**< Inherit code device */
 	struct rte_soc_addr addr;           /**< SoC device Location */
 	struct rte_soc_id *id;              /**< SoC device ID list */
+	struct rte_soc_resource mem_resource[SOC_MAX_RESOURCE];
 	struct rte_intr_handle intr_handle; /**< Interrupt handle */
 	struct rte_soc_driver *driver;      /**< Associated driver */
+	int numa_node;                      /**< NUMA node connection */
+	int is_dma_coherent;                /**< DMA coherent device */
+	enum rte_kernel_driver kdrv;        /**< Kernel driver */
 };
 
 struct rte_soc_driver;
@@ -139,6 +153,8 @@ struct rte_soc_driver {
 #define RTE_SOC_DRV_INTR_LSC	 0x0008
 /** Device driver supports detaching capability */
 #define RTE_SOC_DRV_DETACHABLE	 0x0010
+/** Device driver accepts DMA non-coherent devices */
+#define RTE_SOC_DRV_ACCEPT_NONCC 0x0020
 
 /**
  * Utility function to write a SoC device name, this device name can later be
@@ -256,6 +272,18 @@ int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
 int rte_eal_soc_detach(const struct rte_soc_addr *addr);
 
 /**
+ * Map SoC device resources into userspace.
+ *
+ * This is called by the EAL if (drv_flags & RTE_SOC_DRV_NEED_MAPPING).
+ */
+int rte_eal_soc_map_device(struct rte_soc_device *dev);
+
+/**
+ * Unmap the device resources.
+ */
+void rte_eal_soc_unmap_device(struct rte_soc_device *dev);
+
+/**
  * Dump discovered SoC devices.
  *
  * @param f
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index d8dfe97..95f7565 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -63,6 +63,45 @@ soc_get_sysfs_path(void)
 	return path;
 }
 
+int
+soc_unbind_kernel_driver(struct rte_soc_device *dev)
+{
+	char devpath[PATH_MAX];
+
+	snprintf(devpath, sizeof(devpath), "%s/%s",
+		 soc_get_sysfs_path(), dev->addr.name);
+
+	return rte_eal_unbind_kernel_driver(devpath, dev->addr.name);
+}
+
+int
+rte_eal_soc_map_device(struct rte_soc_device *dev)
+{
+	int ret = -1;
+
+	/* try mapping the NIC resources using VFIO if it exists */
+	switch (dev->kdrv) {
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		ret = 1;
+		break;
+	}
+
+	return ret;
+}
+
+void
+rte_eal_soc_unmap_device(struct rte_soc_device *dev)
+{
+	switch (dev->kdrv) {
+	default:
+	RTE_LOG(DEBUG, EAL,
+		"  Not managed by a supported kernel driver, skipped\n");
+		break;
+	}
+}
+
 static char *
 dev_read_uevent(const char *dirname)
 {
@@ -260,6 +299,68 @@ dev_content_free(struct rte_soc_device *dev)
 	}
 }
 
+static int
+dev_setup_associated_driver(struct rte_soc_device *dev, const char *dirname)
+{
+	char filename[PATH_MAX];
+	char driver[PATH_MAX];
+	int ret;
+
+	/* parse driver */
+	snprintf(filename, sizeof(filename), "%s/driver", dirname);
+	ret = rte_eal_get_kernel_driver_by_path(filename, driver);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "Fail to get kernel driver for %s\n",
+			dirname);
+		return 1;
+	}
+
+	if (!ret)
+		dev->kdrv = RTE_KDRV_UNKNOWN;
+	else
+		dev->kdrv = RTE_KDRV_NONE;
+
+	return 0;
+}
+
+static int
+dev_setup_numa_node(struct rte_soc_device *dev, const char *dirname)
+{
+	char filename[PATH_MAX];
+
+	/* if no NUMA support, set default to 0 */
+	unsigned long tmp = 0;
+	int ret = 0;
+
+	/* get numa node */
+	snprintf(filename, sizeof(filename), "%s/numa_node", dirname);
+
+	if (eal_parse_sysfs_value(filename, &tmp) < 0)
+		ret = 1;
+
+	dev->numa_node = tmp;
+	return ret;
+}
+
+static int
+dev_detect_is_coherent(struct rte_soc_device *dev)
+{
+	char filename[PATH_MAX];
+	FILE *f;
+
+	if (dev->addr.fdt_path == NULL)
+		return 0; /* no way to detect */
+
+	snprintf(filename, sizeof(filename), "%s%s/dma-coherent",
+			"/proc/device-tree", dev->addr.fdt_path);
+	f = fopen(filename, "r");
+	if (f == NULL)
+		return 0;
+
+	fclose(f);
+	return 1;
+}
+
 /**
  * Scan one SoC sysfs entry, and fill the devices list from it.
  * We require to have the uevent file with records: OF_FULLNAME and
@@ -299,6 +400,18 @@ soc_scan_one(const char *dirname, const char *name)
 		goto fail;
 	free(uevent); /* not needed anymore */
 
+	ret = dev_setup_associated_driver(dev, dirname);
+	if (ret)
+		goto fail;
+
+	ret = dev_setup_numa_node(dev, dirname);
+	if (ret < 0)
+		goto fail;
+
+	dev->is_dma_coherent = dev_detect_is_coherent(dev);
+	RTE_LOG(DEBUG, EAL, "  DMA %s\n",
+			dev->is_dma_coherent ? "coherent" : "non-coherent");
+
 	/* device is valid, add in list (sorted) */
 	if (TAILQ_EMPTY(&soc_device_list)) {
 		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
@@ -313,6 +426,11 @@ soc_scan_one(const char *dirname, const char *name)
 			if (ret < 0) {
 				TAILQ_INSERT_BEFORE(dev2, dev, next);
 			} else { /* already registered */
+				dev2->kdrv = dev->kdrv;
+				dev2->is_dma_coherent = dev->is_dma_coherent;
+				memmove(dev2->mem_resource, dev->mem_resource,
+					sizeof(dev->mem_resource));
+
 				dev_content_free(dev2);
 				dev2->addr.fdt_path = dev->addr.fdt_path;
 				dev2->id = dev->id;
@@ -333,6 +451,17 @@ fail:
 }
 
 int
+soc_update_device(const struct rte_soc_addr *addr)
+{
+	char filename[PATH_MAX];
+
+	snprintf(filename, sizeof(filename), "%s/%s",
+			soc_get_sysfs_path(), addr->name);
+
+	return soc_scan_one(filename, addr->name);
+}
+
+int
 rte_eal_soc_scan_platform_bus(void)
 {
 	struct dirent *e;
-- 
2.7.4

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

* [PATCH v7 17/21] ether: utilize container_of for pci_drv
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                             ` (15 preceding siblings ...)
  2016-10-28 12:26           ` [PATCH v7 16/21] eal/soc: additional features for SoC Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-10-28 12:26           ` [PATCH v7 18/21] ether: verify we copy info from a PCI device Shreyansh Jain
                             ` (5 subsequent siblings)
  22 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

It is not necessary to place the rte_pci_driver at the beginning
of the rte_eth_dev struct anymore as we use the container_of macro
to get the parent pointer.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 4 ++--
 lib/librte_ether/rte_ethdev.h | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index fde8112..347c230 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -241,7 +241,7 @@ rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
 
 	int diag;
 
-	eth_drv = (struct eth_driver *)pci_drv;
+	eth_drv = container_of(pci_drv, struct eth_driver, pci_drv);
 
 	rte_eal_pci_device_name(&pci_dev->addr, ethdev_name,
 			sizeof(ethdev_name));
@@ -302,7 +302,7 @@ rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
 	if (eth_dev == NULL)
 		return -ENODEV;
 
-	eth_drv = (const struct eth_driver *)pci_dev->driver;
+	eth_drv = container_of(pci_dev->driver, struct eth_driver, pci_drv);
 
 	/* Invoke PMD device uninit function */
 	if (*eth_drv->eth_dev_uninit) {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 38641e8..f893fe0 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1850,7 +1850,7 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *eth_dev);
  * Each Ethernet driver acts as a PCI driver and is represented by a generic
  * *eth_driver* structure that holds:
  *
- * - An *rte_pci_driver* structure (which must be the first field).
+ * - An *rte_pci_driver* structure.
  *
  * - The *eth_dev_init* function invoked for each matching PCI device.
  *
-- 
2.7.4

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

* [PATCH v7 18/21] ether: verify we copy info from a PCI device
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                             ` (16 preceding siblings ...)
  2016-10-28 12:26           ` [PATCH v7 17/21] ether: utilize container_of for pci_drv Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-10-28 12:26           ` [PATCH v7 19/21] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
                             ` (4 subsequent siblings)
  22 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Now that different types of ethdev exist, check for presence of PCI dev
while copying out the info.
Similar would be done for SoC.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 347c230..a1e3aaf 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3206,6 +3206,8 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_de
 		return;
 	}
 
+	RTE_VERIFY(eth_dev->pci_dev != NULL);
+
 	eth_dev->data->dev_flags = 0;
 	if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC)
 		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
-- 
2.7.4

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

* [PATCH v7 19/21] ether: extract function eth_dev_get_intr_handle
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                             ` (17 preceding siblings ...)
  2016-10-28 12:26           ` [PATCH v7 18/21] ether: verify we copy info from a PCI device Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-10-28 12:26           ` [PATCH v7 20/21] ether: introduce ethernet dev probe remove Shreyansh Jain
                             ` (3 subsequent siblings)
  22 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

We abstract access to the intr_handle here as we want to get
it either from the pci_dev or soc_dev.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index a1e3aaf..4c61246 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2532,6 +2532,16 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
 	rte_spinlock_unlock(&rte_eth_dev_cb_lock);
 }
 
+static inline
+struct rte_intr_handle *eth_dev_get_intr_handle(struct rte_eth_dev *dev)
+{
+	if (dev->pci_dev)
+		return &dev->pci_dev->intr_handle;
+
+	RTE_ASSERT(0);
+	return NULL;
+}
+
 int
 rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 {
@@ -2544,7 +2554,7 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
-	intr_handle = &dev->pci_dev->intr_handle;
+	intr_handle = eth_dev_get_intr_handle(dev);
 	if (!intr_handle->intr_vec) {
 		RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
 		return -EPERM;
@@ -2604,7 +2614,7 @@ rte_eth_dev_rx_intr_ctl_q(uint8_t port_id, uint16_t queue_id,
 		return -EINVAL;
 	}
 
-	intr_handle = &dev->pci_dev->intr_handle;
+	intr_handle = eth_dev_get_intr_handle(dev);
 	if (!intr_handle->intr_vec) {
 		RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
 		return -EPERM;
-- 
2.7.4

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

* [PATCH v7 20/21] ether: introduce ethernet dev probe remove
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                             ` (18 preceding siblings ...)
  2016-10-28 12:26           ` [PATCH v7 19/21] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-10-28 12:26           ` [PATCH v7 21/21] eal/crypto: Support rte_soc_driver/device for cryptodev Shreyansh Jain
                             ` (2 subsequent siblings)
  22 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

From: Jan Viktorin <viktorin@rehivetech.com>

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 lib/librte_ether/rte_ethdev.c | 148 +++++++++++++++++++++++++++++++++++++++++-
 lib/librte_ether/rte_ethdev.h |  31 +++++++++
 2 files changed, 177 insertions(+), 2 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 4c61246..972e916 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -325,6 +325,101 @@ rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
 }
 
 int
+rte_eth_dev_soc_probe(struct rte_soc_driver *soc_drv,
+		      struct rte_soc_device *soc_dev)
+{
+	struct eth_driver    *eth_drv;
+	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
+	int diag;
+
+	eth_drv = container_of(soc_drv, struct eth_driver, soc_drv);
+
+	rte_eal_soc_device_name(&soc_dev->addr, ethdev_name,
+			sizeof(ethdev_name));
+
+	eth_dev = rte_eth_dev_allocate(ethdev_name);
+	if (eth_dev == NULL)
+		return -ENOMEM;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		eth_dev->data->dev_private = rte_zmalloc(
+				  "ethdev private structure",
+				  eth_drv->dev_private_size,
+				  RTE_CACHE_LINE_SIZE);
+		if (eth_dev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private port "
+				  "data\n");
+	}
+	eth_dev->soc_dev = soc_dev;
+	eth_dev->driver = eth_drv;
+	eth_dev->data->rx_mbuf_alloc_failed = 0;
+
+	/* init user callbacks */
+	TAILQ_INIT(&(eth_dev->link_intr_cbs));
+
+	/*
+	 * Set the default MTU.
+	 */
+	eth_dev->data->mtu = ETHER_MTU;
+
+	/* Invoke PMD device initialization function */
+	diag = (*eth_drv->eth_dev_init)(eth_dev);
+	if (diag == 0)
+		return 0;
+
+	RTE_PMD_DEBUG_TRACE("driver %s: eth_dev_init(%s) failed\n",
+			soc_drv->driver.name,
+			soc_dev->addr.name);
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(eth_dev->data->dev_private);
+	rte_eth_dev_release_port(eth_dev);
+	return diag;
+}
+
+int
+rte_eth_dev_soc_remove(struct rte_soc_device *soc_dev)
+{
+	const struct eth_driver *eth_drv;
+	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+	int ret;
+
+	if (soc_dev == NULL)
+		return -EINVAL;
+
+	rte_eal_soc_device_name(&soc_dev->addr, ethdev_name,
+			sizeof(ethdev_name));
+
+	eth_dev = rte_eth_dev_allocated(ethdev_name);
+	if (eth_dev == NULL)
+		return -ENODEV;
+
+	eth_drv = container_of(soc_dev->driver, struct eth_driver, soc_drv);
+
+	/* Invoke PMD device uninit function */
+	if (*eth_drv->eth_dev_uninit) {
+		ret = (*eth_drv->eth_dev_uninit)(eth_dev);
+		if (ret)
+			return ret;
+	}
+
+	/* free ether device */
+	rte_eth_dev_release_port(eth_dev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(eth_dev->data->dev_private);
+
+	eth_dev->soc_dev = NULL;
+	eth_dev->driver = NULL;
+	eth_dev->data = NULL;
+
+	return 0;
+}
+
+
+int
 rte_eth_dev_is_valid_port(uint8_t port_id)
 {
 	if (port_id >= RTE_MAX_ETHPORTS ||
@@ -1557,6 +1652,7 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
 	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
 	dev_info->pci_dev = dev->pci_dev;
+	dev_info->soc_dev = dev->soc_dev;
 	dev_info->driver_name = dev->data->drv_name;
 	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
 	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
@@ -2535,8 +2631,15 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
 static inline
 struct rte_intr_handle *eth_dev_get_intr_handle(struct rte_eth_dev *dev)
 {
-	if (dev->pci_dev)
+	if (dev->pci_dev) {
+		RTE_ASSERT(dev->soc_dev == NULL);
 		return &dev->pci_dev->intr_handle;
+	}
+
+	if (dev->soc_dev) {
+		RTE_ASSERT(dev->pci_dev == NULL);
+		return &dev->soc_dev->intr_handle;
+	}
 
 	RTE_ASSERT(0);
 	return NULL;
@@ -2573,6 +2676,23 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 	return 0;
 }
 
+static inline
+const char *eth_dev_get_driver_name(const struct rte_eth_dev *dev)
+{
+	if (dev->pci_dev) {
+		RTE_ASSERT(dev->soc_dev == NULL);
+		return dev->driver->pci_drv.driver.name;
+	}
+
+	if (dev->soc_dev) {
+		RTE_ASSERT(dev->pci_dev == NULL);
+		return dev->driver->soc_drv.driver.name;
+	}
+
+	RTE_ASSERT(0);
+	return NULL;
+}
+
 const struct rte_memzone *
 rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 			 uint16_t queue_id, size_t size, unsigned align,
@@ -2580,9 +2700,11 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 {
 	char z_name[RTE_MEMZONE_NAMESIZE];
 	const struct rte_memzone *mz;
+	const char *drv_name;
 
+	drv_name = eth_dev_get_driver_name(dev);
 	snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
-		 dev->driver->pci_drv.driver.name, ring_name,
+		 drv_name, ring_name,
 		 dev->data->port_id, queue_id);
 
 	mz = rte_memzone_lookup(z_name);
@@ -3229,6 +3351,28 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_de
 	eth_dev->data->drv_name = pci_dev->driver->driver.name;
 }
 
+void
+rte_eth_copy_soc_info(struct rte_eth_dev *eth_dev,
+		      struct rte_soc_device *soc_dev)
+{
+	if ((eth_dev == NULL) || (soc_dev == NULL)) {
+		RTE_PMD_DEBUG_TRACE("NULL pointer eth_dev=%p soc_dev=%p\n",
+				eth_dev, soc_dev);
+		return;
+	}
+
+	RTE_ASSERT(eth_dev->soc_dev != NULL);
+
+	eth_dev->data->dev_flags = 0;
+	if (soc_dev->driver->drv_flags & RTE_SOC_DRV_INTR_LSC)
+		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
+	if (soc_dev->driver->drv_flags & RTE_SOC_DRV_DETACHABLE)
+		eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
+
+	eth_dev->data->numa_node = soc_dev->device.numa_node;
+	eth_dev->data->drv_name = soc_dev->driver->driver.name;
+}
+
 int
 rte_eth_dev_l2_tunnel_eth_type_conf(uint8_t port_id,
 				    struct rte_eth_l2_tunnel_conf *l2_tunnel)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index f893fe0..ff7958f 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -180,6 +180,7 @@ extern "C" {
 #include <rte_log.h>
 #include <rte_interrupts.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include "rte_ether.h"
@@ -877,6 +878,7 @@ struct rte_eth_conf {
  */
 struct rte_eth_dev_info {
 	struct rte_pci_device *pci_dev; /**< Device PCI information. */
+	struct rte_soc_device *soc_dev; /**< Device SoC information. */
 	const char *driver_name; /**< Device Driver name. */
 	unsigned int if_index; /**< Index to bound host interface, or 0 if none.
 		Use if_indextoname() to translate into an interface name. */
@@ -1626,6 +1628,7 @@ struct rte_eth_dev {
 	const struct eth_driver *driver;/**< Driver for this device */
 	const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
 	struct rte_pci_device *pci_dev; /**< PCI info. supplied by probing */
+	struct rte_soc_device *soc_dev; /**< SoC info. supplied by probing */
 	/** User application callbacks for NIC interrupts */
 	struct rte_eth_dev_cb_list link_intr_cbs;
 	/**
@@ -1860,6 +1863,7 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *eth_dev);
  */
 struct eth_driver {
 	struct rte_pci_driver pci_drv;    /**< The PMD is also a PCI driver. */
+	struct rte_soc_driver soc_drv;    /**< The PMD is also a SoC driver. */
 	eth_dev_init_t eth_dev_init;      /**< Device init function. */
 	eth_dev_uninit_t eth_dev_uninit;  /**< Device uninit function. */
 	unsigned int dev_private_size;    /**< Size of device private data. */
@@ -4262,6 +4266,20 @@ void rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev,
 		struct rte_pci_device *pci_dev);
 
 /**
+ * Copy SoC device info to the Ethernet device data.
+ *
+ * @param eth_dev
+ * The *eth_dev* pointer is the address of the *rte_eth_dev* structure.
+ * @param soc_dev
+ * The *soc_dev* pointer is the address of the *rte_soc_device* structure.
+ *
+ * @return
+ *   - 0 on success, negative on error
+ */
+void rte_eth_copy_soc_info(struct rte_eth_dev *eth_dev,
+		struct rte_soc_device *soc_dev);
+
+/**
  * Create memzone for HW rings.
  * malloc can't be used as the physical address is needed.
  * If the memzone is already created, then this function returns a ptr
@@ -4376,6 +4394,19 @@ int rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
  */
 int rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev);
 
+/**
+ * Wrapper for use by SoC drivers as a .devinit function to attach to a ethdev
+ * interface.
+ */
+int rte_eth_dev_soc_probe(struct rte_soc_driver *soc_drv,
+			  struct rte_soc_device *soc_dev);
+
+/**
+ * Wrapper for use by SoC drivers as a .devuninit function to detach a ethdev
+ * interface.
+ */
+int rte_eth_dev_soc_remove(struct rte_soc_device *soc_dev);
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.7.4

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

* [PATCH v7 21/21] eal/crypto: Support rte_soc_driver/device for cryptodev
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                             ` (19 preceding siblings ...)
  2016-10-28 12:26           ` [PATCH v7 20/21] ether: introduce ethernet dev probe remove Shreyansh Jain
@ 2016-10-28 12:26           ` Shreyansh Jain
  2016-10-28 12:35           ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
  2016-11-09 10:17           ` Thomas Monjalon
  22 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin

- rte_cryptodev_driver/rte_cryptodev_dev embeds rte_soc_driver/device for
  linking SoC PMDs to crypto devices.
- Add probe and remove functions linked

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 lib/librte_cryptodev/rte_cryptodev.c           | 122 ++++++++++++++++++++++++-
 lib/librte_cryptodev/rte_cryptodev.h           |   3 +
 lib/librte_cryptodev/rte_cryptodev_pmd.h       |  18 +++-
 lib/librte_cryptodev/rte_cryptodev_version.map |   2 +
 4 files changed, 140 insertions(+), 5 deletions(-)

diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 127e8d0..77ec9fe 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -422,7 +422,8 @@ rte_cryptodev_pci_probe(struct rte_pci_driver *pci_drv,
 
 	int retval;
 
-	cryptodrv = (struct rte_cryptodev_driver *)pci_drv;
+	cryptodrv = container_of(pci_drv, struct rte_cryptodev_driver,
+				 pci_drv);
 	if (cryptodrv == NULL)
 		return -ENODEV;
 
@@ -489,7 +490,8 @@ rte_cryptodev_pci_remove(struct rte_pci_device *pci_dev)
 	if (cryptodev == NULL)
 		return -ENODEV;
 
-	cryptodrv = (const struct rte_cryptodev_driver *)pci_dev->driver;
+	cryptodrv = container_of(pci_dev->driver, struct rte_cryptodev_driver,
+				 pci_drv);
 	if (cryptodrv == NULL)
 		return -ENODEV;
 
@@ -513,6 +515,111 @@ rte_cryptodev_pci_remove(struct rte_pci_device *pci_dev)
 	return 0;
 }
 
+
+int
+rte_cryptodev_soc_probe(struct rte_soc_driver *soc_drv,
+		      struct rte_soc_device *soc_dev)
+{
+	struct rte_cryptodev_driver *cryptodrv;
+	struct rte_cryptodev *cryptodev;
+
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+
+	int retval;
+
+	cryptodrv = container_of(soc_drv, struct rte_cryptodev_driver,
+				 soc_drv);
+
+	rte_eal_soc_device_name(&soc_dev->addr, cryptodev_name,
+			sizeof(cryptodev_name));
+
+	cryptodev = rte_cryptodev_pmd_allocate(cryptodev_name,
+					       rte_socket_id());
+	if (cryptodev == NULL)
+		return -ENOMEM;
+
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		cryptodev->data->dev_private =
+				rte_zmalloc_socket(
+						"cryptodev private structure",
+						cryptodrv->dev_private_size,
+						RTE_CACHE_LINE_SIZE,
+						rte_socket_id());
+
+		if (cryptodev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private "
+					"device data");
+	}
+
+	cryptodev->soc_dev = soc_dev;
+	cryptodev->driver = cryptodrv;
+
+	/* init user callbacks */
+	TAILQ_INIT(&(cryptodev->link_intr_cbs));
+
+	/* Invoke PMD device initialization function */
+	retval = (*cryptodrv->cryptodev_init)(cryptodrv, cryptodev);
+	if (retval == 0)
+		return 0;
+
+	CDEV_LOG_ERR("driver %s: cryptodev_init(%s) failed\n",
+			soc_drv->driver.name,
+			soc_dev->addr.name);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	cryptodev->attached = RTE_CRYPTODEV_DETACHED;
+	cryptodev_globals.nb_devs--;
+
+	return -ENXIO;
+}
+
+int
+rte_cryptodev_soc_remove(struct rte_soc_device *soc_dev)
+{
+	const struct rte_cryptodev_driver *cryptodrv;
+	struct rte_cryptodev *cryptodev;
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+	int ret;
+
+	if (soc_dev == NULL)
+		return -EINVAL;
+
+	rte_eal_soc_device_name(&soc_dev->addr, cryptodev_name,
+			sizeof(cryptodev_name));
+
+	cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name);
+	if (cryptodev == NULL)
+		return -ENODEV;
+
+	cryptodrv = container_of(soc_dev->driver,
+		struct rte_cryptodev_driver, soc_drv);
+	if (cryptodrv == NULL)
+		return -ENODEV;
+
+	/* Invoke PMD device uninit function */
+	if (*cryptodrv->cryptodev_uninit) {
+		ret = (*cryptodrv->cryptodev_uninit)(cryptodrv, cryptodev);
+		if (ret)
+			return ret;
+	}
+
+	/* free crypto device */
+	rte_cryptodev_pmd_release_device(cryptodev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	cryptodev->pci_dev = NULL;
+	cryptodev->soc_dev = NULL;
+	cryptodev->driver = NULL;
+	cryptodev->data = NULL;
+
+	return 0;
+}
+
 uint16_t
 rte_cryptodev_queue_pair_count(uint8_t dev_id)
 {
@@ -868,8 +975,15 @@ rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
 
 	dev_info->pci_dev = dev->pci_dev;
-	if (dev->driver)
-		dev_info->driver_name = dev->driver->pci_drv.driver.name;
+	dev_info->soc_dev = dev->soc_dev;
+	if (dev->driver) {
+		if (dev->soc_dev)
+			dev_info->driver_name
+				= dev->driver->soc_drv.driver.name;
+		else
+			dev_info->driver_name
+				= dev->driver->pci_drv.driver.name;
+	}
 }
 
 
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 8f63e8f..85ce5cb 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -244,6 +244,7 @@ struct rte_cryptodev_info {
 	const char *driver_name;		/**< Driver name. */
 	enum rte_cryptodev_type dev_type;	/**< Device type */
 	struct rte_pci_device *pci_dev;		/**< PCI information. */
+	struct rte_soc_device *soc_dev;		/**< SoC information. */
 
 	uint64_t feature_flags;			/**< Feature flags */
 
@@ -623,6 +624,8 @@ struct rte_cryptodev {
 	/**< Supported features */
 	struct rte_pci_device *pci_dev;
 	/**< PCI info. supplied by probing */
+	struct rte_soc_device *soc_dev;
+	/**< SoC info. supplied by probing/Scanning */
 
 	enum rte_cryptodev_type dev_type;
 	/**< Crypto device type */
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index abfe2dc..a8af2ce 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -48,6 +48,7 @@ extern "C" {
 
 #include <rte_dev.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_malloc.h>
 #include <rte_mbuf.h>
 #include <rte_mempool.h>
@@ -131,7 +132,8 @@ typedef int (*cryptodev_uninit_t)(const struct rte_cryptodev_driver  *drv,
  * - The size of the private data to allocate for each matching device.
  */
 struct rte_cryptodev_driver {
-	struct rte_pci_driver pci_drv;	/**< The PMD is also a PCI driver. */
+	struct rte_pci_driver pci_drv;	/**< The PMD is PCI type driver. */
+	struct rte_soc_driver soc_drv;	/**< The PMD is SoC type driver. */
 	unsigned dev_private_size;	/**< Size of device private data. */
 
 	cryptodev_init_t cryptodev_init;	/**< Device init function. */
@@ -519,6 +521,20 @@ int rte_cryptodev_pci_probe(struct rte_pci_driver *pci_drv,
  */
 int rte_cryptodev_pci_remove(struct rte_pci_device *pci_dev);
 
+/**
+ * Wrapper for use by SoC drivers as a .devinit function to attach to a
+ * cryptodev interface.
+ */
+int rte_cryptodev_soc_probe(struct rte_soc_driver *soc_drv,
+			  struct rte_soc_device *soc_dev);
+
+/**
+ * Wrapper for use by SoC drivers as a .devuninit function to detach a
+ * cryptodev interface.
+ */
+int rte_cryptodev_soc_remove(struct rte_soc_device *soc_dev);
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index 9dde0e7..d81073e 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -44,5 +44,7 @@ DPDK_16.11 {
 
 	rte_cryptodev_pci_probe;
 	rte_cryptodev_pci_remove;
+	rte_cryptodev_soc_probe;
+	rte_cryptodev_soc_remove;
 
 } DPDK_16.07;
-- 
2.7.4

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

* Re: [PATCH v7 00/21] Introduce SoC device/driver framework for EAL
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                             ` (20 preceding siblings ...)
  2016-10-28 12:26           ` [PATCH v7 21/21] eal/crypto: Support rte_soc_driver/device for cryptodev Shreyansh Jain
@ 2016-10-28 12:35           ` Shreyansh Jain
  2016-11-09 10:17           ` Thomas Monjalon
  22 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-10-28 12:35 UTC (permalink / raw)
  To: dev; +Cc: thomas.monjalon

On Friday 28 October 2016 05:56 PM, Shreyansh Jain wrote:
> Introduction:
> =============
>
> This patch set is direct derivative of Jan's original series [1],[2].
>
>  - This version is based on master HEAD (ca41215)
>
>  - In this, I am merging the series [11] back. It was initially part
>    of this set but I had split considering that those changes in PCI
>    were good standalone as well. But, 1) not much feedback was avail-
>    able and 2) this patchset is a use-case for those patches making
>    it easier to review. Just like what Jan had intended in original
>    series.
>
>  - SoC support is not enabled by default. It needs the 'enable-soc' toggle
>    on command line. This is primarily because this patchset is still
>    experimental and we would like to keep it isolated from non-SoC ops.
>    Though, it does impact the ABI.

Sending v7 as patch 11/21 of v6 wasn't received by mailing list leading 
to automated build failure. No other change has been done.

-
Shreyansh

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

* Re: [PATCH v7 00/21] Introduce SoC device/driver framework for EAL
  2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
                             ` (21 preceding siblings ...)
  2016-10-28 12:35           ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
@ 2016-11-09 10:17           ` Thomas Monjalon
  2016-11-09 13:36             ` Shreyansh Jain
  22 siblings, 1 reply; 231+ messages in thread
From: Thomas Monjalon @ 2016-11-09 10:17 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, viktorin, david.marchand

Hi Shreyansh,

I realize that we had a lot of off-list discussions on this topic
and there was no public explanation of the status of this series.

2016-10-28 17:56, Shreyansh Jain:
[...]
> As of now EAL is primarly focused on PCI initialization/probing.

Right. DPDK was PCI centric.
We must give PCI its right role: a bus as other ones.
A first step was done in 16.11 (thanks to you Shreyansh, Jan and David)
to have a better device model.
The next step is to rework the bus abstraction.

It seems a bus can be defined with the properties scan/match/notify,
leading to initialize the devices.

More comments below your technical presentation.

[...]
> This patchset introduces SoC framework which would enable SoC drivers and
> drivers to be plugged into EAL, very similar to how PCI drivers/devices are
> done today.
> 
> This is a stripped down version of PCI framework which allows the SoC PMDs
> to implement their own routines for detecting devices and linking devices to
> drivers.
> 
> 1) Changes to EAL
>  rte_eal_init()
>   |- rte_eal_pci_init(): Find PCI devices from sysfs
>   |- rte_eal_soc_init(): Calls PMDs->scan_fn
>   |- ...
>   |- rte_eal_memzone_init()
>   |- ...
>   |- rte_eal_pci_probe(): Driver<=>Device initialization, PMD->devinit()
>   `- rte_eal_soc_probe(): Calls PMDs->match_fn and PMDs->devinit();
> 
> 2) New device/driver structures:
>   - rte_soc_driver (inheriting rte_driver)
>   - rte_soc_device (inheriting rte_device)
>   - rte_eth_dev and eth_driver embedded rte_soc_device and rte_soc_driver,
>     respectively.
> 
> 3) The SoC PMDs need to:
>  - define rte_soc_driver with necessary scan and match callbacks
>  - Register themselves using DRIVER_REGISTER_SOC()
>  - Implement respective bus scanning in the scan callbacks to add necessary
>    devices to SoC device list
>  - Implement necessary eth_dev_init/uninint for ethernet instances

These callbacks are not specific to a SoC.
By the way a SoC defines nothing specific. You are using the SoC word
as an equivalent of non-PCI.
We must have a bus abstraction like the one you are defining for the SoC
but it must be generic and defined on top of PCI, so we can plug any
bus in it: PCI, vdev (as a software bus), any other well-defined bus,
and some driver-specific bus which can be implemented directly in the
driver (the NXP case AFAIK).

> 4) Design considerations that are same as PCI:
>  - SoC initialization is being done through rte_eal_init(), just after PCI
>    initialization is done.
>  - As in case of PCI, probe is done after rte_eal_pci_probe() to link the
>    devices detected with the drivers registered.
>  - Device attach/detach functions are available and have been designed on
>    the lines of PCI framework.
>  - PMDs register using DRIVER_REGISTER_SOC, very similar to
>    DRIVER_REGISTER_PCI for PCI devices.
>  - Linked list of SoC driver and devices exists independent of the other
>    driver/device list, but inheriting rte_driver/rte_driver, these are
>    also part of a global list.
> 
> 5) Design considerations that are different from PCI:
>  - Each driver implements its own scan and match function. PCI uses the BDF
>    format to read the device from sysfs, but this _may_not_ be a case for a
>    SoC ethernet device.
>    = This is an important change from initial proposal by Jan in [2].
>    Unlike his attempt to use /sys/bus/platform, this patch relies on the
>    PMD to detect the devices. This is because SoC may require specific or
>    additional info for device detection. Further, SoC may have embedded
>    devices/MACs which require initialization which cannot be covered
>    through sysfs parsing.
>    `-> Point (6) below is a side note to above.
>    = PCI based PMDs rely on EAL's capability to detect devices. This
>    proposal puts the onus on PMD to detect devices, add to soc_device_list
>    and wait for Probe. Matching, of device<=>driver is again PMD's
>    callback.

These PCI considerations can be described as a PCI bus implementation in EAL.

> 6) Adding default scan and match helpers for PMDs
>  - The design warrrants the PMDs implement their own scan of devices
>    on bus, and match routines for probe implementation.
>    This patch introduces helpers which can be used by PMDs for scan of
>    the platform bus and matching devices against the compatible string
>    extracted from the scan.
>  - Intention is to make it easier to integrate known SoC which expose
>    platform bus compliant information (compat, sys/bus/platform...).
>  - PMDs which have deviations from this standard model can implement and
>    hook their bus scanning and probe match callbacks while registering
>    driver.

Yes we can have EAL helpers to scan sys/bus/platform or other common formats.
Then the PMD can use them to implement its specific bus.

I know that David, you and me are on the same page to agree on this generic
design. I hope you will be able to achieve this work soon.
The goal is to be able to plug a SoC driver in DPDK 17.02 with a clean design.
My advice to make reviews and contributions easier, is to split the work in
few steps:
	- clean PCI code (generalize non-PCI stuff)
	- add generic bus functions
	- plug PCI in generic bus abstraction
	- plug vdev in generic bus abstraction
	- plug the new NXP driver

Thanks

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

* Re: [PATCH v7 00/21] Introduce SoC device/driver framework for EAL
  2016-11-09 10:17           ` Thomas Monjalon
@ 2016-11-09 13:36             ` Shreyansh Jain
  0 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-11-09 13:36 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, viktorin, david.marchand

Hello Thomas,

On Wednesday 09 November 2016 03:47 PM, Thomas Monjalon wrote:
> Hi Shreyansh,
>
> I realize that we had a lot of off-list discussions on this topic
> and there was no public explanation of the status of this series.

Thanks for your email. (and all the suggestions you have given 
offline/IRC etc.)
I was beginning to wonder that probably only Jan and me were the ones 
interested in this. Ironically, I felt that being EAL changes, a lot of 
people would come and be critic of it - giving an opportunity to get it 
widely accepted.

>
> 2016-10-28 17:56, Shreyansh Jain:
> [...]
>> As of now EAL is primarly focused on PCI initialization/probing.
>
> Right. DPDK was PCI centric.
> We must give PCI its right role: a bus as other ones.
> A first step was done in 16.11 (thanks to you Shreyansh, Jan and David)
> to have a better device model.
> The next step is to rework the bus abstraction.

Or, this change can be broken into multiple steps:
1. Create a PCI parallel layer for non-PCI devices. (call it SoC, or 
whatever else - doesn't really matter. More below).
2. Generalize this 'soc' changeset into common
3. Complete generalization by introducing a Linux like model of 
bus<=>device<=>driver.

Which was what my current approach was - expecting that SoC patchset 
would allow me to introduce NXP PMD and parallel to it I can keep 
pushing EAL generic changes towards generic bus arch.

>
> It seems a bus can be defined with the properties scan/match/notify,
> leading to initialize the devices.

'notify' is something which I am not completely clear with - but, in 
principle, agree.

>
> More comments below your technical presentation.
>
> [...]
>> This patchset introduces SoC framework which would enable SoC drivers and
>> drivers to be plugged into EAL, very similar to how PCI drivers/devices are
>> done today.
>>
>> This is a stripped down version of PCI framework which allows the SoC PMDs
>> to implement their own routines for detecting devices and linking devices to
>> drivers.
>>
>> 1) Changes to EAL
>>  rte_eal_init()
>>   |- rte_eal_pci_init(): Find PCI devices from sysfs
>>   |- rte_eal_soc_init(): Calls PMDs->scan_fn
>>   |- ...
>>   |- rte_eal_memzone_init()
>>   |- ...
>>   |- rte_eal_pci_probe(): Driver<=>Device initialization, PMD->devinit()
>>   `- rte_eal_soc_probe(): Calls PMDs->match_fn and PMDs->devinit();
>>
>> 2) New device/driver structures:
>>   - rte_soc_driver (inheriting rte_driver)
>>   - rte_soc_device (inheriting rte_device)
>>   - rte_eth_dev and eth_driver embedded rte_soc_device and rte_soc_driver,
>>     respectively.
>>
>> 3) The SoC PMDs need to:
>>  - define rte_soc_driver with necessary scan and match callbacks
>>  - Register themselves using DRIVER_REGISTER_SOC()
>>  - Implement respective bus scanning in the scan callbacks to add necessary
>>    devices to SoC device list
>>  - Implement necessary eth_dev_init/uninint for ethernet instances
>
> These callbacks are not specific to a SoC.

Agree; this is just a note - it exactly what a PCI PMD does.

> By the way a SoC defines nothing specific. You are using the SoC word
> as an equivalent of non-PCI.

Yes, primarily because SoC is a very broad word which can encompass a 
variety of devices (buses/drivers). So, we have PCI set, VDEV set, and 
everything else represented by 'SoC'.
The complete set is based on this principle: to have a generic subsystem 
_parallel_ to PCI (so as not to impact it) which can represent all 
devices not already included in PCI set'. - Actually, it is _nothing_ 
specific.

> We must have a bus abstraction like the one you are defining for the SoC
> but it must be generic and defined on top of PCI, so we can plug any
> bus in it: PCI, vdev (as a software bus), any other well-defined bus,
> and some driver-specific bus which can be implemented directly in the
> driver (the NXP case AFAIK).

Indeed - that is an ideal approach. And honestly, true attribution, it 
is not my original idea. It is yours, from our IRC discussion.
And it was ironic as well because Declan came up with similar suggestion 
much earlier but no one commented on it.

>
>> 4) Design considerations that are same as PCI:
>>  - SoC initialization is being done through rte_eal_init(), just after PCI
>>    initialization is done.
>>  - As in case of PCI, probe is done after rte_eal_pci_probe() to link the
>>    devices detected with the drivers registered.
>>  - Device attach/detach functions are available and have been designed on
>>    the lines of PCI framework.
>>  - PMDs register using DRIVER_REGISTER_SOC, very similar to
>>    DRIVER_REGISTER_PCI for PCI devices.
>>  - Linked list of SoC driver and devices exists independent of the other
>>    driver/device list, but inheriting rte_driver/rte_driver, these are
>>    also part of a global list.
>>
>> 5) Design considerations that are different from PCI:
>>  - Each driver implements its own scan and match function. PCI uses the BDF
>>    format to read the device from sysfs, but this _may_not_ be a case for a
>>    SoC ethernet device.
>>    = This is an important change from initial proposal by Jan in [2].
>>    Unlike his attempt to use /sys/bus/platform, this patch relies on the
>>    PMD to detect the devices. This is because SoC may require specific or
>>    additional info for device detection. Further, SoC may have embedded
>>    devices/MACs which require initialization which cannot be covered
>>    through sysfs parsing.
>>    `-> Point (6) below is a side note to above.
>>    = PCI based PMDs rely on EAL's capability to detect devices. This
>>    proposal puts the onus on PMD to detect devices, add to soc_device_list
>>    and wait for Probe. Matching, of device<=>driver is again PMD's
>>    callback.
>
> These PCI considerations can be described as a PCI bus implementation in EAL.

Yes. Or, we can continue as it is for PCI and allow more buses to plug 
in. And eventually, make the whole bus thing generic. Step-by-Step.

>
>> 6) Adding default scan and match helpers for PMDs
>>  - The design warrrants the PMDs implement their own scan of devices
>>    on bus, and match routines for probe implementation.
>>    This patch introduces helpers which can be used by PMDs for scan of
>>    the platform bus and matching devices against the compatible string
>>    extracted from the scan.
>>  - Intention is to make it easier to integrate known SoC which expose
>>    platform bus compliant information (compat, sys/bus/platform...).
>>  - PMDs which have deviations from this standard model can implement and
>>    hook their bus scanning and probe match callbacks while registering
>>    driver.
>
> Yes we can have EAL helpers to scan sys/bus/platform or other common formats.
> Then the PMD can use them to implement its specific bus.

And:
  - Framework/Developers should be able to 'register/unregister' buses.
  -- Just like drivers/net
  -- So, probably a drivers/bus/pci, drivers/bus/xxx folder structure
  -- and compatible compilation routine
  -- Or maybe librte_bus?
  --- I still haven't got around solving this.
  - RTE_PMD_REGISTER_BUS probably.
  - just EAL helpers are not enough - or at least, not generic enough.

  - Drivers should be able to 'lookup' buses
  -- PCI PMDs find a 'pci' bus during registration, for example.
  -- Unlike Linux, a device tree doesn't exist to solve this issue of 
which PMD is connected to which bus. This needs to solved using explicit 
APIs
  -- Once found, drivers can 'associate' with a bus.

  - Not just bus<->device<->driver, there is pending work with respect 
ethernet devices.
  -- Removing eth_driver->pci_driver linkage. Making it generic.
  -- Multiple places assume eth device to be PCI, rewriting that part.
  -- device_insert changes for vdev

>
> I know that David, you and me are on the same page to agree on this generic
> design. I hope you will be able to achieve this work soon.

I agree with your suggestion in principle - bus model is nice to have. 
There is always a better design. It is about how to achieve it.

I still think that current SoC patchset is a decent first step without 
completely discounting any future changes. (Obviously, assuming it is 
not NACK'd by someone because of some currently unforeseen technical 
argument).
Because:
1. It doesn't break the existing PCI subsystem anywhere. It is disabled 
by default.
2. It is independent - in the sense that changes are limited to SoC 
specific files, with only a few changes in EAL. But, clean patches make 
it easier to validate.
3. It would allow more people to check/validate the overall proposal of 
non-PCI device existence.
4. It paves way for cleaner transit to Bus architecture
  - rte_device/driver inheritance is complete after SoC patchset. Except 
changes in eth_dev/driver which is a completely parallel change with 
little overlap (but wide impact)
  - rte_soc_driver introduces 'scan/match' which can then be generalized 
to rte_driver in next step.
  -- This is very similar to what happened in rte_device/driver change 
where PCI things were generalized to common.

> The goal is to be able to plug a SoC driver in DPDK 17.02 with a clean design.

I am already working on that - now on a higher priority. Hopefully 
within next few days I will send a RFC out. There are still some grey 
ares for me (lack of DPDK internal understand, probably) - but I am 
hoping I would get good support from others - at least this time.

Then, probably for 17.02, we can have either candidate - and we can 
integrate whatever looks best (in terms of design and impact, both).

> My advice to make reviews and contributions easier, is to split the work in
> few steps:
> 	- clean PCI code (generalize non-PCI stuff)
> 	- add generic bus functions
> 	- plug PCI in generic bus abstraction
> 	- plug vdev in generic bus abstraction
> 	- plug the new NXP driver

I agree with above.

>
> Thanks
>

Thank you for your time and suggestions.

-
Shreyansh

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

* Re: [PATCH v7 03/21] eal/linux: generalize PCI kernel unbinding driver to EAL
  2016-10-28 12:26           ` [PATCH v7 03/21] eal/linux: generalize PCI kernel unbinding driver " Shreyansh Jain
@ 2016-11-10  2:24             ` Jianbo Liu
  2016-11-10  5:46               ` Shreyansh Jain
  0 siblings, 1 reply; 231+ messages in thread
From: Jianbo Liu @ 2016-11-10  2:24 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, Thomas Monjalon, Jan Viktorin

On 28 October 2016 at 20:26, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
> From: Jan Viktorin <viktorin@rehivetech.com>
>
> Generalize the PCI-specific pci_unbind_kernel_driver. It is now divided
> into two parts. First, determination of the path and string identification
> of the device to be unbound. Second, the actual unbind operation which is
> generic.
>
> BSD implementation updated as ENOTSUP
>
> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> --
> Changes since v2:
>  - update BSD support for unbind kernel driver
> ---
>  lib/librte_eal/bsdapp/eal/eal.c       |  7 +++++++
>  lib/librte_eal/bsdapp/eal/eal_pci.c   |  4 ++--
>  lib/librte_eal/common/eal_private.h   | 13 +++++++++++++
>  lib/librte_eal/linuxapp/eal/eal.c     | 26 ++++++++++++++++++++++++++
>  lib/librte_eal/linuxapp/eal/eal_pci.c | 33 +++++++++------------------------
>  5 files changed, 57 insertions(+), 26 deletions(-)
>
> diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
> index 35e3117..5271fc2 100644
> --- a/lib/librte_eal/bsdapp/eal/eal.c
> +++ b/lib/librte_eal/bsdapp/eal/eal.c
> @@ -633,3 +633,10 @@ rte_eal_process_type(void)
>  {
>         return rte_config.process_type;
>  }
> +
> +int
> +rte_eal_unbind_kernel_driver(const char *devpath __rte_unused,
> +                            const char *devid __rte_unused)
> +{
> +       return -ENOTSUP;
> +}
> diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
> index 7ed0115..703f034 100644
> --- a/lib/librte_eal/bsdapp/eal/eal_pci.c
> +++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
> @@ -89,11 +89,11 @@
>
>  /* unbind kernel driver for this device */
>  int
> -pci_unbind_kernel_driver(struct rte_pci_device *dev __rte_unused)
> +pci_unbind_kernel_driver(struct rte_pci_device *dev)
>  {
>         RTE_LOG(ERR, EAL, "RTE_PCI_DRV_FORCE_UNBIND flag is not implemented "
>                 "for BSD\n");
> -       return -ENOTSUP;
> +       return rte_eal_unbind_kernel_driver(dev);

Missing the second parameter for devid.

>  }
>
>  /* Map pci device */
> diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
> index 9e7d8f6..b0c208a 100644
> --- a/lib/librte_eal/common/eal_private.h
> +++ b/lib/librte_eal/common/eal_private.h
> @@ -256,6 +256,19 @@ int rte_eal_alarm_init(void);
>  int rte_eal_check_module(const char *module_name);
>
>  /**
> + * Unbind kernel driver bound to the device specified by the given devpath,
> + * and its string identification.
> + *
> + * @param devpath  path to the device directory ("/sys/.../devices/<name>")
> + * @param devid    identification of the device (<name>)
> + *
> + * @return
> + *      -1  unbind has failed
> + *       0  module has been unbound
> + */
> +int rte_eal_unbind_kernel_driver(const char *devpath, const char *devid);
> +
> +/**
>   * Get cpu core_id.
>   *
>   * This function is private to the EAL.
> diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
> index 2075282..5f6676d 100644
> --- a/lib/librte_eal/linuxapp/eal/eal.c
> +++ b/lib/librte_eal/linuxapp/eal/eal.c
> @@ -943,3 +943,29 @@ rte_eal_check_module(const char *module_name)
>         /* Module has been found */
>         return 1;
>  }
> +
> +int
> +rte_eal_unbind_kernel_driver(const char *devpath, const char *devid)
> +{
> +       char filename[PATH_MAX];
> +       FILE *f;
> +
> +       snprintf(filename, sizeof(filename),
> +                "%s/driver/unbind", devpath);
> +
> +       f = fopen(filename, "w");
> +       if (f == NULL) /* device was not bound */
> +               return 0;
> +
> +       if (fwrite(devid, strlen(devid), 1, f) == 0) {
> +               RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
> +                               filename);
> +               goto error;
> +       }
> +
> +       fclose(f);
> +       return 0;
> +error:
> +       fclose(f);
> +       return -1;
> +}
> diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
> index 876ba38..a03553f 100644
> --- a/lib/librte_eal/linuxapp/eal/eal_pci.c
> +++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
> @@ -59,38 +59,23 @@ int
>  pci_unbind_kernel_driver(struct rte_pci_device *dev)
>  {
>         int n;
> -       FILE *f;
> -       char filename[PATH_MAX];
> -       char buf[BUFSIZ];
> +       char devpath[PATH_MAX];
> +       char devid[BUFSIZ];
>         struct rte_pci_addr *loc = &dev->addr;
>
> -       /* open /sys/bus/pci/devices/AAAA:BB:CC.D/driver */
> -       snprintf(filename, sizeof(filename),
> -               "%s/" PCI_PRI_FMT "/driver/unbind", pci_get_sysfs_path(),
> +       /* devpath /sys/bus/pci/devices/AAAA:BB:CC.D */
> +       snprintf(devpath, sizeof(devpath),
> +               "%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
>                 loc->domain, loc->bus, loc->devid, loc->function);
>
> -       f = fopen(filename, "w");
> -       if (f == NULL) /* device was not bound */
> -               return 0;
> -
> -       n = snprintf(buf, sizeof(buf), PCI_PRI_FMT "\n",
> +       n = snprintf(devid, sizeof(devid), PCI_PRI_FMT "\n",
>                      loc->domain, loc->bus, loc->devid, loc->function);
> -       if ((n < 0) || (n >= (int)sizeof(buf))) {
> +       if ((n < 0) || (n >= (int)sizeof(devid))) {
>                 RTE_LOG(ERR, EAL, "%s(): snprintf failed\n", __func__);
> -               goto error;
> -       }
> -       if (fwrite(buf, n, 1, f) == 0) {
> -               RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
> -                               filename);
> -               goto error;
> +               return -1;
>         }
>
> -       fclose(f);
> -       return 0;
> -
> -error:
> -       fclose(f);
> -       return -1;
> +       return rte_eal_unbind_kernel_driver(devpath, devid);
>  }
>
>  static int
> --
> 2.7.4
>

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

* Re: [PATCH v7 08/21] eal/soc: implement SoC device list and dump
  2016-10-28 12:26           ` [PATCH v7 08/21] eal/soc: implement SoC device list and dump Shreyansh Jain
@ 2016-11-10  3:06             ` Jianbo Liu
  2016-11-10  5:56               ` Shreyansh Jain
  0 siblings, 1 reply; 231+ messages in thread
From: Jianbo Liu @ 2016-11-10  3:06 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, Thomas Monjalon, Jan Viktorin

On 28 October 2016 at 20:26, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
> From: Jan Viktorin <viktorin@rehivetech.com>
>
> SoC devices would be linked in a separate list (from PCI). This is used for
> probe function.
> A helper for dumping the device list is added.
>
> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
>  lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  2 ++
>  lib/librte_eal/common/eal_common_soc.c          | 34 +++++++++++++++++++++++++
>  lib/librte_eal/common/include/rte_soc.h         |  9 +++++++
>  lib/librte_eal/linuxapp/eal/rte_eal_version.map |  2 ++
>  4 files changed, 47 insertions(+)
>
> diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> index cf6fb8e..86e3cfd 100644
> --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> @@ -171,11 +171,13 @@ DPDK_16.11 {
>         rte_eal_dev_attach;
>         rte_eal_dev_detach;
>         rte_eal_map_resource;
> +       rte_eal_soc_dump;
>         rte_eal_soc_register;
>         rte_eal_soc_unregister;
>         rte_eal_unmap_resource;
>         rte_eal_vdrv_register;
>         rte_eal_vdrv_unregister;
> +       soc_device_list;
>         soc_driver_list;
>
>  } DPDK_16.07;
> diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
> index 56135ed..5dcddc5 100644
> --- a/lib/librte_eal/common/eal_common_soc.c
> +++ b/lib/librte_eal/common/eal_common_soc.c
> @@ -31,6 +31,8 @@
>   *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>   */
>
> +#include <stddef.h>
> +#include <stdio.h>
>  #include <sys/queue.h>
>
>  #include <rte_log.h>
> @@ -40,6 +42,38 @@
>  /* Global SoC driver list */
>  struct soc_driver_list soc_driver_list =
>         TAILQ_HEAD_INITIALIZER(soc_driver_list);
> +struct soc_device_list soc_device_list =
> +       TAILQ_HEAD_INITIALIZER(soc_device_list);
> +
> +/* dump one device */
> +static int
> +soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
> +{
> +       int i;
> +
> +       fprintf(f, "%s", dev->addr.name);
> +       fprintf(f, " - fdt_path: %s\n",
> +                       dev->addr.fdt_path ? dev->addr.fdt_path : "(none)");
> +
> +       for (i = 0; dev->id && dev->id[i].compatible; ++i)
> +               fprintf(f, "   %s\n", dev->id[i].compatible);
> +
> +       return 0;
> +}
> +
> +/* dump devices on the bus to an output stream */
> +void
> +rte_eal_soc_dump(FILE *f)
> +{
> +       struct rte_soc_device *dev = NULL;
> +
> +       if (!f)
> +               return;
> +
> +       TAILQ_FOREACH(dev, &soc_device_list, next) {
> +               soc_dump_one_device(f, dev);
> +       }
> +}
>
>  /* register a driver */
>  void
> diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
> index 23b06a9..347e611 100644
> --- a/lib/librte_eal/common/include/rte_soc.h
> +++ b/lib/librte_eal/common/include/rte_soc.h
> @@ -56,8 +56,12 @@ extern "C" {
>
>  extern struct soc_driver_list soc_driver_list;
>  /**< Global list of SoC Drivers */
> +extern struct soc_device_list soc_device_list;
> +/**< Global list of SoC Devices */
>
>  TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
> +TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
> +
>
>  struct rte_soc_id {
>         const char *compatible; /**< OF compatible specification */
> @@ -142,6 +146,11 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
>  }
>
>  /**
> + * Dump discovered SoC devices.
> + */
> +void rte_eal_soc_dump(FILE *f);

If it is to dump device information (not driver), is it proper to
rename it rte_eal_soc_device_dump()?

> +
> +/**
>   * Register a SoC driver.
>   */
>  void rte_eal_soc_register(struct rte_soc_driver *driver);
> diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> index ab6b985..0155025 100644
> --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> @@ -175,11 +175,13 @@ DPDK_16.11 {
>         rte_eal_dev_attach;
>         rte_eal_dev_detach;
>         rte_eal_map_resource;
> +       rte_eal_soc_dump;
>         rte_eal_soc_register;
>         rte_eal_soc_unregister;
>         rte_eal_unmap_resource;
>         rte_eal_vdrv_register;
>         rte_eal_vdrv_unregister;
> +       soc_device_list;
>         soc_driver_list;
>
>  } DPDK_16.07;
> --
> 2.7.4
>

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

* Re: [PATCH v7 11/21] eal/soc: implement probing of drivers
  2016-10-28 12:26           ` [PATCH v7 11/21] eal/soc: implement probing of drivers Shreyansh Jain
@ 2016-11-10  3:30             ` Jianbo Liu
  2016-11-10  6:10               ` Shreyansh Jain
  0 siblings, 1 reply; 231+ messages in thread
From: Jianbo Liu @ 2016-11-10  3:30 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, Thomas Monjalon, Jan Viktorin

On 28 October 2016 at 20:26, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
> Each SoC PMD registers a set of callback for scanning its own bus/infra and
> matching devices to drivers when probe is called.
> This patch introduces the infra for calls to SoC scan on rte_eal_soc_init()
> and match on rte_eal_soc_probe().
>
> Patch also adds test case for scan and probe.
>
> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> --
> v4:
>  - Update test_soc for descriptive test function names
>  - Comments over test functions
>  - devinit and devuninint --> probe/remove
>  - RTE_VERIFY at some places
> ---
>  app/test/test_soc.c                             | 205 ++++++++++++++++++++++-
>  lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   4 +
>  lib/librte_eal/common/eal_common_soc.c          | 213 +++++++++++++++++++++++-
>  lib/librte_eal/common/include/rte_soc.h         |  75 ++++++++-
>  lib/librte_eal/linuxapp/eal/eal.c               |   5 +
>  lib/librte_eal/linuxapp/eal/eal_soc.c           |  21 ++-
>  lib/librte_eal/linuxapp/eal/rte_eal_version.map |   4 +
>  7 files changed, 519 insertions(+), 8 deletions(-)
>
.....

>  /**
> + * SoC device scan callback, called from rte_eal_soc_init.
> + * For various SoC, the bus on which devices are attached maynot be compliant
> + * to a standard platform (or platform bus itself). In which case, extra
> + * steps are implemented by PMD to scan over the bus and add devices to SoC
> + * device list.
> + */
> +typedef void (soc_scan_t)(void);

I'm still not sure about the purpose of soc_scan, and how to use it.
If it's for each driver, it should at least struct rte_soc_driver * as
its parameter.
If it's for each bus, why it is in rte_soc_driver?
I know you will implement bus driver in the future, but we need to
make it clear for current simplified implementation.

> +
> +/**
> + * Custom device<=>driver match callback for SoC
> + * Unlike PCI, SoC devices don't have a fixed definition of device
> + * identification. PMDs can implement a specific matching function in which
> + * driver and device objects are provided to perform custom match.
> + */
> +typedef int (soc_match_t)(struct rte_soc_driver *, struct rte_soc_device *);
> +
> +/**
>   * A structure describing a SoC driver.
>   */
>  struct rte_soc_driver {
> @@ -104,6 +120,8 @@ struct rte_soc_driver {
>         struct rte_driver driver;          /**< Inherit core driver. */
>         soc_probe_t *probe;                /**< Device probe */
>         soc_remove_t *remove;              /**< Device remove */
> +       soc_scan_t *scan_fn;               /**< Callback for scanning SoC bus*/
> +       soc_match_t *match_fn;             /**< Callback to match dev<->drv */
>         const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
>  };
>
> @@ -146,12 +164,63 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
>  }
>
>  /**
> + * Default function for matching the Soc driver with device. Each driver can
> + * either use this function or define their own soc matching function.
> + * This function relies on the compatible string extracted from sysfs. But,
> + * a SoC might have different way of identifying its devices. Such SoC can
> + * override match_fn.
> + *
> + * @return
> + *      0 on success
> + *     -1 when no match found
> +  */
> +int
> +rte_eal_soc_match_compat(struct rte_soc_driver *drv,
> +                        struct rte_soc_device *dev);
> +
> +/**
> + * Probe SoC devices for registered drivers.
> + *
> + * @return
> + *     0 on success
> + *     !0 in case of any failure in probe
> + */
> +int rte_eal_soc_probe(void);
> +
> +/**
> + * Probe the single SoC device.
> + */
> +int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
> +
> +/**
> + * Close the single SoC device.
> + *
> + * Scan the SoC devices and find the SoC device specified by the SoC
> + * address, then call the remove() function for registered driver
> + * that has a matching entry in its id_table for discovered device.
> + *
> + * @param addr
> + *     The SoC address to close.
> + * @return
> + *   - 0 on success.
> + *   - Negative on error.
> + */
> +int rte_eal_soc_detach(const struct rte_soc_addr *addr);
> +
> +/**
>   * Dump discovered SoC devices.
> + *
> + * @param f
> + *     File to dump device info in.
>   */
>  void rte_eal_soc_dump(FILE *f);
>
>  /**
>   * Register a SoC driver.
> + *
> + * @param driver
> + *     Object for SoC driver to register
> + * @return void
>   */
>  void rte_eal_soc_register(struct rte_soc_driver *driver);
>
> @@ -167,6 +236,10 @@ RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
>
>  /**
>   * Unregister a SoC driver.
> + *
> + * @param driver
> + *     Object for SoC driver to unregister
> + * @return void
>   */
>  void rte_eal_soc_unregister(struct rte_soc_driver *driver);
>
> diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
> index 098ba02..bd775f3 100644
> --- a/lib/librte_eal/linuxapp/eal/eal.c
> +++ b/lib/librte_eal/linuxapp/eal/eal.c
> @@ -70,6 +70,7 @@
>  #include <rte_cpuflags.h>
>  #include <rte_interrupts.h>
>  #include <rte_pci.h>
> +#include <rte_soc.h>
>  #include <rte_dev.h>
>  #include <rte_devargs.h>
>  #include <rte_common.h>
> @@ -890,6 +891,10 @@ rte_eal_init(int argc, char **argv)
>         if (rte_eal_pci_probe())
>                 rte_panic("Cannot probe PCI\n");
>
> +       /* Probe & Initialize SoC devices */
> +       if (rte_eal_soc_probe())
> +               rte_panic("Cannot probe SoC\n");
> +
>         rte_eal_mcfg_complete();
>
>         return fctret;
> diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
> index 04848b9..3929a76 100644
> --- a/lib/librte_eal/linuxapp/eal/eal_soc.c
> +++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
> @@ -44,13 +44,28 @@
>  #include <rte_log.h>
>  #include <rte_soc.h>
>
> -#include "eal_internal_cfg.h"
> -#include "eal_filesystem.h"
> -#include "eal_private.h"
> +#include <eal_internal_cfg.h>
> +#include <eal_filesystem.h>
> +#include <eal_private.h>
>
>  /* Init the SoC EAL subsystem */
>  int
>  rte_eal_soc_init(void)
>  {
> +       struct rte_soc_driver *drv;
> +
> +       /* SoC is disabled by default */
> +       if (!internal_config.enable_soc)
> +               return 0;
> +
> +       /* For each registered driver, call their scan routine to perform any
> +        * custom scan for devices (for example, custom buses)
> +        */
> +       TAILQ_FOREACH(drv, &soc_driver_list, next) {
> +               RTE_VERIFY(drv->scan_fn);
> +               drv->scan_fn();
> +               /* Ignore all errors from this */
> +       }
> +
>         return 0;
>  }
> diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> index 0155025..c28e093 100644
> --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> @@ -175,7 +175,11 @@ DPDK_16.11 {
>         rte_eal_dev_attach;
>         rte_eal_dev_detach;
>         rte_eal_map_resource;
> +       rte_eal_soc_detach;
>         rte_eal_soc_dump;
> +       rte_eal_soc_match;
> +       rte_eal_soc_probe;
> +       rte_eal_soc_probe_one;
>         rte_eal_soc_register;
>         rte_eal_soc_unregister;
>         rte_eal_unmap_resource;
> --
> 2.7.4
>

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

* Re: [PATCH v7 06/21] eal/soc: introduce very essential SoC infra definitions
  2016-10-28 12:26           ` [PATCH v7 06/21] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
@ 2016-11-10  4:09             ` Jianbo Liu
  2016-11-10  5:51               ` Shreyansh Jain
  0 siblings, 1 reply; 231+ messages in thread
From: Jianbo Liu @ 2016-11-10  4:09 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, Thomas Monjalon, Jan Viktorin

On 28 October 2016 at 20:26, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
> From: Jan Viktorin <viktorin@rehivetech.com>
>
> Define initial structures and functions for the SoC infrastructure.
> This patch supports only a very minimal functions for now.
> More features will be added in the following commits.
>
> Includes rte_device/rte_driver inheritance of
> rte_soc_device/rte_soc_driver.
>
> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
>  app/test/Makefile                       |   1 +
>  app/test/test_soc.c                     |  90 +++++++++++++++++++++
>  lib/librte_eal/common/Makefile          |   2 +-
>  lib/librte_eal/common/eal_private.h     |   4 +
>  lib/librte_eal/common/include/rte_soc.h | 138 ++++++++++++++++++++++++++++++++
>  5 files changed, 234 insertions(+), 1 deletion(-)
>  create mode 100644 app/test/test_soc.c
>  create mode 100644 lib/librte_eal/common/include/rte_soc.h
>
...


> +/**
> + * Utility function to write a SoC device name, this device name can later be
> + * used to retrieve the corresponding rte_soc_addr using above functions.
> + *
> + * @param addr
> + *     The SoC address
> + * @param output
> + *     The output buffer string
> + * @param size
> + *     The output buffer size
> + * @return
> + *  0 on success, negative on error.
> + */
> +static inline void
> +rte_eal_soc_device_name(const struct rte_soc_addr *addr,
> +                       char *output, size_t size)
> +{
> +       int ret;
> +
> +       RTE_VERIFY(addr != NULL);
> +       RTE_VERIFY(size >= strlen(addr->name));

Is it better to use (size > strlen(addr->name)?

> +       ret = snprintf(output, size, "%s", addr->name);
> +       RTE_VERIFY(ret >= 0);
> +}
> +
> +static inline int
> +rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
> +                        const struct rte_soc_addr *a1)
> +{
> +       if (a0 == NULL || a1 == NULL)
> +               return -1;
> +
> +       RTE_VERIFY(a0->name != NULL);
> +       RTE_VERIFY(a1->name != NULL);
> +
> +       return strcmp(a0->name, a1->name);
> +}
> +
> +#endif
> --
> 2.7.4
>

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

* Re: [PATCH v7 03/21] eal/linux: generalize PCI kernel unbinding driver to EAL
  2016-11-10  2:24             ` Jianbo Liu
@ 2016-11-10  5:46               ` Shreyansh Jain
  0 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-11-10  5:46 UTC (permalink / raw)
  To: Jianbo Liu; +Cc: dev, Thomas Monjalon, Jan Viktorin

Hello Jianbo,

Thanks a lot for your time in commenting this. My comments inline (as 
well as on other similar mails).

On Thursday 10 November 2016 07:54 AM, Jianbo Liu wrote:
> On 28 October 2016 at 20:26, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
>> From: Jan Viktorin <viktorin@rehivetech.com>
>>
>> Generalize the PCI-specific pci_unbind_kernel_driver. It is now divided
>> into two parts. First, determination of the path and string identification
>> of the device to be unbound. Second, the actual unbind operation which is
>> generic.
>>
>> BSD implementation updated as ENOTSUP
>>
>> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
>> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
>> --
>> Changes since v2:
>>  - update BSD support for unbind kernel driver
>> ---
>>  lib/librte_eal/bsdapp/eal/eal.c       |  7 +++++++
>>  lib/librte_eal/bsdapp/eal/eal_pci.c   |  4 ++--
>>  lib/librte_eal/common/eal_private.h   | 13 +++++++++++++
>>  lib/librte_eal/linuxapp/eal/eal.c     | 26 ++++++++++++++++++++++++++
>>  lib/librte_eal/linuxapp/eal/eal_pci.c | 33 +++++++++------------------------
>>  5 files changed, 57 insertions(+), 26 deletions(-)
>>
>> diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
>> index 35e3117..5271fc2 100644
>> --- a/lib/librte_eal/bsdapp/eal/eal.c
>> +++ b/lib/librte_eal/bsdapp/eal/eal.c
>> @@ -633,3 +633,10 @@ rte_eal_process_type(void)
>>  {
>>         return rte_config.process_type;
>>  }
>> +
>> +int
>> +rte_eal_unbind_kernel_driver(const char *devpath __rte_unused,
>> +                            const char *devid __rte_unused)
>> +{
>> +       return -ENOTSUP;
>> +}
>> diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
>> index 7ed0115..703f034 100644
>> --- a/lib/librte_eal/bsdapp/eal/eal_pci.c
>> +++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
>> @@ -89,11 +89,11 @@
>>
>>  /* unbind kernel driver for this device */
>>  int
>> -pci_unbind_kernel_driver(struct rte_pci_device *dev __rte_unused)
>> +pci_unbind_kernel_driver(struct rte_pci_device *dev)
>>  {
>>         RTE_LOG(ERR, EAL, "RTE_PCI_DRV_FORCE_UNBIND flag is not implemented "
>>                 "for BSD\n");
>> -       return -ENOTSUP;
>> +       return rte_eal_unbind_kernel_driver(dev);
>
> Missing the second parameter for devid.

Indeed. I will fix this.
Being BSD, I didn't compile test this part. I will have to find a way to 
fix this in my sanity before sending next series.

>
>>  }
>>
>>  /* Map pci device */
>> diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
>> index 9e7d8f6..b0c208a 100644
>> --- a/lib/librte_eal/common/eal_private.h
>> +++ b/lib/librte_eal/common/eal_private.h
>> @@ -256,6 +256,19 @@ int rte_eal_alarm_init(void);
>>  int rte_eal_check_module(const char *module_name);
>>
>>  /**
>> + * Unbind kernel driver bound to the device specified by the given devpath,
>> + * and its string identification.
>> + *
>> + * @param devpath  path to the device directory ("/sys/.../devices/<name>")
>> + * @param devid    identification of the device (<name>)
>> + *
>> + * @return
>> + *      -1  unbind has failed
>> + *       0  module has been unbound
>> + */
>> +int rte_eal_unbind_kernel_driver(const char *devpath, const char *devid);
>> +
>> +/**
>>   * Get cpu core_id.
>>   *
>>   * This function is private to the EAL.
>> diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
>> index 2075282..5f6676d 100644
>> --- a/lib/librte_eal/linuxapp/eal/eal.c
>> +++ b/lib/librte_eal/linuxapp/eal/eal.c
>> @@ -943,3 +943,29 @@ rte_eal_check_module(const char *module_name)
>>         /* Module has been found */
>>         return 1;
>>  }
>> +
>> +int
>> +rte_eal_unbind_kernel_driver(const char *devpath, const char *devid)
>> +{
>> +       char filename[PATH_MAX];
>> +       FILE *f;
>> +
>> +       snprintf(filename, sizeof(filename),
>> +                "%s/driver/unbind", devpath);
>> +
>> +       f = fopen(filename, "w");
>> +       if (f == NULL) /* device was not bound */
>> +               return 0;
>> +
>> +       if (fwrite(devid, strlen(devid), 1, f) == 0) {
>> +               RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
>> +                               filename);
>> +               goto error;
>> +       }
>> +
>> +       fclose(f);
>> +       return 0;
>> +error:
>> +       fclose(f);
>> +       return -1;
>> +}
>> diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
>> index 876ba38..a03553f 100644
>> --- a/lib/librte_eal/linuxapp/eal/eal_pci.c
>> +++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
>> @@ -59,38 +59,23 @@ int
>>  pci_unbind_kernel_driver(struct rte_pci_device *dev)
>>  {
>>         int n;
>> -       FILE *f;
>> -       char filename[PATH_MAX];
>> -       char buf[BUFSIZ];
>> +       char devpath[PATH_MAX];
>> +       char devid[BUFSIZ];
>>         struct rte_pci_addr *loc = &dev->addr;
>>
>> -       /* open /sys/bus/pci/devices/AAAA:BB:CC.D/driver */
>> -       snprintf(filename, sizeof(filename),
>> -               "%s/" PCI_PRI_FMT "/driver/unbind", pci_get_sysfs_path(),
>> +       /* devpath /sys/bus/pci/devices/AAAA:BB:CC.D */
>> +       snprintf(devpath, sizeof(devpath),
>> +               "%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
>>                 loc->domain, loc->bus, loc->devid, loc->function);
>>
>> -       f = fopen(filename, "w");
>> -       if (f == NULL) /* device was not bound */
>> -               return 0;
>> -
>> -       n = snprintf(buf, sizeof(buf), PCI_PRI_FMT "\n",
>> +       n = snprintf(devid, sizeof(devid), PCI_PRI_FMT "\n",
>>                      loc->domain, loc->bus, loc->devid, loc->function);
>> -       if ((n < 0) || (n >= (int)sizeof(buf))) {
>> +       if ((n < 0) || (n >= (int)sizeof(devid))) {
>>                 RTE_LOG(ERR, EAL, "%s(): snprintf failed\n", __func__);
>> -               goto error;
>> -       }
>> -       if (fwrite(buf, n, 1, f) == 0) {
>> -               RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
>> -                               filename);
>> -               goto error;
>> +               return -1;
>>         }
>>
>> -       fclose(f);
>> -       return 0;
>> -
>> -error:
>> -       fclose(f);
>> -       return -1;
>> +       return rte_eal_unbind_kernel_driver(devpath, devid);
>>  }
>>
>>  static int
>> --
>> 2.7.4
>>
>

-
Shreyansh

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

* Re: [PATCH v7 06/21] eal/soc: introduce very essential SoC infra definitions
  2016-11-10  4:09             ` Jianbo Liu
@ 2016-11-10  5:51               ` Shreyansh Jain
  0 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-11-10  5:51 UTC (permalink / raw)
  To: Jianbo Liu; +Cc: dev, Thomas Monjalon, Jan Viktorin

On Thursday 10 November 2016 09:39 AM, Jianbo Liu wrote:
> On 28 October 2016 at 20:26, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
>> From: Jan Viktorin <viktorin@rehivetech.com>
>>
>> Define initial structures and functions for the SoC infrastructure.
>> This patch supports only a very minimal functions for now.
>> More features will be added in the following commits.
>>
>> Includes rte_device/rte_driver inheritance of
>> rte_soc_device/rte_soc_driver.
>>
>> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
>> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>> ---
>>  app/test/Makefile                       |   1 +
>>  app/test/test_soc.c                     |  90 +++++++++++++++++++++
>>  lib/librte_eal/common/Makefile          |   2 +-
>>  lib/librte_eal/common/eal_private.h     |   4 +
>>  lib/librte_eal/common/include/rte_soc.h | 138 ++++++++++++++++++++++++++++++++
>>  5 files changed, 234 insertions(+), 1 deletion(-)
>>  create mode 100644 app/test/test_soc.c
>>  create mode 100644 lib/librte_eal/common/include/rte_soc.h
>>
> ....
>
>
>> +/**
>> + * Utility function to write a SoC device name, this device name can later be
>> + * used to retrieve the corresponding rte_soc_addr using above functions.
>> + *
>> + * @param addr
>> + *     The SoC address
>> + * @param output
>> + *     The output buffer string
>> + * @param size
>> + *     The output buffer size
>> + * @return
>> + *  0 on success, negative on error.
>> + */
>> +static inline void
>> +rte_eal_soc_device_name(const struct rte_soc_addr *addr,
>> +                       char *output, size_t size)
>> +{
>> +       int ret;
>> +
>> +       RTE_VERIFY(addr != NULL);
>> +       RTE_VERIFY(size >= strlen(addr->name));
>
> Is it better to use (size > strlen(addr->name)?

Yes, I missed the '\0' in this.
I will fix this.

>
>> +       ret = snprintf(output, size, "%s", addr->name);
>> +       RTE_VERIFY(ret >= 0);
>> +}
>> +
>> +static inline int
>> +rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
>> +                        const struct rte_soc_addr *a1)
>> +{
>> +       if (a0 == NULL || a1 == NULL)
>> +               return -1;
>> +
>> +       RTE_VERIFY(a0->name != NULL);
>> +       RTE_VERIFY(a1->name != NULL);
>> +
>> +       return strcmp(a0->name, a1->name);
>> +}
>> +
>> +#endif
>> --
>> 2.7.4
>>
>


-- 
-
Shreyansh

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

* Re: [PATCH v7 08/21] eal/soc: implement SoC device list and dump
  2016-11-10  3:06             ` Jianbo Liu
@ 2016-11-10  5:56               ` Shreyansh Jain
  0 siblings, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-11-10  5:56 UTC (permalink / raw)
  To: Jianbo Liu; +Cc: dev, Thomas Monjalon, Jan Viktorin

On Thursday 10 November 2016 08:36 AM, Jianbo Liu wrote:
> On 28 October 2016 at 20:26, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
>> From: Jan Viktorin <viktorin@rehivetech.com>
>>
>> SoC devices would be linked in a separate list (from PCI). This is used for
>> probe function.
>> A helper for dumping the device list is added.
>>
>> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
>> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>> ---
>>  lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  2 ++
>>  lib/librte_eal/common/eal_common_soc.c          | 34 +++++++++++++++++++++++++
>>  lib/librte_eal/common/include/rte_soc.h         |  9 +++++++
>>  lib/librte_eal/linuxapp/eal/rte_eal_version.map |  2 ++
>>  4 files changed, 47 insertions(+)
>>
>> diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
>> index cf6fb8e..86e3cfd 100644
>> --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
>> +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
>> @@ -171,11 +171,13 @@ DPDK_16.11 {
>>         rte_eal_dev_attach;
>>         rte_eal_dev_detach;
>>         rte_eal_map_resource;
>> +       rte_eal_soc_dump;
>>         rte_eal_soc_register;
>>         rte_eal_soc_unregister;
>>         rte_eal_unmap_resource;
>>         rte_eal_vdrv_register;
>>         rte_eal_vdrv_unregister;
>> +       soc_device_list;
>>         soc_driver_list;
>>
>>  } DPDK_16.07;
>> diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
>> index 56135ed..5dcddc5 100644
>> --- a/lib/librte_eal/common/eal_common_soc.c
>> +++ b/lib/librte_eal/common/eal_common_soc.c
>> @@ -31,6 +31,8 @@
>>   *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>>   */
>>
>> +#include <stddef.h>
>> +#include <stdio.h>
>>  #include <sys/queue.h>
>>
>>  #include <rte_log.h>
>> @@ -40,6 +42,38 @@
>>  /* Global SoC driver list */
>>  struct soc_driver_list soc_driver_list =
>>         TAILQ_HEAD_INITIALIZER(soc_driver_list);
>> +struct soc_device_list soc_device_list =
>> +       TAILQ_HEAD_INITIALIZER(soc_device_list);
>> +
>> +/* dump one device */
>> +static int
>> +soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
>> +{
>> +       int i;
>> +
>> +       fprintf(f, "%s", dev->addr.name);
>> +       fprintf(f, " - fdt_path: %s\n",
>> +                       dev->addr.fdt_path ? dev->addr.fdt_path : "(none)");
>> +
>> +       for (i = 0; dev->id && dev->id[i].compatible; ++i)
>> +               fprintf(f, "   %s\n", dev->id[i].compatible);
>> +
>> +       return 0;
>> +}
>> +
>> +/* dump devices on the bus to an output stream */
>> +void
>> +rte_eal_soc_dump(FILE *f)
>> +{
>> +       struct rte_soc_device *dev = NULL;
>> +
>> +       if (!f)
>> +               return;
>> +
>> +       TAILQ_FOREACH(dev, &soc_device_list, next) {
>> +               soc_dump_one_device(f, dev);
>> +       }
>> +}
>>
>>  /* register a driver */
>>  void
>> diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
>> index 23b06a9..347e611 100644
>> --- a/lib/librte_eal/common/include/rte_soc.h
>> +++ b/lib/librte_eal/common/include/rte_soc.h
>> @@ -56,8 +56,12 @@ extern "C" {
>>
>>  extern struct soc_driver_list soc_driver_list;
>>  /**< Global list of SoC Drivers */
>> +extern struct soc_device_list soc_device_list;
>> +/**< Global list of SoC Devices */
>>
>>  TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
>> +TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
>> +
>>
>>  struct rte_soc_id {
>>         const char *compatible; /**< OF compatible specification */
>> @@ -142,6 +146,11 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
>>  }
>>
>>  /**
>> + * Dump discovered SoC devices.
>> + */
>> +void rte_eal_soc_dump(FILE *f);
>
> If it is to dump device information (not driver), is it proper to
> rename it rte_eal_soc_device_dump()?

Well, 'SoC'=='device' in this context. Isn't it?
In which case, 'soc_device' is just redundant/reuse of a descriptive word.

Or, on a second thought, 'SoC' represents a bus type here. In which 
case, this name sounds better. This would also warrant 
rte_eal_soc_register->rte_eal_soc_device_register.

But, if I need to keep it in sync with PCI (rte_eal_pci_register), I 
think original naming is apt.
I prefer continuing with existing (rte_eal_soc_dump) for this reason.

>
>> +
>> +/**
>>   * Register a SoC driver.
>>   */
>>  void rte_eal_soc_register(struct rte_soc_driver *driver);
>> diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
>> index ab6b985..0155025 100644
>> --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
>> +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
>> @@ -175,11 +175,13 @@ DPDK_16.11 {
>>         rte_eal_dev_attach;
>>         rte_eal_dev_detach;
>>         rte_eal_map_resource;
>> +       rte_eal_soc_dump;
>>         rte_eal_soc_register;
>>         rte_eal_soc_unregister;
>>         rte_eal_unmap_resource;
>>         rte_eal_vdrv_register;
>>         rte_eal_vdrv_unregister;
>> +       soc_device_list;
>>         soc_driver_list;
>>
>>  } DPDK_16.07;
>> --
>> 2.7.4
>>
>

-
Shreyansh

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

* Re: [PATCH v7 11/21] eal/soc: implement probing of drivers
  2016-11-10  3:30             ` Jianbo Liu
@ 2016-11-10  6:10               ` Shreyansh Jain
  2016-11-10  7:41                 ` Jianbo Liu
  0 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-11-10  6:10 UTC (permalink / raw)
  To: Jianbo Liu; +Cc: dev, Thomas Monjalon, Jan Viktorin

On Thursday 10 November 2016 09:00 AM, Jianbo Liu wrote:
> On 28 October 2016 at 20:26, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
>> Each SoC PMD registers a set of callback for scanning its own bus/infra and
>> matching devices to drivers when probe is called.
>> This patch introduces the infra for calls to SoC scan on rte_eal_soc_init()
>> and match on rte_eal_soc_probe().
>>
>> Patch also adds test case for scan and probe.
>>
>> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
>> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>> --
>> v4:
>>  - Update test_soc for descriptive test function names
>>  - Comments over test functions
>>  - devinit and devuninint --> probe/remove
>>  - RTE_VERIFY at some places
>> ---
>>  app/test/test_soc.c                             | 205 ++++++++++++++++++++++-
>>  lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   4 +
>>  lib/librte_eal/common/eal_common_soc.c          | 213 +++++++++++++++++++++++-
>>  lib/librte_eal/common/include/rte_soc.h         |  75 ++++++++-
>>  lib/librte_eal/linuxapp/eal/eal.c               |   5 +
>>  lib/librte_eal/linuxapp/eal/eal_soc.c           |  21 ++-
>>  lib/librte_eal/linuxapp/eal/rte_eal_version.map |   4 +
>>  7 files changed, 519 insertions(+), 8 deletions(-)
>>
> ......
>
>>  /**
>> + * SoC device scan callback, called from rte_eal_soc_init.
>> + * For various SoC, the bus on which devices are attached maynot be compliant
>> + * to a standard platform (or platform bus itself). In which case, extra
>> + * steps are implemented by PMD to scan over the bus and add devices to SoC
>> + * device list.
>> + */
>> +typedef void (soc_scan_t)(void);
>
> I'm still not sure about the purpose of soc_scan, and how to use it.

For each device to be used by DPDK, which cannot be scanned/identified 
using the existing PCI/VDEV methods (sysfs/bus/pci), 'soc_scan_t' 
provides a way for driver to make those devices part of device lists.

Ideally, 'scan' is not a function of a driver. It is a bus function - 
which is missing in this case.

> If it's for each driver, it should at least struct rte_soc_driver * as
> its parameter.

Its for each driver - assuming that each non-PCI driver which implements 
it knows how to find devices which it can control (for example, special 
area in sysfs, or even platform bus).

> If it's for each bus, why it is in rte_soc_driver?

Short answer - lack of a better place. It should be in dev.h probably 
(rte_device/driver) but it would look out of place (as that represents 
PCI devices also which cannot implement it - all PCI devices are scanned 
in one go irrespective of driver)

> I know you will implement bus driver in the future, but we need to
> make it clear for current simplified implementation.

Current implementation makes only a single assumption - that rather than 
relying on EAL for identifying devices (as being done now), next best 
option in existing framework (driver) should have control of finding 
devices.

This is primarily to make the SoC work parallel to PCI implementation 
without much top-down changes in EAL.

Bus model, improvises it by moving this implementation a little above in 
hierarchy - in rte_bus<-rte_driver<-PMD.

I understand your apprehension - 'driver-scanning-for-devices' is indeed 
not correct real world analogy. It is just a place holder for enabling 
those drivers/PMDs which cannot work in absence of the right model.
And that is still work in progress.

>
>> +
>> +/**
>> + * Custom device<=>driver match callback for SoC
>> + * Unlike PCI, SoC devices don't have a fixed definition of device
>> + * identification. PMDs can implement a specific matching function in which
>> + * driver and device objects are provided to perform custom match.
>> + */
>> +typedef int (soc_match_t)(struct rte_soc_driver *, struct rte_soc_device *);
>> +
>> +/**
>>   * A structure describing a SoC driver.
>>   */
>>  struct rte_soc_driver {
>> @@ -104,6 +120,8 @@ struct rte_soc_driver {
>>         struct rte_driver driver;          /**< Inherit core driver. */
>>         soc_probe_t *probe;                /**< Device probe */
>>         soc_remove_t *remove;              /**< Device remove */
>> +       soc_scan_t *scan_fn;               /**< Callback for scanning SoC bus*/
>> +       soc_match_t *match_fn;             /**< Callback to match dev<->drv */
>>         const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
>>  };
>>
>> @@ -146,12 +164,63 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
>>  }
>>
>>  /**
>> + * Default function for matching the Soc driver with device. Each driver can
>> + * either use this function or define their own soc matching function.
>> + * This function relies on the compatible string extracted from sysfs. But,
>> + * a SoC might have different way of identifying its devices. Such SoC can
>> + * override match_fn.
>> + *
>> + * @return
>> + *      0 on success
>> + *     -1 when no match found
>> +  */
>> +int
>> +rte_eal_soc_match_compat(struct rte_soc_driver *drv,
>> +                        struct rte_soc_device *dev);
>> +
>> +/**
>> + * Probe SoC devices for registered drivers.
>> + *
>> + * @return
>> + *     0 on success
>> + *     !0 in case of any failure in probe
>> + */
>> +int rte_eal_soc_probe(void);
>> +
>> +/**
>> + * Probe the single SoC device.
>> + */
>> +int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
>> +
>> +/**
>> + * Close the single SoC device.
>> + *
>> + * Scan the SoC devices and find the SoC device specified by the SoC
>> + * address, then call the remove() function for registered driver
>> + * that has a matching entry in its id_table for discovered device.
>> + *
>> + * @param addr
>> + *     The SoC address to close.
>> + * @return
>> + *   - 0 on success.
>> + *   - Negative on error.
>> + */
>> +int rte_eal_soc_detach(const struct rte_soc_addr *addr);
>> +
>> +/**
>>   * Dump discovered SoC devices.
>> + *
>> + * @param f
>> + *     File to dump device info in.
>>   */
>>  void rte_eal_soc_dump(FILE *f);
>>
>>  /**
>>   * Register a SoC driver.
>> + *
>> + * @param driver
>> + *     Object for SoC driver to register
>> + * @return void
>>   */
>>  void rte_eal_soc_register(struct rte_soc_driver *driver);
>>
>> @@ -167,6 +236,10 @@ RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
>>
>>  /**
>>   * Unregister a SoC driver.
>> + *
>> + * @param driver
>> + *     Object for SoC driver to unregister
>> + * @return void
>>   */
>>  void rte_eal_soc_unregister(struct rte_soc_driver *driver);
>>
>> diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
>> index 098ba02..bd775f3 100644
>> --- a/lib/librte_eal/linuxapp/eal/eal.c
>> +++ b/lib/librte_eal/linuxapp/eal/eal.c
>> @@ -70,6 +70,7 @@
>>  #include <rte_cpuflags.h>
>>  #include <rte_interrupts.h>
>>  #include <rte_pci.h>
>> +#include <rte_soc.h>
>>  #include <rte_dev.h>
>>  #include <rte_devargs.h>
>>  #include <rte_common.h>
>> @@ -890,6 +891,10 @@ rte_eal_init(int argc, char **argv)
>>         if (rte_eal_pci_probe())
>>                 rte_panic("Cannot probe PCI\n");
>>
>> +       /* Probe & Initialize SoC devices */
>> +       if (rte_eal_soc_probe())
>> +               rte_panic("Cannot probe SoC\n");
>> +
>>         rte_eal_mcfg_complete();
>>
>>         return fctret;
>> diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
>> index 04848b9..3929a76 100644
>> --- a/lib/librte_eal/linuxapp/eal/eal_soc.c
>> +++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
>> @@ -44,13 +44,28 @@
>>  #include <rte_log.h>
>>  #include <rte_soc.h>
>>
>> -#include "eal_internal_cfg.h"
>> -#include "eal_filesystem.h"
>> -#include "eal_private.h"
>> +#include <eal_internal_cfg.h>
>> +#include <eal_filesystem.h>
>> +#include <eal_private.h>
>>
>>  /* Init the SoC EAL subsystem */
>>  int
>>  rte_eal_soc_init(void)
>>  {
>> +       struct rte_soc_driver *drv;
>> +
>> +       /* SoC is disabled by default */
>> +       if (!internal_config.enable_soc)
>> +               return 0;
>> +
>> +       /* For each registered driver, call their scan routine to perform any
>> +        * custom scan for devices (for example, custom buses)
>> +        */
>> +       TAILQ_FOREACH(drv, &soc_driver_list, next) {
>> +               RTE_VERIFY(drv->scan_fn);
>> +               drv->scan_fn();
>> +               /* Ignore all errors from this */
>> +       }
>> +
>>         return 0;
>>  }
>> diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
>> index 0155025..c28e093 100644
>> --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
>> +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
>> @@ -175,7 +175,11 @@ DPDK_16.11 {
>>         rte_eal_dev_attach;
>>         rte_eal_dev_detach;
>>         rte_eal_map_resource;
>> +       rte_eal_soc_detach;
>>         rte_eal_soc_dump;
>> +       rte_eal_soc_match;
>> +       rte_eal_soc_probe;
>> +       rte_eal_soc_probe_one;
>>         rte_eal_soc_register;
>>         rte_eal_soc_unregister;
>>         rte_eal_unmap_resource;
>> --
>> 2.7.4
>>
>


-- 
-
Shreyansh

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

* Re: [PATCH v7 11/21] eal/soc: implement probing of drivers
  2016-11-10  6:10               ` Shreyansh Jain
@ 2016-11-10  7:41                 ` Jianbo Liu
  2016-11-10  9:10                   ` Shreyansh Jain
  0 siblings, 1 reply; 231+ messages in thread
From: Jianbo Liu @ 2016-11-10  7:41 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, Thomas Monjalon, Jan Viktorin

On 10 November 2016 at 14:10, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
> On Thursday 10 November 2016 09:00 AM, Jianbo Liu wrote:
>>
>> On 28 October 2016 at 20:26, Shreyansh Jain <shreyansh.jain@nxp.com>
>> wrote:
>>>
>>> Each SoC PMD registers a set of callback for scanning its own bus/infra
>>> and
>>> matching devices to drivers when probe is called.
>>> This patch introduces the infra for calls to SoC scan on
>>> rte_eal_soc_init()
>>> and match on rte_eal_soc_probe().
>>>
>>> Patch also adds test case for scan and probe.
>>>
>>> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
>>> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
>>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>>> --
>>> v4:
>>>  - Update test_soc for descriptive test function names
>>>  - Comments over test functions
>>>  - devinit and devuninint --> probe/remove
>>>  - RTE_VERIFY at some places
>>> ---
>>>  app/test/test_soc.c                             | 205
>>> ++++++++++++++++++++++-
>>>  lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   4 +
>>>  lib/librte_eal/common/eal_common_soc.c          | 213
>>> +++++++++++++++++++++++-
>>>  lib/librte_eal/common/include/rte_soc.h         |  75 ++++++++-
>>>  lib/librte_eal/linuxapp/eal/eal.c               |   5 +
>>>  lib/librte_eal/linuxapp/eal/eal_soc.c           |  21 ++-
>>>  lib/librte_eal/linuxapp/eal/rte_eal_version.map |   4 +
>>>  7 files changed, 519 insertions(+), 8 deletions(-)
>>>
>> ......
>>
>>>  /**
>>> + * SoC device scan callback, called from rte_eal_soc_init.
>>> + * For various SoC, the bus on which devices are attached maynot be
>>> compliant
>>> + * to a standard platform (or platform bus itself). In which case, extra
>>> + * steps are implemented by PMD to scan over the bus and add devices to
>>> SoC
>>> + * device list.
>>> + */
>>> +typedef void (soc_scan_t)(void);
>>
>>
>> I'm still not sure about the purpose of soc_scan, and how to use it.
>
>
> For each device to be used by DPDK, which cannot be scanned/identified using
> the existing PCI/VDEV methods (sysfs/bus/pci), 'soc_scan_t' provides a way
> for driver to make those devices part of device lists.
>
> Ideally, 'scan' is not a function of a driver. It is a bus function - which
> is missing in this case.
>
>> If it's for each driver, it should at least struct rte_soc_driver * as
>> its parameter.
>
>
> Its for each driver - assuming that each non-PCI driver which implements it
> knows how to find devices which it can control (for example, special area in
> sysfs, or even platform bus).
>

Considering there are several drivers in a platform bus, each driver
call the scan function, like the rte_eal_soc_scan_platform_bus() you
implemented.
The first will add soc devices to the list, but the remaining calls
are redundant.

The other issue is adding the driver parameter. Do you need extra
information from driver to scan the bus?

>> If it's for each bus, why it is in rte_soc_driver?
>
>
> Short answer - lack of a better place. It should be in dev.h probably
> (rte_device/driver) but it would look out of place (as that represents PCI
> devices also which cannot implement it - all PCI devices are scanned in one
> go irrespective of driver)
>
>> I know you will implement bus driver in the future, but we need to
>> make it clear for current simplified implementation.
>
>
> Current implementation makes only a single assumption - that rather than
> relying on EAL for identifying devices (as being done now), next best option
> in existing framework (driver) should have control of finding devices.
>
> This is primarily to make the SoC work parallel to PCI implementation
> without much top-down changes in EAL.
>
> Bus model, improvises it by moving this implementation a little above in
> hierarchy - in rte_bus<-rte_driver<-PMD.
>
> I understand your apprehension - 'driver-scanning-for-devices' is indeed not
> correct real world analogy. It is just a place holder for enabling those
> drivers/PMDs which cannot work in absence of the right model.
> And that is still work in progress.
>
>
>>
>>> +
>>> +/**
>>> + * Custom device<=>driver match callback for SoC
>>> + * Unlike PCI, SoC devices don't have a fixed definition of device
>>> + * identification. PMDs can implement a specific matching function in
>>> which
>>> + * driver and device objects are provided to perform custom match.
>>> + */
>>> +typedef int (soc_match_t)(struct rte_soc_driver *, struct rte_soc_device
>>> *);
>>> +
>>> +/**
>>>   * A structure describing a SoC driver.
>>>   */
>>>  struct rte_soc_driver {
>>> @@ -104,6 +120,8 @@ struct rte_soc_driver {
>>>         struct rte_driver driver;          /**< Inherit core driver. */
>>>         soc_probe_t *probe;                /**< Device probe */
>>>         soc_remove_t *remove;              /**< Device remove */
>>> +       soc_scan_t *scan_fn;               /**< Callback for scanning SoC
>>> bus*/
>>> +       soc_match_t *match_fn;             /**< Callback to match
>>> dev<->drv */
>>>         const struct rte_soc_id *id_table; /**< ID table, NULL terminated
>>> */
>>>  };
>>>
>>> @@ -146,12 +164,63 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr
>>> *a0,
>>>  }
>>>
>>>  /**
>>> + * Default function for matching the Soc driver with device. Each driver
>>> can
>>> + * either use this function or define their own soc matching function.
>>> + * This function relies on the compatible string extracted from sysfs.
>>> But,
>>> + * a SoC might have different way of identifying its devices. Such SoC
>>> can
>>> + * override match_fn.
>>> + *
>>> + * @return
>>> + *      0 on success
>>> + *     -1 when no match found
>>> +  */
>>> +int
>>> +rte_eal_soc_match_compat(struct rte_soc_driver *drv,
>>> +                        struct rte_soc_device *dev);
>>> +
>>> +/**
>>> + * Probe SoC devices for registered drivers.
>>> + *
>>> + * @return
>>> + *     0 on success
>>> + *     !0 in case of any failure in probe
>>> + */
>>> +int rte_eal_soc_probe(void);
>>> +
>>> +/**
>>> + * Probe the single SoC device.
>>> + */
>>> +int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
>>> +
>>> +/**
>>> + * Close the single SoC device.
>>> + *
>>> + * Scan the SoC devices and find the SoC device specified by the SoC
>>> + * address, then call the remove() function for registered driver
>>> + * that has a matching entry in its id_table for discovered device.
>>> + *
>>> + * @param addr
>>> + *     The SoC address to close.
>>> + * @return
>>> + *   - 0 on success.
>>> + *   - Negative on error.
>>> + */
>>> +int rte_eal_soc_detach(const struct rte_soc_addr *addr);
>>> +
>>> +/**
>>>   * Dump discovered SoC devices.
>>> + *
>>> + * @param f
>>> + *     File to dump device info in.
>>>   */
>>>  void rte_eal_soc_dump(FILE *f);
>>>
>>>  /**
>>>   * Register a SoC driver.
>>> + *
>>> + * @param driver
>>> + *     Object for SoC driver to register
>>> + * @return void
>>>   */
>>>  void rte_eal_soc_register(struct rte_soc_driver *driver);
>>>
>>> @@ -167,6 +236,10 @@ RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
>>>
>>>  /**
>>>   * Unregister a SoC driver.
>>> + *
>>> + * @param driver
>>> + *     Object for SoC driver to unregister
>>> + * @return void
>>>   */
>>>  void rte_eal_soc_unregister(struct rte_soc_driver *driver);
>>>
>>> diff --git a/lib/librte_eal/linuxapp/eal/eal.c
>>> b/lib/librte_eal/linuxapp/eal/eal.c
>>> index 098ba02..bd775f3 100644
>>> --- a/lib/librte_eal/linuxapp/eal/eal.c
>>> +++ b/lib/librte_eal/linuxapp/eal/eal.c
>>> @@ -70,6 +70,7 @@
>>>  #include <rte_cpuflags.h>
>>>  #include <rte_interrupts.h>
>>>  #include <rte_pci.h>
>>> +#include <rte_soc.h>
>>>  #include <rte_dev.h>
>>>  #include <rte_devargs.h>
>>>  #include <rte_common.h>
>>> @@ -890,6 +891,10 @@ rte_eal_init(int argc, char **argv)
>>>         if (rte_eal_pci_probe())
>>>                 rte_panic("Cannot probe PCI\n");
>>>
>>> +       /* Probe & Initialize SoC devices */
>>> +       if (rte_eal_soc_probe())
>>> +               rte_panic("Cannot probe SoC\n");
>>> +
>>>         rte_eal_mcfg_complete();
>>>
>>>         return fctret;
>>> diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c
>>> b/lib/librte_eal/linuxapp/eal/eal_soc.c
>>> index 04848b9..3929a76 100644
>>> --- a/lib/librte_eal/linuxapp/eal/eal_soc.c
>>> +++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
>>> @@ -44,13 +44,28 @@
>>>  #include <rte_log.h>
>>>  #include <rte_soc.h>
>>>
>>> -#include "eal_internal_cfg.h"
>>> -#include "eal_filesystem.h"
>>> -#include "eal_private.h"
>>> +#include <eal_internal_cfg.h>
>>> +#include <eal_filesystem.h>
>>> +#include <eal_private.h>
>>>
>>>  /* Init the SoC EAL subsystem */
>>>  int
>>>  rte_eal_soc_init(void)
>>>  {
>>> +       struct rte_soc_driver *drv;
>>> +
>>> +       /* SoC is disabled by default */
>>> +       if (!internal_config.enable_soc)
>>> +               return 0;
>>> +
>>> +       /* For each registered driver, call their scan routine to perform
>>> any
>>> +        * custom scan for devices (for example, custom buses)
>>> +        */
>>> +       TAILQ_FOREACH(drv, &soc_driver_list, next) {
>>> +               RTE_VERIFY(drv->scan_fn);
>>> +               drv->scan_fn();
>>> +               /* Ignore all errors from this */
>>> +       }
>>> +
>>>         return 0;
>>>  }
>>> diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
>>> b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
>>> index 0155025..c28e093 100644
>>> --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
>>> +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
>>> @@ -175,7 +175,11 @@ DPDK_16.11 {
>>>         rte_eal_dev_attach;
>>>         rte_eal_dev_detach;
>>>         rte_eal_map_resource;
>>> +       rte_eal_soc_detach;
>>>         rte_eal_soc_dump;
>>> +       rte_eal_soc_match;
>>> +       rte_eal_soc_probe;
>>> +       rte_eal_soc_probe_one;
>>>         rte_eal_soc_register;
>>>         rte_eal_soc_unregister;
>>>         rte_eal_unmap_resource;
>>> --
>>> 2.7.4
>>>
>>
>
>
> --
> -
> Shreyansh

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

* Re: [PATCH v7 11/21] eal/soc: implement probing of drivers
  2016-11-10  7:41                 ` Jianbo Liu
@ 2016-11-10  9:10                   ` Shreyansh Jain
  2016-11-10  9:26                     ` Thomas Monjalon
  0 siblings, 1 reply; 231+ messages in thread
From: Shreyansh Jain @ 2016-11-10  9:10 UTC (permalink / raw)
  To: Jianbo Liu; +Cc: dev, Thomas Monjalon, Jan Viktorin

On Thursday 10 November 2016 01:11 PM, Jianbo Liu wrote:
> On 10 November 2016 at 14:10, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
>> On Thursday 10 November 2016 09:00 AM, Jianbo Liu wrote:
>>>
>>> On 28 October 2016 at 20:26, Shreyansh Jain <shreyansh.jain@nxp.com>
>>> wrote:
>>>>
>>>> Each SoC PMD registers a set of callback for scanning its own bus/infra
>>>> and
>>>> matching devices to drivers when probe is called.
>>>> This patch introduces the infra for calls to SoC scan on
>>>> rte_eal_soc_init()
>>>> and match on rte_eal_soc_probe().
>>>>
>>>> Patch also adds test case for scan and probe.
>>>>
>>>> Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
>>>> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
>>>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>>>> --
>>>> v4:
>>>>  - Update test_soc for descriptive test function names
>>>>  - Comments over test functions
>>>>  - devinit and devuninint --> probe/remove
>>>>  - RTE_VERIFY at some places
>>>> ---
>>>>  app/test/test_soc.c                             | 205
>>>> ++++++++++++++++++++++-
>>>>  lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   4 +
>>>>  lib/librte_eal/common/eal_common_soc.c          | 213
>>>> +++++++++++++++++++++++-
>>>>  lib/librte_eal/common/include/rte_soc.h         |  75 ++++++++-
>>>>  lib/librte_eal/linuxapp/eal/eal.c               |   5 +
>>>>  lib/librte_eal/linuxapp/eal/eal_soc.c           |  21 ++-
>>>>  lib/librte_eal/linuxapp/eal/rte_eal_version.map |   4 +
>>>>  7 files changed, 519 insertions(+), 8 deletions(-)
>>>>
>>> ......
>>>
>>>>  /**
>>>> + * SoC device scan callback, called from rte_eal_soc_init.
>>>> + * For various SoC, the bus on which devices are attached maynot be
>>>> compliant
>>>> + * to a standard platform (or platform bus itself). In which case, extra
>>>> + * steps are implemented by PMD to scan over the bus and add devices to
>>>> SoC
>>>> + * device list.
>>>> + */
>>>> +typedef void (soc_scan_t)(void);
>>>
>>>
>>> I'm still not sure about the purpose of soc_scan, and how to use it.
>>
>>
>> For each device to be used by DPDK, which cannot be scanned/identified using
>> the existing PCI/VDEV methods (sysfs/bus/pci), 'soc_scan_t' provides a way
>> for driver to make those devices part of device lists.
>>
>> Ideally, 'scan' is not a function of a driver. It is a bus function - which
>> is missing in this case.
>>
>>> If it's for each driver, it should at least struct rte_soc_driver * as
>>> its parameter.
>>
>>
>> Its for each driver - assuming that each non-PCI driver which implements it
>> knows how to find devices which it can control (for example, special area in
>> sysfs, or even platform bus).
>>
>
> Considering there are several drivers in a platform bus, each driver
> call the scan function, like the rte_eal_soc_scan_platform_bus() you
> implemented.
> The first will add soc devices to the list, but the remaining calls
> are redundant.

Indeed. This is exactly the issue we will face if we try and move this 
scan/match logic to PCI - all devices are identified in one step.

There is a difference in principle here:
A SoC device/driver combination is essentially focused towards a single 
type of bus<->devices. For example, a NXP PMD would implement a scan 
function which would scan for all devices on NXP's bus. This would not 
conflict with another XYZ SoC PMD which scans its specific bus.

There is caveat to this - the platform bus. There can be multiple 
drivers which can serve platform bus compliant devices. First 
PMD->scan() initiated for such a bus/device would leave all other scans 
redundant.

More similar caveats will come if we consider somewhat generic buses. At 
least I couldn't find any interest for such devices in the ML when I 
picked this series (from where Jan left it).

Probably when more common type of PMDs come in, some default scan 
implementation can check for skipping those devices which are already 
added. It would be redundant but harmless.

>
> The other issue is adding the driver parameter. Do you need extra
> information from driver to scan the bus?
>
>>> If it's for each bus, why it is in rte_soc_driver?
>>
>>
>> Short answer - lack of a better place. It should be in dev.h probably
>> (rte_device/driver) but it would look out of place (as that represents PCI
>> devices also which cannot implement it - all PCI devices are scanned in one
>> go irrespective of driver)
>>
>>> I know you will implement bus driver in the future, but we need to
>>> make it clear for current simplified implementation.
>>
>>
>> Current implementation makes only a single assumption - that rather than
>> relying on EAL for identifying devices (as being done now), next best option
>> in existing framework (driver) should have control of finding devices.
>>
>> This is primarily to make the SoC work parallel to PCI implementation
>> without much top-down changes in EAL.
>>
>> Bus model, improvises it by moving this implementation a little above in
>> hierarchy - in rte_bus<-rte_driver<-PMD.
>>
>> I understand your apprehension - 'driver-scanning-for-devices' is indeed not
>> correct real world analogy. It is just a place holder for enabling those
>> drivers/PMDs which cannot work in absence of the right model.
>> And that is still work in progress.
>>
>>
>>>
>>>> +
>>>> +/**
>>>> + * Custom device<=>driver match callback for SoC
>>>> + * Unlike PCI, SoC devices don't have a fixed definition of device
>>>> + * identification. PMDs can implement a specific matching function in
>>>> which
>>>> + * driver and device objects are provided to perform custom match.
>>>> + */
>>>> +typedef int (soc_match_t)(struct rte_soc_driver *, struct rte_soc_device
>>>> *);
>>>> +
>>>> +/**
>>>>   * A structure describing a SoC driver.
>>>>   */
>>>>  struct rte_soc_driver {
>>>> @@ -104,6 +120,8 @@ struct rte_soc_driver {
>>>>         struct rte_driver driver;          /**< Inherit core driver. */
>>>>         soc_probe_t *probe;                /**< Device probe */
>>>>         soc_remove_t *remove;              /**< Device remove */
>>>> +       soc_scan_t *scan_fn;               /**< Callback for scanning SoC
>>>> bus*/
>>>> +       soc_match_t *match_fn;             /**< Callback to match
>>>> dev<->drv */
>>>>         const struct rte_soc_id *id_table; /**< ID table, NULL terminated
>>>> */
>>>>  };
>>>>
>>>> @@ -146,12 +164,63 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr
>>>> *a0,
>>>>  }
>>>>
>>>>  /**
>>>> + * Default function for matching the Soc driver with device. Each driver
>>>> can
>>>> + * either use this function or define their own soc matching function.
>>>> + * This function relies on the compatible string extracted from sysfs.
>>>> But,
>>>> + * a SoC might have different way of identifying its devices. Such SoC
>>>> can
>>>> + * override match_fn.
>>>> + *
>>>> + * @return
>>>> + *      0 on success
>>>> + *     -1 when no match found
>>>> +  */
>>>> +int
>>>> +rte_eal_soc_match_compat(struct rte_soc_driver *drv,
>>>> +                        struct rte_soc_device *dev);
>>>> +
>>>> +/**
>>>> + * Probe SoC devices for registered drivers.
>>>> + *
>>>> + * @return
>>>> + *     0 on success
>>>> + *     !0 in case of any failure in probe
>>>> + */
>>>> +int rte_eal_soc_probe(void);
>>>> +
>>>> +/**
>>>> + * Probe the single SoC device.
>>>> + */
>>>> +int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
>>>> +
>>>> +/**
>>>> + * Close the single SoC device.
>>>> + *
>>>> + * Scan the SoC devices and find the SoC device specified by the SoC
>>>> + * address, then call the remove() function for registered driver
>>>> + * that has a matching entry in its id_table for discovered device.
>>>> + *
>>>> + * @param addr
>>>> + *     The SoC address to close.
>>>> + * @return
>>>> + *   - 0 on success.
>>>> + *   - Negative on error.
>>>> + */
>>>> +int rte_eal_soc_detach(const struct rte_soc_addr *addr);
>>>> +
>>>> +/**
>>>>   * Dump discovered SoC devices.
>>>> + *
>>>> + * @param f
>>>> + *     File to dump device info in.
>>>>   */
>>>>  void rte_eal_soc_dump(FILE *f);
>>>>
>>>>  /**
>>>>   * Register a SoC driver.
>>>> + *
>>>> + * @param driver
>>>> + *     Object for SoC driver to register
>>>> + * @return void
>>>>   */
>>>>  void rte_eal_soc_register(struct rte_soc_driver *driver);
>>>>
>>>> @@ -167,6 +236,10 @@ RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
>>>>
>>>>  /**
>>>>   * Unregister a SoC driver.
>>>> + *
>>>> + * @param driver
>>>> + *     Object for SoC driver to unregister
>>>> + * @return void
>>>>   */
>>>>  void rte_eal_soc_unregister(struct rte_soc_driver *driver);
>>>>
>>>> diff --git a/lib/librte_eal/linuxapp/eal/eal.c
>>>> b/lib/librte_eal/linuxapp/eal/eal.c
>>>> index 098ba02..bd775f3 100644
>>>> --- a/lib/librte_eal/linuxapp/eal/eal.c
>>>> +++ b/lib/librte_eal/linuxapp/eal/eal.c
>>>> @@ -70,6 +70,7 @@
>>>>  #include <rte_cpuflags.h>
>>>>  #include <rte_interrupts.h>
>>>>  #include <rte_pci.h>
>>>> +#include <rte_soc.h>
>>>>  #include <rte_dev.h>
>>>>  #include <rte_devargs.h>
>>>>  #include <rte_common.h>
>>>> @@ -890,6 +891,10 @@ rte_eal_init(int argc, char **argv)
>>>>         if (rte_eal_pci_probe())
>>>>                 rte_panic("Cannot probe PCI\n");
>>>>
>>>> +       /* Probe & Initialize SoC devices */
>>>> +       if (rte_eal_soc_probe())
>>>> +               rte_panic("Cannot probe SoC\n");
>>>> +
>>>>         rte_eal_mcfg_complete();
>>>>
>>>>         return fctret;
>>>> diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c
>>>> b/lib/librte_eal/linuxapp/eal/eal_soc.c
>>>> index 04848b9..3929a76 100644
>>>> --- a/lib/librte_eal/linuxapp/eal/eal_soc.c
>>>> +++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
>>>> @@ -44,13 +44,28 @@
>>>>  #include <rte_log.h>
>>>>  #include <rte_soc.h>
>>>>
>>>> -#include "eal_internal_cfg.h"
>>>> -#include "eal_filesystem.h"
>>>> -#include "eal_private.h"
>>>> +#include <eal_internal_cfg.h>
>>>> +#include <eal_filesystem.h>
>>>> +#include <eal_private.h>
>>>>
>>>>  /* Init the SoC EAL subsystem */
>>>>  int
>>>>  rte_eal_soc_init(void)
>>>>  {
>>>> +       struct rte_soc_driver *drv;
>>>> +
>>>> +       /* SoC is disabled by default */
>>>> +       if (!internal_config.enable_soc)
>>>> +               return 0;
>>>> +
>>>> +       /* For each registered driver, call their scan routine to perform
>>>> any
>>>> +        * custom scan for devices (for example, custom buses)
>>>> +        */
>>>> +       TAILQ_FOREACH(drv, &soc_driver_list, next) {
>>>> +               RTE_VERIFY(drv->scan_fn);
>>>> +               drv->scan_fn();
>>>> +               /* Ignore all errors from this */
>>>> +       }
>>>> +
>>>>         return 0;
>>>>  }
>>>> diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
>>>> b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
>>>> index 0155025..c28e093 100644
>>>> --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
>>>> +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
>>>> @@ -175,7 +175,11 @@ DPDK_16.11 {
>>>>         rte_eal_dev_attach;
>>>>         rte_eal_dev_detach;
>>>>         rte_eal_map_resource;
>>>> +       rte_eal_soc_detach;
>>>>         rte_eal_soc_dump;
>>>> +       rte_eal_soc_match;
>>>> +       rte_eal_soc_probe;
>>>> +       rte_eal_soc_probe_one;
>>>>         rte_eal_soc_register;
>>>>         rte_eal_soc_unregister;
>>>>         rte_eal_unmap_resource;
>>>> --
>>>> 2.7.4
>>>>
>>>
>>
>>
>> --
>> -
>> Shreyansh
>


-- 
-
Shreyansh

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

* Re: [PATCH v7 11/21] eal/soc: implement probing of drivers
  2016-11-10  9:10                   ` Shreyansh Jain
@ 2016-11-10  9:26                     ` Thomas Monjalon
  2016-11-11  1:58                       ` Jianbo Liu
  2016-11-11  6:04                       ` Shreyansh Jain
  0 siblings, 2 replies; 231+ messages in thread
From: Thomas Monjalon @ 2016-11-10  9:26 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: Jianbo Liu, dev, Jan Viktorin, david.marchand

2016-11-10 14:40, Shreyansh Jain:
> On Thursday 10 November 2016 01:11 PM, Jianbo Liu wrote:
> > On 10 November 2016 at 14:10, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
> >> On Thursday 10 November 2016 09:00 AM, Jianbo Liu wrote:
> >>> I'm still not sure about the purpose of soc_scan, and how to use it.
> >>
> >>
> >> For each device to be used by DPDK, which cannot be scanned/identified using
> >> the existing PCI/VDEV methods (sysfs/bus/pci), 'soc_scan_t' provides a way
> >> for driver to make those devices part of device lists.
> >>
> >> Ideally, 'scan' is not a function of a driver. It is a bus function - which
> >> is missing in this case.
> >>
> >>> If it's for each driver, it should at least struct rte_soc_driver * as
> >>> its parameter.
> >>
> >>
> >> Its for each driver - assuming that each non-PCI driver which implements it
> >> knows how to find devices which it can control (for example, special area in
> >> sysfs, or even platform bus).
> >>
> >
> > Considering there are several drivers in a platform bus, each driver
> > call the scan function, like the rte_eal_soc_scan_platform_bus() you
> > implemented.
> > The first will add soc devices to the list, but the remaining calls
> > are redundant.
> 
> Indeed. This is exactly the issue we will face if we try and move this 
> scan/match logic to PCI - all devices are identified in one step.
> 
> There is a difference in principle here:
> A SoC device/driver combination is essentially focused towards a single 
> type of bus<->devices. For example, a NXP PMD would implement a scan 
> function which would scan for all devices on NXP's bus. This would not 
> conflict with another XYZ SoC PMD which scans its specific bus.
> 
> There is caveat to this - the platform bus. There can be multiple 
> drivers which can serve platform bus compliant devices. First 
> PMD->scan() initiated for such a bus/device would leave all other scans 
> redundant.
> 
> More similar caveats will come if we consider somewhat generic buses. At 
> least I couldn't find any interest for such devices in the ML when I 
> picked this series (from where Jan left it).
> 
> Probably when more common type of PMDs come in, some default scan 
> implementation can check for skipping those devices which are already 
> added. It would be redundant but harmless.

If several drivers use the same bus, it means the bus is standard enough
to be implemented in EAL. So the scan function of this bus should be
called only once when calling the generic EAL scan function.

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

* Re: [PATCH v7 11/21] eal/soc: implement probing of drivers
  2016-11-10  9:26                     ` Thomas Monjalon
@ 2016-11-11  1:58                       ` Jianbo Liu
  2016-11-11  6:04                       ` Shreyansh Jain
  1 sibling, 0 replies; 231+ messages in thread
From: Jianbo Liu @ 2016-11-11  1:58 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: Shreyansh Jain, dev, Jan Viktorin, David Marchand

On 10 November 2016 at 17:26, Thomas Monjalon <thomas.monjalon@6wind.com> wrote:
> 2016-11-10 14:40, Shreyansh Jain:
>> On Thursday 10 November 2016 01:11 PM, Jianbo Liu wrote:
>> > On 10 November 2016 at 14:10, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
>> >> On Thursday 10 November 2016 09:00 AM, Jianbo Liu wrote:
>> >>> I'm still not sure about the purpose of soc_scan, and how to use it.
>> >>
>> >>
>> >> For each device to be used by DPDK, which cannot be scanned/identified using
>> >> the existing PCI/VDEV methods (sysfs/bus/pci), 'soc_scan_t' provides a way
>> >> for driver to make those devices part of device lists.
>> >>
>> >> Ideally, 'scan' is not a function of a driver. It is a bus function - which
>> >> is missing in this case.
>> >>
>> >>> If it's for each driver, it should at least struct rte_soc_driver * as
>> >>> its parameter.
>> >>
>> >>
>> >> Its for each driver - assuming that each non-PCI driver which implements it
>> >> knows how to find devices which it can control (for example, special area in
>> >> sysfs, or even platform bus).
>> >>
>> >
>> > Considering there are several drivers in a platform bus, each driver
>> > call the scan function, like the rte_eal_soc_scan_platform_bus() you
>> > implemented.
>> > The first will add soc devices to the list, but the remaining calls
>> > are redundant.
>>
>> Indeed. This is exactly the issue we will face if we try and move this
>> scan/match logic to PCI - all devices are identified in one step.
>>
>> There is a difference in principle here:
>> A SoC device/driver combination is essentially focused towards a single
>> type of bus<->devices. For example, a NXP PMD would implement a scan
>> function which would scan for all devices on NXP's bus. This would not
>> conflict with another XYZ SoC PMD which scans its specific bus.
>>
>> There is caveat to this - the platform bus. There can be multiple
>> drivers which can serve platform bus compliant devices. First
>> PMD->scan() initiated for such a bus/device would leave all other scans
>> redundant.
>>
>> More similar caveats will come if we consider somewhat generic buses. At
>> least I couldn't find any interest for such devices in the ML when I
>> picked this series (from where Jan left it).
>>
>> Probably when more common type of PMDs come in, some default scan
>> implementation can check for skipping those devices which are already
>> added. It would be redundant but harmless.
>
> If several drivers use the same bus, it means the bus is standard enough
> to be implemented in EAL. So the scan function of this bus should be
> called only once when calling the generic EAL scan function.

Agree. rte_eal_soc_scan_platform_bus can be the scanning func for platform bus.

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

* Re: [PATCH v7 11/21] eal/soc: implement probing of drivers
  2016-11-10  9:26                     ` Thomas Monjalon
  2016-11-11  1:58                       ` Jianbo Liu
@ 2016-11-11  6:04                       ` Shreyansh Jain
  1 sibling, 0 replies; 231+ messages in thread
From: Shreyansh Jain @ 2016-11-11  6:04 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: Jianbo Liu, dev, Jan Viktorin, david.marchand

On Thursday 10 November 2016 02:56 PM, Thomas Monjalon wrote:
> 2016-11-10 14:40, Shreyansh Jain:
>> On Thursday 10 November 2016 01:11 PM, Jianbo Liu wrote:
>>> On 10 November 2016 at 14:10, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
>>>> On Thursday 10 November 2016 09:00 AM, Jianbo Liu wrote:
>>>>> I'm still not sure about the purpose of soc_scan, and how to use it.
>>>>
>>>>
>>>> For each device to be used by DPDK, which cannot be scanned/identified using
>>>> the existing PCI/VDEV methods (sysfs/bus/pci), 'soc_scan_t' provides a way
>>>> for driver to make those devices part of device lists.
>>>>
>>>> Ideally, 'scan' is not a function of a driver. It is a bus function - which
>>>> is missing in this case.
>>>>
>>>>> If it's for each driver, it should at least struct rte_soc_driver * as
>>>>> its parameter.
>>>>
>>>>
>>>> Its for each driver - assuming that each non-PCI driver which implements it
>>>> knows how to find devices which it can control (for example, special area in
>>>> sysfs, or even platform bus).
>>>>
>>>
>>> Considering there are several drivers in a platform bus, each driver
>>> call the scan function, like the rte_eal_soc_scan_platform_bus() you
>>> implemented.
>>> The first will add soc devices to the list, but the remaining calls
>>> are redundant.
>>
>> Indeed. This is exactly the issue we will face if we try and move this
>> scan/match logic to PCI - all devices are identified in one step.
>>
>> There is a difference in principle here:
>> A SoC device/driver combination is essentially focused towards a single
>> type of bus<->devices. For example, a NXP PMD would implement a scan
>> function which would scan for all devices on NXP's bus. This would not
>> conflict with another XYZ SoC PMD which scans its specific bus.
>>
>> There is caveat to this - the platform bus. There can be multiple
>> drivers which can serve platform bus compliant devices. First
>> PMD->scan() initiated for such a bus/device would leave all other scans
>> redundant.
>>
>> More similar caveats will come if we consider somewhat generic buses. At
>> least I couldn't find any interest for such devices in the ML when I
>> picked this series (from where Jan left it).
>>
>> Probably when more common type of PMDs come in, some default scan
>> implementation can check for skipping those devices which are already
>> added. It would be redundant but harmless.
>
> If several drivers use the same bus, it means the bus is standard enough
> to be implemented in EAL. So the scan function of this bus should be
> called only once when calling the generic EAL scan function.
>

In the current model, without a bus like object, this can only be 
implemented as a hack. This is because:
- If each driver has its scan, some of them (those on a common bus) 
would have their scan nullified
- Then, EAL would initiate the scan on their behalf. (rte_eal_init)
- Whereas, for those drivers which are 'special' scan, EAL would have to 
call each driver's scan.
- This selection is manual code change (nullifying the scan function).
- And then, EAL would have various 'generic' scan's chained together 
other than driver->scan().

A cleaner model would have been that EAL always calls the drivers->scan().

Obviously, this issue vanishes as soon as we have the bus->scan() like 
implementation where a bus would represent multiple devices/drivers.

_________
Shreyansh

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

end of thread, other threads:[~2016-11-11  6:01 UTC | newest]

Thread overview: 231+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
2016-01-01 21:05 ` [RFC 1/7] eal/common: define rte_soc_* related common interface Jan Viktorin
2016-01-02 18:01   ` Stephen Hemminger
2016-01-02 18:35     ` Wiles, Keith
2016-01-02 18:52       ` Jan Viktorin
2016-01-02 19:13         ` Wiles, Keith
2016-01-02 19:14         ` Stephen Hemminger
2016-01-02 19:22           ` Wiles, Keith
2016-01-02 18:45     ` Jan Viktorin
2016-01-03 17:12       ` Jan Viktorin
2016-01-04 15:21         ` Wiles, Keith
2016-01-01 21:05 ` [RFC 2/7] eal: introduce --no-soc option Jan Viktorin
2016-01-01 21:05 ` [RFC 3/7] eal: add common part of the SoC infra Jan Viktorin
2016-01-01 21:05 ` [RFC 4/7] eal/linuxapp: support SoC infra in linuxapp Jan Viktorin
2016-01-01 21:05 ` [RFC 5/7] eal: init SoC infra on rte_eal_init Jan Viktorin
2016-01-01 21:05 ` [RFC 6/7] eal/soc: make SoC infra testable on any platform Jan Viktorin
2016-01-01 21:05 ` [RFC 7/7] app/test: add SoC infra probe/detach test Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 00/28] Support non-PCI devices Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 01/28] eal: make enum rte_kernel_driver non-PCI specific Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 02/28] eal: extract function eal_parse_sysfs_valuef Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 03/28] eal/linux: extract function rte_eal_unbind_kernel_driver Jan Viktorin
2016-05-13  1:22   ` Jianbo Liu
2016-05-17 18:14     ` Jan Viktorin
2016-05-18 13:45       ` Jianbo Liu
2016-05-06 13:47 ` [PATCH v1 04/28] eal/linux: extract function rte_eal_get_kernel_driver_by_path Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 05/28] eal: remove pci_ prefix from pci_(un)map_resource Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 06/28] eal/soc: introduce very essential SoC infra definitions Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 07/28] eal/soc: add rte_eal_soc_register/unregister logic Jan Viktorin
2016-06-13 14:19   ` Shreyansh Jain
2016-06-13 14:25     ` Jan Viktorin
2016-06-15  5:57     ` Shreyansh Jain
2016-06-15  9:50       ` Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 08/28] eal/soc: implement SoC device discovery Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 09/28] eal: introduce --no-soc option Jan Viktorin
2016-05-13  3:28   ` Jianbo Liu
2016-05-17 18:10     ` Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 10/28] eal/soc: init SoC infra from EAL Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 11/28] eal/soc: implement probing of drivers Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 12/28] eal/soc: extend and utilize devargs Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 13/28] eal/soc: update device on probe when already exists Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 14/28] eal/soc: detect assigned kernel driver Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 15/28] eal/soc: map/unmap resources Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 16/28] eal/soc: add intr_handle Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 17/28] eal/soc: hack (const char *) compatible setting Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 18/28] eal/soc: detect numa_node of the rte_soc_device Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 19/28] eal/soc: add drv_flags Jan Viktorin
2016-06-13 14:21   ` Shreyansh Jain
2016-06-13 14:26     ` Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 20/28] eal/soc: map resources conditionally Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 21/28] eal/soc: unbind kernel driver on probe Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 22/28] eal/soc: detect DMA non-coherent devices Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 23/28] eal: define macro container_of Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 24/28] ether: utilize container_of for pci_drv Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 25/28] ether: verify we copy info from a PCI device Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 26/28] ether: extract function eth_dev_get_intr_handle Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 27/28] ether: extract function eth_dev_get_driver_name Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 28/28] ether: support SoC device/driver Jan Viktorin
2016-06-29  9:42   ` Shreyansh jain
2016-07-04 13:04     ` Jan Viktorin
2016-07-04 14:27       ` Shreyansh jain
2016-07-04 14:36         ` Jan Viktorin
2016-07-05  4:42           ` Shreyansh jain
2016-07-05  5:16             ` Jan Viktorin
2016-07-07 10:29               ` Shreyansh jain
2016-07-12  8:45           ` Shreyansh jain
2016-07-12 10:41             ` Jan Viktorin
2016-08-31 11:00 ` [PATCH v2 00/14] Introduce SoC device/driver framework for EAL Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 01/14] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 02/14] eal/soc: add rte_eal_soc_register/unregister logic Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 03/14] eal/soc: Implement SoC device list and dump Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 04/14] eal: introduce --no-soc option Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 05/14] eal/soc: init SoC infra from EAL Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 06/14] eal/soc: implement probing of drivers Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 07/14] eal/soc: extend and utilize devargs Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 08/14] eal/soc: add drv_flags Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 09/14] eal/soc: add intr_handle Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 10/14] ether: utilize container_of for pci_drv Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 11/14] ether: verify we copy info from a PCI device Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 12/14] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 13/14] ether: extract function eth_dev_get_driver_name Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 14/14] ether: Support rte_soc_driver/device for etherdev Shreyansh Jain
2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 01/15] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
2016-09-15 12:58     ` Hunt, David
2016-09-16  6:17       ` Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 02/15] eal/soc: add rte_eal_soc_register/unregister logic Shreyansh Jain
2016-09-15 13:00     ` Hunt, David
2016-09-15 13:09       ` Jan Viktorin
2016-09-15 14:09         ` Thomas Monjalon
2016-09-16  7:32           ` Panu Matilainen
2016-09-09  8:43   ` [PATCH v3 03/15] eal/soc: Implement SoC device list and dump Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 04/15] eal: introduce --no-soc option Shreyansh Jain
2016-09-16 11:36     ` Jan Viktorin
2016-09-16 11:55       ` Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 05/15] eal/soc: init SoC infra from EAL Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 06/15] eal/soc: implement probing of drivers Shreyansh Jain
2016-09-16 12:27     ` Jan Viktorin
2016-09-19  6:47       ` Shreyansh Jain
2016-09-19 11:34         ` Jan Viktorin
2016-09-20  6:46           ` Shreyansh Jain
2016-09-20 10:49             ` Jan Viktorin
2016-09-09  8:43   ` [PATCH v3 07/15] eal/soc: extend and utilize devargs Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 08/15] eal/soc: add drv_flags Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 09/15] eal/soc: add intr_handle Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 10/15] ether: utilize container_of for pci_drv Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 11/15] ether: verify we copy info from a PCI device Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 12/15] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
2016-09-15 13:02     ` Hunt, David
2016-09-15 14:05       ` Thomas Monjalon
2016-09-16  7:17         ` Panu Matilainen
2016-09-09  8:43   ` [PATCH v3 13/15] ether: extract function eth_dev_get_driver_name Shreyansh Jain
2016-09-15 13:03     ` Hunt, David
2016-09-09  8:43   ` [PATCH v3 14/15] ether: Support rte_soc_driver/device for etherdev Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 15/15] eal/crypto: Support rte_soc_driver/device for cryptodev Shreyansh Jain
2016-09-15 12:56   ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Hunt, David
2016-09-16  6:14     ` Shreyansh Jain
2016-09-18  5:58   ` Jianbo Liu
2016-09-18  7:22     ` Jan Viktorin
2016-09-18  8:56       ` Jianbo Liu
2016-09-18  9:17         ` Jan Viktorin
2016-09-18  9:41           ` Hemant Agrawal
2016-09-18 10:04             ` Jan Viktorin
2016-09-19 12:33               ` Hemant Agrawal
2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
2016-10-15 13:44     ` [PATCH v4 01/17] eal: define container macro Shreyansh Jain
2016-10-15 13:44     ` [PATCH v4 02/17] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
2016-10-15 13:44     ` [PATCH v4 03/17] eal/soc: add SoC PMD register/unregister logic Shreyansh Jain
2016-10-15 13:44     ` [PATCH v4 04/17] eal/soc: implement SoC device list and dump Shreyansh Jain
2016-10-15 13:44     ` [PATCH v4 05/17] eal: introduce command line enable SoC option Shreyansh Jain
2016-10-15 13:44     ` [PATCH v4 06/17] eal/soc: init SoC infra from EAL Shreyansh Jain
2016-10-15 13:44     ` [PATCH v4 07/17] eal/soc: implement probing of drivers Shreyansh Jain
2016-10-15 13:44     ` [PATCH v4 08/17] eal/soc: extend and utilize devargs Shreyansh Jain
2016-10-15 13:45     ` [PATCH v4 09/17] eal/soc: add drv_flags Shreyansh Jain
2016-10-15 13:45     ` [PATCH v4 10/17] eal/soc: add intr_handle Shreyansh Jain
2016-10-15 13:45     ` [PATCH v4 11/17] eal/soc: add default scan for Soc devices Shreyansh Jain
2016-10-16  0:56       ` Jan Viktorin
2016-10-16  7:12         ` Shreyansh Jain
2016-10-24 12:08           ` Shreyansh Jain
2016-10-24 16:11             ` Jan Viktorin
2016-10-15 13:45     ` [PATCH v4 12/17] eal/soc: additional features for SoC Shreyansh Jain
2016-10-15 13:45     ` [PATCH v4 13/17] ether: utilize container_of for pci_drv Shreyansh Jain
2016-10-15 13:45     ` [PATCH v4 14/17] ether: verify we copy info from a PCI device Shreyansh Jain
2016-10-15 13:45     ` [PATCH v4 15/17] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
2016-10-15 13:45     ` [PATCH v4 16/17] ether: introduce ethernet dev probe remove Shreyansh Jain
2016-10-15 13:45     ` [PATCH v4 17/17] eal/crypto: Support rte_soc_driver/device for cryptodev Shreyansh Jain
2016-10-15 13:53     ` [PATCH v4 00/17] Introduce SoC device/driver framework for EAL Shreyansh Jain
2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 01/21] eal: generalize PCI kernel driver enum to EAL Shreyansh Jain
2016-10-24 16:13         ` Jan Viktorin
2016-10-24 11:59       ` [PATCH v5 02/21] eal: generalize PCI map/unmap resource " Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 03/21] eal/linux: generalize PCI kernel unbinding driver " Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 04/21] eal/linux: generalize PCI kernel driver extraction " Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 05/21] eal: define container macro Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 06/21] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
2016-10-24 16:21         ` Jan Viktorin
2016-10-25  5:36           ` Shreyansh Jain
2016-10-25 12:38             ` Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 07/21] eal/soc: add SoC PMD register/unregister logic Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 08/21] eal/soc: implement SoC device list and dump Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 09/21] eal: introduce command line enable SoC option Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 10/21] eal/soc: init SoC infra from EAL Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 11/21] eal/soc: implement probing of drivers Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 12/21] eal/soc: extend and utilize devargs Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 13/21] eal/soc: add drv_flags Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 14/21] eal/soc: add intr_handle Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 15/21] eal/soc: add default scan for Soc devices Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 16/21] eal/soc: additional features for SoC Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 17/21] ether: utilize container_of for pci_drv Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 18/21] ether: verify we copy info from a PCI device Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 19/21] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 20/21] ether: introduce ethernet dev probe remove Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 21/21] eal/crypto: Support rte_soc_driver/device for cryptodev Shreyansh Jain
2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 01/21] eal: generalize PCI kernel driver enum to EAL Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 02/21] eal: generalize PCI map/unmap resource " Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 03/21] eal/linux: generalize PCI kernel unbinding driver " Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 04/21] eal/linux: generalize PCI kernel driver extraction " Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 05/21] eal: define container macro Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 06/21] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 07/21] eal/soc: add SoC PMD register/unregister logic Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 08/21] eal/soc: implement SoC device list and dump Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 09/21] eal: introduce command line enable SoC option Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 10/21] eal/soc: init SoC infra from EAL Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 12/21] eal/soc: extend and utilize devargs Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 13/21] eal/soc: add drv_flags Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 14/21] eal/soc: add intr_handle Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 15/21] eal/soc: add default scan for Soc devices Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 16/21] eal/soc: additional features for SoC Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 17/21] ether: utilize container_of for pci_drv Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 18/21] ether: verify we copy info from a PCI device Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 19/21] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 20/21] ether: introduce ethernet dev probe remove Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 21/21] eal/crypto: Support rte_soc_driver/device for cryptodev Shreyansh Jain
2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 01/21] eal: generalize PCI kernel driver enum to EAL Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 02/21] eal: generalize PCI map/unmap resource " Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 03/21] eal/linux: generalize PCI kernel unbinding driver " Shreyansh Jain
2016-11-10  2:24             ` Jianbo Liu
2016-11-10  5:46               ` Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 04/21] eal/linux: generalize PCI kernel driver extraction " Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 05/21] eal: define container macro Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 06/21] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
2016-11-10  4:09             ` Jianbo Liu
2016-11-10  5:51               ` Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 07/21] eal/soc: add SoC PMD register/unregister logic Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 08/21] eal/soc: implement SoC device list and dump Shreyansh Jain
2016-11-10  3:06             ` Jianbo Liu
2016-11-10  5:56               ` Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 09/21] eal: introduce command line enable SoC option Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 10/21] eal/soc: init SoC infra from EAL Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 11/21] eal/soc: implement probing of drivers Shreyansh Jain
2016-11-10  3:30             ` Jianbo Liu
2016-11-10  6:10               ` Shreyansh Jain
2016-11-10  7:41                 ` Jianbo Liu
2016-11-10  9:10                   ` Shreyansh Jain
2016-11-10  9:26                     ` Thomas Monjalon
2016-11-11  1:58                       ` Jianbo Liu
2016-11-11  6:04                       ` Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 12/21] eal/soc: extend and utilize devargs Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 13/21] eal/soc: add drv_flags Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 14/21] eal/soc: add intr_handle Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 15/21] eal/soc: add default scan for Soc devices Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 16/21] eal/soc: additional features for SoC Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 17/21] ether: utilize container_of for pci_drv Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 18/21] ether: verify we copy info from a PCI device Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 19/21] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 20/21] ether: introduce ethernet dev probe remove Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 21/21] eal/crypto: Support rte_soc_driver/device for cryptodev Shreyansh Jain
2016-10-28 12:35           ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
2016-11-09 10:17           ` Thomas Monjalon
2016-11-09 13:36             ` Shreyansh Jain

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.