]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c
Minor code enhancement.
[mirror_edk2.git] / IntelFrameworkModulePkg / Library / GenericBdsLib / BdsBoot.c
index f80f36ffc8841dcce4d82adb76774d3c86a19b19..7a9756e1f1d10dd2477e8e251cf8264ecc2ef414 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   BDS Lib functions which relate with create or process the boot option.\r
 \r
-Copyright (c) 2004 - 2008, Intel Corporation. <BR>\r
+Copyright (c) 2004 - 2010, Intel Corporation. <BR>\r
 All rights reserved. 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
@@ -55,7 +55,7 @@ BdsLibDoLegacyBoot (
   BdsRefreshBbsTableForBoot (Option);\r
 \r
   //\r
-  // Write boot to OS performance data to a file\r
+  // Write boot to OS performance data for legacy boot.\r
   //\r
   PERF_CODE (\r
     WriteBootToOsPerformanceData ();\r
@@ -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
@@ -150,7 +149,7 @@ BdsLibBootViaBootOption (
   //\r
   // Record the performance data for End of BDS\r
   //\r
-  PERF_END (0, "BDS", NULL, 0);\r
+  PERF_END(NULL, "BDS", NULL, 0);\r
 \r
   *ExitDataSize = 0;\r
   *ExitData     = NULL;\r
@@ -187,8 +186,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 +219,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,16 +232,78 @@ 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
-  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Booting %S\n", Option->Description));\r
+  DEBUG_CODE_BEGIN();\r
+    UINTN                     DevicePathTypeValue;\r
+    CHAR16                    *HiiString;\r
+    CHAR16                    *BootStringNumber;\r
+    UINTN                     BufferSize;\r
+  \r
+    DevicePathTypeValue = BdsGetBootTypeFromDevicePath (Option->DevicePath);\r
+  \r
+    //\r
+    // store number string of boot option temporary.\r
+    //\r
+    HiiString = NULL;\r
+    switch (DevicePathTypeValue) {\r
+    case BDS_EFI_ACPI_FLOPPY_BOOT:\r
+      HiiString = L"EFI Floppy";\r
+      break;\r
+    case BDS_EFI_MEDIA_CDROM_BOOT:\r
+    case BDS_EFI_MESSAGE_SATA_BOOT:\r
+    case BDS_EFI_MESSAGE_ATAPI_BOOT:\r
+      HiiString = L"EFI DVD/CDROM";\r
+      break;\r
+    case BDS_EFI_MESSAGE_USB_DEVICE_BOOT:\r
+      HiiString = L"EFI USB Device";\r
+      break;\r
+    case BDS_EFI_MESSAGE_SCSI_BOOT:\r
+      HiiString = L"EFI SCSI Device";\r
+      break;\r
+    case BDS_EFI_MESSAGE_MISC_BOOT:\r
+      HiiString = L"EFI Misc Device";\r
+      break;\r
+    case BDS_EFI_MESSAGE_MAC_BOOT:\r
+      HiiString = L"EFI Network";\r
+      break;\r
+    case BBS_DEVICE_PATH:\r
+      //\r
+      // Do nothing for legacy boot option.\r
+      //\r
+      break;\r
+    default:\r
+      DEBUG((EFI_D_INFO, "Can not find HiiString for given device path type 0x%x\n", DevicePathTypeValue));\r
+    }\r
 \r
+    //\r
+    // If found Hii description string then cat Hii string with original description.\r
+    //\r
+    if (HiiString != NULL) {\r
+      BootStringNumber = Option->Description;\r
+      BufferSize = StrSize(BootStringNumber);\r
+      BufferSize += StrSize(HiiString);\r
+      Option->Description = AllocateZeroPool(BufferSize);\r
+      ASSERT (Option->Description != NULL);\r
+      StrCpy (Option->Description, HiiString);\r
+      if (StrnCmp (BootStringNumber, L"0", 1) != 0) {\r
+        StrCat (Option->Description, L" ");\r
+        StrCat (Option->Description, BootStringNumber);\r
+      } \r
+      \r
+      FreePool (BootStringNumber);\r
+    }\r
+  \r
+    DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Booting %S\n", Option->Description));\r
+    \r
+  DEBUG_CODE_END();\r
+  \r
   Status = gBS->LoadImage (\r
                   TRUE,\r
                   mBdsImageHandle,\r
@@ -253,7 +314,7 @@ BdsLibBootViaBootOption (
                   );\r
 \r
   //\r
-  // If we didn't find an image directly, we need to try as if it is a removable device boot opotion\r
+  // If we didn't find an image directly, we need to try as if it is a removable device boot option\r
   // and load the image according to the default boot behavior for removable device.\r
   //\r
   if (EFI_ERROR (Status)) {\r
@@ -269,7 +330,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
@@ -311,6 +372,13 @@ BdsLibBootViaBootOption (
   //\r
   gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);\r
 \r
+  //\r
+  // Write boot to OS performance data for UEFI boot\r
+  //\r
+  PERF_CODE (\r
+    WriteBootToOsPerformanceData ();\r
+  );\r
+\r
   Status = gBS->StartImage (ImageHandle, ExitDataSize, ExitData);\r
   DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Image Return Status = %r\n", Status));\r
 \r
@@ -382,7 +450,7 @@ BdsExpandPartitionPartialDevicePathToFull (
                       &mHdBootVariablePrivateGuid,\r
                       &CachedDevicePathSize\r
                       );\r
-                      \r
+\r
   if (CachedDevicePath != NULL) {\r
     TempNewDevicePath = CachedDevicePath;\r
     DeviceExist = FALSE;\r
@@ -430,7 +498,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 +516,7 @@ BdsExpandPartitionPartialDevicePathToFull (
                         CachedDevicePath\r
                         );\r
       }\r
-      \r
+\r
       FreePool (Instance);\r
       FreePool (CachedDevicePath);\r
       return FullDevicePath;\r
@@ -547,7 +615,7 @@ BdsExpandPartitionPartialDevicePathToFull (
       break;\r
     }\r
   }\r
-  \r
+\r
   FreePool (CachedDevicePath);\r
   if (BlockIoBuffer != NULL) {\r
     FreePool (BlockIoBuffer);\r
@@ -582,7 +650,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 +679,7 @@ MatchPartitionDevicePathNode (
   //\r
   TmpHdPath = (HARDDRIVE_DEVICE_PATH *) BlockIoHdDevicePathNode;\r
   Match = FALSE;\r
-  \r
+\r
   //\r
   // Check for the match\r
   //\r
@@ -699,7 +767,7 @@ BdsLibDeleteOptionFromHandle (
                       &gEfiGlobalVariableGuid,\r
                       &BootOptionSize\r
                       );\r
-                      \r
+\r
     if (BootOptionVar == NULL) {\r
       FreePool (BootOrder);\r
       return EFI_OUT_OF_RESOURCES;\r
@@ -743,8 +811,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 +834,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 +867,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 +881,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 +927,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 +968,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,21 +981,22 @@ BdsLibEnumerateAllBootOption (
   UINT16                        CdromNumber;\r
   UINT16                        UsbNumber;\r
   UINT16                        MiscNumber;\r
+  UINT16                        ScsiNumber;\r
   UINT16                        NonBlockNumber;\r
   UINTN                         NumberBlockIoHandles;\r
   EFI_HANDLE                    *BlockIoHandles;\r
   EFI_BLOCK_IO_PROTOCOL         *BlkIo;\r
   UINTN                         Index;\r
-  UINTN                         NumberSimpleNetworkHandles;\r
-  EFI_HANDLE                    *SimpleNetworkHandles;\r
+  UINTN                         NumberNetworkHandles;\r
+  EFI_HANDLE                    *NetworkHandles;\r
   UINTN                         FvHandleCount;\r
   EFI_HANDLE                    *FvHandleBuffer;\r
   EFI_FV_FILETYPE               Type;\r
   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 +1010,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 +1033,7 @@ BdsLibEnumerateAllBootOption (
   // Delete invalid boot option\r
   //\r
   BdsDeleteAllInvalidEfiBootOption ();\r
-  \r
+\r
   //\r
   // Parse removable media\r
   //\r
@@ -940,7 +1044,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 +1064,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 +1138,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 +1154,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
@@ -1083,24 +1167,37 @@ BdsLibEnumerateAllBootOption (
   //\r
   // Parse Network Boot Device\r
   //\r
+  NumberNetworkHandles = 0;\r
+  //\r
+  // Search MNP Service Binding protocol for UEFI network stack\r
+  //\r
   gBS->LocateHandleBuffer (\r
         ByProtocol,\r
-        &gEfiSimpleNetworkProtocolGuid,\r
+        &gEfiManagedNetworkServiceBindingProtocolGuid,\r
         NULL,\r
-        &NumberSimpleNetworkHandles,\r
-        &SimpleNetworkHandles\r
+        &NumberNetworkHandles,\r
+        &NetworkHandles\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
-    BdsLibBuildOptionFromHandle (SimpleNetworkHandles[Index], BdsBootOptionList, Buffer);\r
+  if (NumberNetworkHandles == 0) {\r
+    //\r
+    // MNP Service Binding protocol not found, search SNP for EFI network stack\r
+    //\r
+    gBS->LocateHandleBuffer (\r
+          ByProtocol,\r
+          &gEfiSimpleNetworkProtocolGuid,\r
+          NULL,\r
+          &NumberNetworkHandles,\r
+          &NetworkHandles\r
+          );\r
+  }\r
+\r
+  for (Index = 0; Index < NumberNetworkHandles; Index++) {\r
+    UnicodeSPrint (Buffer, sizeof (Buffer), L"%d", Index);\r
+    BdsLibBuildOptionFromHandle (NetworkHandles[Index], BdsBootOptionList, Buffer);\r
   }\r
 \r
-  if (NumberSimpleNetworkHandles != 0) {\r
-    FreePool (SimpleNetworkHandles);\r
+  if (NumberNetworkHandles != 0) {\r
+    FreePool (NetworkHandles);\r
   }\r
 \r
   //\r
@@ -1114,18 +1211,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 +1219,7 @@ BdsLibEnumerateAllBootOption (
 \r
     Status = Fv->ReadFile (\r
                   Fv,\r
-                  &gEfiShellFileGuid,\r
+                  PcdGetPtr(PcdShellFile),\r
                   NULL,\r
                   &Size,\r
                   &Type,\r
@@ -1160,10 +1245,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 +1271,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 +1304,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 +1375,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 +1405,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 +1458,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 +1505,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
@@ -1466,7 +1551,17 @@ BdsLibNetworkBootWithMediaPresent (
   MediaPresent = FALSE;\r
 \r
   UpdatedDevicePath = DevicePath;\r
-  Status = gBS->LocateDevicePath (&gEfiSimpleNetworkProtocolGuid, &UpdatedDevicePath, &Handle);\r
+  //\r
+  // Locate MNP Service Binding protocol for UEFI network stack first\r
+  //\r
+  Status = gBS->LocateDevicePath (&gEfiManagedNetworkServiceBindingProtocolGuid, &UpdatedDevicePath, &Handle);\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // MNP Service Binding protocol not found, search SNP for EFI network stack\r
+    //\r
+    UpdatedDevicePath = DevicePath;\r
+    Status = gBS->LocateDevicePath (&gEfiSimpleNetworkProtocolGuid, &UpdatedDevicePath, &Handle);\r
+  }\r
   if (EFI_ERROR (Status)) {\r
     //\r
     // Device not present so see if we need to connect it\r
@@ -1476,12 +1571,32 @@ BdsLibNetworkBootWithMediaPresent (
       //\r
       // This one should work after we did the connect\r
       //\r
-      Status = gBS->LocateDevicePath (&gEfiSimpleNetworkProtocolGuid, &UpdatedDevicePath, &Handle);\r
+      Status = gBS->LocateDevicePath (&gEfiManagedNetworkServiceBindingProtocolGuid, &UpdatedDevicePath, &Handle);\r
+      if (EFI_ERROR (Status)) {\r
+        UpdatedDevicePath = DevicePath;\r
+        Status = gBS->LocateDevicePath (&gEfiSimpleNetworkProtocolGuid, &UpdatedDevicePath, &Handle);\r
+      }\r
     }\r
   }\r
 \r
   if (!EFI_ERROR (Status)) {\r
     Status = gBS->HandleProtocol (Handle, &gEfiSimpleNetworkProtocolGuid, (VOID **)&Snp);\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Failed to open SNP from this handle, try to get SNP from parent handle\r
+      //\r
+      UpdatedDevicePath = DevicePathFromHandle (Handle);\r
+      if (UpdatedDevicePath != NULL) {\r
+        Status = gBS->LocateDevicePath (&gEfiSimpleNetworkProtocolGuid, &UpdatedDevicePath, &Handle);\r
+        if (!EFI_ERROR (Status)) {\r
+          //\r
+          // SNP handle found, get SNP from it\r
+          //\r
+          Status = gBS->HandleProtocol (Handle, &gEfiSimpleNetworkProtocolGuid, (VOID **) &Snp);\r
+        }\r
+      }\r
+    }\r
+\r
     if (!EFI_ERROR (Status)) {\r
       if (Snp->Mode->MediaPresentSupported) {\r
         if (Snp->Mode->State == EfiSimpleNetworkInitialized) {\r
@@ -1518,23 +1633,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
@@ -1546,7 +1660,7 @@ BdsGetBootTypeFromDevicePath (
   ACPI_HID_DEVICE_PATH          *Acpi;\r
   EFI_DEVICE_PATH_PROTOCOL      *TempDevicePath;\r
   EFI_DEVICE_PATH_PROTOCOL      *LastDeviceNode;\r
-\r
+  UINT32                        BootType;\r
 \r
   if (NULL == DevicePath) {\r
     return BDS_EFI_UNSUPPORT;\r
@@ -1579,7 +1693,7 @@ BdsGetBootTypeFromDevicePath (
         if (DevicePathSubType(LastDeviceNode) == MSG_DEVICE_LOGICAL_UNIT_DP) {\r
           //\r
           // if the next node type is Device Logical Unit, which specify the Logical Unit Number (LUN),\r
-          // skit it\r
+          // skip it\r
           //\r
           LastDeviceNode = NextDevicePathNode (LastDeviceNode);\r
         }\r
@@ -1587,17 +1701,37 @@ 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
-          return BDS_EFI_MESSAGE_ATAPI_BOOT;\r
-        } else if (DevicePathSubType(TempDevicePath) == MSG_USB_DP) {\r
-          return BDS_EFI_MESSAGE_USB_DEVICE_BOOT;\r
-        } else if (DevicePathSubType(TempDevicePath) == MSG_SCSI_DP) {\r
-          return BDS_EFI_MESSAGE_SCSI_BOOT;\r
+        switch (DevicePathSubType (TempDevicePath)) {\r
+        case MSG_ATAPI_DP:\r
+          BootType = BDS_EFI_MESSAGE_ATAPI_BOOT;\r
+          break;\r
+\r
+        case MSG_USB_DP:\r
+          BootType = BDS_EFI_MESSAGE_USB_DEVICE_BOOT;\r
+          break;\r
+\r
+        case MSG_SCSI_DP:\r
+          BootType = BDS_EFI_MESSAGE_SCSI_BOOT;\r
+          break;\r
+\r
+        case MSG_SATA_DP:\r
+          BootType = BDS_EFI_MESSAGE_SATA_BOOT;\r
+          break;\r
+\r
+        case MSG_MAC_ADDR_DP:\r
+        case MSG_VLAN_DP:\r
+          BootType = BDS_EFI_MESSAGE_MAC_BOOT;\r
+          break;\r
+\r
+        default:\r
+          BootType = BDS_EFI_MESSAGE_MISC_BOOT;\r
+          break;\r
         }\r
-        return BDS_EFI_MESSAGE_MISC_BOOT;\r
+        return BootType;\r
+\r
       default:\r
         break;\r
     }\r
@@ -1624,26 +1758,61 @@ 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
   EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;\r
   EFI_DEVICE_PATH_PROTOCOL  *LastDeviceNode;\r
   EFI_BLOCK_IO_PROTOCOL     *BlockIo;\r
+  EFI_LOAD_FILE_PROTOCOL    *LoadFile;\r
 \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
-  // there is the network card there.\r
+  // Check if there is MNP Service Binding Protocol or SimpleNetworkProtocol\r
+  // installed. If yes, that means there is the network card there.\r
   //\r
   Status = gBS->LocateDevicePath (\r
-                  &gEfiSimpleNetworkProtocolGuid,\r
+                  &gEfiManagedNetworkServiceBindingProtocolGuid,\r
                   &TempDevicePath,\r
                   &Handle\r
                   );\r
+  if (EFI_ERROR (Status)) {\r
+    TempDevicePath = DevPath;\r
+    Status = gBS->LocateDevicePath (\r
+                    &gEfiSimpleNetworkProtocolGuid,\r
+                    &TempDevicePath,\r
+                    &Handle\r
+                    );\r
+  }\r
   if (EFI_ERROR (Status)) {\r
     //\r
     // Device not present so see if we need to connect it\r
@@ -1651,22 +1820,43 @@ BdsLibIsValidEFIBootOptDevicePath (
     TempDevicePath = DevPath;\r
     BdsLibConnectDevicePath (TempDevicePath);\r
     Status = gBS->LocateDevicePath (\r
-                    &gEfiSimpleNetworkProtocolGuid,\r
+                    &gEfiManagedNetworkServiceBindingProtocolGuid,\r
                     &TempDevicePath,\r
                     &Handle\r
                     );\r
+    if (EFI_ERROR (Status)) {\r
+      TempDevicePath = DevPath;\r
+      Status = gBS->LocateDevicePath (\r
+                      &gEfiSimpleNetworkProtocolGuid,\r
+                      &TempDevicePath,\r
+                      &Handle\r
+                      );\r
+    }\r
   }\r
-  \r
+\r
   if (!EFI_ERROR (Status)) {\r
-    if (CheckMedia) {\r
-      //\r
-      // Test if it is ready to boot now\r
-      //\r
-      if (BdsLibNetworkBootWithMediaPresent(DevPath)) {\r
+    //\r
+    // Check whether LoadFile protocol is installed\r
+    //\r
+    Status = gBS->HandleProtocol (Handle, &gEfiLoadFileProtocolGuid, (VOID **)&LoadFile);\r
+    if (!EFI_ERROR (Status)) {\r
+      if (!IsDevicePathEnd (TempDevicePath)) {\r
+        //\r
+        // LoadFile protocol is not installed on handle with exactly the same DevPath\r
+        //\r
+        return FALSE;\r
+      }\r
+\r
+      if (CheckMedia) {\r
+        //\r
+        // Test if it is ready to boot now\r
+        //\r
+        if (BdsLibNetworkBootWithMediaPresent(DevPath)) {\r
+          return TRUE;\r
+        }\r
+      } else {\r
         return TRUE;\r
       }\r
-    } else {\r
-      return TRUE;\r
     }\r
   }\r
 \r
@@ -1690,20 +1880,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 +1912,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 +2001,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 +2135,7 @@ BdsLibUpdateFvFileDevicePath (
     }\r
 \r
     if (FvHandleBuffer != NULL) {\r
-      FreePool (FvHandleBuffer);  \r
+      FreePool (FvHandleBuffer);\r
     }\r
   }\r
 \r