From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id DE3D641E25; Thu, 9 Mar 2023 13:42:20 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id CB31140ED7; Thu, 9 Mar 2023 13:42:20 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 4E849400D7 for ; Thu, 9 Mar 2023 13:42:19 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3295QFk3019859; Thu, 9 Mar 2023 04:42:18 -0800 Received: from nam12-bn8-obe.outbound.protection.outlook.com (mail-bn8nam12lp2169.outbound.protection.outlook.com [104.47.55.169]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3p6ff3hfju-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 09 Mar 2023 04:42:18 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=OzD3tX6vLQIGjNmugTH5LxyzEQs2XgD+Kdg9kyjIOmqul/klRxMwam3oC6MFUZgmDwodqVsWeCi3lBf9SicatotTjOtlGUGvownYxKC/1PqlzALARSOoIqQwdjwUZhAx/hxFSixLbGFTi6DhwdrGb02RI6qojY3NwMpgsn35aTJr6PxqookuWVAPwrIl9o2DVcAzq+av2vgOuZPOUt4frD8+oW9Wn7xIrPNR+ZddbENlUdApu0JWT1NY8wwnIee1gLEF1fBnLj2QqAelTvaxD7AnQv4E1EcwsnFWPv/iTIB87exdTFCLp3735t9x6d1QrKyZ+vhC3Fi1atcj22Qpfg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=2w5w6A+dOA2W89go+4+Glnaym0zymPv8NlSko9p6MhM=; b=efbigOfTHX/PKHslIwp1wp/0TUF9foUTsHpPuRvVE5v8h4hrW6gZXPfxHOucMOeuqDv9j9Lf1g/yjNAHgjbn/ZTsR9PNj6bKtPDd/g/fxogVNDhSc9Nh535+qCCXH+gUXEcVYoISziX92oUvRAB3rbf3gsE70/PwxGpsm8JgI0w/PVTTRY5lfEujyyCYoqmBaLofNzfCYhBTPHF3RjZORZk+JgvJrwnufDJYWw7SIRGPaBKiLbc7cXWJdDN5QDHRhNoQiT4GofUnbPLldNad2N/quOt8lBIWWkmMh4Zu6bboaPtf4w1hZvuFxL34Xzd0Q9ZNN4VmLQfmuSt+0Asb0A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=marvell.com; dmarc=pass action=none header.from=marvell.com; dkim=pass header.d=marvell.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.onmicrosoft.com; s=selector1-marvell-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=2w5w6A+dOA2W89go+4+Glnaym0zymPv8NlSko9p6MhM=; b=qGX8KyQnppjgJrZ/yYCyzBY1TuqjgQErSIIlwmvqDczvNvKzVy2LDR3ZSV++BryXCyrc9Hs2zGJ3wNG3+vV+DmkOdFNPQsXC42hDbs2LIY2p5AHOJBG+I3BIqOvz7V3uKO+1ES/n4iKOiyKI6PPOdSFASwATL0cGViBFlHl8508= Received: from DM4PR18MB4368.namprd18.prod.outlook.com (2603:10b6:5:39d::6) by CO6PR18MB3842.namprd18.prod.outlook.com (2603:10b6:5:341::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6178.19; Thu, 9 Mar 2023 12:42:14 +0000 Received: from DM4PR18MB4368.namprd18.prod.outlook.com ([fe80::a836:b2fe:215d:8148]) by DM4PR18MB4368.namprd18.prod.outlook.com ([fe80::a836:b2fe:215d:8148%6]) with mapi id 15.20.6178.017; Thu, 9 Mar 2023 12:42:14 +0000 From: Tomasz Duszynski To: Tomasz Duszynski , "dev@dpdk.org" , Thomas Monjalon CC: "chenbo.xia@intel.com" , Jerin Jacob Kollanukkaran , "stephen@networkplumber.org" , "david.marchand@redhat.com" Subject: RE: [PATCH v4] bus: add platform bus Thread-Topic: [PATCH v4] bus: add platform bus Thread-Index: AQHZTHhULQpdSd69W0+igCIWl8OuVa7yb5hA Date: Thu, 9 Mar 2023 12:42:13 +0000 Message-ID: References: <20230215111031.2235204-1-tduszynski@marvell.com> <20230301195912.3835720-1-tduszynski@marvell.com> In-Reply-To: <20230301195912.3835720-1-tduszynski@marvell.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-publictraffictype: Email x-ms-traffictypediagnostic: DM4PR18MB4368:EE_|CO6PR18MB3842:EE_ x-ms-office365-filtering-correlation-id: f34a675f-604a-42f2-3424-08db209bb573 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: ENl+agR4WLa8VkSiYqqnA2fs/pedb38yOXA256atQLgVeejoK7/9QCiig7mev76A7GrLFx3TI4FQuGVdVOhfNW9SzC5J3dad3Taa++jEJ+JVlvkC9RiFCkptkgUy596/KNM6Nr7JN3/2SVIMcGbvw+Opb61yuZsqibD9t+pYYQwrxwJ4o/6cQMZJhcToZuvvzl1ny1R+WAAfcVoT8qlYz8+nfg43sSE8lgXlk8Dw1gYI9eIzOoBYiISwdaV24lKtssDiqlr1wKyzYk7S6IutLEur/Bxgo8wNPxqNpPqAy49/BWH8NN6iJ/3GSrefm4IHngKuD4xxeofAvZxVSnBIe1PesB2rCAYi2XEEg3mo/ByMCRpihD7zTiNi26IEb5df8i+J0Hkvj2o2FJxkzetdTOihJemzbLb3XtaMmQpNtQpYCeY3jsKHzki9cCsLKSKzYzGQDE0Kv+Nf0tCqepS+p7a5dtUWteW4yg0m2/SuEj+mIfQ7IjZ81zK09CEtuwxs4zSs0Tl2Fn60OXInsjJRUPhKj2fj/3Rf0Lf7k1npLNvitR1leDXSTHOXIS7nGSTZ4hKgRRzYWKeA5z+8t05zjc3bxs0JJSZ097/di7y/OmY0MkpbfJnYxne+PYC6w3jj74PvORmixW1AIrwUAMZ0ROxHpYqZdpjxJLEf/xZiRKOTcVCABtBGGs8jhpLfIfvQnO1reOxXq/34eOIeKaubdA== x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DM4PR18MB4368.namprd18.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230025)(4636009)(346002)(39860400002)(376002)(136003)(366004)(396003)(451199018)(186003)(7696005)(71200400001)(33656002)(478600001)(122000001)(38070700005)(55016003)(54906003)(110136005)(38100700002)(316002)(86362001)(26005)(6506007)(9686003)(83380400001)(41300700001)(5660300002)(30864003)(66946007)(76116006)(66556008)(66476007)(8936002)(52536014)(66446008)(2906002)(4326008)(8676002)(64756008)(579004)(559001); DIR:OUT; SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?ORuN0ziQZAMOMRS8QBbvNAsbkKmJVVV8wPugT+CzfFA+SB8CdKWBKCo3QWaY?= =?us-ascii?Q?y3E7b252sZFdaxEOt9ha6IvZ5rZVPk4iq0BBmGu9jtWbyv9XPvqEA/JNqild?= =?us-ascii?Q?HBhwvzretqtDScpJy52JbuVLjCO/O4hn5nRWOGeFEe/Zy6Kkl+vMHEFuMY4P?= =?us-ascii?Q?yCL2uMcEY/U04tveQqKrCsNkGsl+gjz7ER2lHh5Ak++ZOJA6MNDFX+JCinZF?= =?us-ascii?Q?DAiExlSImtl2gNST/WOWfxCnAltjucNX5zlRJkpZ+njEfHw9IAL9+T64+ic5?= =?us-ascii?Q?4FMMVntBe4yh7cRzXwpYutb2eGCpp6FSsHUr32RLbBVsQH7yoss0zUanKr+N?= =?us-ascii?Q?A12cKnfeCF0ibblKFmRnetG+h3/cYrZ228m4g3clkkv44JajqqU5n8VrcCpY?= =?us-ascii?Q?MVAIbF60HgafT9Ji/eBlwRejHb/65qM+pCmbqq/7VPx7k0RUAhDGwZGk8qdj?= =?us-ascii?Q?xqrzgkXiSeFpKqK9c62R06vSPacdCxpNytAOCDtDgG8Cb5bI4uXqA51O8bGy?= =?us-ascii?Q?L4K+lUOXJRcZo6kye28TGZbbL7zCEQvk00+/8ibAc384AtFdUXJVofQ2iQ1M?= =?us-ascii?Q?hoIGW/TQLVXJukoCqMuQ8DkaHTYlJ3Fhc6g5bLI5N8iFF1p/wX1YRzAkRJuN?= =?us-ascii?Q?g0AjGfRF1h2RC3SIaXORYoIWl/Lx55Y9VDJf6W42Ul3cfMJyN500I5z5E+GI?= =?us-ascii?Q?zpPihwRr0q1me8o0Q63nnbKz7MT5PFbwzGl+rSebnp5L4ZOuI/CDzvIV/T7E?= =?us-ascii?Q?6jDymsSk9Nb/7mUduH1cKvD/bUzt1zSWP4Mw3ARZWOmHTNDa3sMFJlansZeC?= =?us-ascii?Q?d6VsXIm7fUb6i9cJHuHNvh0oLbTMjgvHfO5pAIAh694k0hqqesvDEw1OOVDW?= =?us-ascii?Q?83EWps37K3K37psPBbHiJP/F73+Ng+Hkqnf9yGoVsFIe/h5nASecc+jUc+V1?= =?us-ascii?Q?2kh6SLuOsJDZu4yQkj9kUI0gDgpU7H/IOLHCpvnfW2C7VvS3l3EKXX/6ukFN?= =?us-ascii?Q?/qdQ5TwGWBTC3InJi6NW2LUKmNbuacH7gqS5JZEH9IRi9hNucuTmr1Gt9Bbk?= =?us-ascii?Q?4z++mM1t/TSebXZYOaIY1aAzRQ6khq1AbCiQc+nDFYUxoawvSozAypG6YrmN?= =?us-ascii?Q?EI9ff/2fbqGRxbWbgD8ahvUdTZ5+drquw9bOdweFOFn8Gz8dRvmY8n5GLFK5?= =?us-ascii?Q?/QhC/pj8lgAeet8IvFDUxb+zeEDttbRSEON+tn5cUuKngk/kWFg8QwXJuoWV?= =?us-ascii?Q?6AR8lgCCiEWW490WdMLzqzTkMIJoRzXs44OWadwuv5rEwVK1zF9UdHL+spHV?= =?us-ascii?Q?3Oqk2MEac33qfiEkWqXHjR7WcZCdNeKebfAgh3XnmThmUD8AsAj/1wYJzDzl?= =?us-ascii?Q?SbJp5A7Qy1y2+EeRZtpmUtdseX/NQ34MRM1KhryRHy9Ij/VXLIF17ACUojYG?= =?us-ascii?Q?BDgMH/sM/skyZbEndQGfUTepOWtSA0jxOosnLzA+3XnqvddWu1wCQwlNiuHg?= =?us-ascii?Q?v5Yy4YLMyiFcfgeD08rXbNAXp5Rpx06DtZRvS+B5/65SFiA6rM95W9jMKgtI?= =?us-ascii?Q?y4tP5Tg7GIky4NsCy2mu77vxSFj/u3CP2EMTH2vD?= Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: marvell.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: DM4PR18MB4368.namprd18.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: f34a675f-604a-42f2-3424-08db209bb573 X-MS-Exchange-CrossTenant-originalarrivaltime: 09 Mar 2023 12:42:13.8834 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 70e1fb47-1155-421d-87fc-2e58f638b6e0 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: 68iSOwNsmwbusMPmFkJwuLOZx/FSDHEh8Qd+V/Ut6hQoCxm2/pTtRR0UpP7XGWfQjhul18quKgcLf7Fa/HuZww== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO6PR18MB3842 X-Proofpoint-ORIG-GUID: v1C-R-lIH27XU2EcsV23pk_mhbLc_jne X-Proofpoint-GUID: v1C-R-lIH27XU2EcsV23pk_mhbLc_jne X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.942,Hydra:6.0.573,FMLib:17.11.170.22 definitions=2023-03-09_06,2023-03-08_03,2023-02-09_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Hi, A gentle reminder, any other comments regarding this change? >-----Original Message----- >From: Tomasz Duszynski >Sent: Wednesday, March 1, 2023 8:59 PM >To: dev@dpdk.org; Thomas Monjalon ; Tomasz Duszynski = >Cc: chenbo.xia@intel.com; Jerin Jacob Kollanukkaran ; >stephen@networkplumber.org; david.marchand@redhat.com >Subject: [PATCH v4] bus: add platform bus > >Platform bus is a software bus under Linux that manages devices which gene= rally do not have built- >in discovery mechanisms. Linux normally learns about platform devices dire= ctly from device-tree >during boot-up phase. > >Up to this point, whenever some userspace app needed control over platform= device or a range of >thereof some sort of driver being a mixture of vdev/rawdev was required. > >In order to simplify this task, provide an auto-probe experience and separ= ate bus logic from the >driver itself, add platform bus support. > >Currently devices backed up by vfio-platform kernel driver are supported. > >Signed-off-by: Tomasz Duszynski >--- >v4: >- add more documentation >- address failing compilation on systems running pre vfio-platform kernels >v3: >- fix device blocking >- fix conditional compilation based on VFIO_PRESENT >v2: >- take a step back and do not add eal changes that simplify parsing > sysfs string. That should be moved to a more generic library and > submitted separately. >- compile code conditionally based on VFIO_PRESENT > > MAINTAINERS | 4 + > doc/guides/linux_gsg/linux_drivers.rst | 45 ++ > doc/guides/rel_notes/release_23_03.rst | 5 + > drivers/bus/meson.build | 1 + > drivers/bus/platform/bus_platform_driver.h | 193 ++++++ > drivers/bus/platform/meson.build | 16 + > drivers/bus/platform/platform.c | 645 +++++++++++++++++++++ > drivers/bus/platform/platform_params.c | 75 +++ > drivers/bus/platform/private.h | 48 ++ > drivers/bus/platform/version.map | 10 + > 10 files changed, 1042 insertions(+) > create mode 100644 drivers/bus/platform/bus_platform_driver.h > create mode 100644 drivers/bus/platform/meson.build create mode 100644 >drivers/bus/platform/platform.c create mode 100644 drivers/bus/platform/p= latform_params.c > create mode 100644 drivers/bus/platform/private.h create mode 100644 >drivers/bus/platform/version.map > >diff --git a/MAINTAINERS b/MAINTAINERS >index ffbf91296e..7aea426b53 100644 >--- a/MAINTAINERS >+++ b/MAINTAINERS >@@ -581,6 +581,10 @@ VDEV bus driver > F: drivers/bus/vdev/ > F: app/test/test_vdev.c > >+Platform bus driver >+M: Tomasz Duszynski >+F: drivers/bus/platform >+ > VMBUS bus driver > M: Long Li > F: drivers/bus/vmbus/ >diff --git a/doc/guides/linux_gsg/linux_drivers.rst b/doc/guides/linux_gsg= /linux_drivers.rst >index 2f3f079aab..5e8a3ae810 100644 >--- a/doc/guides/linux_gsg/linux_drivers.rst >+++ b/doc/guides/linux_gsg/linux_drivers.rst >@@ -296,6 +296,51 @@ If ``CONFIG_VFIO_NOIOMMU`` is not enabled in the kern= el configuration, VFIO >driver will not support the no-IOMMU mode, and other alternatives (such a= s UIO drivers) will have >to be used. > >+VFIO Platform >+------------- >+ >+VFIO Platform is a kernel driver that extends capabilities of VFIO by >+adding support for platform devices that reside behind an IOMMU. Linux >+usually learns about platform devices directly from device tree during bo= ot-up phase. >+Unlike, for example, PCI devices which have necessary information built-i= n. >+ >+To make use of VFIO platform, the ``vfio-platform`` module must be loaded= first: >+ >+.. code-block:: console >+ >+ sudo modprobe vfio-platform >+ >+.. note:: >+ >+ By default ``vfio-platform`` assumes that platform device has dedicate= d reset >+ driver. If such driver is missing or device does not require one this >+ option can be turned off by setting ``reset_required=3D0`` module para= meter. >+ >+Afterwards platform device needs to be bound to ``vfio-platform``. This >+is standard procedure requiring two steps. First ``driver_override``, >+which is available inside platform device directory, needs to be set to >+``vfio-platform``: >+ >+.. code-block:: console >+ >+ sudo echo vfio-platform > >+ /sys/bus/platform/devices/DEV/driver_override >+ >+Next ``DEV`` device must be bound to ``vfio-platform`` driver: >+ >+.. code-block:: console >+ >+ sudo echo DEV > /sys/bus/platform/drivers/vfio-platform/bind >+ >+On application startup DPDK platform bus driver scans >+``/sys/bus/platform/devices`` searching for devices that have >+``driver`` symbolic link pointing to ``vfio-platform`` driver. Finally, >+scanned devices are matched against available PMDs. Matching is >+successful if either PMD name or PMD alias matches kernel driver name or = PMD name matches platform >device name, all in that order. >+ >+VFIO Platform depends on ARM/ARM64 and is usually enabled on >+distributions running on these systems. Consult your distributions >+documentation to make sure that is the case. >+ > .. _bifurcated_driver: > > Bifurcated Driver >diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes= /release_23_03.rst >index 49c18617a5..4bde86165f 100644 >--- a/doc/guides/rel_notes/release_23_03.rst >+++ b/doc/guides/rel_notes/release_23_03.rst >@@ -197,6 +197,11 @@ New Features > * Added support to capture packets at each graph node with packet metad= ata and > node name. > >+* **Added platform bus support.** >+ >+ A platform bus provides a way to use Linux platform devices which >+ are compatible with vfio-platform kernel driver. >+ > > Removed Items > ------------- >diff --git a/drivers/bus/meson.build b/drivers/bus/meson.build index 45eab= 5233d..6d2520c543 100644 >--- a/drivers/bus/meson.build >+++ b/drivers/bus/meson.build >@@ -7,6 +7,7 @@ drivers =3D [ > 'fslmc', > 'ifpga', > 'pci', >+ 'platform', > 'vdev', > 'vmbus', > ] >diff --git a/drivers/bus/platform/bus_platform_driver.h >b/drivers/bus/platform/bus_platform_driver.h >new file mode 100644 >index 0000000000..a7445f77de >--- /dev/null >+++ b/drivers/bus/platform/bus_platform_driver.h >@@ -0,0 +1,193 @@ >+/* SPDX-License-Identifier: BSD-3-Clause >+ * Copyright(C) 2023 Marvell. >+ */ >+ >+#ifndef _BUS_PLATFORM_DRIVER_H_ >+#define _BUS_PLATFORM_DRIVER_H_ >+ >+/** >+ * @file >+ * Platform bus interface. >+ */ >+ >+#ifdef __cplusplus >+extern "C" { >+#endif >+ >+#include >+#include >+ >+#include >+#include >+#include >+#include >+#include >+ >+/* Forward declarations */ >+struct rte_platform_bus; >+struct rte_platform_device; >+struct rte_platform_driver; >+ >+/** >+ * Initialization function for the driver called during platform device p= robing. >+ * >+ * @param pdev >+ * Pointer to the platform device. >+ * @return >+ * 0 on success, negative value otherwise. >+ */ >+typedef int (rte_platform_probe_t)(struct rte_platform_device *pdev); >+ >+/** >+ * Removal function for the driver called during platform device removal. >+ * >+ * @param pdev >+ * Pointer to the platform device. >+ * @return >+ * 0 on success, negative value otherwise. >+ */ >+typedef int (rte_platform_remove_t)(struct rte_platform_device *pdev); >+ >+/** >+ * Driver specific DMA mapping. >+ * >+ * @param pdev >+ * Pointer to the platform device. >+ * @param addr >+ * Starting virtual address of memory to be mapped. >+ * @param iova >+ * Starting IOVA address of memory to be mapped. >+ * @param len >+ * Length of memory segment being mapped. >+ * @return >+ * - 0 on success, negative value and rte_errno is set otherwise. >+ */ >+typedef int (rte_platform_dma_map_t)(struct rte_platform_device *pdev, vo= id *addr, uint64_t iova, >+ size_t len); >+ >+/** >+ * Driver specific DMA unmapping. >+ * >+ * @param pdev >+ * Pointer to the platform device. >+ * @param addr >+ * Starting virtual address of memory to be mapped. >+ * @param iova >+ * Starting IOVA address of memory to be mapped. >+ * @param len >+ * Length of memory segment being mapped. >+ * @return >+ * - 0 on success, negative value and rte_errno is set otherwise. >+ */ >+typedef int (rte_platform_dma_unmap_t)(struct rte_platform_device *pdev, = void *addr, uint64_t >iova, >+ size_t len); >+ >+/** >+ * A structure describing a platform device resource. >+ */ >+struct rte_platform_resource { >+ char *name; /**< Resource name specified via reg-names prop in device-tr= ee */ >+ struct rte_mem_resource mem; /**< Memory resource */ }; >+ >+/** >+ * A structure describing a platform device. >+ */ >+struct rte_platform_device { >+ RTE_TAILQ_ENTRY(rte_platform_device) next; /**< Next attached platform d= evice */ >+ struct rte_device device; /**< Core device */ >+ struct rte_platform_driver *driver; /**< Matching device driver */ >+ char name[RTE_DEV_NAME_MAX_LEN]; /**< Device name */ >+ unsigned int num_resource; /**< Number of device resources */ >+ struct rte_platform_resource *resource; /**< Device resources */ >+ int dev_fd; /**< VFIO device fd */ >+}; >+ >+/** >+ * A structure describing a platform device driver. >+ */ >+struct rte_platform_driver { >+ RTE_TAILQ_ENTRY(rte_platform_driver) next; /**< Next available platform = driver */ >+ struct rte_driver driver; /**< Core driver */ >+ rte_platform_probe_t *probe; /**< Device probe function */ >+ rte_platform_remove_t *remove; /**< Device remove function */ >+ rte_platform_dma_map_t *dma_map; /**< Device DMA map function */ >+ rte_platform_dma_unmap_t *dma_unmap; /**< Device DMA unmap function */ >+ uint32_t drv_flags; /**< Driver flags RTE_PLATFORM_DRV_* */ }; >+ >+/** Device driver needs IOVA as VA and cannot work with IOVA as PA */ >+#define RTE_PLATFORM_DRV_NEED_IOVA_AS_VA 0x0001 >+ >+/** >+ * @internal >+ * Helper macros used to convert core device to platform device. >+ */ >+#define RTE_DEV_TO_PLATFORM_DEV(ptr) \ >+ container_of(ptr, struct rte_platform_device, device) >+ >+#define RTE_DEV_TO_PLATFORM_DEV_CONST(ptr) \ >+ container_of(ptr, const struct rte_platform_device, device) >+ >+/** Helper for platform driver registration. */ #define >+RTE_PMD_REGISTER_PLATFORM(nm, platform_drv) \ static const char >+*pdrvinit_ ## nm ## _alias; \ RTE_INIT(pdrvinitfn_ ##nm) \ { \ >+ (platform_drv).driver.name =3D RTE_STR(nm); \ >+ (platform_drv).driver.alias =3D pdrvinit_ ## nm ## _alias; \ >+ rte_platform_register(&(platform_drv)); \ } \ RTE_PMD_EXPORT_NAME(nm, >+__COUNTER__) >+ >+/** Helper for setting platform driver alias. */ #define >+RTE_PMD_REGISTER_ALIAS(nm, alias) \ static const char *pdrvinit_ ## nm >+## _alias =3D RTE_STR(alias) >+ >+#ifdef VFIO_PRESENT >+ >+/** >+ * Register a platform device driver. >+ * >+ * @warning >+ * @b EXPERIMENTAL: this API may change without prior notice. >+ * >+ * @param pdrv >+ * A pointer to a rte_platform_driver structure describing driver to be= registered. >+ */ >+__rte_internal >+void rte_platform_register(struct rte_platform_driver *pdrv); >+ >+/** >+ * Unregister a platform device driver. >+ * >+ * @warning >+ * @b EXPERIMENTAL: this API may change without prior notice. >+ * >+ * @param pdrv >+ * A pointer to a rte_platform_driver structure describing driver to be= unregistered. >+ */ >+__rte_internal >+void rte_platform_unregister(struct rte_platform_driver *pdrv); >+ >+#else >+ >+__rte_internal >+static inline void >+rte_platform_register(struct rte_platform_driver *pdrv __rte_unused) { >+} >+ >+__rte_internal >+static inline void >+rte_platform_unregister(struct rte_platform_driver *pdrv __rte_unused) >+{ } >+ >+#endif /* VFIO_PRESENT */ >+ >+#ifdef __cplusplus >+} >+#endif >+ >+#endif /* _BUS_PLATFORM_DRIVER_H_ */ >diff --git a/drivers/bus/platform/meson.build b/drivers/bus/platform/meson= .build >new file mode 100644 >index 0000000000..417d7b81f8 >--- /dev/null >+++ b/drivers/bus/platform/meson.build >@@ -0,0 +1,16 @@ >+# SPDX-License-Identifier: BSD-3-Clause # Copyright(C) 2023 Marvell. >+# >+ >+if not is_linux >+ build =3D false >+ reason =3D 'only supported on Linux' >+ subdir_done() >+endif >+ >+deps +=3D ['kvargs'] >+sources =3D files( >+ 'platform_params.c', >+ 'platform.c', >+) >+driver_sdk_headers +=3D files('bus_platform_driver.h') >diff --git a/drivers/bus/platform/platform.c b/drivers/bus/platform/platfo= rm.c new file mode 100644 >index 0000000000..536d9524c6 >--- /dev/null >+++ b/drivers/bus/platform/platform.c >@@ -0,0 +1,645 @@ >+/* SPDX-License-Identifier: BSD-3-Clause >+ * Copyright(C) 2023 Marvell. >+ */ >+ >+#include >+#include >+#include >+#include >+#include >+#include >+#include >+#include >+ >+#include >+#include >+#include >+#include >+#include >+#include >+#include >+#include >+#include >+#include >+ >+#include "private.h" >+ >+#ifdef VFIO_PRESENT >+ >+#define PLATFORM_BUS_DEVICES_PATH "/sys/bus/platform/devices" >+ >+void >+rte_platform_register(struct rte_platform_driver *pdrv) { >+ TAILQ_INSERT_TAIL(&platform_bus.driver_list, pdrv, next); } >+ >+void >+rte_platform_unregister(struct rte_platform_driver *pdrv) { >+ TAILQ_REMOVE(&platform_bus.driver_list, pdrv, next); } >+ >+static struct rte_devargs * >+dev_devargs(const char *dev_name) >+{ >+ struct rte_devargs *devargs; >+ >+ RTE_EAL_DEVARGS_FOREACH("platform", devargs) { >+ if (!strcmp(devargs->name, dev_name)) >+ return devargs; >+ } >+ >+ return NULL; >+} >+ >+static bool >+dev_allowed(const char *dev_name) >+{ >+ struct rte_devargs *devargs; >+ >+ devargs =3D dev_devargs(dev_name); >+ if (devargs =3D=3D NULL) >+ return true; >+ >+ switch (platform_bus.bus.conf.scan_mode) { >+ case RTE_BUS_SCAN_UNDEFINED: >+ case RTE_BUS_SCAN_ALLOWLIST: >+ if (devargs->policy =3D=3D RTE_DEV_ALLOWED) >+ return true; >+ break; >+ case RTE_BUS_SCAN_BLOCKLIST: >+ if (devargs->policy =3D=3D RTE_DEV_BLOCKED) >+ return false; >+ break; >+ } >+ >+ return true; >+} >+ >+static int >+dev_add(const char *dev_name) >+{ >+ struct rte_platform_device *pdev, *tmp; >+ char path[PATH_MAX]; >+ unsigned long val; >+ >+ pdev =3D calloc(1, sizeof(*pdev)); >+ if (pdev =3D=3D NULL) >+ return -ENOMEM; >+ >+ rte_strscpy(pdev->name, dev_name, sizeof(pdev->name)); >+ pdev->device.name =3D pdev->name; >+ pdev->device.devargs =3D dev_devargs(dev_name); >+ pdev->device.bus =3D &platform_bus.bus; >+ snprintf(path, sizeof(path), PLATFORM_BUS_DEVICES_PATH "/%s/numa_node", = dev_name); >+ pdev->device.numa_node =3D eal_parse_sysfs_value(path, &val) ? >+rte_socket_id() : val; >+ >+ FOREACH_DEVICE_ON_PLATFORM_BUS(tmp) { >+ if (!strcmp(tmp->name, pdev->name)) { >+ PLATFORM_LOG(INFO, "device %s already added\n", pdev->name); >+ >+ if (tmp->device.devargs !=3D pdev->device.devargs) >+ rte_devargs_remove(pdev->device.devargs); >+ >+ free(pdev); >+ } >+ } >+ >+ TAILQ_INSERT_HEAD(&platform_bus.device_list, pdev, next); >+ >+ PLATFORM_LOG(INFO, "adding device %s to the list\n", dev_name); >+ >+ return 0; >+} >+ >+static char * >+dev_kernel_driver_name(const char *dev_name) { >+ char path[PATH_MAX], buf[BUFSIZ] =3D { }; >+ char *kdrv; >+ int ret; >+ >+ snprintf(path, sizeof(path), PLATFORM_BUS_DEVICES_PATH "/%s/driver", dev= _name); >+ /* save space for NUL */ >+ ret =3D readlink(path, buf, sizeof(buf) - 1); >+ if (ret <=3D 0) >+ return NULL; >+ >+ /* last token is kernel driver name */ >+ kdrv =3D strrchr(buf, '/'); >+ if (kdrv !=3D NULL) >+ return strdup(kdrv + 1); >+ >+ return NULL; >+} >+ >+static bool >+dev_is_bound_vfio_platform(const char *dev_name) { >+ char *kdrv; >+ int ret; >+ >+ kdrv =3D dev_kernel_driver_name(dev_name); >+ if (!kdrv) >+ return false; >+ >+ ret =3D strcmp(kdrv, "vfio-platform"); >+ free(kdrv); >+ >+ return ret =3D=3D 0; >+} >+ >+static int >+platform_bus_scan(void) >+{ >+ const struct dirent *ent; >+ const char *dev_name; >+ int ret =3D 0; >+ DIR *dp; >+ >+ dp =3D opendir(PLATFORM_BUS_DEVICES_PATH); >+ if (dp =3D=3D NULL) { >+ PLATFORM_LOG(INFO, "failed to open %s\n", PLATFORM_BUS_DEVICES_PATH); >+ return -errno; >+ } >+ >+ while ((ent =3D readdir(dp))) { >+ dev_name =3D ent->d_name; >+ if (dev_name[0] =3D=3D '.') >+ continue; >+ >+ if (!dev_allowed(dev_name)) >+ continue; >+ >+ if (!dev_is_bound_vfio_platform(dev_name)) >+ continue; >+ >+ ret =3D dev_add(dev_name); >+ if (ret) >+ break; >+ } >+ >+ closedir(dp); >+ >+ return ret; >+} >+ >+static int >+device_map_resource_offset(struct rte_platform_device *pdev, struct rte_p= latform_resource *res, >+ size_t offset) >+{ >+ res->mem.addr =3D mmap(NULL, res->mem.len, PROT_READ | PROT_WRITE, MAP_S= HARED, pdev->dev_fd, >+ offset); >+ if (res->mem.addr =3D=3D MAP_FAILED) >+ return -errno; >+ >+ PLATFORM_LOG(DEBUG, "adding resource va =3D %p len =3D %"PRIu64" name = =3D %s\n", res->mem.addr, >+ res->mem.len, res->name); >+ >+ return 0; >+} >+ >+static void >+device_unmap_resources(struct rte_platform_device *pdev) { >+ struct rte_platform_resource *res; >+ unsigned int i; >+ >+ for (i =3D 0; i < pdev->num_resource; i++) { >+ res =3D &pdev->resource[i]; >+ munmap(res->mem.addr, res->mem.len); >+ free(res->name); >+ } >+ >+ free(pdev->resource); >+ pdev->resource =3D NULL; >+ pdev->num_resource =3D 0; >+} >+ >+static int >+read_sysfs_string(const char *path, char *buf, size_t size) { >+ FILE *f; >+ char *p; >+ >+ f =3D fopen(path, "r"); >+ if (f =3D=3D NULL) >+ return -errno; >+ >+ if (fgets(buf, size, f) =3D=3D NULL) { >+ fclose(f); >+ return -ENODATA; >+ } >+ >+ fclose(f); >+ >+ p =3D strrchr(buf, '\n'); >+ if (p !=3D NULL) >+ *p =3D '\0'; >+ >+ return 0; >+} >+ >+static char * >+of_resource_name(const char *dev_name, int index) { >+ char path[PATH_MAX], buf[BUFSIZ] =3D { }; >+ int num =3D 0, ret; >+ char *name; >+ >+ snprintf(path, sizeof(path), PLATFORM_BUS_DEVICES_PATH "/%s/of_node/reg-= names", dev_name); >+ ret =3D read_sysfs_string(path, buf, sizeof(buf)); >+ if (ret) >+ return NULL; >+ >+ for (name =3D buf; name; name +=3D strlen(name) + 1) { >+ if (num++ !=3D index) >+ continue; >+ return strdup(name); >+ } >+ >+ return NULL; >+} >+ >+static int >+device_map_resources(struct rte_platform_device *pdev, unsigned int >+num) { >+ struct rte_platform_resource *res; >+ unsigned int i; >+ int ret; >+ >+ if (num =3D=3D 0) >+ PLATFORM_LOG(WARNING, "device %s has no resources\n", pdev->name); >+ >+ pdev->resource =3D calloc(num, sizeof(*pdev->resource)); >+ if (pdev->resource =3D=3D NULL) >+ return -ENOMEM; >+ >+ for (i =3D 0; i < num; i++) { >+ struct vfio_region_info reg_info =3D { >+ .argsz =3D sizeof(reg_info), >+ .index =3D i, >+ }; >+ >+ ret =3D ioctl(pdev->dev_fd, VFIO_DEVICE_GET_REGION_INFO, ®_info); >+ if (ret) { >+ PLATFORM_LOG(ERR, "failed to get region info at %d\n", i); >+ ret =3D -errno; >+ goto out; >+ } >+ >+ res =3D &pdev->resource[i]; >+ res->name =3D of_resource_name(pdev->name, reg_info.index); >+ res->mem.len =3D reg_info.size; >+ ret =3D device_map_resource_offset(pdev, res, reg_info.offset); >+ if (ret) { >+ PLATFORM_LOG(ERR, "failed to ioremap resource at %d\n", i); >+ goto out; >+ } >+ >+ pdev->num_resource++; >+ } >+ >+ return 0; >+out: >+ device_unmap_resources(pdev); >+ >+ return ret; >+} >+ >+static void >+device_cleanup(struct rte_platform_device *pdev) { >+ device_unmap_resources(pdev); >+ rte_vfio_release_device(PLATFORM_BUS_DEVICES_PATH, pdev->name, >+pdev->dev_fd); } >+ >+static int >+device_setup(struct rte_platform_device *pdev) { >+ struct vfio_device_info dev_info =3D { .argsz =3D sizeof(dev_info), }; >+ const char *name =3D pdev->name; >+ int ret; >+ >+ ret =3D rte_vfio_setup_device(PLATFORM_BUS_DEVICES_PATH, name, &pdev->de= v_fd, &dev_info); >+ if (ret) { >+ PLATFORM_LOG(ERR, "failed to setup %s\n", name); >+ return -ENODEV; >+ } >+ >+ /* This is an extra check to confirm that platform device was initialize= d >+ * by a kernel vfio-platform driver. On kernels that predate vfio-platfo= rm >+ * driver this flag obviously does not exist. In such scenarios this >+ * check needs to be removed otherwise compilation fails. >+ * >+ * Now, on such old kernels code will never reach here because >+ * there is another check much earlier which verifies whether >+ * device has been bound to vfio-platform driver. >+ */ >+#ifdef VFIO_DEVICE_FLAGS_PLATFORM >+ if (!(dev_info.flags & VFIO_DEVICE_FLAGS_PLATFORM)) { >+ PLATFORM_LOG(ERR, "device not backed by vfio-platform\n"); >+ ret =3D -ENOTSUP; >+ goto out; >+ } >+#endif >+ >+ ret =3D device_map_resources(pdev, dev_info.num_regions); >+ if (ret) { >+ PLATFORM_LOG(ERR, "failed to setup platform resources\n"); >+ goto out; >+ } >+ >+ return 0; >+out: >+ device_cleanup(pdev); >+ >+ return ret; >+} >+ >+static int >+driver_call_probe(struct rte_platform_driver *pdrv, struct >+rte_platform_device *pdev) { >+ int ret; >+ >+ if (rte_dev_is_probed(&pdev->device)) >+ return -EBUSY; >+ >+ if (pdrv->probe !=3D NULL) { >+ pdev->driver =3D pdrv; >+ ret =3D pdrv->probe(pdev); >+ if (ret) >+ return ret; >+ } >+ >+ pdev->device.driver =3D &pdrv->driver; >+ >+ return 0; >+} >+ >+static int >+driver_probe_device(struct rte_platform_driver *pdrv, struct >+rte_platform_device *pdev) { >+ enum rte_iova_mode iova_mode; >+ int ret; >+ >+ iova_mode =3D rte_eal_iova_mode(); >+ if (pdrv->drv_flags & RTE_PLATFORM_DRV_NEED_IOVA_AS_VA && iova_mode !=3D= RTE_IOVA_VA) { >+ PLATFORM_LOG(ERR, "driver %s expects VA IOVA mode but current mode is P= A\n", >+ pdrv->driver.name); >+ return -EINVAL; >+ } >+ >+ ret =3D device_setup(pdev); >+ if (ret) >+ return ret; >+ >+ ret =3D driver_call_probe(pdrv, pdev); >+ if (ret) >+ device_cleanup(pdev); >+ >+ return ret; >+} >+ >+static bool >+driver_match_device(struct rte_platform_driver *pdrv, struct >+rte_platform_device *pdev) { >+ bool match =3D false; >+ char *kdrv; >+ >+ kdrv =3D dev_kernel_driver_name(pdev->name); >+ if (!kdrv) >+ return false; >+ >+ /* match by driver name */ >+ if (!strcmp(kdrv, pdrv->driver.name)) { >+ match =3D true; >+ goto out; >+ } >+ >+ /* match by driver alias */ >+ if (pdrv->driver.alias !=3D NULL && !strcmp(kdrv, pdrv->driver.alias)) { >+ match =3D true; >+ goto out; >+ } >+ >+ /* match by device name */ >+ if (!strcmp(pdev->name, pdrv->driver.name)) >+ match =3D true; >+ >+out: >+ free(kdrv); >+ >+ return match; >+} >+ >+static int >+device_attach(struct rte_platform_device *pdev) { >+ struct rte_platform_driver *pdrv; >+ >+ FOREACH_DRIVER_ON_PLATFORM_BUS(pdrv) { >+ if (driver_match_device(pdrv, pdev)) >+ break; >+ } >+ >+ if (pdrv =3D=3D NULL) >+ return -ENODEV; >+ >+ return driver_probe_device(pdrv, pdev); } >+ >+static int >+platform_bus_probe(void) >+{ >+ struct rte_platform_device *pdev; >+ int ret; >+ >+ FOREACH_DEVICE_ON_PLATFORM_BUS(pdev) { >+ ret =3D device_attach(pdev); >+ if (ret =3D=3D -EBUSY) { >+ PLATFORM_LOG(DEBUG, "device %s already probed\n", pdev->name); >+ continue; >+ } >+ if (ret) >+ PLATFORM_LOG(ERR, "failed to probe %s\n", pdev->name); >+ } >+ >+ return 0; >+} >+ >+static struct rte_device * >+platform_bus_find_device(const struct rte_device *start, rte_dev_cmp_t >+cmp, const void *data) { >+ struct rte_platform_device *pdev; >+ >+ pdev =3D start ? RTE_TAILQ_NEXT(RTE_DEV_TO_PLATFORM_DEV_CONST(start), ne= xt) : >+ RTE_TAILQ_FIRST(&platform_bus.device_list); >+ while (pdev) { >+ if (cmp(&pdev->device, data) =3D=3D 0) >+ return &pdev->device; >+ >+ pdev =3D RTE_TAILQ_NEXT(pdev, next); >+ } >+ >+ return NULL; >+} >+ >+static int >+platform_bus_plug(struct rte_device *dev) { >+ struct rte_platform_device *pdev; >+ >+ if (!dev_allowed(dev->name)) >+ return -EPERM; >+ >+ if (!dev_is_bound_vfio_platform(dev->name)) >+ return -EPERM; >+ >+ pdev =3D RTE_DEV_TO_PLATFORM_DEV(dev); >+ if (pdev =3D=3D NULL) >+ return -EINVAL; >+ >+ return device_attach(pdev); >+} >+ >+static void >+device_release_driver(struct rte_platform_device *pdev) { >+ struct rte_platform_driver *pdrv; >+ int ret; >+ >+ pdrv =3D pdev->driver; >+ if (pdrv !=3D NULL && pdrv->remove !=3D NULL) { >+ ret =3D pdrv->remove(pdev); >+ if (ret) >+ PLATFORM_LOG(WARNING, "failed to remove %s\n", pdev->name); >+ } >+ >+ pdev->device.driver =3D NULL; >+ pdev->driver =3D NULL; >+} >+ >+static int >+platform_bus_unplug(struct rte_device *dev) { >+ struct rte_platform_device *pdev; >+ >+ pdev =3D RTE_DEV_TO_PLATFORM_DEV(dev); >+ if (pdev =3D=3D NULL) >+ return -EINVAL; >+ >+ device_release_driver(pdev); >+ device_cleanup(pdev); >+ rte_devargs_remove(pdev->device.devargs); >+ free(pdev); >+ >+ return 0; >+} >+ >+static int >+platform_bus_parse(const char *name, void *addr) { >+ struct rte_platform_device pdev =3D { }; >+ struct rte_platform_driver *pdrv; >+ const char **out =3D addr; >+ >+ rte_strscpy(pdev.name, name, sizeof(pdev.name)); >+ >+ FOREACH_DRIVER_ON_PLATFORM_BUS(pdrv) { >+ if (driver_match_device(pdrv, &pdev)) >+ break; >+ } >+ >+ if (pdrv !=3D NULL && addr !=3D NULL) >+ *out =3D name; >+ >+ return pdrv !=3D NULL ? 0 : -ENODEV; >+} >+ >+static int >+platform_bus_dma_map(struct rte_device *dev, void *addr, uint64_t iova, >+size_t len) { >+ struct rte_platform_device *pdev; >+ >+ pdev =3D RTE_DEV_TO_PLATFORM_DEV(dev); >+ if (pdev =3D=3D NULL || pdev->driver =3D=3D NULL) { >+ rte_errno =3D EINVAL; >+ return -1; >+ } >+ >+ if (pdev->driver->dma_map !=3D NULL) >+ return pdev->driver->dma_map(pdev, addr, iova, len); >+ >+ return rte_vfio_container_dma_map(RTE_VFIO_DEFAULT_CONTAINER_FD, >+(uint64_t)addr, iova, len); } >+ >+static int >+platform_bus_dma_unmap(struct rte_device *dev, void *addr, uint64_t >+iova, size_t len) { >+ struct rte_platform_device *pdev; >+ >+ pdev =3D RTE_DEV_TO_PLATFORM_DEV(dev); >+ if (pdev =3D=3D NULL || pdev->driver =3D=3D NULL) { >+ rte_errno =3D EINVAL; >+ return -1; >+ } >+ >+ if (pdev->driver->dma_unmap !=3D NULL) >+ return pdev->driver->dma_unmap(pdev, addr, iova, len); >+ >+ return rte_vfio_container_dma_unmap(RTE_VFIO_DEFAULT_CONTAINER_FD, (uint= 64_t)addr, iova, >+ len); >+} >+ >+static enum rte_iova_mode >+platform_bus_get_iommu_class(void) >+{ >+ struct rte_platform_driver *pdrv; >+ struct rte_platform_device *pdev; >+ >+ FOREACH_DEVICE_ON_PLATFORM_BUS(pdev) { >+ pdrv =3D pdev->driver; >+ if (pdrv !=3D NULL && pdrv->drv_flags & RTE_PLATFORM_DRV_NEED_IOVA_AS_V= A) >+ return RTE_IOVA_VA; >+ } >+ >+ return RTE_IOVA_DC; >+} >+ >+static int >+platform_bus_cleanup(void) >+{ >+ struct rte_platform_device *pdev, *tmp; >+ >+ RTE_TAILQ_FOREACH_SAFE(pdev, &platform_bus.device_list, next, tmp) { >+ platform_bus_unplug(&pdev->device); >+ TAILQ_REMOVE(&platform_bus.device_list, pdev, next); >+ } >+ >+ return 0; >+} >+ >+struct rte_platform_bus platform_bus =3D { >+ .bus =3D { >+ .scan =3D platform_bus_scan, >+ .probe =3D platform_bus_probe, >+ .find_device =3D platform_bus_find_device, >+ .plug =3D platform_bus_plug, >+ .unplug =3D platform_bus_unplug, >+ .parse =3D platform_bus_parse, >+ .dma_map =3D platform_bus_dma_map, >+ .dma_unmap =3D platform_bus_dma_unmap, >+ .get_iommu_class =3D platform_bus_get_iommu_class, >+ .dev_iterate =3D platform_bus_dev_iterate, >+ .cleanup =3D platform_bus_cleanup, >+ }, >+ .device_list =3D TAILQ_HEAD_INITIALIZER(platform_bus.device_list), >+ .driver_list =3D TAILQ_HEAD_INITIALIZER(platform_bus.driver_list), >+}; >+ >+RTE_REGISTER_BUS(platform, platform_bus.bus); >+RTE_LOG_REGISTER_DEFAULT(platform_bus_logtype, NOTICE); >+ >+#endif /* VFIO_PRESENT */ >diff --git a/drivers/bus/platform/platform_params.c b/drivers/bus/platform= /platform_params.c >new file mode 100644 >index 0000000000..edc246b53e >--- /dev/null >+++ b/drivers/bus/platform/platform_params.c >@@ -0,0 +1,75 @@ >+/* SPDX-License-Identifier: BSD-3-Clause >+ * Copyright(C) 2023 Marvell. >+ */ >+ >+#include >+#include >+ >+#include >+#include >+#include >+#include >+#include >+#include >+ >+#include "bus_platform_driver.h" >+#include "private.h" >+ >+#ifdef VFIO_PRESENT >+ >+enum platform_params { >+ RTE_PLATFORM_PARAM_NAME, >+}; >+ >+static const char * const platform_params_keys[] =3D { >+ [RTE_PLATFORM_PARAM_NAME] =3D "name", >+ NULL >+}; >+ >+static int >+platform_dev_match(const struct rte_device *dev, const void *_kvlist) { >+ const char *key =3D platform_params_keys[RTE_PLATFORM_PARAM_NAME]; >+ const struct rte_kvargs *kvlist =3D _kvlist; >+ const char *name; >+ >+ /* no kvlist arg, all devices match */ >+ if (kvlist =3D=3D NULL) >+ return 0; >+ >+ /* if key is present in kvlist and does not match, filter device */ >+ name =3D rte_kvargs_get(kvlist, key); >+ if (name !=3D NULL && strcmp(name, dev->name)) >+ return -1; >+ >+ return 0; >+} >+ >+void * >+platform_bus_dev_iterate(const void *start, const char *str, >+ const struct rte_dev_iterator *it __rte_unused) { >+ rte_bus_find_device_t find_device; >+ struct rte_kvargs *kvargs =3D NULL; >+ struct rte_device *dev; >+ >+ if (str !=3D NULL) { >+ kvargs =3D rte_kvargs_parse(str, platform_params_keys); >+ if (!kvargs) { >+ PLATFORM_LOG(ERR, "cannot parse argument list %s", str); >+ rte_errno =3D EINVAL; >+ return NULL; >+ } >+ } >+ >+ find_device =3D platform_bus.bus.find_device; >+ if (find_device =3D=3D NULL) >+ return NULL; >+ >+ dev =3D platform_bus.bus.find_device(start, platform_dev_match, kvargs); >+ rte_kvargs_free(kvargs); >+ >+ return dev; >+} >+ >+#endif /* VFIO_PRESENT */ >diff --git a/drivers/bus/platform/private.h b/drivers/bus/platform/private= .h new file mode 100644 >index 0000000000..dcd992f8a7 >--- /dev/null >+++ b/drivers/bus/platform/private.h >@@ -0,0 +1,48 @@ >+/* SPDX-License-Identifier: BSD-3-Clause >+ * Copyright(C) 2023 Marvell. >+ */ >+ >+#ifndef _PLATFORM_PRIVATE_H_ >+#define _PLATFORM_PRIVATE_H_ >+ >+#include >+#include >+#include >+#include >+#include >+#include >+ >+#include "bus_platform_driver.h" >+ >+extern struct rte_platform_bus platform_bus; extern int >+platform_bus_logtype; >+ >+/* Platform bus iterators. */ >+#define FOREACH_DEVICE_ON_PLATFORM_BUS(p) \ >+ RTE_TAILQ_FOREACH(p, &(platform_bus.device_list), next) >+ >+#define FOREACH_DRIVER_ON_PLATFORM_BUS(p) \ >+ RTE_TAILQ_FOREACH(p, &(platform_bus.driver_list), next) >+ >+/* >+ * Structure describing platform bus. >+ */ >+struct rte_platform_bus { >+ struct rte_bus bus; /* Core bus */ >+ RTE_TAILQ_HEAD(, rte_platform_device) device_list; /* List of bus device= s */ >+ RTE_TAILQ_HEAD(, rte_platform_driver) driver_list; /* List of bus >+drivers */ }; >+ >+#define PLATFORM_LOG(level, ...) \ >+ rte_log(RTE_LOG_ ## level, platform_bus_logtype, \ >+ RTE_FMT("platform bus: " RTE_FMT_HEAD(__VA_ARGS__,), \ >+ RTE_FMT_TAIL(__VA_ARGS__,))) >+ >+/* >+ * Iterate registered platform devices and find one that matches provided= string. >+ */ >+void * >+platform_bus_dev_iterate(const void *start, const char *str, >+ const struct rte_dev_iterator *it __rte_unused); >+ >+#endif /* _PLATFORM_PRIVATE_H_ */ >diff --git a/drivers/bus/platform/version.map b/drivers/bus/platform/versi= on.map >new file mode 100644 >index 0000000000..bacce4da08 >--- /dev/null >+++ b/drivers/bus/platform/version.map >@@ -0,0 +1,10 @@ >+DPDK_23 { >+ local: *; >+}; >+ >+INTERNAL { >+ global: >+ >+ rte_platform_register; >+ rte_platform_unregister; >+}; >-- >2.34.1