From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM11-DM6-obe.outbound.protection.outlook.com (NAM11-DM6-obe.outbound.protection.outlook.com [40.107.223.41]) by mx.groups.io with SMTP id smtpd.web10.16308.1688140636061797340 for ; Fri, 30 Jun 2023 08:57:16 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@nvidia.com header.s=selector2 header.b=UXJPVWxS; 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.223.41, mailfrom: jbrasen@nvidia.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=BLsR4lcyzVn9F5273+WNvSWT8T3v2Tk6rUwdyQVllL+nNMz6mFAX9LAAldmmRJ8Ott47eg8YGKXCc26I4Z3FM+xXCIP+S8DQVPUP+Ohx5i3FA/aH1ABdCMdVQQvZT63ENRxujZz5QTt8rSAxZUkW7aMzTMfz5f32pj5+BOKJgZttZ81PUndGX396v8E+T9zarvPPK1eocb5k8+obR7GOStn0W3l4fzGTZc/Ubj4KwrRwclJdEY7M6cj1sMRU9bXntmOcav7NlvVwaFnB6ZG8vZzrJD8L15j8Z+8VYBGIbtMQnjWJI3H5GZP/S7QI/bakzeCfaluC4f2PI/KZku1kQg== 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=1VcuUepdi0k2ewt+W5e9jL+A59OWaH8VLJH+3yyhSRQ=; b=OJ4CAsmqx2QCDjOb3DEBCf8Z86RfEc1Trf6eUV7OBon64RSX2QRZo21jGK+w3Z0YS4I+eX4HelGYe/cniBn0IphrqPk1noCz45OwQ5ee1uOKDA/++BgvUgBda0CFEDKxTxBBaJtpPbonheLs4TV/Hm9nHRDNBWC5PP6NzsPp3RK7aC1RDRxPYByQdN93LOFvSDGykSp5ztHiz+4Ikee0bXrVfkai2YU2guAxG8ECo2ipkEH8XC0Q7/syMXeG94BxbrU82jnIwSbGtWHfbelPjkMwhOWzWoJgOME8kYtnQGbIa3/ueuefeMZ7JrnP9MLaS3z6a/RgT/Uw3+uQbTv+PA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; 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=1VcuUepdi0k2ewt+W5e9jL+A59OWaH8VLJH+3yyhSRQ=; b=UXJPVWxSBlwGXsNPSv0TFaEAbeW5AfsHsaSsxqDxtNpzzRjI256QgFDGOThbk7RFZGDa/yzlO6OY4zfj1d+WZ1eQBWZ4qqNKWpnd7SOAK5JGZ86gMDo7esuS6eD8TceWbkaV2i2s8b59ztUGYZCjmpU6sd72yCJRQYX0VlZCn6BbEy+duNNCsKDOlxgYuXQFozPruEtbAXH++D4tj7KeEd/tQXFvS2bQjBPCm7rRvw+zYM36m39fdPBc9eUXgO3qmlUtQHK/Ori1fSrHaYUGkXDHTEPIj4BPRMSNUeK4OcLeRK+YCZchh7UaPn+4ov9MVsX7gBQ+wFBD9vrDrgnTSg== Received: from DS7PR12MB5789.namprd12.prod.outlook.com (2603:10b6:8:74::21) by CH3PR12MB8353.namprd12.prod.outlook.com (2603:10b6:610:12c::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6521.26; Fri, 30 Jun 2023 15:57:13 +0000 Received: from DS7PR12MB5789.namprd12.prod.outlook.com ([fe80::a5f2:5641:7bf8:84a4]) by DS7PR12MB5789.namprd12.prod.outlook.com ([fe80::a5f2:5641:7bf8:84a4%4]) with mapi id 15.20.6544.019; Fri, 30 Jun 2023 15:57:12 +0000 From: "Jeff Brasen" To: "Ni, Ray" , "devel@edk2.groups.io" CC: "Wang, Jian J" , "Gao, Liming" , "Wu, Hao A" Subject: Re: [PATCH] MdeModulePkg/PciHostBridge: Add support for driver binding Thread-Topic: [PATCH] MdeModulePkg/PciHostBridge: Add support for driver binding Thread-Index: AQHZqsva1IIzn7T6d0y/htmTfHXEKq+in76AgAANIdCAAAv4gIAAx2jg Date: Fri, 30 Jun 2023 15:57:12 +0000 Message-ID: References: <6add8a5bbb40cd1602acc09345496043ac47fc3e.1688071965.git.jbrasen@nvidia.com> In-Reply-To: Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: DS7PR12MB5789:EE_|CH3PR12MB8353:EE_ x-ms-office365-filtering-correlation-id: 050dd6fb-a09c-41fd-7a81-08db7982ab3b x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: BU9GCBNLpsfSveVMnLGjU3JN3ulH2bnrtAZ9XR1ejKgTydMRg3y03Iwr5EnijoaE/zVZoTLm9RdIguYNrx0204+FupaMReUcnL2zIsjN+rDg0PnSxUHO+KLjxgCw46wHOREDoCVFV6mDpIrsDl9dERw/BCQLNrzRxdu+XAdLqWeKwY83qVZqbD4Wc/6tDgLZUogMdoo9Hzv1m0rd7KSo0EHHuEAgbg7T1kEPVntl8Zn2T9xfL/9Wa7s8QuMvCmxEv9otx/nacKJDSo26Xku3pInEBiIxeShg7GEJARlt296UygGF1SqxmJLKBUZ8g65/vc9boxldQ42k2rbjIfeVoU5qPjXCIcje0Z+sKyJ7zX9+nt111XuYl9CpVqw8Nn+le+CinF+EVXUr9OtJ8VD4k/i1CMhwy2yHoL8/B5vkVEBenDrJFpAE0VeYA0KxuLS/CyLfZ0ojcWDyDeYY2hnNnXewzlhbPe4eSr2nmKXar89Q9R9OAztlC0yJBzvSBgkrGauSgORlXxXNmfOuxCVDhZvBpH5K0aEiNG7IFZr9GM7oSnJYH7haAILUH4nZazWJnk7XV4pfTbwquYoAkaUJsZXUX1ImhBlp2NG1RLk9PPu6gIlWqwLusfSRzesjNVxIzPkK8iCJwlTESw1rNsm0WUNotfCxRZuZ0AsjXyOEW7M= x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DS7PR12MB5789.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230028)(4636009)(366004)(136003)(346002)(396003)(39860400002)(376002)(451199021)(76116006)(66899021)(186003)(2906002)(66476007)(66446008)(30864003)(5660300002)(26005)(55016003)(7696005)(33656002)(316002)(54906003)(8676002)(86362001)(19627235002)(478600001)(110136005)(4326008)(122000001)(38070700005)(38100700002)(9686003)(71200400001)(52536014)(66946007)(41300700001)(64756008)(66556008)(8936002)(83380400001)(6506007)(53546011)(559001)(579004)(44824005)(14943795004);DIR:OUT;SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?ApQcRwo8iW3x0G44OAkW3Lle9+Mb+4NcYQRv0qbuQ6+tLBBNNLquOg9Rl9vD?= =?us-ascii?Q?lNetry8aI/t0+uUC5jaSJZJvQSlxryBTUuXAAEdpRI+yD9BkPo5Pl0E9xSki?= =?us-ascii?Q?0X0mA6ILB2MhkirsHRYn4wCmHUj6Q9Y5jXQmIj9hQKA9ZuZfoiI6g4M5nNQa?= =?us-ascii?Q?C3VU7GvrnBVuxgAdoUve024PkhR5SxYXQSXhMqAoMp7jFB0yEmr9KuNk4qeF?= =?us-ascii?Q?SLB7EI8jZdjaCDDi/GPGynk7Erl1azMH7+Pj9cOloDIFYSEiVwHLD6e5WluY?= =?us-ascii?Q?VZvDoVaZoN5vwOCIPE5WADiruvxqNncH79czpCpRkrSVZHUXDUecYd5ACvK9?= =?us-ascii?Q?kFQoZZm0VdCPcxp0W4IoRyW48RmmqgK0Z7FzdJhMItYJFuZCUSM8YLhSgLZR?= =?us-ascii?Q?itq8nk64AtXGSlA5hrB56SZIwrokiGFi+eIkpFAu3YBK6dcxeWYTB/jouTF1?= =?us-ascii?Q?WE4/WCdhuzhHQOUh/NKcimMV756WWvjX0oeFpRB01IWP1YrrnoYlQ/84dXps?= =?us-ascii?Q?/4tCRquu9yB0toqueDlxJFopHVJ8W4NQiwvkoN1AHx525Jz4/S5EQC8cphC7?= =?us-ascii?Q?+dL6BVCTCQCwIeBwo68ZYHx5NEhEoz2G6YQV7mRHnqJwKxLQs6UnrgDZpad3?= =?us-ascii?Q?Ye1KtycE1FywOhqSvv7nF4Nryg+/bB0pRMz4X1jXA/Y43NciNlsrT3m0Fl9T?= =?us-ascii?Q?1vVp0syd3wg8PImrHu3zyX+t0NpZMeXdcaGlaMMIocmRJQOGILs8/2VWXZDY?= =?us-ascii?Q?K+tTPov9zheSnpq6g/kLDnZ3vRRkMQR0JGIcUvfiWib2VPJ1ayc04DaC+s9t?= =?us-ascii?Q?81WlYbyQmfESl8zNPsB6hhv90+xM1U2T38BmlyNJsHqgKbSvqVSp3fMHzXuA?= =?us-ascii?Q?KnaTHlRXTMGErYvd/AgqgEIIcNLQYnMLXeNzEkNUt1s6MCwC4ENrWxGt1+IT?= =?us-ascii?Q?jAWuTOlhtFFLtkq3E6ylRaCiBnpP0Cf8/59DCKMjB2I96uLiFn6VHmw1paau?= =?us-ascii?Q?FcrnmTNxgtdXR8OpwECNbNU7raAf1Vw6fgAAjvGhQm0HPhnSJ/Lwx3NerJmK?= =?us-ascii?Q?velbHWaYaQPC4/tTLS7Ll2l7vfyNtx98ATwmFchRbuv2rnKVDEea3yrI6Pue?= =?us-ascii?Q?R/LM7k1nbvNuqCmRp/zm1zGT3DePZqfXxlEaPK0K4NrTyJv8xrNs27Iz5lDe?= =?us-ascii?Q?SiHOWxeA1zakdGitCBPd/lTeiiswjSKMbqR6BwBQDZQJ9v9BHTlI/6iwBRh0?= =?us-ascii?Q?wNBLRAiivwp4Zy1MYd8xB/xnI60Ni+DvlU4Oe2Y9xr9SyxYpIO5f25FrsH37?= =?us-ascii?Q?LI8jEyGIMBg7FrD2RWZpSSSY0Z5AN6XPm87Nxp4KnP2ndwUFMcmcCPj4EgFg?= =?us-ascii?Q?3vM5p2KaOk1X4JxYIBL/T1XVuQRpxilM03QoNyQ43+4umAN805QKcLLwf3ng?= =?us-ascii?Q?VAHTgsTJ3Ho0VwlXO/Ze6rDcv4oUord2AogzAVEPIDrG/ho7GcsxUawPCnfO?= =?us-ascii?Q?J5eQjUQz9wx6PyM/o/3aYh7d6m/HxT1Z156HmJce2E0uawuXAg/ij8KLKtnh?= =?us-ascii?Q?U2/uBSeiQfZi34C+BCf7BL0rVGn/bn27G2SBL8JQ?= MIME-Version: 1.0 X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: DS7PR12MB5789.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 050dd6fb-a09c-41fd-7a81-08db7982ab3b X-MS-Exchange-CrossTenant-originalarrivaltime: 30 Jun 2023 15:57:12.8029 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: gA9Le7HpkLOxrojBoj3c40J5zINdmrC7qSpcJ8g1O3n0DvV13mamENOkin0tJLdtYtpNjQDDqjn50gJUymGagA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH3PR12MB8353 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable > -----Original Message----- > From: Ni, Ray > Sent: Thursday, June 29, 2023 9:59 PM > To: Jeff Brasen ; devel@edk2.groups.io > Cc: Wang, Jian J ; Gao, Liming > ; Wu, Hao A > Subject: RE: [PATCH] MdeModulePkg/PciHostBridge: Add support for driver > binding >=20 > External email: Use caution opening links or attachments >=20 >=20 > > -----Original Message----- > > From: Jeff Brasen > > Sent: Friday, June 30, 2023 11:21 AM > > To: Ni, Ray ; devel@edk2.groups.io > > Cc: Wang, Jian J ; Gao, Liming > > ; Wu, Hao A > > Subject: RE: [PATCH] MdeModulePkg/PciHostBridge: Add support for > > driver binding > > > > Not sure why the patch failed to apply I'll see if there is something > > wrong with my gitconfig tomorrow. The path you suggested below is > > exactly what our current implementation does. However, I am trying to > > make our pcie controller driver do async initialization so that using > > a depex is less ideal as we may have to postpone driver load to after > > end of dxe instead of just the connection. It seemed that a driver bind= ing > type approach was a good approach for this. >=20 > I am curious how the pcie root (root complex) initialization is done in a= sync > way? > Does it use a timer callback to poll the initialization status every cert= ain > interval? >=20 [JB] That is correct, we use a timer when we expect sleeps or polling loops= . > On the other hand, even you make PciHostBridge as a UEFI driver-model > driver, you still require some code to initiate the "ConnectController()"= . How is > that done? >=20 > Comparing the two paths (today's =3D my proposal, new way =3D your patch)= , > both require some code to explicitly call "ConnectController()". >=20 [JB] We have a sync point in BDS prior to the ConnectController call that i= s made. I could put that and a dispatch call prior to EndOfDxe signal but w= as hoping to not trigger any of the driver seen but not loaded debug messag= es from the main dispatch loop if possible as that can be a useful message = to trigger something might be wrong.=20 > > > > On a less important implementation if the pieces that live under the > > library are driver binding we have to reject any stop requests as > > there is no driver linkage between the two layers. >=20 > In x86, root complex (pcie root) is almost the root of all peripherals. I= cannot > see a value to Stop () the pcie root. > If you check the PciBus implementation, it supports Stop() but the Stop()= only > succeeds when all upper layer drivers succeed to Stop(). (usually it's no= t the > case.) And even PciBus.Stop() succeeds, the resource(MMIO/IO/BUS) > allocation is not un-done. It's only the PciIo handles that are destroyed= in > software level. >=20 [JB] Yeah, not allowing stop to work on this isn't a big deal (and what we = currently have implemented) but it was something we noticed a while ago is = that we couldn't implement this even if we wanted to as there was no way to= stop the host bridge driver. > Thanks, > Ray >=20 >=20 > > > > -Jeff > > > > > > -----Original Message----- > > From: Ni, Ray > > Sent: Thursday, June 29, 2023 8:29 PM > > To: Jeff Brasen ; devel@edk2.groups.io > > Cc: Wang, Jian J ; Gao, Liming > > ; Wu, Hao A > > Subject: RE: [PATCH] MdeModulePkg/PciHostBridge: Add support for > > driver binding > > > > External email: Use caution opening links or attachments > > > > > > I failed to apply the patch in my local tree. > > > > It seems you invented a new EdkiiRootBridgeIo protocol and a certain > > proprietary driver would produce this protocol instance. > > Then the open source PciHostBridge driver starts on that. > > > > Then, why not implement your own PciHostBridgeLib and let it depends > > on some "AllRootBridgeIoInformationIsReady" protocol. > > So that the PciHostBridge driver could still call PciHostBridgeLib and > > all your implementation in this patch can be in that lib. > > > > Thanks, > > Ray > > > > > -----Original Message----- > > > From: Jeff Brasen > > > Sent: Friday, June 30, 2023 4:54 AM > > > To: devel@edk2.groups.io > > > Cc: Wang, Jian J ; Gao, Liming > > > ; Wu, Hao A ; Ni, Ray > > > ; Jeff Brasen > > > Subject: [PATCH] MdeModulePkg/PciHostBridge: Add support for driver > > > binding > > > > > > 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/MdeModulePkg/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 ( > > > > > > } > > > > > > > > > > > > /** > > > > > > + PCI Root Bridge Memory setup. > > > > > > > > > > > > - Entry point of this driver. > > > > > > + @param RootBridge Root Bridge instance. > > > > > > > > > > > > - @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 > > > > > > > > > > > > **/ > > > > > > 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; > > > > > > > > > > > > - 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 Host 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; > > > > > > } > > > > > > > > > > > > - // > > > > > > - // Make sure all root bridges share the same ResourceAssigned va= lue. > > > > > > - // > > > > > > - if (Index =3D=3D 0) { > > > > > > - ResourceAssigned =3D RootBridges[Index].ResourceAssigned; > > > > > > - } else { > > > > > > - ASSERT (ResourceAssigned =3D=3D RootBridges[Index].ResourceAss= igned); > > > > > > + 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; > > > > > > > > > > > > - 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[MemApertureIndex]->Limit) { > > > > > > // > > > > > > // Base and Limit in PCI_ROOT_BRIDGE_APERTURE are device addre= ss. > > > > > > // 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[MemApertureIndex]->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[In= dex].Io.Base + 1, > > > > > > + MemApertures[MemApertureIndex]->Limit - > > > MemApertures[MemApertureIndex]->Base + 1, > > > > > > &HostAddress, > > > > > > gImageHandle, > > > > > > NULL > > > > > > ); > > > > > > ASSERT_EFI_ERROR (Status); > > > > > > + if (EFI_ERROR (Status)) { > > > > > > + return Status; > > > > > > + } > > > > > > } > > > > > > } > > > > > > + } > > > > > > + > > > > > > + return EFI_SUCCESS; > > > > > > +} > > > > > > > > > > > > +/** > > > > > > + 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 > > > (MemApertures); MemApertureIndex++) { > > > > > > - if (MemApertures[MemApertureIndex]->Base <=3D > > > MemApertures[MemApertureIndex]->Limit) { > > > > > > - // > > > > > > - // Base and Limit in PCI_ROOT_BRIDGE_APERTURE are device add= ress. > > > > > > - // For GCD resource manipulation, we need to use host addres= s. > > > > > > - // > > > > > > - HostAddress =3D TO_HOST_ADDRESS ( > > > > > > - MemApertures[MemApertureIndex]->Base, > > > > > > - MemApertures[MemApertureIndex]->Translation > > > > > > - ); > > > > > > - Status =3D AddMemoryMappedIoSpace ( > > > > > > - HostAddress, > > > > > > - MemApertures[MemApertureIndex]->Limit - > > > MemApertures[MemApertureIndex]->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 > > > + - > > > + RootBridge- > > > >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[MemApertureIndex]->Limit) { > > > > > > + // > > > > > > + // Base and Limit in PCI_ROOT_BRIDGE_APERTURE are device addre= ss. > > > > > > + // 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 - > > > 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 (ResourceAssigned) { > > > > > > - Status =3D gDS->AllocateMemorySpace ( > > > > > > - EfiGcdAllocateAddress, > > > > > > - EfiGcdMemoryTypeMemoryMappedIo, > > > > > > - 0, > > > > > > - MemApertures[MemApertureIndex]->Limit - > > > MemApertures[MemApertureIndex]->Base + 1, > > > > > > - &HostAddress, > > > > > > - gImageHandle, > > > > > > - NULL > > > > > > - ); > > > > > > - ASSERT_EFI_ERROR (Status); > > > > > > + return Status; > > > > > > } > > > > > > } > > > > > > } > > > > > > + } > > > > > > > > > > > > - // > > > > > > - // Insert Root Bridge Handle Instance > > > > > > - // > > > > > > - InsertTailList (&HostBridge->RootBridges, &RootBridge->Link); > > > > > > + return EFI_SUCCESS; > > > > > > +} > > > > > > + > > > > > > +/** > > > > > > + Test to see if this driver supports ControllerHandle. Any > > > + ControllerHandle > > > > > > + than contains a gEdkiiPciHostBridgeProtocolGuid protocol can be > supported. > > > > > > + > > > > > > + @param This Protocol instance pointer. > > > > > > + @param Controller Handle of device to test. > > > > > > + @param RemainingDevicePath Optional parameter use to pick a > > > + specific child > > > > > > + device to start. > > > > > > + > > > > > > + @retval EFI_SUCCESS This driver supports this device. > > > > > > + @retval EFI_ALREADY_STARTED This driver is already running on this > device. > > > > > > + @retval other This driver does not support this devi= ce. > > > > > > + > > > > > > +**/ > > > > > > +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; > > > > > > } > > > > > > > > > > > > // > > > > > > - // 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 child > > > > > > + device to start. > > > > > > + > > > > > > + @retval EFI_SUCCESS This driver is added to ControllerHan= dle. > > > > > > + @retval EFI_ALREADY_STARTED This driver is already running on > > > ControllerHandle. > > > > > > + @retval other This driver does not support this dev= ice. > > > > > > + > > > > > > +**/ > > > > > > +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; > > > > > > + } > > > > > > > > > > > > - 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; > > > > > > + } > > > > > > > > > > > > - 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 > > > > > > + ); > > > > > > } > > > > > > > > > > > > - 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 > > > number of > > > > > > + children is zero stop the entire bus dri= ver. > > > > > > + @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 de= vice. > > > > > > + > > > > > > +**/ > > > > > > +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 Host > > > 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].ResourceAssigned); > > > > > > + } > > > > > > + > > > > > > + 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 GetNextRootBridg= e; > > > > > > + 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_LIN= K (Link); > > > > > > + 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); > > > > > > + } > > > > > > > > > > > > if (!EFI_ERROR (Status)) { > > > > > > mIoMmuEvent =3D EfiCreateProtocolNotifyEvent ( > > > > > > diff --git > > > a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf > > > b/MdeModulePkg/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_CONSU= MES > > > > > > + gEdkiiPciHostBridgeProtocolGuid ## SOMETIMES_CONSU= MES > > > > > > > > > > > > [Depex] > > > > > > gEfiCpuIo2ProtocolGuid AND > > > > > > diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h > > > b/MdeModulePkg/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 > > > > > > ); > > > > > > > > > > > > +/** > > > > > > + 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/MdeModulePkg/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; > > > > > > } > > > > > > > > > > > > +/** > > > > > > + 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. > > > > > > > > > > > > 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, > > > { 0xBD, 0x95, 0x9A, 0x6E, 0x4F, 0x09, 0x25, 0xC3 } } > > > > > > > > > > > > + ## 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.
> > > > > > -- > > > > > > 2.25.1 > > > > > >