[dpdk-dev] [RFC 1/7] eal/common: define rte_soc_* related common interface
Jan Viktorin
viktorin at rehivetech.com
Fri Jan 1 22:05:20 CET 2016
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 at 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
More information about the dev
mailing list