]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c
Clean up PERF macro usage. The macros were being used with 0 as the first parameter...
[mirror_edk2.git] / IntelFrameworkModulePkg / Library / GenericBdsLib / BdsBoot.c
index bc0904e84eaba8bf7950bfce1ec5c7ec9c2c8bbd..9042cc3428b624c0fa9a61c98ef1e94b5a5e50bd 100644 (file)
@@ -77,9 +77,8 @@ BdsLibDoLegacyBoot (
 \r
   @retval TRUE      This boot option matches a valid EFI NV Boot####.\r
   @retval FALSE     If not.\r
-  \r
-**/\r
 \r
+**/\r
 BOOLEAN\r
 IsBootOptionValidNVVarialbe (\r
   IN  BDS_COMMON_OPTION             *OptionToCheck\r
@@ -101,7 +100,7 @@ IsBootOptionValidNVVarialbe (
   }\r
 \r
   //\r
-  // If the Boot Option Number and Device Path matches, OptionToCheck matches a \r
+  // If the Boot Option Number and Device Path matches, OptionToCheck matches a\r
   // valid EFI NV Boot####.\r
   //\r
   if ((OptionToCheck->BootCurrent == BootOption->BootCurrent) &&\r
@@ -111,7 +110,7 @@ IsBootOptionValidNVVarialbe (
   }\r
 \r
   FreePool (BootOption);\r
-    \r
+\r
   return Valid;\r
 }\r
 /**\r
@@ -146,11 +145,12 @@ BdsLibBootViaBootOption (
   EFI_DEVICE_PATH_PROTOCOL  *WorkingDevicePath;\r
   EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save;\r
   LIST_ENTRY                TempBootLists;\r
+  EFI_SECURITY_ARCH_PROTOCOL *SecurityProtocol;\r
 \r
   //\r
   // Record the performance data for End of BDS\r
   //\r
-  PERF_END (0, BDS_TOK, NULL, 0);\r
+  PERF_END(NULL, "BDS", NULL, 0);\r
 \r
   *ExitDataSize = 0;\r
   *ExitData     = NULL;\r
@@ -187,8 +187,8 @@ BdsLibBootViaBootOption (
   // Signal the EVT_SIGNAL_READY_TO_BOOT event\r
   //\r
   EfiSignalEventReadyToBoot();\r
-  \r
-  \r
+\r
+\r
   //\r
   // Set Boot Current\r
   //\r
@@ -220,7 +220,7 @@ BdsLibBootViaBootOption (
   //\r
   // If the boot option point to Internal FV shell, make sure it is valid\r
   //\r
-  Status = BdsLibUpdateFvFileDevicePath (&DevicePath, &gEfiShellFileGuid);\r
+  Status = BdsLibUpdateFvFileDevicePath (&DevicePath, PcdGetPtr(PcdShellFile));\r
   if (!EFI_ERROR(Status)) {\r
     if (Option->DevicePath != NULL) {\r
       FreePool(Option->DevicePath);\r
@@ -233,14 +233,26 @@ BdsLibBootViaBootOption (
     //\r
     InitializeListHead (&TempBootLists);\r
     BdsLibRegisterNewOption (&TempBootLists, DevicePath, L"EFI Internal Shell", L"BootOrder");\r
-    \r
+\r
     //\r
     // free the temporary device path created by BdsLibUpdateFvFileDevicePath()\r
     //\r
-    FreePool (DevicePath); \r
+    FreePool (DevicePath);\r
     DevicePath = Option->DevicePath;\r
   }\r
 \r
+  //\r
+  // Measure GPT Table by SAP protocol.\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiSecurityArchProtocolGuid,\r
+                  NULL,\r
+                  (VOID**) &SecurityProtocol\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = SecurityProtocol->FileAuthenticationState (SecurityProtocol, 0, DevicePath);\r
+  }\r
+\r
   DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Booting %S\n", Option->Description));\r
 \r
   Status = gBS->LoadImage (\r
@@ -269,7 +281,7 @@ BdsLibBootViaBootOption (
     // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from removable Media\r
     //  machinename is ia32, ia64, x64, ...\r
     //\r
-    FilePath = FileDevicePath (Handle, (CONST CHAR16*)PcdGetPtr(PcdDefaultBootFileName));\r
+    FilePath = FileDevicePath (Handle, EFI_REMOVABLE_MEDIA_FILE_NAME);\r
     if (FilePath != NULL) {\r
       Status = gBS->LoadImage (\r
                       TRUE,\r
@@ -382,7 +394,7 @@ BdsExpandPartitionPartialDevicePathToFull (
                       &mHdBootVariablePrivateGuid,\r
                       &CachedDevicePathSize\r
                       );\r
-                      \r
+\r
   if (CachedDevicePath != NULL) {\r
     TempNewDevicePath = CachedDevicePath;\r
     DeviceExist = FALSE;\r
@@ -430,7 +442,7 @@ BdsExpandPartitionPartialDevicePathToFull (
         TempNewDevicePath = CachedDevicePath;\r
         CachedDevicePath  = BdsLibDelPartMatchInstance (CachedDevicePath, Instance );\r
         FreePool (TempNewDevicePath);\r
-        \r
+\r
         //\r
         // Second, append the remaining path after the matched instance\r
         //\r
@@ -448,7 +460,7 @@ BdsExpandPartitionPartialDevicePathToFull (
                         CachedDevicePath\r
                         );\r
       }\r
-      \r
+\r
       FreePool (Instance);\r
       FreePool (CachedDevicePath);\r
       return FullDevicePath;\r
@@ -547,7 +559,7 @@ BdsExpandPartitionPartialDevicePathToFull (
       break;\r
     }\r
   }\r
-  \r
+\r
   FreePool (CachedDevicePath);\r
   if (BlockIoBuffer != NULL) {\r
     FreePool (BlockIoBuffer);\r
@@ -582,7 +594,7 @@ MatchPartitionDevicePathNode (
   if ((BlockIoDevicePath == NULL) || (HardDriveDevicePath == NULL)) {\r
     return FALSE;\r
   }\r
-  \r
+\r
   //\r
   // Make PreviousDevicePath == the device path node before the end node\r
   //\r
@@ -611,7 +623,7 @@ MatchPartitionDevicePathNode (
   //\r
   TmpHdPath = (HARDDRIVE_DEVICE_PATH *) BlockIoHdDevicePathNode;\r
   Match = FALSE;\r
-  \r
+\r
   //\r
   // Check for the match\r
   //\r
@@ -699,7 +711,7 @@ BdsLibDeleteOptionFromHandle (
                       &gEfiGlobalVariableGuid,\r
                       &BootOptionSize\r
                       );\r
-                      \r
+\r
     if (BootOptionVar == NULL) {\r
       FreePool (BootOrder);\r
       return EFI_OUT_OF_RESOURCES;\r
@@ -743,8 +755,7 @@ BdsLibDeleteOptionFromHandle (
 \r
 \r
 /**\r
-  Delete all invalid EFI boot options. The probable invalid boot option could\r
-  be Removable media or Network boot device.\r
+  Delete all invalid EFI boot options.\r
 \r
   @retval EFI_SUCCESS            Delete all invalid boot option success\r
   @retval EFI_NOT_FOUND          Variable "BootOrder" is not found\r
@@ -767,6 +778,7 @@ BdsDeleteAllInvalidEfiBootOption (
   UINT16                    BootOption[BOOT_OPTION_MAX_CHAR];\r
   EFI_DEVICE_PATH_PROTOCOL  *OptionDevicePath;\r
   UINT8                     *TempPtr;\r
+  CHAR16                    *Description;\r
 \r
   Status        = EFI_SUCCESS;\r
   BootOrder     = NULL;\r
@@ -799,6 +811,7 @@ BdsDeleteAllInvalidEfiBootOption (
 \r
     TempPtr = BootOptionVar;\r
     TempPtr += sizeof (UINT32) + sizeof (UINT16);\r
+    Description = (CHAR16 *) TempPtr;\r
     TempPtr += StrSize ((CHAR16 *) TempPtr);\r
     OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;\r
 \r
@@ -812,7 +825,7 @@ BdsDeleteAllInvalidEfiBootOption (
       continue;\r
     }\r
 \r
-    if (!BdsLibIsValidEFIBootOptDevicePath (OptionDevicePath, FALSE)) {\r
+    if (!BdsLibIsValidEFIBootOptDevicePathExt (OptionDevicePath, FALSE, Description)) {\r
       //\r
       // Delete this invalid boot option "Boot####"\r
       //\r
@@ -858,8 +871,40 @@ BdsDeleteAllInvalidEfiBootOption (
 \r
 \r
 /**\r
-  This function will enumerate all possible boot device in the system,\r
-  it will only execute once of every boot.\r
+  For EFI boot option, BDS separate them as six types:\r
+  1. Network - The boot option points to the SimpleNetworkProtocol device.\r
+               Bds will try to automatically create this type boot option when enumerate.\r
+  2. Shell   - The boot option points to internal flash shell.\r
+               Bds will try to automatically create this type boot option when enumerate.\r
+  3. Removable BlockIo      - The boot option only points to the removable media\r
+                              device, like USB flash disk, DVD, Floppy etc.\r
+                              These device should contain a *removable* blockIo\r
+                              protocol in their device handle.\r
+                              Bds will try to automatically create this type boot option\r
+                              when enumerate.\r
+  4. Fixed BlockIo          - The boot option only points to a Fixed blockIo device,\r
+                              like HardDisk.\r
+                              These device should contain a *fixed* blockIo\r
+                              protocol in their device handle.\r
+                              BDS will skip fixed blockIo devices, and NOT\r
+                              automatically create boot option for them. But BDS\r
+                              will help to delete those fixed blockIo boot option,\r
+                              whose description rule conflict with other auto-created\r
+                              boot options.\r
+  5. Non-BlockIo Simplefile - The boot option points to a device whose handle\r
+                              has SimpleFileSystem Protocol, but has no blockio\r
+                              protocol. These devices do not offer blockIo\r
+                              protocol, but BDS still can get the\r
+                              \EFI\BOOT\boot{machinename}.EFI by SimpleFileSystem\r
+                              Protocol.\r
+  6. File    - The boot option points to a file. These boot options are usually\r
+               created by user manually or OS loader. BDS will not delete or modify\r
+               these boot options.\r
+\r
+  This function will enumerate all possible boot device in the system, and\r
+  automatically create boot options for Network, Shell, Removable BlockIo,\r
+  and Non-BlockIo Simplefile devices.\r
+  It will only execute once of every boot.\r
 \r
   @param  BdsBootOptionList      The header of the link list which indexed all\r
                                  current boot options\r
@@ -867,6 +912,7 @@ BdsDeleteAllInvalidEfiBootOption (
   @retval EFI_SUCCESS            Finished all the boot device enumerate and create\r
                                  the boot option base on that boot device\r
 \r
+  @retval EFI_OUT_OF_RESOURCES   Failed to enumerate the boot device and create the boot option list\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -879,6 +925,7 @@ BdsLibEnumerateAllBootOption (
   UINT16                        CdromNumber;\r
   UINT16                        UsbNumber;\r
   UINT16                        MiscNumber;\r
+  UINT16                        ScsiNumber;\r
   UINT16                        NonBlockNumber;\r
   UINTN                         NumberBlockIoHandles;\r
   EFI_HANDLE                    *BlockIoHandles;\r
@@ -892,8 +939,8 @@ BdsLibEnumerateAllBootOption (
   UINTN                         Size;\r
   EFI_FV_FILE_ATTRIBUTES        Attributes;\r
   UINT32                        AuthenticationStatus;\r
-  EFI_FIRMWARE_VOLUME2_PROTOCOL  *Fv;\r
-  EFI_DEVICE_PATH_PROTOCOL     *DevicePath;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
+  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;\r
   UINTN                         DevicePathType;\r
   CHAR16                        Buffer[40];\r
   EFI_HANDLE                    *FileSystemHandles;\r
@@ -907,17 +954,18 @@ BdsLibEnumerateAllBootOption (
   CdromNumber   = 0;\r
   UsbNumber     = 0;\r
   MiscNumber    = 0;\r
+  ScsiNumber    = 0;\r
   ZeroMem (Buffer, sizeof (Buffer));\r
-  \r
+\r
   //\r
   // If the boot device enumerate happened, just get the boot\r
   // device from the boot order variable\r
   //\r
   if (mEnumBootDevice) {\r
-    BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");\r
-    return EFI_SUCCESS;\r
+    Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");\r
+    return Status;\r
   }\r
-  \r
+\r
   //\r
   // Notes: this dirty code is to get the legacy boot option from the\r
   // BBS table and create to variable as the EFI boot option, it should\r
@@ -929,7 +977,7 @@ BdsLibEnumerateAllBootOption (
   // Delete invalid boot option\r
   //\r
   BdsDeleteAllInvalidEfiBootOption ();\r
-  \r
+\r
   //\r
   // Parse removable media\r
   //\r
@@ -940,7 +988,7 @@ BdsLibEnumerateAllBootOption (
         &NumberBlockIoHandles,\r
         &BlockIoHandles\r
         );\r
-        \r
+\r
   for (Index = 0; Index < NumberBlockIoHandles; Index++) {\r
     Status = gBS->HandleProtocol (\r
                     BlockIoHandles[Index],\r
@@ -960,51 +1008,35 @@ BdsLibEnumerateAllBootOption (
 \r
     switch (DevicePathType) {\r
     case BDS_EFI_ACPI_FLOPPY_BOOT:\r
-      if (FloppyNumber == 0) {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Floppy");\r
-      } else {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Floppy %d", FloppyNumber);\r
-      }\r
+      UnicodeSPrint (Buffer, sizeof (Buffer), L"%d", FloppyNumber);\r
       BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
       FloppyNumber++;\r
       break;\r
 \r
+    //\r
+    // Assume a removable SATA device should be the DVD/CD device\r
+    //\r
     case BDS_EFI_MESSAGE_ATAPI_BOOT:\r
-      if (CdromNumber == 0) {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI DVD/CDROM");\r
-      } else {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI DVD/CDROM %d", CdromNumber);\r
-      }\r
+    case BDS_EFI_MESSAGE_SATA_BOOT:\r
+      UnicodeSPrint (Buffer, sizeof (Buffer), L"%d", CdromNumber);\r
       BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
       CdromNumber++;\r
       break;\r
 \r
     case BDS_EFI_MESSAGE_USB_DEVICE_BOOT:\r
-      if (UsbNumber == 0) {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI USB Device");\r
-      } else {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI USB Device %d", UsbNumber);\r
-      }\r
+      UnicodeSPrint (Buffer, sizeof (Buffer), L"%d", UsbNumber);\r
       BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
       UsbNumber++;\r
       break;\r
 \r
     case BDS_EFI_MESSAGE_SCSI_BOOT:\r
-      if (UsbNumber == 0) {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI SCSI Device");\r
-      } else {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI SCSI Device %d", UsbNumber);\r
-      }\r
+      UnicodeSPrint (Buffer, sizeof (Buffer), L"%d", ScsiNumber);\r
       BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
-      UsbNumber++;\r
+      ScsiNumber++;\r
       break;\r
 \r
     case BDS_EFI_MESSAGE_MISC_BOOT:\r
-      if (MiscNumber == 0) {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Misc Device");\r
-      } else {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Misc Device %d", MiscNumber);\r
-      }\r
+      UnicodeSPrint (Buffer, sizeof (Buffer), L"%d", MiscNumber);\r
       BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
       MiscNumber++;\r
       break;\r
@@ -1050,7 +1082,7 @@ BdsLibEnumerateAllBootOption (
     NeedDelete = TRUE;\r
     Status     = BdsLibGetImageHeader (\r
                    FileSystemHandles[Index],\r
-                   (CHAR16*)PcdGetPtr (PcdDefaultBootFileName),\r
+                   EFI_REMOVABLE_MEDIA_FILE_NAME,\r
                    &DosHeader,\r
                    Hdr\r
                    );\r
@@ -1066,11 +1098,7 @@ BdsLibEnumerateAllBootOption (
       //\r
       BdsLibDeleteOptionFromHandle (FileSystemHandles[Index]);\r
     } else {\r
-      if (NonBlockNumber == 0) {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Non-Block Boot Device");\r
-      } else {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Non-Block Boot Device %d", NonBlockNumber);\r
-      }\r
+      UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Non-Block Boot Device %d", NonBlockNumber);\r
       BdsLibBuildOptionFromHandle (FileSystemHandles[Index], BdsBootOptionList, Buffer);\r
       NonBlockNumber++;\r
     }\r
@@ -1090,12 +1118,9 @@ BdsLibEnumerateAllBootOption (
         &NumberSimpleNetworkHandles,\r
         &SimpleNetworkHandles\r
         );\r
+\r
   for (Index = 0; Index < NumberSimpleNetworkHandles; Index++) {\r
-    if (Index == 0) {\r
-      UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Network");\r
-    } else {\r
-      UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Network %d", Index);\r
-    }\r
+    UnicodeSPrint (Buffer, sizeof (Buffer), L"%d", Index);\r
     BdsLibBuildOptionFromHandle (SimpleNetworkHandles[Index], BdsBootOptionList, Buffer);\r
   }\r
 \r
@@ -1114,18 +1139,6 @@ BdsLibEnumerateAllBootOption (
         &FvHandleBuffer\r
         );\r
   for (Index = 0; Index < FvHandleCount; Index++) {\r
-    //\r
-    // Only care the dispatched FV. If no dispatch protocol on the FV, it is not dispatched, then skip it.\r
-    //\r
-    Status = gBS->HandleProtocol (\r
-                    FvHandleBuffer[Index],\r
-                    &gEfiFirmwareVolumeDispatchProtocolGuid,\r
-                    (VOID **) &Fv\r
-                    );\r
-    if (EFI_ERROR (Status)) {\r
-      continue;\r
-    }\r
-    \r
     gBS->HandleProtocol (\r
           FvHandleBuffer[Index],\r
           &gEfiFirmwareVolume2ProtocolGuid,\r
@@ -1134,7 +1147,7 @@ BdsLibEnumerateAllBootOption (
 \r
     Status = Fv->ReadFile (\r
                   Fv,\r
-                  &gEfiShellFileGuid,\r
+                  PcdGetPtr(PcdShellFile),\r
                   NULL,\r
                   &Size,\r
                   &Type,\r
@@ -1160,10 +1173,10 @@ BdsLibEnumerateAllBootOption (
   // Make sure every boot only have one time\r
   // boot device enumerate\r
   //\r
-  BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");\r
+  Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");\r
   mEnumBootDevice = TRUE;\r
 \r
-  return EFI_SUCCESS;\r
+  return Status;\r
 }\r
 \r
 /**\r
@@ -1186,7 +1199,7 @@ BdsLibBuildOptionFromHandle (
 {\r
   EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
 \r
-  DevicePath  = DevicePathFromHandle (Handle);\r
+  DevicePath = DevicePathFromHandle (Handle);\r
 \r
   //\r
   // Create and register new boot option\r
@@ -1219,7 +1232,7 @@ BdsLibBuildOptionFromShell (
   //\r
   // Build the shell device path\r
   //\r
-  EfiInitializeFwVolDevicepathNode (&ShellNode, &gEfiShellFileGuid);\r
+  EfiInitializeFwVolDevicepathNode (&ShellNode, PcdGetPtr(PcdShellFile));\r
 \r
   DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &ShellNode);\r
 \r
@@ -1290,9 +1303,9 @@ BdsLibBootNext (
   Second, check whether the device path point to a device which support SimpleFileSystemProtocol,\r
   Third, detect the the default boot file in the Media, and return the removable Media handle.\r
 \r
-  @param  DevicePath             Device Path to a  bootable device\r
+  @param  DevicePath  Device Path to a  bootable device\r
 \r
-  @retval NULL                   The media on the DevicePath is not bootable\r
+  @return  The bootable media handle. If the media on the DevicePath is not bootable, NULL will return.\r
 \r
 **/\r
 EFI_HANDLE\r
@@ -1320,7 +1333,7 @@ BdsLibGetBootableHandle (
   EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;\r
 \r
   UpdatedDevicePath = DevicePath;\r
-  \r
+\r
   //\r
   // Check whether the device is connected\r
   //\r
@@ -1373,7 +1386,7 @@ BdsLibGetBootableHandle (
   //\r
   DupDevicePath = DuplicateDevicePath (DevicePath);\r
   ASSERT (DupDevicePath != NULL);\r
-  \r
+\r
   UpdatedDevicePath = DupDevicePath;\r
   Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &UpdatedDevicePath, &Handle);\r
   //\r
@@ -1420,7 +1433,7 @@ BdsLibGetBootableHandle (
       Hdr.Union = &HdrData;\r
       Status = BdsLibGetImageHeader (\r
                  SimpleFileSystemHandles[Index],\r
-                 (CHAR16*)PcdGetPtr(PcdDefaultBootFileName),\r
+                 EFI_REMOVABLE_MEDIA_FILE_NAME,\r
                  &DosHeader,\r
                  Hdr\r
                  );\r
@@ -1518,23 +1531,22 @@ BdsLibNetworkBootWithMediaPresent (
 \r
   @param  DevicePath                      The bootable device Path to check\r
 \r
-  @retval BDS_EFI_MEDIA_HD_BOOT           If the device path contains any media device path node, it is media boot type\r
-                                          For the floppy node, handle it as media node\r
-  @retval BDS_EFI_MEDIA_CDROM_BOOT        If the device path contains any media device path node, it is media boot type\r
-                                          For the floppy node, handle it as media node\r
-  @retval BDS_EFI_ACPI_FLOPPY_BOOT        If the device path contains any media device path node, it is media boot type\r
-                                          For the floppy node, handle it as media node\r
-  @retval BDS_EFI_MESSAGE_ATAPI_BOOT      If the device path not contains any media device path node,  and\r
-                                          its last device path node point to a message device path node, it is\r
-  \r
-  @retval BDS_EFI_MESSAGE_SCSI_BOOT       If the device path not contains any media device path node,  and\r
-                                          its last device path node point to a message device path node, it is\r
-  @retval BDS_EFI_MESSAGE_USB_DEVICE_BOOT If the device path not contains any media device path node,  and\r
-                                          its last device path node point to a message device path node, it is\r
+  @retval BDS_EFI_MEDIA_HD_BOOT           If given device path contains MEDIA_DEVICE_PATH type device path node\r
+                                          which subtype is MEDIA_HARDDRIVE_DP\r
+  @retval BDS_EFI_MEDIA_CDROM_BOOT        If given device path contains MEDIA_DEVICE_PATH type device path node\r
+                                          which subtype is MEDIA_CDROM_DP\r
+  @retval BDS_EFI_ACPI_FLOPPY_BOOT        If given device path contains ACPI_DEVICE_PATH type device path node\r
+                                          which HID is floppy device.\r
+  @retval BDS_EFI_MESSAGE_ATAPI_BOOT      If given device path contains MESSAGING_DEVICE_PATH type device path node\r
+                                          and its last device path node's subtype is MSG_ATAPI_DP.\r
+  @retval BDS_EFI_MESSAGE_SCSI_BOOT       If given device path contains MESSAGING_DEVICE_PATH type device path node\r
+                                          and its last device path node's subtype is MSG_SCSI_DP.\r
+  @retval BDS_EFI_MESSAGE_USB_DEVICE_BOOT If given device path contains MESSAGING_DEVICE_PATH type device path node\r
+                                          and its last device path node's subtype is MSG_USB_DP.\r
   @retval BDS_EFI_MESSAGE_MISC_BOOT       If the device path not contains any media device path node,  and\r
-                                          its last device path node point to a message device path node, it is\r
-  @retval BDS_LEGACY_BBS_BOOT             Legacy boot type\r
-  @retval BDS_EFI_UNSUPPORT               An EFI Removable BlockIO device path not point to a media and message device,   \r
+                                          its last device path node point to a message device path node.\r
+  @retval BDS_LEGACY_BBS_BOOT             If given device path contains BBS_DEVICE_PATH type device path node.\r
+  @retval BDS_EFI_UNSUPPORT               An EFI Removable BlockIO device path not point to a media and message device,\r
 \r
 **/\r
 UINT32\r
@@ -1587,7 +1599,7 @@ BdsGetBootTypeFromDevicePath (
         // if the device path not only point to driver device, it is not a messaging device path,\r
         //\r
         if (!IsDevicePathEndType (LastDeviceNode)) {\r
-          break;        \r
+          break;\r
         }\r
 \r
         if (DevicePathSubType(TempDevicePath) == MSG_ATAPI_DP) {\r
@@ -1596,6 +1608,10 @@ BdsGetBootTypeFromDevicePath (
           return BDS_EFI_MESSAGE_USB_DEVICE_BOOT;\r
         } else if (DevicePathSubType(TempDevicePath) == MSG_SCSI_DP) {\r
           return BDS_EFI_MESSAGE_SCSI_BOOT;\r
+        } else if (DevicePathSubType(TempDevicePath) == MSG_SATA_DP) {\r
+          return BDS_EFI_MESSAGE_SATA_BOOT;\r
+        } else if (DevicePathSubType(TempDevicePath) == MSG_MAC_ADDR_DP) {\r
+          return BDS_EFI_MESSAGE_MAC_BOOT;\r
         }\r
         return BDS_EFI_MESSAGE_MISC_BOOT;\r
       default:\r
@@ -1624,6 +1640,32 @@ BdsLibIsValidEFIBootOptDevicePath (
   IN EFI_DEVICE_PATH_PROTOCOL     *DevPath,\r
   IN BOOLEAN                      CheckMedia\r
   )\r
+{\r
+  return BdsLibIsValidEFIBootOptDevicePathExt (DevPath, CheckMedia, NULL);\r
+}\r
+\r
+/**\r
+  Check whether the Device path in a boot option point to a valid bootable device,\r
+  And if CheckMedia is true, check the device is ready to boot now.\r
+  If Description is not NULL and the device path point to a fixed BlockIo\r
+  device, check the description whether conflict with other auto-created\r
+  boot options.\r
+\r
+  @param  DevPath     the Device path in a boot option\r
+  @param  CheckMedia  if true, check the device is ready to boot now.\r
+  @param  Description the description in a boot option\r
+\r
+  @retval TRUE        the Device path  is valid\r
+  @retval FALSE       the Device path  is invalid .\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+BdsLibIsValidEFIBootOptDevicePathExt (\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath,\r
+  IN BOOLEAN                      CheckMedia,\r
+  IN CHAR16                       *Description\r
+  )\r
 {\r
   EFI_STATUS                Status;\r
   EFI_HANDLE                Handle;\r
@@ -1633,7 +1675,7 @@ BdsLibIsValidEFIBootOptDevicePath (
 \r
   TempDevicePath = DevPath;\r
   LastDeviceNode = DevPath;\r
-  \r
+\r
   //\r
   // Check if it's a valid boot option for network boot device\r
   // Only check if there is SimpleNetworkProtocol installed. If yes, that means\r
@@ -1656,7 +1698,7 @@ BdsLibIsValidEFIBootOptDevicePath (
                     &Handle\r
                     );\r
   }\r
-  \r
+\r
   if (!EFI_ERROR (Status)) {\r
     if (CheckMedia) {\r
       //\r
@@ -1690,20 +1732,22 @@ BdsLibIsValidEFIBootOptDevicePath (
     //\r
     // If the boot option point to Internal FV shell, make sure it is valid\r
     //\r
-    TempDevicePath = DevPath; \r
-    Status = BdsLibUpdateFvFileDevicePath (&TempDevicePath, &gEfiShellFileGuid);\r
+    TempDevicePath = DevPath;\r
+    Status = BdsLibUpdateFvFileDevicePath (&TempDevicePath, PcdGetPtr(PcdShellFile));\r
     if (Status == EFI_ALREADY_STARTED) {\r
       return TRUE;\r
     } else {\r
       if (Status == EFI_SUCCESS) {\r
-        FreePool (TempDevicePath); \r
+        FreePool (TempDevicePath);\r
       }\r
       return FALSE;\r
     }\r
   }\r
-  \r
+\r
   //\r
-  // If the boot option point to a blockIO device, no matter whether or not it is a removeable device, it is a valid EFI boot option\r
+  // If the boot option point to a blockIO device:\r
+  //    if it is a removable blockIo device, it is valid.\r
+  //    if it is a fixed blockIo device, check its description confliction.\r
   //\r
   TempDevicePath = DevPath;\r
   Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &TempDevicePath, &Handle);\r
@@ -1720,7 +1764,7 @@ BdsLibIsValidEFIBootOptDevicePath (
       Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &TempDevicePath, &Handle);\r
     }\r
   }\r
-  \r
+\r
   if (!EFI_ERROR (Status)) {\r
     Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);\r
     if (!EFI_ERROR (Status)) {\r
@@ -1809,7 +1853,7 @@ BdsLibUpdateFvFileDevicePath (
   if (FileGuid == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+\r
   //\r
   // Check whether the device path point to the default the input Fv file\r
   //\r
@@ -1943,7 +1987,7 @@ BdsLibUpdateFvFileDevicePath (
     }\r
 \r
     if (FvHandleBuffer != NULL) {\r
-      FreePool (FvHandleBuffer);  \r
+      FreePool (FvHandleBuffer);\r
     }\r
   }\r
 \r