]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Library / UefiBootManagerLib / BmBoot.c
index ce19ae4006604a9cc80261bda04e0254b949fd12..952033fc825bb72891918bff59eb0695182efffe 100644 (file)
@@ -1,15 +1,9 @@
 /** @file\r
   Library functions which relates with booting.\r
 \r
-Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.<BR>\r
 (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<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
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -45,7 +39,7 @@ BmEndOfBdsPerfCode (
   //\r
   // Record the performance data for End of BDS\r
   //\r
-  PERF_END(NULL, "BDS", NULL, 0);\r
+  PERF_CROSSMODULE_END("BDS");\r
 \r
   return ;\r
 }\r
@@ -109,7 +103,7 @@ BmFindBootOptionInVariable (
   EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;\r
   UINTN                        BootOptionCount;\r
   UINTN                        Index;\r
-  \r
+\r
   OptionNumber = LoadOptionNumberUnassigned;\r
 \r
   //\r
@@ -233,7 +227,7 @@ BmAdjustFvFilePath (
       break;\r
     }\r
   }\r
-  \r
+\r
   if (FvHandles != NULL) {\r
     FreePool (FvHandles);\r
   }\r
@@ -242,7 +236,7 @@ BmAdjustFvFilePath (
 \r
 /**\r
   Check if it's a Device Path pointing to FV file.\r
-  \r
+\r
   The function doesn't garentee the device path points to existing FV file.\r
 \r
   @param  DevicePath     Input device path.\r
@@ -471,13 +465,13 @@ BmMatchUsbWwid (
 }\r
 \r
 /**\r
-  Find a USB device which match the specified short-form device path start with \r
+  Find a USB device which match the specified short-form device path start with\r
   USB Class or USB WWID device path. If ParentDevicePath is NULL, this function\r
   will search in all USB devices of the platform. If ParentDevicePath is not NULL,\r
   this function will only search in its child devices.\r
 \r
   @param DevicePath           The device path that contains USB Class or USB WWID device path.\r
-  @param ParentDevicePathSize The length of the device path before the USB Class or \r
+  @param ParentDevicePathSize The length of the device path before the USB Class or\r
                               USB WWID device path.\r
   @param UsbIoHandleCount     A pointer to the count of the returned USB IO handles.\r
 \r
@@ -499,7 +493,7 @@ BmFindUsbDevice (
   UINTN                     Index;\r
   BOOLEAN                   Matched;\r
 \r
-  ASSERT (UsbIoHandleCount != NULL);  \r
+  ASSERT (UsbIoHandleCount != NULL);\r
 \r
   //\r
   // Get all UsbIo Handles.\r
@@ -655,7 +649,7 @@ BmExpandFileDevicePath (
   UINTN                           MediaType;\r
   EFI_DEVICE_PATH_PROTOCOL        *NextFullPath;\r
   BOOLEAN                         GetNext;\r
-  \r
+\r
   EfiBootManagerConnectAll ();\r
   Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &Handles);\r
   if (EFI_ERROR (Status)) {\r
@@ -780,7 +774,7 @@ BmCachePartitionDevicePath (
 {\r
   EFI_DEVICE_PATH_PROTOCOL        *TempDevicePath;\r
   UINTN                           Count;\r
-  \r
+\r
   if (BmMatchDevicePaths (*CachedDevicePath, DevicePath)) {\r
     TempDevicePath = *CachedDevicePath;\r
     *CachedDevicePath = BmDelPartMatchInstance (*CachedDevicePath, DevicePath);\r
@@ -1069,6 +1063,9 @@ BmExpandMediaDevicePath (
   //\r
   Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo);\r
   ASSERT_EFI_ERROR (Status);\r
+  if (EFI_ERROR (Status)) {\r
+    return NULL;\r
+  }\r
   Buffer = AllocatePool (BlockIo->Media->BlockSize);\r
   if (Buffer != NULL) {\r
     BlockIo->ReadBlocks (\r
@@ -1667,15 +1664,60 @@ BmIsBootManagerMenuFilePath (
   return FALSE;\r
 }\r
 \r
+/**\r
+  Report status code with EFI_RETURN_STATUS_EXTENDED_DATA about LoadImage() or\r
+  StartImage() failure.\r
+\r
+  @param[in] ErrorCode      An Error Code in the Software Class, DXE Boot\r
+                            Service Driver Subclass. ErrorCode will be used to\r
+                            compose the Value parameter for status code\r
+                            reporting. Must be one of\r
+                            EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR and\r
+                            EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED.\r
+\r
+  @param[in] FailureStatus  The failure status returned by the boot service\r
+                            that should be reported.\r
+**/\r
+VOID\r
+BmReportLoadFailure (\r
+  IN UINT32     ErrorCode,\r
+  IN EFI_STATUS FailureStatus\r
+  )\r
+{\r
+  EFI_RETURN_STATUS_EXTENDED_DATA ExtendedData;\r
+\r
+  if (!ReportErrorCodeEnabled ()) {\r
+    return;\r
+  }\r
+\r
+  ASSERT (\r
+    (ErrorCode == EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR) ||\r
+    (ErrorCode == EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED)\r
+    );\r
+\r
+  ZeroMem (&ExtendedData, sizeof (ExtendedData));\r
+  ExtendedData.ReturnStatus = FailureStatus;\r
+\r
+  REPORT_STATUS_CODE_EX (\r
+    (EFI_ERROR_CODE | EFI_ERROR_MINOR),\r
+    (EFI_SOFTWARE_DXE_BS_DRIVER | ErrorCode),\r
+    0,\r
+    NULL,\r
+    NULL,\r
+    &ExtendedData.DataHeader + 1,\r
+    sizeof (ExtendedData) - sizeof (ExtendedData.DataHeader)\r
+    );\r
+}\r
+\r
 /**\r
   Attempt to boot the EFI boot option. This routine sets L"BootCurent" and\r
   also signals the EFI ready to boot event. If the device path for the option\r
-  starts with a BBS device path a legacy boot is attempted via the registered \r
-  gLegacyBoot function. Short form device paths are also supported via this \r
+  starts with a BBS device path a legacy boot is attempted via the registered\r
+  gLegacyBoot function. Short form device paths are also supported via this\r
   rountine. A device path starting with MEDIA_HARDDRIVE_DP, MSG_USB_WWID_DP,\r
   MSG_USB_CLASS_DP gets expaned out to find the first device that matches.\r
-  If the BootOption Device Path fails the removable media boot algorithm \r
-  is attempted (\EFI\BOOTIA32.EFI, \EFI\BOOTX64.EFI,... only one file type \r
+  If the BootOption Device Path fails the removable media boot algorithm\r
+  is attempted (\EFI\BOOTIA32.EFI, \EFI\BOOTX64.EFI,... only one file type\r
   is tried per processor type)\r
 \r
   @param  BootOption    Boot Option to try and boot.\r
@@ -1767,7 +1809,7 @@ EfiBootManagerBoot (
     //\r
     // 4. Repair system through DriverHealth protocol\r
     //\r
-    BmRepairAllControllers ();\r
+    BmRepairAllControllers (0);\r
   }\r
 \r
   PERF_START_EX (gImageHandle, "BdsAttempt", NULL, 0, (UINT32) OptionNumber);\r
@@ -1820,12 +1862,9 @@ EfiBootManagerBoot (
 \r
     if (EFI_ERROR (Status)) {\r
       //\r
-      // Report Status Code to indicate that the failure to load boot option\r
+      // Report Status Code with the failure status to indicate that the failure to load boot option\r
       //\r
-      REPORT_STATUS_CODE (\r
-        EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
-        (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR)\r
-        );\r
+      BmReportLoadFailure (EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR, Status);\r
       BootOption->Status = Status;\r
       //\r
       // Destroy the RAM disk\r
@@ -1854,7 +1893,7 @@ EfiBootManagerBoot (
         Status = EfiCreateEventLegacyBootEx(\r
                    TPL_NOTIFY,\r
                    BmEndOfBdsPerfCode,\r
-                   NULL, \r
+                   NULL,\r
                    &LegacyBootEvent\r
                    );\r
         ASSERT_EFI_ERROR (Status);\r
@@ -1868,7 +1907,7 @@ EfiBootManagerBoot (
     PERF_END_EX (gImageHandle, "BdsAttempt", NULL, 0, (UINT32) OptionNumber);\r
     return;\r
   }\r
\r
+\r
   //\r
   // Provide the image with its load options\r
   //\r
@@ -1904,12 +1943,9 @@ EfiBootManagerBoot (
   BootOption->Status = Status;\r
   if (EFI_ERROR (Status)) {\r
     //\r
-    // Report Status Code to indicate that boot failure\r
+    // Report Status Code with the failure status to indicate that boot failure\r
     //\r
-    REPORT_STATUS_CODE (\r
-      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
-      (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED)\r
-      );\r
+    BmReportLoadFailure (EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED, Status);\r
   }\r
   PERF_END_EX (gImageHandle, "BdsAttempt", NULL, 0, (UINT32) OptionNumber);\r
 \r
@@ -1979,37 +2015,33 @@ BmMatchPartitionDevicePathNode (
   }\r
 \r
   //\r
-  // find the partition device path node\r
+  // Match all the partition device path nodes including the nested partition nodes\r
   //\r
   while (!IsDevicePathEnd (BlockIoDevicePath)) {\r
     if ((DevicePathType (BlockIoDevicePath) == MEDIA_DEVICE_PATH) &&\r
         (DevicePathSubType (BlockIoDevicePath) == MEDIA_HARDDRIVE_DP)\r
         ) {\r
-      break;\r
+      //\r
+      // See if the harddrive device path in blockio matches the orig Hard Drive Node\r
+      //\r
+      Node = (HARDDRIVE_DEVICE_PATH *) BlockIoDevicePath;\r
+\r
+      //\r
+      // Match Signature and PartitionNumber.\r
+      // Unused bytes in Signature are initiaized with zeros.\r
+      //\r
+      if ((Node->PartitionNumber == HardDriveDevicePath->PartitionNumber) &&\r
+          (Node->MBRType == HardDriveDevicePath->MBRType) &&\r
+          (Node->SignatureType == HardDriveDevicePath->SignatureType) &&\r
+          (CompareMem (Node->Signature, HardDriveDevicePath->Signature, sizeof (Node->Signature)) == 0)) {\r
+        return TRUE;\r
+      }\r
     }\r
 \r
     BlockIoDevicePath = NextDevicePathNode (BlockIoDevicePath);\r
   }\r
 \r
-  if (IsDevicePathEnd (BlockIoDevicePath)) {\r
-    return FALSE;\r
-  }\r
-\r
-  //\r
-  // See if the harddrive device path in blockio matches the orig Hard Drive Node\r
-  //\r
-  Node = (HARDDRIVE_DEVICE_PATH *) BlockIoDevicePath;\r
-\r
-  //\r
-  // Match Signature and PartitionNumber.\r
-  // Unused bytes in Signature are initiaized with zeros.\r
-  //\r
-  return (BOOLEAN) (\r
-    (Node->PartitionNumber == HardDriveDevicePath->PartitionNumber) &&\r
-    (Node->MBRType == HardDriveDevicePath->MBRType) &&\r
-    (Node->SignatureType == HardDriveDevicePath->SignatureType) &&\r
-    (CompareMem (Node->Signature, HardDriveDevicePath->Signature, sizeof (Node->Signature)) == 0)\r
-    );\r
+  return FALSE;\r
 }\r
 \r
 /**\r
@@ -2021,7 +2053,7 @@ BmMatchPartitionDevicePathNode (
   3. Non-BlockIo SimpleFileSystem - The boot option points to a device supporting\r
                                     SimpleFileSystem Protocol, but not supporting BlockIo\r
                                     protocol.\r
-  4. LoadFile                     - The boot option points to the media supporting \r
+  4. LoadFile                     - The boot option points to the media supporting\r
                                     LoadFile protocol.\r
   Reference: UEFI Spec chapter 3.3 Boot Option Variables Default Boot Behavior\r
 \r
@@ -2246,7 +2278,7 @@ EfiBootManagerRefreshAllBootOption (
   // Remove invalid EFI boot options from NV\r
   //\r
   for (Index = 0; Index < NvBootOptionCount; Index++) {\r
-    if (((DevicePathType (NvBootOptions[Index].FilePath) != BBS_DEVICE_PATH) || \r
+    if (((DevicePathType (NvBootOptions[Index].FilePath) != BBS_DEVICE_PATH) ||\r
          (DevicePathSubType (NvBootOptions[Index].FilePath) != BBS_BBS_DP)\r
         ) && BmIsAutoCreateBootOption (&NvBootOptions[Index])\r
        ) {\r
@@ -2429,7 +2461,7 @@ EfiBootManagerGetBootManagerMenu (
   UINTN                        BootOptionCount;\r
   EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;\r
   UINTN                        Index;\r
-  \r
+\r
   BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);\r
 \r
   for (Index = 0; Index < BootOptionCount; Index++) {\r
@@ -2461,3 +2493,26 @@ EfiBootManagerGetBootManagerMenu (
   }\r
 }\r
 \r
+/**\r
+  Get the next possible full path pointing to the load option.\r
+  The routine doesn't guarantee the returned full path points to an existing\r
+  file, and it also doesn't guarantee the existing file is a valid load option.\r
+  BmGetNextLoadOptionBuffer() guarantees.\r
+\r
+  @param FilePath  The device path pointing to a load option.\r
+                   It could be a short-form device path.\r
+  @param FullPath  The full path returned by the routine in last call.\r
+                   Set to NULL in first call.\r
+\r
+  @return The next possible full path pointing to the load option.\r
+          Caller is responsible to free the memory.\r
+**/\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+EFIAPI\r
+EfiBootManagerGetNextLoadOptionDevicePath (\r
+  IN  EFI_DEVICE_PATH_PROTOCOL          *FilePath,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL          *FullPath\r
+  )\r
+{\r
+  return BmGetNextLoadOptionDevicePath(FilePath, FullPath);\r
+}\r