]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / PciBusDxe / PciBus.c
index a463bea80f3d8ee2366f293e768acbd6ebb47be4..337b2090d98e41f9ed9cfcb5c160e4fac32b2d7d 100644 (file)
@@ -8,14 +8,8 @@
   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
@@ -24,7 +18,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 //\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
@@ -35,16 +29,17 @@ EFI_DRIVER_BINDING_PROTOCOL                   gPciBusDriverBinding = {
 \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
@@ -66,8 +61,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL mPciHotPlugReques
 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
@@ -113,7 +108,7 @@ PciBusEntryPoint (
 \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
@@ -124,22 +119,22 @@ PciBusEntryPoint (
 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
@@ -148,9 +143,10 @@ PciBusDriverBindingSupported (
       // 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
@@ -162,7 +158,7 @@ PciBusDriverBindingSupported (
   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
@@ -179,11 +175,11 @@ PciBusDriverBindingSupported (
   // 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
@@ -191,7 +187,7 @@ PciBusDriverBindingSupported (
   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
@@ -208,11 +204,11 @@ PciBusDriverBindingSupported (
   // 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
@@ -223,7 +219,7 @@ PciBusDriverBindingSupported (
 \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
@@ -239,15 +235,21 @@ PciBusDriverBindingStart (
   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
@@ -258,7 +260,7 @@ PciBusDriverBindingStart (
   gBS->LocateProtocol (\r
          &gEfiIncompatiblePciDeviceSupportProtocolGuid,\r
          NULL,\r
-         (VOID **) &gIncompatiblePciDeviceSupport\r
+         (VOID **)&gIncompatiblePciDeviceSupport\r
          );\r
 \r
   //\r
@@ -267,27 +269,43 @@ PciBusDriverBindingStart (
   //\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
@@ -296,11 +314,11 @@ PciBusDriverBindingStart (
   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
@@ -312,12 +330,34 @@ PciBusDriverBindingStart (
     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
@@ -328,11 +368,23 @@ PciBusDriverBindingStart (
   //\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
@@ -348,10 +400,10 @@ PciBusDriverBindingStart (
 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
@@ -363,17 +415,17 @@ PciBusDriverBindingStop (
     // 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
@@ -389,7 +441,6 @@ PciBusDriverBindingStop (
   AllChildrenStopped = TRUE;\r
 \r
   for (Index = 0; Index < NumberOfChildren; Index++) {\r
-\r
     //\r
     // De register all the pci device\r
     //\r
@@ -406,4 +457,3 @@ PciBusDriverBindingStop (
 \r
   return EFI_SUCCESS;\r
 }\r
-\r