PCI Root Bridges. So it means platform needs install PCI Root Bridge IO protocol for each\r
PCI Root Bus and install PCI Host Bridge Resource Allocation Protocol.\r
\r
-Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
//\r
// PCI Bus Driver Global Variables\r
//\r
-EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding = {\r
+EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding = {\r
PciBusDriverBindingSupported,\r
PciBusDriverBindingStart,\r
PciBusDriverBindingStop,\r
\r
EFI_HANDLE gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM];\r
EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *gIncompatiblePciDeviceSupport = NULL;\r
-UINTN gPciHostBridgeNumber = 0;\r
-BOOLEAN gFullEnumeration = TRUE;\r
-UINT64 gAllOne = 0xFFFFFFFFFFFFFFFFULL;\r
-UINT64 gAllZero = 0;\r
-\r
-EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol;\r
-EFI_PCI_OVERRIDE_PROTOCOL *gPciOverrideProtocol;\r
+UINTN gPciHostBridgeNumber = 0;\r
+BOOLEAN gFullEnumeration = TRUE;\r
+UINT64 gAllOne = 0xFFFFFFFFFFFFFFFFULL;\r
+UINT64 gAllZero = 0;\r
\r
+EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol;\r
+EFI_PCI_OVERRIDE_PROTOCOL *gPciOverrideProtocol;\r
+EDKII_IOMMU_PROTOCOL *mIoMmuProtocol;\r
+EDKII_DEVICE_SECURITY_PROTOCOL *mDeviceSecurityProtocol;\r
\r
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL mPciHotPlugRequest = {\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL mPciHotPlugRequest = {\r
PciHotPlugRequestNotify\r
};\r
\r
EFI_STATUS\r
EFIAPI\r
PciBusEntryPoint (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
)\r
{\r
EFI_STATUS Status;\r
\r
@param This Protocol instance pointer.\r
@param Controller Handle of device to test.\r
- @param RemainingDevicePath Optional parameter use to pick a specific child.\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
device to start.\r
\r
@retval EFI_SUCCESS This driver supports this device.\r
EFI_STATUS\r
EFIAPI\r
PciBusDriverBindingSupported (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
- EFI_DEV_PATH_PTR Node;\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+ EFI_DEV_PATH_PTR Node;\r
\r
//\r
// Check RemainingDevicePath validation\r
//\r
if (RemainingDevicePath != NULL) {\r
//\r
- // Check if RemainingDevicePath is the End of Device Path Node, \r
+ // Check if RemainingDevicePath is the End of Device Path Node,\r
// if yes, go on checking other conditions\r
//\r
if (!IsDevicePathEnd (RemainingDevicePath)) {\r
// check its validation\r
//\r
Node.DevPath = RemainingDevicePath;\r
- if (Node.DevPath->Type != HARDWARE_DEVICE_PATH ||\r
- Node.DevPath->SubType != HW_PCI_DP ||\r
- DevicePathNodeLength(Node.DevPath) != sizeof(PCI_DEVICE_PATH)) {\r
+ if ((Node.DevPath->Type != HARDWARE_DEVICE_PATH) ||\r
+ (Node.DevPath->SubType != HW_PCI_DP) ||\r
+ (DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH)))\r
+ {\r
return EFI_UNSUPPORTED;\r
}\r
}\r
Status = gBS->OpenProtocol (\r
Controller,\r
&gEfiPciRootBridgeIoProtocolGuid,\r
- (VOID **) &PciRootBridgeIo,\r
+ (VOID **)&PciRootBridgeIo,\r
This->DriverBindingHandle,\r
Controller,\r
EFI_OPEN_PROTOCOL_BY_DRIVER\r
// Close the I/O Abstraction(s) used to perform the supported test\r
//\r
gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciRootBridgeIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ Controller,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
\r
//\r
// Open the EFI Device Path protocol needed to perform the supported test\r
Status = gBS->OpenProtocol (\r
Controller,\r
&gEfiDevicePathProtocolGuid,\r
- (VOID **) &ParentDevicePath,\r
+ (VOID **)&ParentDevicePath,\r
This->DriverBindingHandle,\r
Controller,\r
EFI_OPEN_PROTOCOL_BY_DRIVER\r
// Close protocol, don't use device path protocol in the Support() function\r
//\r
gBS->CloseProtocol (\r
- Controller,\r
- &gEfiDevicePathProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
\r
return EFI_SUCCESS;\r
}\r
\r
@param This Protocol instance pointer.\r
@param Controller Handle of device to bind driver to.\r
- @param RemainingDevicePath Optional parameter use to pick a specific child.\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
device to start.\r
\r
@retval EFI_SUCCESS This driver is added to ControllerHandle.\r
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+\r
+ //\r
+ // Initialize PciRootBridgeIo to suppress incorrect compiler warning.\r
+ //\r
+ PciRootBridgeIo = NULL;\r
\r
//\r
// Check RemainingDevicePath validation\r
//\r
if (RemainingDevicePath != NULL) {\r
//\r
- // Check if RemainingDevicePath is the End of Device Path Node, \r
+ // Check if RemainingDevicePath is the End of Device Path Node,\r
// if yes, return EFI_SUCCESS\r
//\r
if (IsDevicePathEnd (RemainingDevicePath)) {\r
gBS->LocateProtocol (\r
&gEfiIncompatiblePciDeviceSupportProtocolGuid,\r
NULL,\r
- (VOID **) &gIncompatiblePciDeviceSupport\r
+ (VOID **)&gIncompatiblePciDeviceSupport\r
);\r
\r
//\r
//\r
gPciPlatformProtocol = NULL;\r
gBS->LocateProtocol (\r
- &gEfiPciPlatformProtocolGuid,\r
- NULL,\r
- (VOID **) &gPciPlatformProtocol\r
- );\r
+ &gEfiPciPlatformProtocolGuid,\r
+ NULL,\r
+ (VOID **)&gPciPlatformProtocol\r
+ );\r
\r
//\r
// If PCI Platform protocol doesn't exist, try to Pci Override Protocol.\r
//\r
- if (gPciPlatformProtocol == NULL) { \r
+ if (gPciPlatformProtocol == NULL) {\r
gPciOverrideProtocol = NULL;\r
gBS->LocateProtocol (\r
- &gEfiPciOverrideProtocolGuid,\r
- NULL,\r
- (VOID **) &gPciOverrideProtocol\r
- );\r
- } \r
+ &gEfiPciOverrideProtocolGuid,\r
+ NULL,\r
+ (VOID **)&gPciOverrideProtocol\r
+ );\r
+ }\r
+\r
+ if (mIoMmuProtocol == NULL) {\r
+ gBS->LocateProtocol (\r
+ &gEdkiiIoMmuProtocolGuid,\r
+ NULL,\r
+ (VOID **)&mIoMmuProtocol\r
+ );\r
+ }\r
+\r
+ if (mDeviceSecurityProtocol == NULL) {\r
+ gBS->LocateProtocol (\r
+ &gEdkiiDeviceSecurityProtocolGuid,\r
+ NULL,\r
+ (VOID **)&mDeviceSecurityProtocol\r
+ );\r
+ }\r
\r
if (PcdGetBool (PcdPciDisableBusEnumeration)) {\r
gFullEnumeration = FALSE;\r
} else {\r
- gFullEnumeration = (BOOLEAN) ((SearchHostBridgeHandle (Controller) ? FALSE : TRUE));\r
+ gFullEnumeration = (BOOLEAN)((SearchHostBridgeHandle (Controller) ? FALSE : TRUE));\r
}\r
\r
//\r
Status = gBS->OpenProtocol (\r
Controller,\r
&gEfiDevicePathProtocolGuid,\r
- (VOID **) &ParentDevicePath,\r
+ (VOID **)&ParentDevicePath,\r
This->DriverBindingHandle,\r
Controller,\r
EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- ); \r
+ );\r
ASSERT_EFI_ERROR (Status);\r
\r
//\r
ParentDevicePath\r
);\r
\r
+ Status = EFI_SUCCESS;\r
//\r
// Enumerate the entire host bridge\r
// After enumeration, a database that records all the device information will be created\r
//\r
//\r
- Status = PciEnumerator (Controller);\r
+ if (gFullEnumeration) {\r
+ //\r
+ // Get the rootbridge Io protocol to find the host bridge handle\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ (VOID **)&PciRootBridgeIo,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = PciEnumerator (Controller, PciRootBridgeIo->ParentHandle);\r
+ }\r
+ } else {\r
+ //\r
+ // If PCI bus has already done the full enumeration, never do it again\r
+ //\r
+ Status = PciEnumeratorLight (Controller);\r
+ }\r
\r
if (EFI_ERROR (Status)) {\r
return Status;\r
//\r
StartPciDevices (Controller);\r
\r
- return EFI_SUCCESS;\r
+ if (gFullEnumeration) {\r
+ gFullEnumeration = FALSE;\r
+\r
+ Status = gBS->InstallProtocolInterface (\r
+ &PciRootBridgeIo->ParentHandle,\r
+ &gEfiPciEnumerationCompleteProtocolGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+\r
+ return Status;\r
}\r
\r
/**\r
- Stop this driver on ControllerHandle. Support stoping any child handles\r
+ Stop this driver on ControllerHandle. Support stopping any child handles\r
created by this driver.\r
\r
@param This Protocol instance pointer.\r
EFI_STATUS\r
EFIAPI\r
PciBusDriverBindingStop (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE *ChildHandleBuffer\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
)\r
{\r
EFI_STATUS Status;\r
// Close the bus driver\r
//\r
gBS->CloseProtocol (\r
- Controller,\r
- &gEfiDevicePathProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciRootBridgeIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ Controller,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
\r
DestroyRootBridgeByHandle (\r
Controller\r
AllChildrenStopped = TRUE;\r
\r
for (Index = 0; Index < NumberOfChildren; Index++) {\r
-\r
//\r
// De register all the pci device\r
//\r
\r
return EFI_SUCCESS;\r
}\r
-\r