From mboxrd@z Thu Jan 1 00:00:00 1970 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 Authentication-Results: mx.groups.io; dkim=pass header.i=@nvidia.com header.s=selector2 header.b=XLhkU9HA; spf=permerror, err=parse error for token &{10 18 %{i}._ip.%{h}._ehlo.%{d}._spf.vali.email}: invalid domain name (domain: nvidia.com, ip: 40.107.243.53, mailfrom: jbrasen@nvidia.com) 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=G9XwWN5hqEPOXzq0DZsuUxd6NfL8/PkpDbSFIOtUFL4=; b=XLhkU9HAw9d3V8TyhrIKK1G3oPheZjuA0TlWsE6qEhB2nHn9/89t9eRaRXMhmFLngGJZ1mbmz/qJyE/8/JiaNVfdAw60jq5XsoyUA4Mh0RGXwwSSOQHzM7wxLzQ2HeRkKe2sA9sTt8DWvkl93Km4qsZy6osCDUwOm4D+Q8HcQmtzJnH55RJKJGolQoegzWH0d644pldL+VfepbxDoZDzO8Qqh7ges5aV7y1QVqN6oeb8wbKdhM8Zml8GPuK2MqaWXWSOB+saj4BBzgcKb58w850ffLA1rKGynHfyJx4Q/lFL2+9E0X7ZkWndKuvDWKnZlxM+n8iBdv5DnyHj5vVfog== 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 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 (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 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 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 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 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" To: CC: , , , , Jeff Brasen Subject: [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> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-NVConfidentiality: public Return-Path: jbrasen@nvidia.com 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: BCL: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-Forefront-Antispam-Report: CIP:216.228.117.161;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail.nvidia.com;PTR:dc6edge2.nvidia.com;CAT:NONE;SFS:(13230028)(4636009)(346002)(396003)(376002)(39860400002)(136003)(451199021)(40470700004)(36840700001)(46966006)(5660300002)(4326008)(6916009)(478600001)(70206006)(36756003)(316002)(70586007)(8936002)(8676002)(2906002)(6666004)(40460700003)(19627235002)(30864003)(36860700001)(54906003)(41300700001)(82310400005)(7696005)(40480700001)(186003)(47076005)(426003)(26005)(336012)(356005)(107886003)(86362001)(83380400001)(82740400003)(2616005)(7636003)(44824005)(14943795004);DIR:OUT;SFP:1101; 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 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain If the platform does not support any PCIe devices using the library=0D method allow devices to connect to host bridge via driver binding.=0D =0D Signed-off-by: Jeff Brasen =0D ---=0D .../Bus/Pci/PciHostBridgeDxe/PciHostBridge.c | 649 ++++++++++++++----=0D .../Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf | 1 +=0D .../Bus/Pci/PciHostBridgeDxe/PciRootBridge.h | 13 +=0D .../Pci/PciHostBridgeDxe/PciRootBridgeIo.c | 24 +=0D MdeModulePkg/MdeModulePkg.dec | 4 +=0D 5 files changed, 562 insertions(+), 129 deletions(-)=0D =0D diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c b/MdeMod= ulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c=0D index d573e532ba..506c6660ae 100644=0D --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c=0D +++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c=0D @@ -422,167 +422,320 @@ IoMmuProtocolCallback (=0D }=0D =0D /**=0D + PCI Root Bridge Memory setup.=0D =0D - Entry point of this driver.=0D + @param RootBridge Root Bridge instance.=0D =0D - @param ImageHandle Image handle of this driver.=0D - @param SystemTable Pointer to standard EFI system table.=0D -=0D - @retval EFI_SUCCESS Succeed.=0D - @retval EFI_DEVICE_ERROR Fail to install PCI_ROOT_BRIDGE_IO protocol.=0D + @retval EFI_SUCCESS Memory was setup correctly=0D + @retval others Error in setup=0D =0D **/=0D EFI_STATUS=0D EFIAPI=0D -InitializePciHostBridge (=0D - IN EFI_HANDLE ImageHandle,=0D - IN EFI_SYSTEM_TABLE *SystemTable=0D +PciRootBridgeMemorySetup (=0D + IN PCI_ROOT_BRIDGE *RootBridge=0D )=0D {=0D EFI_STATUS Status;=0D - PCI_HOST_BRIDGE_INSTANCE *HostBridge;=0D - PCI_ROOT_BRIDGE_INSTANCE *RootBridge;=0D - PCI_ROOT_BRIDGE *RootBridges;=0D - UINTN RootBridgeCount;=0D - UINTN Index;=0D + UINT64 HostAddress;=0D PCI_ROOT_BRIDGE_APERTURE *MemApertures[4];=0D UINTN MemApertureIndex;=0D - BOOLEAN ResourceAssigned;=0D - LIST_ENTRY *Link;=0D - UINT64 HostAddress;=0D =0D - RootBridges =3D PciHostBridgeGetRootBridges (&RootBridgeCount);=0D - if ((RootBridges =3D=3D NULL) || (RootBridgeCount =3D=3D 0)) {=0D - return EFI_UNSUPPORTED;=0D - }=0D -=0D - Status =3D gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID **)= &mCpuIo);=0D - ASSERT_EFI_ERROR (Status);=0D -=0D - //=0D - // Most systems in the world including complex servers have only one Hos= t Bridge.=0D - //=0D - HostBridge =3D AllocateZeroPool (sizeof (PCI_HOST_BRIDGE_INSTANCE));=0D - ASSERT (HostBridge !=3D NULL);=0D -=0D - HostBridge->Signature =3D PCI_HOST_BRIDGE_SIGNATURE;=0D - HostBridge->CanRestarted =3D TRUE;=0D - InitializeListHead (&HostBridge->RootBridges);=0D - ResourceAssigned =3D FALSE;=0D -=0D - //=0D - // Create Root Bridge Device Handle in this Host Bridge=0D - //=0D - for (Index =3D 0; Index < RootBridgeCount; Index++) {=0D + if (RootBridge->Io.Base <=3D RootBridge->Io.Limit) {=0D //=0D - // Create Root Bridge Handle Instance=0D + // Base and Limit in PCI_ROOT_BRIDGE_APERTURE are device address.=0D + // For GCD resource manipulation, we need to use host address.=0D //=0D - RootBridge =3D CreateRootBridge (&RootBridges[Index]);=0D - ASSERT (RootBridge !=3D NULL);=0D - if (RootBridge =3D=3D NULL) {=0D - continue;=0D + HostAddress =3D TO_HOST_ADDRESS (=0D + RootBridge->Io.Base,=0D + RootBridge->Io.Translation=0D + );=0D +=0D + Status =3D AddIoSpace (=0D + HostAddress,=0D + RootBridge->Io.Limit - RootBridge->Io.Base + 1=0D + );=0D + ASSERT_EFI_ERROR (Status);=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D }=0D =0D - //=0D - // Make sure all root bridges share the same ResourceAssigned value.=0D - //=0D - if (Index =3D=3D 0) {=0D - ResourceAssigned =3D RootBridges[Index].ResourceAssigned;=0D - } else {=0D - ASSERT (ResourceAssigned =3D=3D RootBridges[Index].ResourceAssigned)= ;=0D + if (RootBridge->ResourceAssigned) {=0D + Status =3D gDS->AllocateIoSpace (=0D + EfiGcdAllocateAddress,=0D + EfiGcdIoTypeIo,=0D + 0,=0D + RootBridge->Io.Limit - RootBridge->Io.Base + 1,=0D + &HostAddress,=0D + gImageHandle,=0D + NULL=0D + );=0D + ASSERT_EFI_ERROR (Status);=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D }=0D + }=0D +=0D + //=0D + // Add all the Mem/PMem aperture to GCD=0D + // Mem/PMem shouldn't overlap with each other=0D + // Root bridge which needs to combine MEM and PMEM should only report=0D + // the MEM aperture in Mem=0D + //=0D + MemApertures[0] =3D &RootBridge->Mem;=0D + MemApertures[1] =3D &RootBridge->MemAbove4G;=0D + MemApertures[2] =3D &RootBridge->PMem;=0D + MemApertures[3] =3D &RootBridge->PMemAbove4G;=0D =0D - if (RootBridges[Index].Io.Base <=3D RootBridges[Index].Io.Limit) {=0D + for (MemApertureIndex =3D 0; MemApertureIndex < ARRAY_SIZE (MemApertures= ); MemApertureIndex++) {=0D + if (MemApertures[MemApertureIndex]->Base <=3D MemApertures[MemAperture= Index]->Limit) {=0D //=0D // Base and Limit in PCI_ROOT_BRIDGE_APERTURE are device address.=0D // For GCD resource manipulation, we need to use host address.=0D //=0D HostAddress =3D TO_HOST_ADDRESS (=0D - RootBridges[Index].Io.Base,=0D - RootBridges[Index].Io.Translation=0D + MemApertures[MemApertureIndex]->Base,=0D + MemApertures[MemApertureIndex]->Translation=0D );=0D -=0D - Status =3D AddIoSpace (=0D + Status =3D AddMemoryMappedIoSpace (=0D HostAddress,=0D - RootBridges[Index].Io.Limit - RootBridges[Index].Io.Base = + 1=0D + MemApertures[MemApertureIndex]->Limit - MemApertures[MemA= pertureIndex]->Base + 1,=0D + EFI_MEMORY_UC=0D );=0D ASSERT_EFI_ERROR (Status);=0D - if (ResourceAssigned) {=0D - Status =3D gDS->AllocateIoSpace (=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D +=0D + Status =3D gDS->SetMemorySpaceAttributes (=0D + HostAddress,=0D + MemApertures[MemApertureIndex]->Limit - MemApertures= [MemApertureIndex]->Base + 1,=0D + EFI_MEMORY_UC=0D + );=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_WARN, "PciHostBridge driver failed to set EFI_MEMORY= _UC to MMIO aperture - %r.\n", Status));=0D + }=0D +=0D + if (RootBridge->ResourceAssigned) {=0D + Status =3D gDS->AllocateMemorySpace (=0D EfiGcdAllocateAddress,=0D - EfiGcdIoTypeIo,=0D + EfiGcdMemoryTypeMemoryMappedIo,=0D 0,=0D - RootBridges[Index].Io.Limit - RootBridges[Index].I= o.Base + 1,=0D + MemApertures[MemApertureIndex]->Limit - MemApertur= es[MemApertureIndex]->Base + 1,=0D &HostAddress,=0D gImageHandle,=0D NULL=0D );=0D ASSERT_EFI_ERROR (Status);=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D }=0D }=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D =0D +/**=0D + PCI Root Bridge Memory free.=0D +=0D + @param RootBridge Root Bridge instance.=0D +=0D + @retval EFI_SUCCESS Memory was setup correctly=0D + @retval others Error in setup=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +PciRootBridgeMemoryFree (=0D + IN PCI_ROOT_BRIDGE *RootBridge=0D + )=0D +{=0D + EFI_STATUS Status;=0D + UINT64 HostAddress;=0D + PCI_ROOT_BRIDGE_APERTURE *MemApertures[4];=0D + UINTN MemApertureIndex;=0D +=0D + if (RootBridge->Io.Base <=3D RootBridge->Io.Limit) {=0D //=0D - // Add all the Mem/PMem aperture to GCD=0D - // Mem/PMem shouldn't overlap with each other=0D - // Root bridge which needs to combine MEM and PMEM should only report= =0D - // the MEM aperture in Mem=0D + // Base and Limit in PCI_ROOT_BRIDGE_APERTURE are device address.=0D + // For GCD resource manipulation, we need to use host address.=0D //=0D - MemApertures[0] =3D &RootBridges[Index].Mem;=0D - MemApertures[1] =3D &RootBridges[Index].MemAbove4G;=0D - MemApertures[2] =3D &RootBridges[Index].PMem;=0D - MemApertures[3] =3D &RootBridges[Index].PMemAbove4G;=0D -=0D - for (MemApertureIndex =3D 0; MemApertureIndex < ARRAY_SIZE (MemApertur= es); MemApertureIndex++) {=0D - if (MemApertures[MemApertureIndex]->Base <=3D MemApertures[MemApertu= reIndex]->Limit) {=0D - //=0D - // Base and Limit in PCI_ROOT_BRIDGE_APERTURE are device address.= =0D - // For GCD resource manipulation, we need to use host address.=0D - //=0D - HostAddress =3D TO_HOST_ADDRESS (=0D - MemApertures[MemApertureIndex]->Base,=0D - MemApertures[MemApertureIndex]->Translation=0D - );=0D - Status =3D AddMemoryMappedIoSpace (=0D - HostAddress,=0D - MemApertures[MemApertureIndex]->Limit - MemApertures[Me= mApertureIndex]->Base + 1,=0D - EFI_MEMORY_UC=0D - );=0D + HostAddress =3D TO_HOST_ADDRESS (=0D + RootBridge->Io.Base,=0D + RootBridge->Io.Translation=0D + );=0D +=0D + if (RootBridge->ResourceAssigned) {=0D + Status =3D gDS->FreeIoSpace (HostAddress, RootBridge->Io.Limit - Roo= tBridge->Io.Base + 1);=0D + ASSERT_EFI_ERROR (Status);=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D + }=0D + }=0D +=0D + //=0D + // Add all the Mem/PMem aperture to GCD=0D + // Mem/PMem shouldn't overlap with each other=0D + // Root bridge which needs to combine MEM and PMEM should only report=0D + // the MEM aperture in Mem=0D + //=0D + MemApertures[0] =3D &RootBridge->Mem;=0D + MemApertures[1] =3D &RootBridge->MemAbove4G;=0D + MemApertures[2] =3D &RootBridge->PMem;=0D + MemApertures[3] =3D &RootBridge->PMemAbove4G;=0D +=0D + for (MemApertureIndex =3D 0; MemApertureIndex < ARRAY_SIZE (MemApertures= ); MemApertureIndex++) {=0D + if (MemApertures[MemApertureIndex]->Base <=3D MemApertures[MemAperture= Index]->Limit) {=0D + //=0D + // Base and Limit in PCI_ROOT_BRIDGE_APERTURE are device address.=0D + // For GCD resource manipulation, we need to use host address.=0D + //=0D + HostAddress =3D TO_HOST_ADDRESS (=0D + MemApertures[MemApertureIndex]->Base,=0D + MemApertures[MemApertureIndex]->Translation=0D + );=0D + if (RootBridge->ResourceAssigned) {=0D + Status =3D gDS->FreeMemorySpace (HostAddress, RootBridge->Io.Limit= - RootBridge->Io.Base + 1);=0D ASSERT_EFI_ERROR (Status);=0D - Status =3D gDS->SetMemorySpaceAttributes (=0D - HostAddress,=0D - MemApertures[MemApertureIndex]->Limit - MemApertur= es[MemApertureIndex]->Base + 1,=0D - EFI_MEMORY_UC=0D - );=0D if (EFI_ERROR (Status)) {=0D - DEBUG ((DEBUG_WARN, "PciHostBridge driver failed to set EFI_MEMO= RY_UC to MMIO aperture - %r.\n", Status));=0D - }=0D -=0D - if (ResourceAssigned) {=0D - Status =3D gDS->AllocateMemorySpace (=0D - EfiGcdAllocateAddress,=0D - EfiGcdMemoryTypeMemoryMappedIo,=0D - 0,=0D - MemApertures[MemApertureIndex]->Limit - MemApert= ures[MemApertureIndex]->Base + 1,=0D - &HostAddress,=0D - gImageHandle,=0D - NULL=0D - );=0D - ASSERT_EFI_ERROR (Status);=0D + return Status;=0D }=0D }=0D }=0D + }=0D =0D - //=0D - // Insert Root Bridge Handle Instance=0D - //=0D - InsertTailList (&HostBridge->RootBridges, &RootBridge->Link);=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + Test to see if this driver supports ControllerHandle. Any ControllerHand= le=0D + than contains a gEdkiiPciHostBridgeProtocolGuid protocol can be supporte= d.=0D +=0D + @param This Protocol instance pointer.=0D + @param Controller Handle of device to test.=0D + @param RemainingDevicePath Optional parameter use to pick a specific ch= ild=0D + device to start.=0D +=0D + @retval EFI_SUCCESS This driver supports this device.=0D + @retval EFI_ALREADY_STARTED This driver is already running on this devic= e.=0D + @retval other This driver does not support this device.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +PciHostBrigeDriverBindingSupported (=0D + IN EFI_DRIVER_BINDING_PROTOCOL *This,=0D + IN EFI_HANDLE Controller,=0D + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath=0D + )=0D +{=0D + EFI_STATUS Status;=0D + PCI_ROOT_BRIDGE *PciRootBridge;=0D +=0D + //=0D + // Check if Pci Host Bridge protocol is installed by platform=0D + //=0D + Status =3D gBS->OpenProtocol (=0D + Controller,=0D + &gEdkiiPciHostBridgeProtocolGuid,=0D + (VOID **)&PciRootBridge,=0D + This->DriverBindingHandle,=0D + Controller,=0D + EFI_OPEN_PROTOCOL_BY_DRIVER=0D + );=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D }=0D =0D //=0D - // When resources were assigned, it's not needed to expose=0D - // PciHostBridgeResourceAllocation protocol.=0D + // Close the protocol used to perform the supported test=0D + //=0D + gBS->CloseProtocol (=0D + Controller,=0D + &gEdkiiPciHostBridgeProtocolGuid,=0D + This->DriverBindingHandle,=0D + Controller=0D + );=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + Start this driver on ControllerHandle and enumerate Pci bus and start=0D + all device under PCI bus.=0D +=0D + @param This Protocol instance pointer.=0D + @param Controller Handle of device to bind driver to.=0D + @param RemainingDevicePath Optional parameter use to pick a specific c= hild=0D + device to start.=0D +=0D + @retval EFI_SUCCESS This driver is added to ControllerHandle.=0D + @retval EFI_ALREADY_STARTED This driver is already running on Controlle= rHandle.=0D + @retval other This driver does not support this device.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +PciHostBrigeDriverBindingStart (=0D + IN EFI_DRIVER_BINDING_PROTOCOL *This,=0D + IN EFI_HANDLE Controller,=0D + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath=0D + )=0D +{=0D + EFI_STATUS Status;=0D + PCI_ROOT_BRIDGE *PciRootBridge;=0D + PCI_ROOT_BRIDGE_INSTANCE *RootBridge;=0D + PCI_HOST_BRIDGE_INSTANCE *HostBridge;=0D + BOOLEAN MemorySetupDone;=0D +=0D + MemorySetupDone =3D FALSE;=0D + //=0D + // Check if Pci Host Bridge protocol is installed by platform=0D //=0D - if (!ResourceAssigned) {=0D + Status =3D gBS->OpenProtocol (=0D + Controller,=0D + &gEdkiiPciHostBridgeProtocolGuid,=0D + (VOID **)&PciRootBridge,=0D + This->DriverBindingHandle,=0D + Controller,=0D + EFI_OPEN_PROTOCOL_BY_DRIVER=0D + );=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D +=0D + RootBridge =3D CreateRootBridge (PciRootBridge);=0D + ASSERT (RootBridge !=3D NULL);=0D + if (RootBridge =3D=3D NULL) {=0D + Status =3D EFI_DEVICE_ERROR;=0D + goto ErrorExit;=0D + }=0D +=0D + Status =3D PciRootBridgeMemorySetup (PciRootBridge);=0D + if (EFI_ERROR (Status)) {=0D + goto ErrorExit;=0D + }=0D +=0D + MemorySetupDone =3D TRUE;=0D +=0D + if (!PciRootBridge->ResourceAssigned) {=0D + // Create host bridge=0D + HostBridge =3D AllocateZeroPool (sizeof (PCI_HOST_BRIDGE_INSTANCE));=0D + ASSERT (HostBridge !=3D NULL);=0D + if (HostBridge =3D=3D NULL) {=0D + Status =3D EFI_OUT_OF_RESOURCES;=0D + goto ErrorExit;=0D + }=0D +=0D + HostBridge->Handle =3D 0;=0D + HostBridge->Signature =3D PCI_HOST_BRIDGE_SIGNATURE;=0D + HostBridge->CanRestarted =3D TRUE;=0D + InitializeListHead (&HostBridge->RootBridges);=0D +=0D HostBridge->ResAlloc.NotifyPhase =3D NotifyPhase;=0D HostBridge->ResAlloc.GetNextRootBridge =3D GetNextRootBridge;=0D HostBridge->ResAlloc.GetAllocAttributes =3D GetAttributes;=0D @@ -599,28 +752,266 @@ InitializePciHostBridge (=0D NULL=0D );=0D ASSERT_EFI_ERROR (Status);=0D - }=0D + if (EFI_ERROR (Status)) {=0D + goto ErrorExit;=0D + }=0D =0D - for (Link =3D GetFirstNode (&HostBridge->RootBridges)=0D - ; !IsNull (&HostBridge->RootBridges, Link)=0D - ; Link =3D GetNextNode (&HostBridge->RootBridges, Link)=0D - )=0D - {=0D - RootBridge =3D ROOT_BRIDGE_FROM_LINK (Link)= ;=0D + //=0D + // Insert Root Bridge Handle Instance=0D + //=0D + InsertTailList (&HostBridge->RootBridges, &RootBridge->Link);=0D RootBridge->RootBridgeIo.ParentHandle =3D HostBridge->Handle;=0D + } else {=0D + RootBridge->RootBridgeIo.ParentHandle =3D 0;=0D + }=0D =0D - Status =3D gBS->InstallMultipleProtocolInterfaces (=0D - &RootBridge->Handle,=0D - &gEfiDevicePathProtocolGuid,=0D - RootBridge->DevicePath,=0D - &gEfiPciRootBridgeIoProtocolGuid,=0D - &RootBridge->RootBridgeIo,=0D - NULL=0D - );=0D - ASSERT_EFI_ERROR (Status);=0D + RootBridge->Handle =3D Controller;=0D + Status =3D gBS->InstallMultipleProtocolInterfaces (=0D + &RootBridge->Handle,=0D + &gEfiPciRootBridgeIoProtocolGuid,=0D + &RootBridge->RootBridgeIo,=0D + NULL=0D + );=0D +=0D +ErrorExit:=0D + if (EFI_ERROR (Status)) {=0D + if (MemorySetupDone) {=0D + PciRootBridgeMemoryFree (PciRootBridge);=0D + }=0D +=0D + if (RootBridge !=3D NULL) {=0D + if (!IsListEmpty (&RootBridge->Link)) {=0D + RemoveEntryList (&RootBridge->Link);=0D + }=0D +=0D + FreeRootBridge (RootBridge);=0D + }=0D +=0D + gBS->CloseProtocol (=0D + Controller,=0D + &gEdkiiPciHostBridgeProtocolGuid,=0D + This->DriverBindingHandle,=0D + Controller=0D + );=0D }=0D =0D - PciHostBridgeFreeRootBridges (RootBridges, RootBridgeCount);=0D + return Status;=0D +}=0D +=0D +/**=0D + Stop this driver on ControllerHandle. Support stopping any child handles= =0D + created by this driver.=0D +=0D + @param This Protocol instance pointer.=0D + @param Controller Handle of device to stop driver on.=0D + @param NumberOfChildren Number of Handles in ChildHandleBuffer. If num= ber of=0D + children is zero stop the entire bus driver.=0D + @param ChildHandleBuffer List of Child Handles to Stop.=0D +=0D + @retval EFI_SUCCESS This driver is removed ControllerHandle.=0D + @retval other This driver was not removed from this device.= =0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +PciHostBrigeDriverBindingStop (=0D + IN EFI_DRIVER_BINDING_PROTOCOL *This,=0D + IN EFI_HANDLE Controller,=0D + IN UINTN NumberOfChildren,=0D + IN EFI_HANDLE *ChildHandleBuffer=0D + )=0D +{=0D + EFI_STATUS Status;=0D + PCI_ROOT_BRIDGE *PciRootBridge;=0D + PCI_ROOT_BRIDGE_INSTANCE *RootBridge;=0D + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo;=0D +=0D + Status =3D gBS->HandleProtocol (=0D + Controller,=0D + &gEfiPciRootBridgeIoProtocolGuid,=0D + (VOID **)&RootBridgeIo=0D + );=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D +=0D + RootBridge =3D ROOT_BRIDGE_FROM_THIS (RootBridgeIo);=0D +=0D + Status =3D gBS->HandleProtocol (=0D + Controller,=0D + &gEdkiiPciHostBridgeProtocolGuid,=0D + (VOID **)&PciRootBridge=0D + );=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D +=0D + Status =3D gBS->UninstallMultipleProtocolInterfaces (=0D + Controller,=0D + &gEfiPciRootBridgeIoProtocolGuid,=0D + (VOID **)&PciRootBridge=0D + );=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D +=0D + if (!IsListEmpty (&RootBridge->Link)) {=0D + RemoveEntryList (&RootBridge->Link);=0D + }=0D +=0D + PciRootBridgeMemoryFree (PciRootBridge);=0D +=0D + FreeRootBridge (RootBridge);=0D + gBS->CloseProtocol (=0D + Controller,=0D + &gEdkiiPciHostBridgeProtocolGuid,=0D + This->DriverBindingHandle,=0D + Controller=0D + );=0D + return EFI_SUCCESS;=0D +}=0D +=0D +//=0D +// PCI Bus Driver Global Variables=0D +//=0D +EFI_DRIVER_BINDING_PROTOCOL gPciHostBrigeDriverBinding =3D {=0D + PciHostBrigeDriverBindingSupported,=0D + PciHostBrigeDriverBindingStart,=0D + PciHostBrigeDriverBindingStop,=0D + 0xa,=0D + NULL,=0D + NULL=0D +};=0D +=0D +/**=0D +=0D + Entry point of this driver.=0D +=0D + @param ImageHandle Image handle of this driver.=0D + @param SystemTable Pointer to standard EFI system table.=0D +=0D + @retval EFI_SUCCESS Succeed.=0D + @retval EFI_DEVICE_ERROR Fail to install PCI_ROOT_BRIDGE_IO protocol.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +InitializePciHostBridge (=0D + IN EFI_HANDLE ImageHandle,=0D + IN EFI_SYSTEM_TABLE *SystemTable=0D + )=0D +{=0D + EFI_STATUS Status;=0D + PCI_HOST_BRIDGE_INSTANCE *HostBridge;=0D + PCI_ROOT_BRIDGE_INSTANCE *RootBridge;=0D + PCI_ROOT_BRIDGE *RootBridges;=0D + UINTN RootBridgeCount;=0D + UINTN Index;=0D + BOOLEAN ResourceAssigned;=0D + LIST_ENTRY *Link;=0D +=0D + Status =3D gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID **)= &mCpuIo);=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + RootBridges =3D PciHostBridgeGetRootBridges (&RootBridgeCount);=0D + if ((RootBridges =3D=3D NULL) || (RootBridgeCount =3D=3D 0)) {=0D + // Register for binding protocol if library enumeration is not used=0D + Status =3D EfiLibInstallDriverBinding (=0D + ImageHandle,=0D + SystemTable,=0D + &gPciHostBrigeDriverBinding,=0D + ImageHandle=0D + );=0D + ASSERT_EFI_ERROR (Status);=0D + } else {=0D + //=0D + // Most systems in the world including complex servers have only one H= ost Bridge.=0D + //=0D + HostBridge =3D AllocateZeroPool (sizeof (PCI_HOST_BRIDGE_INSTANCE));=0D + ASSERT (HostBridge !=3D NULL);=0D +=0D + HostBridge->Signature =3D PCI_HOST_BRIDGE_SIGNATURE;=0D + HostBridge->CanRestarted =3D TRUE;=0D + InitializeListHead (&HostBridge->RootBridges);=0D + ResourceAssigned =3D FALSE;=0D +=0D + //=0D + // Create Root Bridge Device Handle in this Host Bridge=0D + //=0D + for (Index =3D 0; Index < RootBridgeCount; Index++) {=0D + //=0D + // Create Root Bridge Handle Instance=0D + //=0D + RootBridge =3D CreateRootBridge (&RootBridges[Index]);=0D + ASSERT (RootBridge !=3D NULL);=0D + if (RootBridge =3D=3D NULL) {=0D + continue;=0D + }=0D +=0D + //=0D + // Make sure all root bridges share the same ResourceAssigned value.= =0D + //=0D + if (Index =3D=3D 0) {=0D + ResourceAssigned =3D RootBridges[Index].ResourceAssigned;=0D + } else {=0D + ASSERT (ResourceAssigned =3D=3D RootBridges[Index].ResourceAssigne= d);=0D + }=0D +=0D + Status =3D PciRootBridgeMemorySetup (&RootBridges[Index]);=0D + if (EFI_ERROR (Status)) {=0D + continue;=0D + }=0D +=0D + //=0D + // Insert Root Bridge Handle Instance=0D + //=0D + InsertTailList (&HostBridge->RootBridges, &RootBridge->Link);=0D + }=0D +=0D + //=0D + // When resources were assigned, it's not needed to expose=0D + // PciHostBridgeResourceAllocation protocol.=0D + //=0D + if (!ResourceAssigned) {=0D + HostBridge->ResAlloc.NotifyPhase =3D NotifyPhase;=0D + HostBridge->ResAlloc.GetNextRootBridge =3D GetNextRootBridge;=0D + HostBridge->ResAlloc.GetAllocAttributes =3D GetAttributes;=0D + HostBridge->ResAlloc.StartBusEnumeration =3D StartBusEnumeration;=0D + HostBridge->ResAlloc.SetBusNumbers =3D SetBusNumbers;=0D + HostBridge->ResAlloc.SubmitResources =3D SubmitResources;=0D + HostBridge->ResAlloc.GetProposedResources =3D GetProposedResources;= =0D + HostBridge->ResAlloc.PreprocessController =3D PreprocessController;= =0D +=0D + Status =3D gBS->InstallMultipleProtocolInterfaces (=0D + &HostBridge->Handle,=0D + &gEfiPciHostBridgeResourceAllocationProtocolGuid,=0D + &HostBridge->ResAlloc,=0D + NULL=0D + );=0D + ASSERT_EFI_ERROR (Status);=0D + }=0D +=0D + for (Link =3D GetFirstNode (&HostBridge->RootBridges)=0D + ; !IsNull (&HostBridge->RootBridges, Link)=0D + ; Link =3D GetNextNode (&HostBridge->RootBridges, Link)=0D + )=0D + {=0D + RootBridge =3D ROOT_BRIDGE_FROM_LINK (Lin= k);=0D + RootBridge->RootBridgeIo.ParentHandle =3D HostBridge->Handle;=0D +=0D + Status =3D gBS->InstallMultipleProtocolInterfaces (=0D + &RootBridge->Handle,=0D + &gEfiDevicePathProtocolGuid,=0D + RootBridge->DevicePath,=0D + &gEfiPciRootBridgeIoProtocolGuid,=0D + &RootBridge->RootBridgeIo,=0D + NULL=0D + );=0D + ASSERT_EFI_ERROR (Status);=0D + }=0D +=0D + PciHostBridgeFreeRootBridges (RootBridges, RootBridgeCount);=0D + }=0D =0D if (!EFI_ERROR (Status)) {=0D mIoMmuEvent =3D EfiCreateProtocolNotifyEvent (=0D diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf b/M= deModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf=0D index 9c24cacc30..ee4740b14f 100644=0D --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf=0D +++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf=0D @@ -46,6 +46,7 @@=0D gEfiPciRootBridgeIoProtocolGuid ## BY_START=0D gEfiPciHostBridgeResourceAllocationProtocolGuid ## BY_START=0D gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES=0D + gEdkiiPciHostBridgeProtocolGuid ## SOMETIMES_CONSUMES=0D =0D [Depex]=0D gEfiCpuIo2ProtocolGuid AND=0D diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h b/MdeMod= ulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h=0D index 10a6200719..7923c4677b 100644=0D --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h=0D +++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h=0D @@ -93,6 +93,19 @@ CreateRootBridge (=0D IN PCI_ROOT_BRIDGE *Bridge=0D );=0D =0D +/**=0D + Free the Pci Root Bridge instance.=0D +=0D + @param Bridge The root bridge instance.=0D +=0D + @return The pointer to PCI_ROOT_BRIDGE_INSTANCE just created=0D + or NULL if creation fails.=0D +**/=0D +VOID=0D +FreeRootBridge (=0D + IN PCI_ROOT_BRIDGE_INSTANCE *Bridge=0D + );=0D +=0D //=0D // Protocol Member Function Prototypes=0D //=0D diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c b/MdeM= odulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c=0D index 157a0ada80..f0eb465a9d 100644=0D --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c=0D +++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c=0D @@ -286,6 +286,30 @@ CreateRootBridge (=0D return RootBridge;=0D }=0D =0D +/**=0D + Free the Pci Root Bridge instance.=0D +=0D + @param Bridge The root bridge instance.=0D +=0D + @return The pointer to PCI_ROOT_BRIDGE_INSTANCE just created=0D + or NULL if creation fails.=0D +**/=0D +VOID=0D +FreeRootBridge (=0D + IN PCI_ROOT_BRIDGE_INSTANCE *Bridge=0D + )=0D +{=0D + if (Bridge->ConfigBuffer !=3D NULL) {=0D + FreePool (Bridge->ConfigBuffer);=0D + }=0D +=0D + if (Bridge->DevicePath !=3D NULL) {=0D + FreePool (Bridge->DevicePath);=0D + }=0D +=0D + FreePool (Bridge);=0D +}=0D +=0D /**=0D Check parameters for IO,MMIO,PCI read/write services of PCI Root Bridge = IO.=0D =0D diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec= =0D index d65dae18aa..24700fa797 100644=0D --- a/MdeModulePkg/MdeModulePkg.dec=0D +++ b/MdeModulePkg/MdeModulePkg.dec=0D @@ -692,6 +692,10 @@=0D ## Include/Protocol/VariablePolicy.h=0D gEdkiiVariablePolicyProtocolGuid =3D { 0x81D1675C, 0x86F6, 0x48DF, { 0xB= D, 0x95, 0x9A, 0x6E, 0x4F, 0x09, 0x25, 0xC3 } }=0D =0D + ## Include/Library/PciHostBridgeLib.h=0D + # Exposes a PCI_HOST_BRIDGE structure for driver binding usage=0D + gEdkiiPciHostBridgeProtocolGuid =3D { 0xaff2b72d, 0x202e, 0x40e3, { 0x82= , 0xd5, 0x9f, 0x6f, 0x61, 0xaf, 0x2a, 0x0b } }=0D +=0D [PcdsFeatureFlag]=0D ## Indicates if the platform can support update capsule across a system = reset.

=0D # TRUE - Supports update capsule across a system reset.
=0D -- =0D 2.25.1=0D =0D