From: Jan Viktorin <vikto...@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 at rehivetech.com> [Shreyansh: update PMD registration method] Signed-off-by: Shreyansh Jain <shreyansh.jain at nxp.com> Signed-off-by: Hemant Agrawal <hemant.agrawal at 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