From nobody Sun May 12 10:00:14 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+106532+1787277+3901457@groups.io; arc=fail (BodyHash is different from the expected one) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1688072051632261.20118552593783; Thu, 29 Jun 2023 13:54:11 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id 06fxYY1788612xwmuRbODm3c; Thu, 29 Jun 2023 13:54:11 -0700 X-Received: from NAM12-DM6-obe.outbound.protection.outlook.com (NAM12-DM6-obe.outbound.protection.outlook.com [40.107.243.53]) by mx.groups.io with SMTP id smtpd.web11.8320.1688072050429614365 for ; Thu, 29 Jun 2023 13:54:10 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=BfXtYK7kTug9DbZTEuV0dHkC3CH7g0VlZQUgQiHMWKnSIgKu1PrBSr+85MsN5am5gQtrHLMhOdRoA49YcZavVif0GWC815MH+CGm3TSGDI+xotjZPcQ6+8w/5QT5Il0At6Pgl31xsQAFdhPMrcgoG0g3XxLGNU1d3i6Jxb6ZkD4fXE4EXpTqPuoXXP0uotxxEAa0qGzFW2EMcN9rA7C40YBtH+LSokudDTQ/4ZSkpsa9eYngsAWBSoqgusrD42bI4LVa4bf/cqK3fwr0zm4xxts48Kdz2v5kAY603gYAu+M6pdNmAh1v+crz0U6NDcJh78wtO+AsUmdqRf1dw2aabg== 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=G9XwWN5hqEPOXzq0DZsuUxd6NfL8/PkpDbSFIOtUFL4=; b=G3oRekMA+dFqT5wEkZUm3SkPjKrCts7J3F6t3IYckoREZPtAwR1HjvlTG8X5b/C4wzV9v/WsTEJ9PpjTiCX1dlZF65hOMuKQuh62ZrBawrzIbQY0te2JRXRNB6ja5pj2anUcQOe1EqRF+tsqjD2sWLWkfI5VxxMB8KZBcQC8M8Mc4J8O7rDgjVSILFLxNfyqDdW1E/T/HtBpffXkRctTEbuKfMSycybRRsbezz1mEfugI6JNhhHgYxtdBlvjmsLsd6MXOpZ0Ky5o9Vp8EeriSAQohtFfPldwCAITgB5usIoRfAPRODE/OKvHJGL+dbqrxT4baWIMuAPvJGqGcIK2og== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.117.161) smtp.rcpttodomain=edk2.groups.io smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none X-Received: from BN0PR02CA0040.namprd02.prod.outlook.com (2603:10b6:408:e5::15) by CH3PR12MB8257.namprd12.prod.outlook.com (2603:10b6:610:121::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6521.26; Thu, 29 Jun 2023 20:54:05 +0000 X-Received: from BN8NAM11FT007.eop-nam11.prod.protection.outlook.com (2603:10b6:408:e5:cafe::a4) by BN0PR02CA0040.outlook.office365.com (2603:10b6:408:e5::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6521.35 via Frontend Transport; Thu, 29 Jun 2023 20:54:05 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.117.161) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+106532+1787277+3901457@groups.io; helo=mail02.groups.io; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.117.161 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.117.161; helo=mail.nvidia.com; pr=C X-Received: from mail.nvidia.com (216.228.117.161) by BN8NAM11FT007.mail.protection.outlook.com (10.13.177.109) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6500.49 via Frontend Transport; Thu, 29 Jun 2023 20:54:05 +0000 X-Received: from rnnvmail202.nvidia.com (10.129.68.7) by mail.nvidia.com (10.129.200.67) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.5; Thu, 29 Jun 2023 13:53:50 -0700 X-Received: from rnnvmail201.nvidia.com (10.129.68.8) by rnnvmail202.nvidia.com (10.129.68.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.37; Thu, 29 Jun 2023 13:53:49 -0700 X-Received: from 6cd8174ac25c.nvidia.com (10.127.8.9) by mail.nvidia.com (10.129.68.8) with Microsoft SMTP Server id 15.2.986.37 via Frontend Transport; Thu, 29 Jun 2023 13:53:49 -0700 From: "Jeff Brasen via groups.io" To: CC: , , , , Jeff Brasen Subject: [edk2-devel] [PATCH] MdeModulePkg/PciHostBridge: Add support for driver binding Date: Thu, 29 Jun 2023 20:53:45 +0000 Message-ID: <6add8a5bbb40cd1602acc09345496043ac47fc3e.1688071965.git.jbrasen@nvidia.com> MIME-Version: 1.0 X-NVConfidentiality: public X-NV-OnPremToCloud: ExternallySecured X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BN8NAM11FT007:EE_|CH3PR12MB8257:EE_ X-MS-Office365-Filtering-Correlation-Id: 0773debb-f0fc-4c66-bdc5-08db78e2f9f9 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: SbKu35pEV+Uld38maiToB5Sj3KVpID3A1Eni2h7IcydM/i6X4knW2Iyc5t1Z6bC4QOjcyjbXoKrGRvh2zbg8frXEmd9YRZQzgB3WRdiaabjeOG2Ps+W5tL+MTULAlfCS6iFshVk2A3s2zPMMvJpIqtfY+CZe/9rmkz5pX3tnf3EzSRCs6pSmWUSc5tIvowvtD04HtEeFZo0ryOlE+/Xl31++20VEMgQvORs2TczF9nB1+HN4/+lJ6YPdWrJxnLVVB0zAYIo+utkndWvl23NhdA1i5GptzghWLNqrezKwOP/xU9n+0rVeCRvaVh3BzGqtZwC5CjwND4BkMOYQIF1qUOEX/v0R1BYeuvvf0NPTNmQHGZTNHRXL9om5qj8iwCLunRqgtEUvtjLXvzlXZNaLrXp+BvvRv+M7o1DACKX6jkJk6aZA8/Erks6AHEEUEukE5CV5fcX1byNub8zDF7++zuHhpxZDr28Zys2mBnxR/6be3mBr1M98Y+N2x/MihE9ViPlTvaMHSN3DR/aS2LQ8vvNPmY8UZD/KD0oTNGFgN3yZccnc0RCpGcMhTXyCNC7asFxbVdSNe1UvdNiZ/vnv5QKLWUALlJh5Jv+MYd6la28N84HTKFgkcXtaPescOmn8eneSiqim2vuaYdSth/jMT9zFMb8xrVqT4MJAJamCVlEl4FghsVJrSpgPtsVH3xEd+tlN7X06U1R2UxkEPL3h2AiNgMiN2ukdQ0AkIGUjWKq5f+S5S+BpDV5Zlvjl8Tp175/S8JtJYKb3xGLlTPJsgMLrPaaGAbgW+SJMhx2wRds= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Jun 2023 20:54:05.2861 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 0773debb-f0fc-4c66-bdc5-08db78e2f9f9 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[216.228.117.161];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BN8NAM11FT007.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH3PR12MB8257 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,jbrasen@nvidia.com X-Gm-Message-State: pJpHhm4qxztrnA7qX55AaV4Vx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1688072051; bh=HyW+cTHnGuQnLdd+S+3CmJ79t+odYny17MdJ93LqQrY=; h=CC:Content-Type:Date:From:Reply-To:Subject:To; b=Dqhuc283NC+H5izEyLQFA9+DV9Whw53Czh7ZzeahfSFsPigktOxC76vV6JybagmbwQk iCFBhU6uqebjaXuMeTuJ9NAbs80vwjFd3L5Gq0riZgwiSokPUwU4ZqU/prjxPOCFohExl +VU+VzBLX/pAVxQHo6oIg84RHRpAqSsSIlY= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1688072052787100003 Content-Type: text/plain; charset="utf-8" If the platform does not support any PCIe devices using the library method allow devices to connect to host bridge via driver binding. Signed-off-by: Jeff Brasen --- .../Bus/Pci/PciHostBridgeDxe/PciHostBridge.c | 649 ++++++++++++++---- .../Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf | 1 + .../Bus/Pci/PciHostBridgeDxe/PciRootBridge.h | 13 + .../Pci/PciHostBridgeDxe/PciRootBridgeIo.c | 24 + MdeModulePkg/MdeModulePkg.dec | 4 + 5 files changed, 562 insertions(+), 129 deletions(-) diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c b/MdeMod= ulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c index d573e532ba..506c6660ae 100644 --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c +++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c @@ -422,167 +422,320 @@ IoMmuProtocolCallback ( } =20 /** + PCI Root Bridge Memory setup. =20 - Entry point of this driver. + @param RootBridge Root Bridge instance. =20 - @param ImageHandle Image handle of this driver. - @param SystemTable Pointer to standard EFI system table. - - @retval EFI_SUCCESS Succeed. - @retval EFI_DEVICE_ERROR Fail to install PCI_ROOT_BRIDGE_IO protocol. + @retval EFI_SUCCESS Memory was setup correctly + @retval others Error in setup =20 **/ EFI_STATUS EFIAPI -InitializePciHostBridge ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable +PciRootBridgeMemorySetup ( + IN PCI_ROOT_BRIDGE *RootBridge ) { EFI_STATUS Status; - PCI_HOST_BRIDGE_INSTANCE *HostBridge; - PCI_ROOT_BRIDGE_INSTANCE *RootBridge; - PCI_ROOT_BRIDGE *RootBridges; - UINTN RootBridgeCount; - UINTN Index; + UINT64 HostAddress; PCI_ROOT_BRIDGE_APERTURE *MemApertures[4]; UINTN MemApertureIndex; - BOOLEAN ResourceAssigned; - LIST_ENTRY *Link; - UINT64 HostAddress; =20 - RootBridges =3D PciHostBridgeGetRootBridges (&RootBridgeCount); - if ((RootBridges =3D=3D NULL) || (RootBridgeCount =3D=3D 0)) { - return EFI_UNSUPPORTED; - } - - Status =3D gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID **)= &mCpuIo); - ASSERT_EFI_ERROR (Status); - - // - // Most systems in the world including complex servers have only one Hos= t Bridge. - // - HostBridge =3D AllocateZeroPool (sizeof (PCI_HOST_BRIDGE_INSTANCE)); - ASSERT (HostBridge !=3D NULL); - - HostBridge->Signature =3D PCI_HOST_BRIDGE_SIGNATURE; - HostBridge->CanRestarted =3D TRUE; - InitializeListHead (&HostBridge->RootBridges); - ResourceAssigned =3D FALSE; - - // - // Create Root Bridge Device Handle in this Host Bridge - // - for (Index =3D 0; Index < RootBridgeCount; Index++) { + if (RootBridge->Io.Base <=3D RootBridge->Io.Limit) { // - // Create Root Bridge Handle Instance + // Base and Limit in PCI_ROOT_BRIDGE_APERTURE are device address. + // For GCD resource manipulation, we need to use host address. // - RootBridge =3D CreateRootBridge (&RootBridges[Index]); - ASSERT (RootBridge !=3D NULL); - if (RootBridge =3D=3D NULL) { - continue; + HostAddress =3D TO_HOST_ADDRESS ( + RootBridge->Io.Base, + RootBridge->Io.Translation + ); + + Status =3D AddIoSpace ( + HostAddress, + RootBridge->Io.Limit - RootBridge->Io.Base + 1 + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; } =20 - // - // Make sure all root bridges share the same ResourceAssigned value. - // - if (Index =3D=3D 0) { - ResourceAssigned =3D RootBridges[Index].ResourceAssigned; - } else { - ASSERT (ResourceAssigned =3D=3D RootBridges[Index].ResourceAssigned); + if (RootBridge->ResourceAssigned) { + Status =3D gDS->AllocateIoSpace ( + EfiGcdAllocateAddress, + EfiGcdIoTypeIo, + 0, + RootBridge->Io.Limit - RootBridge->Io.Base + 1, + &HostAddress, + gImageHandle, + NULL + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; + } } + } + + // + // Add all the Mem/PMem aperture to GCD + // Mem/PMem shouldn't overlap with each other + // Root bridge which needs to combine MEM and PMEM should only report + // the MEM aperture in Mem + // + MemApertures[0] =3D &RootBridge->Mem; + MemApertures[1] =3D &RootBridge->MemAbove4G; + MemApertures[2] =3D &RootBridge->PMem; + MemApertures[3] =3D &RootBridge->PMemAbove4G; =20 - if (RootBridges[Index].Io.Base <=3D RootBridges[Index].Io.Limit) { + for (MemApertureIndex =3D 0; MemApertureIndex < ARRAY_SIZE (MemApertures= ); MemApertureIndex++) { + if (MemApertures[MemApertureIndex]->Base <=3D MemApertures[MemAperture= Index]->Limit) { // // Base and Limit in PCI_ROOT_BRIDGE_APERTURE are device address. // For GCD resource manipulation, we need to use host address. // HostAddress =3D TO_HOST_ADDRESS ( - RootBridges[Index].Io.Base, - RootBridges[Index].Io.Translation + MemApertures[MemApertureIndex]->Base, + MemApertures[MemApertureIndex]->Translation ); - - Status =3D AddIoSpace ( + Status =3D AddMemoryMappedIoSpace ( HostAddress, - RootBridges[Index].Io.Limit - RootBridges[Index].Io.Base = + 1 + MemApertures[MemApertureIndex]->Limit - MemApertures[MemA= pertureIndex]->Base + 1, + EFI_MEMORY_UC ); ASSERT_EFI_ERROR (Status); - if (ResourceAssigned) { - Status =3D gDS->AllocateIoSpace ( + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D gDS->SetMemorySpaceAttributes ( + HostAddress, + MemApertures[MemApertureIndex]->Limit - MemApertures= [MemApertureIndex]->Base + 1, + EFI_MEMORY_UC + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "PciHostBridge driver failed to set EFI_MEMORY= _UC to MMIO aperture - %r.\n", Status)); + } + + if (RootBridge->ResourceAssigned) { + Status =3D gDS->AllocateMemorySpace ( EfiGcdAllocateAddress, - EfiGcdIoTypeIo, + EfiGcdMemoryTypeMemoryMappedIo, 0, - RootBridges[Index].Io.Limit - RootBridges[Index].I= o.Base + 1, + MemApertures[MemApertureIndex]->Limit - MemApertur= es[MemApertureIndex]->Base + 1, &HostAddress, gImageHandle, NULL ); ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; + } } } + } + + return EFI_SUCCESS; +} =20 +/** + PCI Root Bridge Memory free. + + @param RootBridge Root Bridge instance. + + @retval EFI_SUCCESS Memory was setup correctly + @retval others Error in setup + +**/ +EFI_STATUS +EFIAPI +PciRootBridgeMemoryFree ( + IN PCI_ROOT_BRIDGE *RootBridge + ) +{ + EFI_STATUS Status; + UINT64 HostAddress; + PCI_ROOT_BRIDGE_APERTURE *MemApertures[4]; + UINTN MemApertureIndex; + + if (RootBridge->Io.Base <=3D RootBridge->Io.Limit) { // - // Add all the Mem/PMem aperture to GCD - // Mem/PMem shouldn't overlap with each other - // Root bridge which needs to combine MEM and PMEM should only report - // the MEM aperture in Mem + // Base and Limit in PCI_ROOT_BRIDGE_APERTURE are device address. + // For GCD resource manipulation, we need to use host address. // - MemApertures[0] =3D &RootBridges[Index].Mem; - MemApertures[1] =3D &RootBridges[Index].MemAbove4G; - MemApertures[2] =3D &RootBridges[Index].PMem; - MemApertures[3] =3D &RootBridges[Index].PMemAbove4G; - - for (MemApertureIndex =3D 0; MemApertureIndex < ARRAY_SIZE (MemApertur= es); MemApertureIndex++) { - if (MemApertures[MemApertureIndex]->Base <=3D MemApertures[MemApertu= reIndex]->Limit) { - // - // Base and Limit in PCI_ROOT_BRIDGE_APERTURE are device address. - // For GCD resource manipulation, we need to use host address. - // - HostAddress =3D TO_HOST_ADDRESS ( - MemApertures[MemApertureIndex]->Base, - MemApertures[MemApertureIndex]->Translation - ); - Status =3D AddMemoryMappedIoSpace ( - HostAddress, - MemApertures[MemApertureIndex]->Limit - MemApertures[Me= mApertureIndex]->Base + 1, - EFI_MEMORY_UC - ); + HostAddress =3D TO_HOST_ADDRESS ( + RootBridge->Io.Base, + RootBridge->Io.Translation + ); + + if (RootBridge->ResourceAssigned) { + Status =3D gDS->FreeIoSpace (HostAddress, RootBridge->Io.Limit - Roo= tBridge->Io.Base + 1); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; + } + } + } + + // + // Add all the Mem/PMem aperture to GCD + // Mem/PMem shouldn't overlap with each other + // Root bridge which needs to combine MEM and PMEM should only report + // the MEM aperture in Mem + // + MemApertures[0] =3D &RootBridge->Mem; + MemApertures[1] =3D &RootBridge->MemAbove4G; + MemApertures[2] =3D &RootBridge->PMem; + MemApertures[3] =3D &RootBridge->PMemAbove4G; + + for (MemApertureIndex =3D 0; MemApertureIndex < ARRAY_SIZE (MemApertures= ); MemApertureIndex++) { + if (MemApertures[MemApertureIndex]->Base <=3D MemApertures[MemAperture= Index]->Limit) { + // + // Base and Limit in PCI_ROOT_BRIDGE_APERTURE are device address. + // For GCD resource manipulation, we need to use host address. + // + HostAddress =3D TO_HOST_ADDRESS ( + MemApertures[MemApertureIndex]->Base, + MemApertures[MemApertureIndex]->Translation + ); + if (RootBridge->ResourceAssigned) { + Status =3D gDS->FreeMemorySpace (HostAddress, RootBridge->Io.Limit= - RootBridge->Io.Base + 1); ASSERT_EFI_ERROR (Status); - Status =3D gDS->SetMemorySpaceAttributes ( - HostAddress, - MemApertures[MemApertureIndex]->Limit - MemApertur= es[MemApertureIndex]->Base + 1, - EFI_MEMORY_UC - ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_WARN, "PciHostBridge driver failed to set EFI_MEMO= RY_UC to MMIO aperture - %r.\n", Status)); - } - - if (ResourceAssigned) { - Status =3D gDS->AllocateMemorySpace ( - EfiGcdAllocateAddress, - EfiGcdMemoryTypeMemoryMappedIo, - 0, - MemApertures[MemApertureIndex]->Limit - MemApert= ures[MemApertureIndex]->Base + 1, - &HostAddress, - gImageHandle, - NULL - ); - ASSERT_EFI_ERROR (Status); + return Status; } } } + } =20 - // - // Insert Root Bridge Handle Instance - // - InsertTailList (&HostBridge->RootBridges, &RootBridge->Link); + return EFI_SUCCESS; +} + +/** + Test to see if this driver supports ControllerHandle. Any ControllerHand= le + than contains a gEdkiiPciHostBridgeProtocolGuid protocol can be supporte= d. + + @param This Protocol instance pointer. + @param Controller Handle of device to test. + @param RemainingDevicePath Optional parameter use to pick a specific ch= ild + device to start. + + @retval EFI_SUCCESS This driver supports this device. + @retval EFI_ALREADY_STARTED This driver is already running on this devic= e. + @retval other This driver does not support this device. + +**/ +EFI_STATUS +EFIAPI +PciHostBrigeDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + PCI_ROOT_BRIDGE *PciRootBridge; + + // + // Check if Pci Host Bridge protocol is installed by platform + // + Status =3D gBS->OpenProtocol ( + Controller, + &gEdkiiPciHostBridgeProtocolGuid, + (VOID **)&PciRootBridge, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return Status; } =20 // - // When resources were assigned, it's not needed to expose - // PciHostBridgeResourceAllocation protocol. + // Close the protocol used to perform the supported test + // + gBS->CloseProtocol ( + Controller, + &gEdkiiPciHostBridgeProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + return EFI_SUCCESS; +} + +/** + Start this driver on ControllerHandle and enumerate Pci bus and start + all device under PCI bus. + + @param This Protocol instance pointer. + @param Controller Handle of device to bind driver to. + @param RemainingDevicePath Optional parameter use to pick a specific c= hild + device to start. + + @retval EFI_SUCCESS This driver is added to ControllerHandle. + @retval EFI_ALREADY_STARTED This driver is already running on Controlle= rHandle. + @retval other This driver does not support this device. + +**/ +EFI_STATUS +EFIAPI +PciHostBrigeDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + PCI_ROOT_BRIDGE *PciRootBridge; + PCI_ROOT_BRIDGE_INSTANCE *RootBridge; + PCI_HOST_BRIDGE_INSTANCE *HostBridge; + BOOLEAN MemorySetupDone; + + MemorySetupDone =3D FALSE; + // + // Check if Pci Host Bridge protocol is installed by platform // - if (!ResourceAssigned) { + Status =3D gBS->OpenProtocol ( + Controller, + &gEdkiiPciHostBridgeProtocolGuid, + (VOID **)&PciRootBridge, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return Status; + } + + RootBridge =3D CreateRootBridge (PciRootBridge); + ASSERT (RootBridge !=3D NULL); + if (RootBridge =3D=3D NULL) { + Status =3D EFI_DEVICE_ERROR; + goto ErrorExit; + } + + Status =3D PciRootBridgeMemorySetup (PciRootBridge); + if (EFI_ERROR (Status)) { + goto ErrorExit; + } + + MemorySetupDone =3D TRUE; + + if (!PciRootBridge->ResourceAssigned) { + // Create host bridge + HostBridge =3D AllocateZeroPool (sizeof (PCI_HOST_BRIDGE_INSTANCE)); + ASSERT (HostBridge !=3D NULL); + if (HostBridge =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + + HostBridge->Handle =3D 0; + HostBridge->Signature =3D PCI_HOST_BRIDGE_SIGNATURE; + HostBridge->CanRestarted =3D TRUE; + InitializeListHead (&HostBridge->RootBridges); + HostBridge->ResAlloc.NotifyPhase =3D NotifyPhase; HostBridge->ResAlloc.GetNextRootBridge =3D GetNextRootBridge; HostBridge->ResAlloc.GetAllocAttributes =3D GetAttributes; @@ -599,28 +752,266 @@ InitializePciHostBridge ( NULL ); ASSERT_EFI_ERROR (Status); - } + if (EFI_ERROR (Status)) { + goto ErrorExit; + } =20 - for (Link =3D GetFirstNode (&HostBridge->RootBridges) - ; !IsNull (&HostBridge->RootBridges, Link) - ; Link =3D GetNextNode (&HostBridge->RootBridges, Link) - ) - { - RootBridge =3D ROOT_BRIDGE_FROM_LINK (Link); + // + // Insert Root Bridge Handle Instance + // + InsertTailList (&HostBridge->RootBridges, &RootBridge->Link); RootBridge->RootBridgeIo.ParentHandle =3D HostBridge->Handle; + } else { + RootBridge->RootBridgeIo.ParentHandle =3D 0; + } =20 - Status =3D gBS->InstallMultipleProtocolInterfaces ( - &RootBridge->Handle, - &gEfiDevicePathProtocolGuid, - RootBridge->DevicePath, - &gEfiPciRootBridgeIoProtocolGuid, - &RootBridge->RootBridgeIo, - NULL - ); - ASSERT_EFI_ERROR (Status); + RootBridge->Handle =3D Controller; + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &RootBridge->Handle, + &gEfiPciRootBridgeIoProtocolGuid, + &RootBridge->RootBridgeIo, + NULL + ); + +ErrorExit: + if (EFI_ERROR (Status)) { + if (MemorySetupDone) { + PciRootBridgeMemoryFree (PciRootBridge); + } + + if (RootBridge !=3D NULL) { + if (!IsListEmpty (&RootBridge->Link)) { + RemoveEntryList (&RootBridge->Link); + } + + FreeRootBridge (RootBridge); + } + + gBS->CloseProtocol ( + Controller, + &gEdkiiPciHostBridgeProtocolGuid, + This->DriverBindingHandle, + Controller + ); } =20 - PciHostBridgeFreeRootBridges (RootBridges, RootBridgeCount); + return Status; +} + +/** + Stop this driver on ControllerHandle. Support stopping any child handles + created by this driver. + + @param This Protocol instance pointer. + @param Controller Handle of device to stop driver on. + @param NumberOfChildren Number of Handles in ChildHandleBuffer. If num= ber of + children is zero stop the entire bus driver. + @param ChildHandleBuffer List of Child Handles to Stop. + + @retval EFI_SUCCESS This driver is removed ControllerHandle. + @retval other This driver was not removed from this device. + +**/ +EFI_STATUS +EFIAPI +PciHostBrigeDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + EFI_STATUS Status; + PCI_ROOT_BRIDGE *PciRootBridge; + PCI_ROOT_BRIDGE_INSTANCE *RootBridge; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo; + + Status =3D gBS->HandleProtocol ( + Controller, + &gEfiPciRootBridgeIoProtocolGuid, + (VOID **)&RootBridgeIo + ); + if (EFI_ERROR (Status)) { + return Status; + } + + RootBridge =3D ROOT_BRIDGE_FROM_THIS (RootBridgeIo); + + Status =3D gBS->HandleProtocol ( + Controller, + &gEdkiiPciHostBridgeProtocolGuid, + (VOID **)&PciRootBridge + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D gBS->UninstallMultipleProtocolInterfaces ( + Controller, + &gEfiPciRootBridgeIoProtocolGuid, + (VOID **)&PciRootBridge + ); + if (EFI_ERROR (Status)) { + return Status; + } + + if (!IsListEmpty (&RootBridge->Link)) { + RemoveEntryList (&RootBridge->Link); + } + + PciRootBridgeMemoryFree (PciRootBridge); + + FreeRootBridge (RootBridge); + gBS->CloseProtocol ( + Controller, + &gEdkiiPciHostBridgeProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return EFI_SUCCESS; +} + +// +// PCI Bus Driver Global Variables +// +EFI_DRIVER_BINDING_PROTOCOL gPciHostBrigeDriverBinding =3D { + PciHostBrigeDriverBindingSupported, + PciHostBrigeDriverBindingStart, + PciHostBrigeDriverBindingStop, + 0xa, + NULL, + NULL +}; + +/** + + Entry point of this driver. + + @param ImageHandle Image handle of this driver. + @param SystemTable Pointer to standard EFI system table. + + @retval EFI_SUCCESS Succeed. + @retval EFI_DEVICE_ERROR Fail to install PCI_ROOT_BRIDGE_IO protocol. + +**/ +EFI_STATUS +EFIAPI +InitializePciHostBridge ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + PCI_HOST_BRIDGE_INSTANCE *HostBridge; + PCI_ROOT_BRIDGE_INSTANCE *RootBridge; + PCI_ROOT_BRIDGE *RootBridges; + UINTN RootBridgeCount; + UINTN Index; + BOOLEAN ResourceAssigned; + LIST_ENTRY *Link; + + Status =3D gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID **)= &mCpuIo); + ASSERT_EFI_ERROR (Status); + + RootBridges =3D PciHostBridgeGetRootBridges (&RootBridgeCount); + if ((RootBridges =3D=3D NULL) || (RootBridgeCount =3D=3D 0)) { + // Register for binding protocol if library enumeration is not used + Status =3D EfiLibInstallDriverBinding ( + ImageHandle, + SystemTable, + &gPciHostBrigeDriverBinding, + ImageHandle + ); + ASSERT_EFI_ERROR (Status); + } else { + // + // Most systems in the world including complex servers have only one H= ost Bridge. + // + HostBridge =3D AllocateZeroPool (sizeof (PCI_HOST_BRIDGE_INSTANCE)); + ASSERT (HostBridge !=3D NULL); + + HostBridge->Signature =3D PCI_HOST_BRIDGE_SIGNATURE; + HostBridge->CanRestarted =3D TRUE; + InitializeListHead (&HostBridge->RootBridges); + ResourceAssigned =3D FALSE; + + // + // Create Root Bridge Device Handle in this Host Bridge + // + for (Index =3D 0; Index < RootBridgeCount; Index++) { + // + // Create Root Bridge Handle Instance + // + RootBridge =3D CreateRootBridge (&RootBridges[Index]); + ASSERT (RootBridge !=3D NULL); + if (RootBridge =3D=3D NULL) { + continue; + } + + // + // Make sure all root bridges share the same ResourceAssigned value. + // + if (Index =3D=3D 0) { + ResourceAssigned =3D RootBridges[Index].ResourceAssigned; + } else { + ASSERT (ResourceAssigned =3D=3D RootBridges[Index].ResourceAssigne= d); + } + + Status =3D PciRootBridgeMemorySetup (&RootBridges[Index]); + if (EFI_ERROR (Status)) { + continue; + } + + // + // Insert Root Bridge Handle Instance + // + InsertTailList (&HostBridge->RootBridges, &RootBridge->Link); + } + + // + // When resources were assigned, it's not needed to expose + // PciHostBridgeResourceAllocation protocol. + // + if (!ResourceAssigned) { + HostBridge->ResAlloc.NotifyPhase =3D NotifyPhase; + HostBridge->ResAlloc.GetNextRootBridge =3D GetNextRootBridge; + HostBridge->ResAlloc.GetAllocAttributes =3D GetAttributes; + HostBridge->ResAlloc.StartBusEnumeration =3D StartBusEnumeration; + HostBridge->ResAlloc.SetBusNumbers =3D SetBusNumbers; + HostBridge->ResAlloc.SubmitResources =3D SubmitResources; + HostBridge->ResAlloc.GetProposedResources =3D GetProposedResources; + HostBridge->ResAlloc.PreprocessController =3D PreprocessController; + + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &HostBridge->Handle, + &gEfiPciHostBridgeResourceAllocationProtocolGuid, + &HostBridge->ResAlloc, + NULL + ); + ASSERT_EFI_ERROR (Status); + } + + for (Link =3D GetFirstNode (&HostBridge->RootBridges) + ; !IsNull (&HostBridge->RootBridges, Link) + ; Link =3D GetNextNode (&HostBridge->RootBridges, Link) + ) + { + RootBridge =3D ROOT_BRIDGE_FROM_LINK (Lin= k); + RootBridge->RootBridgeIo.ParentHandle =3D HostBridge->Handle; + + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &RootBridge->Handle, + &gEfiDevicePathProtocolGuid, + RootBridge->DevicePath, + &gEfiPciRootBridgeIoProtocolGuid, + &RootBridge->RootBridgeIo, + NULL + ); + ASSERT_EFI_ERROR (Status); + } + + PciHostBridgeFreeRootBridges (RootBridges, RootBridgeCount); + } =20 if (!EFI_ERROR (Status)) { mIoMmuEvent =3D EfiCreateProtocolNotifyEvent ( diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf b/M= deModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf index 9c24cacc30..ee4740b14f 100644 --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf +++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf @@ -46,6 +46,7 @@ gEfiPciRootBridgeIoProtocolGuid ## BY_START gEfiPciHostBridgeResourceAllocationProtocolGuid ## BY_START gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES + gEdkiiPciHostBridgeProtocolGuid ## SOMETIMES_CONSUMES =20 [Depex] gEfiCpuIo2ProtocolGuid AND diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h b/MdeMod= ulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h index 10a6200719..7923c4677b 100644 --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h +++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h @@ -93,6 +93,19 @@ CreateRootBridge ( IN PCI_ROOT_BRIDGE *Bridge ); =20 +/** + Free the Pci Root Bridge instance. + + @param Bridge The root bridge instance. + + @return The pointer to PCI_ROOT_BRIDGE_INSTANCE just created + or NULL if creation fails. +**/ +VOID +FreeRootBridge ( + IN PCI_ROOT_BRIDGE_INSTANCE *Bridge + ); + // // Protocol Member Function Prototypes // diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c b/MdeM= odulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c index 157a0ada80..f0eb465a9d 100644 --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c +++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c @@ -286,6 +286,30 @@ CreateRootBridge ( return RootBridge; } =20 +/** + Free the Pci Root Bridge instance. + + @param Bridge The root bridge instance. + + @return The pointer to PCI_ROOT_BRIDGE_INSTANCE just created + or NULL if creation fails. +**/ +VOID +FreeRootBridge ( + IN PCI_ROOT_BRIDGE_INSTANCE *Bridge + ) +{ + if (Bridge->ConfigBuffer !=3D NULL) { + FreePool (Bridge->ConfigBuffer); + } + + if (Bridge->DevicePath !=3D NULL) { + FreePool (Bridge->DevicePath); + } + + FreePool (Bridge); +} + /** Check parameters for IO,MMIO,PCI read/write services of PCI Root Bridge = IO. =20 diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index d65dae18aa..24700fa797 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -692,6 +692,10 @@ ## Include/Protocol/VariablePolicy.h gEdkiiVariablePolicyProtocolGuid =3D { 0x81D1675C, 0x86F6, 0x48DF, { 0xB= D, 0x95, 0x9A, 0x6E, 0x4F, 0x09, 0x25, 0xC3 } } =20 + ## Include/Library/PciHostBridgeLib.h + # Exposes a PCI_HOST_BRIDGE structure for driver binding usage + gEdkiiPciHostBridgeProtocolGuid =3D { 0xaff2b72d, 0x202e, 0x40e3, { 0x82= , 0xd5, 0x9f, 0x6f, 0x61, 0xaf, 0x2a, 0x0b } } + [PcdsFeatureFlag] ## Indicates if the platform can support update capsule across a system = reset.

# TRUE - Supports update capsule across a system reset.
--=20 2.25.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#106532): https://edk2.groups.io/g/devel/message/106532 Mute This Topic: https://groups.io/mt/99859311/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-