From patchwork Wed Aug 31 11:00:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shreyansh Jain X-Patchwork-Id: 15563 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 155945591; Wed, 31 Aug 2016 13:01:58 +0200 (CEST) Received: from NAM01-SN1-obe.outbound.protection.outlook.com (mail-sn1nam01on0047.outbound.protection.outlook.com [104.47.32.47]) by dpdk.org (Postfix) with ESMTP id 0A1D747D0 for ; Wed, 31 Aug 2016 13:01:51 +0200 (CEST) Received: from BN3PR0301CA0020.namprd03.prod.outlook.com (10.160.180.158) by BLUPR0301MB2001.namprd03.prod.outlook.com (10.164.22.15) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id 15.1.599.9; Wed, 31 Aug 2016 11:01:45 +0000 Received: from BY2FFO11FD011.protection.gbl (2a01:111:f400:7c0c::101) by BN3PR0301CA0020.outlook.office365.com (2a01:111:e400:4000::30) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id 15.1.599.9 via Frontend Transport; Wed, 31 Aug 2016 11:01:45 +0000 Authentication-Results: spf=fail (sender IP is 192.88.168.50) smtp.mailfrom=nxp.com; nxp.com; dkim=none (message not signed) header.d=none; nxp.com; dmarc=fail action=none header.from=nxp.com; nxp.com; dkim=none (message not signed) header.d=none; Received-SPF: Fail (protection.outlook.com: domain of nxp.com does not designate 192.88.168.50 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.168.50; helo=tx30smr01.am.freescale.net; Received: from tx30smr01.am.freescale.net (192.88.168.50) by BY2FFO11FD011.mail.protection.outlook.com (10.1.14.129) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.587.6 via Frontend Transport; Wed, 31 Aug 2016 11:01:46 +0000 Received: from Tophie.ap.freescale.net ([10.232.14.87]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id u7VB0laX010481; Wed, 31 Aug 2016 04:01:44 -0700 From: Shreyansh Jain To: CC: Shreyansh Jain , Jan Viktorin , Hemant Agrawal Date: Wed, 31 Aug 2016 16:30:27 +0530 Message-ID: <1472641235-23626-7-git-send-email-shreyansh.jain@nxp.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1472641235-23626-1-git-send-email-shreyansh.jain@nxp.com> References: <1451682326-5834-1-git-send-email-viktorin@rehivetech.com> <1472641235-23626-1-git-send-email-shreyansh.jain@nxp.com> X-EOPAttributedMessage: 0 X-Matching-Connectors: 131171149064392603; (91ab9b29-cfa4-454e-5278-08d120cd25b8); () X-Forefront-Antispam-Report: CIP:192.88.168.50; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(6009001)(7916002)(2980300002)(1110001)(1109001)(339900001)(199003)(189002)(77096005)(76176999)(19580405001)(5890100001)(5660300001)(189998001)(2950100001)(19580395003)(87936001)(86362001)(97736004)(626004)(33646002)(50986999)(85426001)(105606002)(2351001)(36756003)(106466001)(229853001)(5003940100001)(8676002)(11100500001)(81156014)(104016004)(4326007)(8666005)(81166006)(68736007)(305945005)(2906002)(110136002)(50226002)(586003)(92566002)(47776003)(7846002)(356003)(50466002)(48376002)(8936002)(7059030); DIR:OUT; SFP:1101; SCL:1; SRVR:BLUPR0301MB2001; H:tx30smr01.am.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BY2FFO11FD011; 1:G+bcA88Pv0hWBLtt+JvX7+a9wUyFEXIeRltBzCZ2+AVCGgQ295C4Kuiw7ECTxx8jrjyeQ0BozFtyCz+9PCRWFOfOnhk64ONPsydYuuT6ZEwioUYboC063ps41v4sHazKy6PQgPMsdgbJtoje8hAxEf6yIWDnooyZAyjw9l/+3tkAo1Xn+j26qzAkTxp28rTSeu4BTOZC67NMAbpLisROtyb0tuMXzqfw3wK3YBQ3NHmq+iiOU+1Nu38PlfVGSpM2YVxEP2wEdz6jRIqGNin/nBV0mLsP30F3bkE1NPhRpdJKDS7VzQupGpAJHp8z42+2TVpX4ciZ6Qkt9OA4nqhxU966Hr0NDQjL2U7JtIhBy0V0YcuW3nS3GxjIi+JKatB74BaZGOsPR6xJVDkZWZQ8sJt1WhhX40XKixi0bseG4yEDeMHtF8Eg5QEutCJ1LQvdSiOoOMNlEYcnEHvM6nmHM9obC4uhW0tjlJzKll0XpnMzOvc1kQo1bysHsXvdqjg8G1Rl35STS+aeL4Bn0L6AmaISihpsq66mRgLOMpCMjQP+gl9D2RZazZsi3OK2EZoLBKVLD9INV0jPVFKdCwnpR2bR9oedoTTf/azIn7Fxj5JQbSpMddKATXhwOeJRBbz8+KYD+OTJcvJ6nSHsrvMSLS7bAxuLAUjk1fY3BVts4DcqGjZOjq92+rmgqSwIXCBY91b1SGVWDkub6MZK2p5c++c82103R2pGwNEx1jOYeZo= MIME-Version: 1.0 X-MS-Office365-Filtering-Correlation-Id: a2d38fa6-afbe-4c46-ee3a-08d3d18e3337 X-Microsoft-Exchange-Diagnostics: 1; BLUPR0301MB2001; 2:YW0PUTYgkEROgXtLe2k8z8jrrSPDJwwNHS0aaHeMayFBcY8tT6nWEFN26WYhObY4rPMx9bh8QcpCakU57VsW0Ysb8ybVPYIhVSvreceC9/mUV/y6AiQVDY+PRP6G+jVW2JguLZAlE0ZPhIVVjONDstckvLKUOG/UY8lsSmNmkgsxz8X1a883MS6cCQeEclG0; 3:IkQqhq1m3BGny16xmvCqIvjZtyKXdgS0GSkPAMiKFBcpbzCXtsW3ntKihHXqzp+ctkFW4Df/hCFIrtT1b4WjgNsIGTKzzVrr7RjDbV+gSS0c5utepn5XK6e0nTDYiNODwLMht9aweApnfx42YCPdJcSbnr142kiNF+GI49xcBu3fg8MZzTeDyq/ik1TVfzmTBRp512U9d5C48zZvjkQxQETXcwih0H0v8xTwpOnnupg=; 25:ColxDw2NUoqrNEkena5oqlLohaDQImbysmat/f2dxyr2JXdtiZVpBzNKAHC3SuqOD88sARZp3Yl83cTkuhjxzQ2je3UymAWoh5CsvP/9E/GzYaO68o1ASnqBZsA257O3PcnoPFHllfKV7bglzdY6FfxZL7jL7z47K4Fv4/88DpndE1HibAmTHHPTFfotqdkllNY5pDoozfyYBv/9SOcNZrx3eWIoqLxOindF6aFIH05650mogV6YCh//8xgmqMVW825iQg2QWGoIqlMIdHjWBjmQ5R5x5+1CfcPQia0oJhF1l0mjUd8DbpFBnT2MZFmOgXEo/mpfDNVIKHGjgzE5VF7Dic/bVN+Y/lgo9xqC5PeKOk/pUvtTcv6g9KPh1bW+1/5IQ6dsaWc9UpFZ8TqoU2iTYFBCtzpqP29f7hPMlxo= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BLUPR0301MB2001; X-Microsoft-Exchange-Diagnostics: 1; BLUPR0301MB2001; 31:tHbrCDLctfrJkAYihWof/7ZTgmJKD1jsM/rJP5Lj9UztzlChWWum21qxuaoFgVTj/Jfef7B5+9uGpw8Ym0CtZ0kAr+LbSCziX0s8bjJ1lsTCJueqU6GxUXFlyjIoenXeR1llD5kq4QhrUZI4oPHTOxIjvxrfwpzl1jkV7XA81iMbrD6GugXNdOUpzm6H0YXOzF1xCWkLIcj5geiDvgoynFCdeLe2jxAYcgW0ra8xRNs=; 4:gELUDSE/WOX9q701Viu2a/s9/36xljBxSC6QZ60nEWidJA1Aw3/4vhciG1KGTnsgqP/AkBSknhjI6JFP1r3T9YEUxNtCkoEp8TdkUurauVvcMwG6USwNWEMaYgj+blYQ3pjad1MFmpyjbbku0mD605ujkXLk9P/ODJFYE0zSxSFgV7bQmMMBrzT1HVKPumq/XeP8xshSXukKpXTezevwr+gjxNU7KM69AUhlcPjNz/csq/LFNTGGG8TM+dbvSqj/8Bcn3alK3+1buXbmFTg9KMJ1Hz0hcWoSQXpcRT2zX8qXfPztx5jX7XHYCrYPFlRU/LYb4rm8ZfTP4w8qX/RJHRz+AVs9I0lRZjOcrEwh88uVzASg0uEUspNpe2qD5K7CpPWUyoKz5QLzcKu9JAFthpT9JDJdR8eblEXyQiMMDUSP9dA2y9cNxiFk3sl4Ox+lvwBCQf/HcwVBb3egAq1kqR2i0exMBf60zkYxLTHfhDHTkVyhNGZw7arVZzGgHbgW5XZpEIHDQJ9U7zZ6NdAO6mW1NbUkZxt7Y1G3FhikyQo= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(185117386973197); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040176)(601004)(2401047)(13015025)(13017025)(13023025)(13024025)(13018025)(8121501046)(5005006)(10201501046)(3002001)(6055026); SRVR:BLUPR0301MB2001; BCL:0; PCL:0; RULEID:(400006); SRVR:BLUPR0301MB2001; X-Forefront-PRVS: 00514A2FE6 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BLUPR0301MB2001; 23:y7yhatVebSuFxwPdwt9XA7H2cBx4lmFk5q4szCZ?= =?us-ascii?Q?F4oFktHZDBa7YQWqz9DeqId+or8jqKRPXfK4Oy1mUxpIR8w1wpLeZ7pevKYh?= =?us-ascii?Q?fUoVJFggApDC/yDJI5UJSC14n5H/mn/2X3nsJfBeO9nVNR5Tho7gPkFSG4Kp?= =?us-ascii?Q?DGuBYQu22+JfOV8YxMrFbimQvqzjaHm50SSULJiHGx+c+Yd+Vdb5hKu51TZ8?= =?us-ascii?Q?VGgisjBSeT250H3+w5zjOsOXvpPUEQLjs4P6Q1ozELXMxjZ468HBlCSXgPll?= =?us-ascii?Q?rXXBcPPDAKLA/it42uo3fU0dEO6zp4+0AvD5vK2E85MxDMvcZENQOMmC/4pU?= =?us-ascii?Q?yAtSTMo2WQdJxUj4PGDyIvK3gasps5YLazpeN1pVzZq8qJJAof4P+UBENQe4?= =?us-ascii?Q?bJZthu1iVvuh8AYyW4mhEzOn9DKkmXc3UCXHjIEd8S8NQSXjfRCM/RG1Y7M+?= =?us-ascii?Q?B/PzXYb7lK+3PXDI2JxnUbPnBvCZ1jlLQYFbQtgEtHpBWMii1X1HOX2Uv1JK?= =?us-ascii?Q?BrX3FVL6Njw83D/s4k3MoE1xK56YAiNtw1L7CwToo0E8SlLYA9DdxtcUa1C8?= =?us-ascii?Q?jljeNjoXuThUDeOFl2RLzGYDb9zP8dlgNqfIjNnmMQjwao9qFeQg71v7EZm8?= =?us-ascii?Q?FR1xXkywE93rR915vlEdmOlcalqm4iQdb1E6atS0ybt0e4sFpVeespWDPhsG?= =?us-ascii?Q?MPwR+dQo9I3z/WvQaSIkSZutC69O7MjxJLNZ+f/iyfS9Nn6yvfJiXkXJSsBp?= =?us-ascii?Q?hZFhx+dXjUKsY56uPOTTx7PV3Dcis+g/7X3+9lLdDu3DVGjqQPcT9OdEn723?= =?us-ascii?Q?mvW1yE3MHQurtAmeGVEIuK+sVowy2I7oYgxc8fwRA90qBKlX6EjNVgqPDivu?= =?us-ascii?Q?6263GQ8vJbE4fRul/aC5oQDNDlKz+KCjMjHKn/QK1Kr7A5YIRkrg0HWTDd8p?= =?us-ascii?Q?OkYXdXdLMnKdgDwyiHkGStAYdCnuiAXbihvbEXTt9zohrjAtYjrH6pTgwJEu?= =?us-ascii?Q?u0T5OXs5UOKLA1DJjPU85AJW2YAsSkIok3H3nrYZdl1NzJ8Gf1Jq/baHTMCP?= =?us-ascii?Q?PhpFz76GcdQbIH8hDcwHoQi20ezJkZ97BeTXgf9etZh/juWuk0Ll0zTPTQzZ?= =?us-ascii?Q?Atc6odIpjVzde5fHlAhKXfogW0QIqLs+rkGxxyNOFPwxP6askjqaFNJujgyt?= =?us-ascii?Q?Q+Ok1AXfeThV2xDcTXZmuf4Bj+k7NQ/M2jMcj?= X-Microsoft-Exchange-Diagnostics: 1; BLUPR0301MB2001; 6:+Y86yXP91ynhPSZRZPt1R5fMz18yNMT+HDKwOUdU1tWUXgNzI/BEmQ4xbiZtcYvM+5FwXnyukb+6ZarTy9r6ArzPMsprqnd5oPsteGsWEhuNRVGlKLVxFz4EgKkPZiRzvMcprG4IN5nEGkP2t4j2OUiS7FxxarSR5Ji9NBA4G520OVWt83swo2Y7mEeeYPJsEuhMMmIZv31k/AFonL/cCL+x9mMP7G3YuSEDficH5uD9CiFMFjuHFN8oydx7mEAu+tiIfUsfW1IKeESf55ixWkHYLjQNeoVrGTO06XdiPd4=; 5:rrsqcLGGRdRO4VEwF1w/Gm4pp7jSNvg4WuHLBT+XlHY6G9ym83aaMVLZLfOFRqgM7bVL40CU2Tb8A2x9i5MmTL8SwM6TP0imHkuV9BWeax7beT8OdF5AXQQby0DmaQ98/RWO9LetWd/cnF42QAcsAsocatWDL9Vw8Y4eE8fM2gM=; 24:rotak1b9EyRzmXHmKSZ0syktEeoH9MRvae2eK7z+ibFPyhVWMBgw17AmsMQmxMOXH0SmrRpidVFeXNgh9jEKdR7L+AiCcpSYxeUuVLZxLjQ=; 7:97gOChrc8v29qhJW2q6cZ+lFBBy6MEm/jQ8T62v6t0yi1XB0aCe6FrrcHR8udioXheKfi//zT8XNYPf8zbOtiaWvk7c+i61V4P3q7Lh9Eegl5Knqab0QsNdBC4lGnz2w62pggVJQGf6hunerPA0zFhPPtx90b63kPOMHTkJiszrGpeCOV2XBdXMmfBw4Lb/4ImE0xrIhla0cJXU6gXfHYL57gRqGYzFoetjVNAqBCY6SrmDaz2+7jmY2o/v4YtwH SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 31 Aug 2016 11:01:46.2364 (UTC) X-MS-Exchange-CrossTenant-Id: 5afe0b00-7697-4969-b663-5eab37d5f47e X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=5afe0b00-7697-4969-b663-5eab37d5f47e; Ip=[192.88.168.50]; Helo=[tx30smr01.am.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BLUPR0301MB2001 Subject: [dpdk-dev] [PATCH v2 06/14] eal/soc: implement probing of drivers 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: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 Signed-off-by: Shreyansh Jain Signed-off-by: Hemant Agrawal --- 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 #include +#include +#include #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 #include #include +#include #include #include #include @@ -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;