From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from wes1-so2.wedos.net (wes1-so2.wedos.net [46.28.106.16]) by dpdk.org (Postfix) with ESMTP id 93ED55A1F for ; Fri, 1 Jan 2016 22:06:52 +0100 (CET) Received: from pcviktorin.fit.vutbr.cz (pcviktorin.fit.vutbr.cz [147.229.13.147]) by wes1-so2.wedos.net (Postfix) with ESMTPSA id 3pXJnS1C19zrG; Fri, 1 Jan 2016 22:06:52 +0100 (CET) From: Jan Viktorin To: dev@dpdk.org Date: Fri, 1 Jan 2016 22:05:20 +0100 Message-Id: <1451682326-5834-2-git-send-email-viktorin@rehivetech.com> X-Mailer: git-send-email 2.6.3 In-Reply-To: <1451682326-5834-1-git-send-email-viktorin@rehivetech.com> References: <1451682326-5834-1-git-send-email-viktorin@rehivetech.com> Cc: Jan Viktorin Subject: [dpdk-dev] [RFC 1/7] eal/common: define rte_soc_* related common interface X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 01 Jan 2016 21:06:52 -0000 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 --- 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 #include #include +#include /** * 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 +#include +#include +#include +#include +#include +#include +#include + +#include + +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