]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Refine BdsDxe driver and GenericBdsLib library so that the GenericBdsLib doesn't...
authorniruiyu <niruiyu@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 1 Jun 2012 03:39:39 +0000 (03:39 +0000)
committerniruiyu <niruiyu@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 1 Jun 2012 03:39:39 +0000 (03:39 +0000)
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13418 6f19259b-4bc3-4df7-8a09-765794883524

IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c
IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c
IntelFrameworkModulePkg/Library/GenericBdsLib/InternalBdsLib.h
IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.c
IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.h
IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BmLib.c
IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c
IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootMaint.h
IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/Variable.c
IntelFrameworkModulePkg/Universal/BdsDxe/BootMngr/BootManager.c

index 9a8b68752991ad88b2ead7d7dc8d30449eb84956..360760c48a0b6390c57b8a1766f9175c73d1d3da 100644 (file)
@@ -50,7 +50,1602 @@ GenericBdsLibConstructor (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Deletete the Boot Option from EFI Variable. The Boot Order Arrray\r
+  is also updated.\r
+\r
+  @param OptionNumber    The number of Boot option want to be deleted.\r
+  @param BootOrder       The Boot Order array.\r
+  @param BootOrderSize   The size of the Boot Order Array.\r
+\r
+  @retval  EFI_SUCCESS           The Boot Option Variable was found and removed\r
+  @retval  EFI_UNSUPPORTED       The Boot Option Variable store was inaccessible\r
+  @retval  EFI_NOT_FOUND         The Boot Option Variable was not found\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BdsDeleteBootOption (\r
+  IN UINTN                       OptionNumber,\r
+  IN OUT UINT16                  *BootOrder,\r
+  IN OUT UINTN                   *BootOrderSize\r
+  )\r
+{\r
+  CHAR16      BootOption[9];\r
+  UINTN       Index;\r
+  EFI_STATUS  Status;\r
+\r
+  UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", OptionNumber);\r
+  Status = gRT->SetVariable (\r
+                  BootOption,\r
+                  &gEfiGlobalVariableGuid,\r
+                  0,\r
+                  0,\r
+                  NULL\r
+                  );\r
+\r
+  //\r
+  // adjust boot order array\r
+  //\r
+  for (Index = 0; Index < *BootOrderSize / sizeof (UINT16); Index++) {\r
+    if (BootOrder[Index] == OptionNumber) {\r
+      CopyMem (&BootOrder[Index], &BootOrder[Index+1], *BootOrderSize - (Index+1) * sizeof (UINT16));\r
+      *BootOrderSize -= sizeof (UINT16);\r
+      break;\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
+/**\r
+\r
+  Translate the first n characters of an Ascii string to\r
+  Unicode characters. The count n is indicated by parameter\r
+  Size. If Size is greater than the length of string, then\r
+  the entire string is translated.\r
+\r
+\r
+  @param AStr               Pointer to input Ascii string.\r
+  @param Size               The number of characters to translate.\r
+  @param UStr               Pointer to output Unicode string buffer.\r
+\r
+**/\r
+VOID\r
+AsciiToUnicodeSize (\r
+  IN UINT8              *AStr,\r
+  IN UINTN              Size,\r
+  OUT UINT16            *UStr\r
+  )\r
+{\r
+  UINTN Idx;\r
+\r
+  Idx = 0;\r
+  while (AStr[Idx] != 0) {\r
+    UStr[Idx] = (CHAR16) AStr[Idx];\r
+    if (Idx == Size) {\r
+      break;\r
+    }\r
+\r
+    Idx++;\r
+  }\r
+  UStr[Idx] = 0;\r
+}\r
+\r
+/**\r
+  Build Legacy Device Name String according.\r
+\r
+  @param CurBBSEntry     BBS Table.\r
+  @param Index           Index.\r
+  @param BufSize         The buffer size.\r
+  @param BootString      The output string.\r
+\r
+**/\r
+VOID\r
+BdsBuildLegacyDevNameString (\r
+  IN  BBS_TABLE                 *CurBBSEntry,\r
+  IN  UINTN                     Index,\r
+  IN  UINTN                     BufSize,\r
+  OUT CHAR16                    *BootString\r
+  )\r
+{\r
+  CHAR16  *Fmt;\r
+  CHAR16  *Type;\r
+  UINT8   *StringDesc;\r
+  CHAR16  Temp[80];\r
+\r
+  switch (Index) {\r
+  //\r
+  // Primary Master\r
+  //\r
+  case 1:\r
+    Fmt = L"Primary Master %s";\r
+    break;\r
+\r
+ //\r
+ // Primary Slave\r
+ //\r
+  case 2:\r
+    Fmt = L"Primary Slave %s";\r
+    break;\r
+\r
+  //\r
+  // Secondary Master\r
+  //\r
+  case 3:\r
+    Fmt = L"Secondary Master %s";\r
+    break;\r
+\r
+  //\r
+  // Secondary Slave\r
+  //\r
+  case 4:\r
+    Fmt = L"Secondary Slave %s";\r
+    break;\r
+\r
+  default:\r
+    Fmt = L"%s";\r
+    break;\r
+  }\r
+\r
+  switch (CurBBSEntry->DeviceType) {\r
+  case BBS_FLOPPY:\r
+    Type = L"Floppy";\r
+    break;\r
+\r
+  case BBS_HARDDISK:\r
+    Type = L"Harddisk";\r
+    break;\r
+\r
+  case BBS_CDROM:\r
+    Type = L"CDROM";\r
+    break;\r
+\r
+  case BBS_PCMCIA:\r
+    Type = L"PCMCIAe";\r
+    break;\r
+\r
+  case BBS_USB:\r
+    Type = L"USB";\r
+    break;\r
+\r
+  case BBS_EMBED_NETWORK:\r
+    Type = L"Network";\r
+    break;\r
+\r
+  case BBS_BEV_DEVICE:\r
+    Type = L"BEVe";\r
+    break;\r
+\r
+  case BBS_UNKNOWN:\r
+  default:\r
+    Type = L"Unknown";\r
+    break;\r
+  }\r
+  //\r
+  // If current BBS entry has its description then use it.\r
+  //\r
+  StringDesc = (UINT8 *) (UINTN) ((CurBBSEntry->DescStringSegment << 4) + CurBBSEntry->DescStringOffset);\r
+  if (NULL != StringDesc) {\r
+    //\r
+    // Only get fisrt 32 characters, this is suggested by BBS spec\r
+    //\r
+    AsciiToUnicodeSize (StringDesc, 32, Temp);\r
+    Fmt   = L"%s";\r
+    Type  = Temp;\r
+  }\r
+\r
+  //\r
+  // BbsTable 16 entries are for onboard IDE.\r
+  // Set description string for SATA harddisks, Harddisk 0 ~ Harddisk 11\r
+  //\r
+  if (Index >= 5 && Index <= 16 && (CurBBSEntry->DeviceType == BBS_HARDDISK || CurBBSEntry->DeviceType == BBS_CDROM)) {\r
+    Fmt = L"%s %d";\r
+    UnicodeSPrint (BootString, BufSize, Fmt, Type, Index - 5);\r
+  } else {\r
+    UnicodeSPrint (BootString, BufSize, Fmt, Type);\r
+  }\r
+}\r
+\r
+/**\r
+\r
+  Create a legacy boot option for the specified entry of\r
+  BBS table, save it as variable, and append it to the boot\r
+  order list.\r
+\r
+\r
+  @param CurrentBbsEntry    Pointer to current BBS table.\r
+  @param CurrentBbsDevPath  Pointer to the Device Path Protocol instance of BBS\r
+  @param Index              Index of the specified entry in BBS table.\r
+  @param BootOrderList      On input, the original boot order list.\r
+                            On output, the new boot order list attached with the\r
+                            created node.\r
+  @param BootOrderListSize  On input, the original size of boot order list.\r
+                            On output, the size of new boot order list.\r
+\r
+  @retval  EFI_SUCCESS             Boot Option successfully created.\r
+  @retval  EFI_OUT_OF_RESOURCES    Fail to allocate necessary memory.\r
+  @retval  Other                   Error occurs while setting variable.\r
+\r
+**/\r
+EFI_STATUS\r
+BdsCreateLegacyBootOption (\r
+  IN BBS_TABLE                        *CurrentBbsEntry,\r
+  IN EFI_DEVICE_PATH_PROTOCOL         *CurrentBbsDevPath,\r
+  IN UINTN                            Index,\r
+  IN OUT UINT16                       **BootOrderList,\r
+  IN OUT UINTN                        *BootOrderListSize\r
+  )\r
+{\r
+  EFI_STATUS           Status;\r
+  UINT16               CurrentBootOptionNo;\r
+  UINT16               BootString[10];\r
+  CHAR16               BootDesc[100];\r
+  CHAR8                HelpString[100];\r
+  UINT16               *NewBootOrderList;\r
+  UINTN                BufferSize;\r
+  UINTN                StringLen;\r
+  VOID                 *Buffer;\r
+  UINT8                *Ptr;\r
+  UINT16               CurrentBbsDevPathSize;\r
+  UINTN                BootOrderIndex;\r
+  UINTN                BootOrderLastIndex;\r
+  UINTN                ArrayIndex;\r
+  BOOLEAN              IndexNotFound;\r
+  BBS_BBS_DEVICE_PATH  *NewBbsDevPathNode;\r
+\r
+  if ((*BootOrderList) == NULL) {\r
+    CurrentBootOptionNo = 0;\r
+  } else {\r
+    for (ArrayIndex = 0; ArrayIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); ArrayIndex++) {\r
+      IndexNotFound = TRUE;\r
+      for (BootOrderIndex = 0; BootOrderIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); BootOrderIndex++) {\r
+        if ((*BootOrderList)[BootOrderIndex] == ArrayIndex) {\r
+          IndexNotFound = FALSE;\r
+          break;\r
+        }\r
+      }\r
+\r
+      if (!IndexNotFound) {\r
+        continue;\r
+      } else {\r
+        break;\r
+      }\r
+    }\r
+\r
+    CurrentBootOptionNo = (UINT16) ArrayIndex;\r
+  }\r
+\r
+  UnicodeSPrint (\r
+    BootString,\r
+    sizeof (BootString),\r
+    L"Boot%04x",\r
+    CurrentBootOptionNo\r
+    );\r
+\r
+  BdsBuildLegacyDevNameString (CurrentBbsEntry, Index, sizeof (BootDesc), BootDesc);\r
+\r
+  //\r
+  // Create new BBS device path node with description string\r
+  //\r
+  UnicodeStrToAsciiStr (BootDesc, HelpString);\r
+\r
+  StringLen = AsciiStrLen (HelpString);\r
+  NewBbsDevPathNode = AllocateZeroPool (sizeof (BBS_BBS_DEVICE_PATH) + StringLen);\r
+  if (NewBbsDevPathNode == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  CopyMem (NewBbsDevPathNode, CurrentBbsDevPath, sizeof (BBS_BBS_DEVICE_PATH));\r
+  CopyMem (NewBbsDevPathNode->String, HelpString, StringLen + 1);\r
+  SetDevicePathNodeLength (&(NewBbsDevPathNode->Header), sizeof (BBS_BBS_DEVICE_PATH) + StringLen);\r
+\r
+  //\r
+  // Create entire new CurrentBbsDevPath with end node\r
+  //\r
+  CurrentBbsDevPath = AppendDevicePathNode (\r
+                        NULL,\r
+                        (EFI_DEVICE_PATH_PROTOCOL *) NewBbsDevPathNode\r
+                        );\r
+   if (CurrentBbsDevPath == NULL) {\r
+    FreePool (NewBbsDevPathNode);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  CurrentBbsDevPathSize = (UINT16) (GetDevicePathSize (CurrentBbsDevPath));\r
+\r
+  BufferSize = sizeof (UINT32) +\r
+    sizeof (UINT16) +\r
+    StrSize (BootDesc) +\r
+    CurrentBbsDevPathSize +\r
+    sizeof (BBS_TABLE) +\r
+    sizeof (UINT16);\r
+\r
+  Buffer = AllocateZeroPool (BufferSize);\r
+  if (Buffer == NULL) {\r
+    FreePool (NewBbsDevPathNode);\r
+    FreePool (CurrentBbsDevPath);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  Ptr               = (UINT8 *) Buffer;\r
+\r
+  *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE;\r
+  Ptr += sizeof (UINT32);\r
+\r
+  *((UINT16 *) Ptr) = CurrentBbsDevPathSize;\r
+  Ptr += sizeof (UINT16);\r
+\r
+  CopyMem (\r
+    Ptr,\r
+    BootDesc,\r
+    StrSize (BootDesc)\r
+    );\r
+  Ptr += StrSize (BootDesc);\r
+\r
+  CopyMem (\r
+    Ptr,\r
+    CurrentBbsDevPath,\r
+    CurrentBbsDevPathSize\r
+    );\r
+  Ptr += CurrentBbsDevPathSize;\r
+\r
+  CopyMem (\r
+    Ptr,\r
+    CurrentBbsEntry,\r
+    sizeof (BBS_TABLE)\r
+    );\r
+\r
+  Ptr += sizeof (BBS_TABLE);\r
+  *((UINT16 *) Ptr) = (UINT16) Index;\r
+\r
+  Status = gRT->SetVariable (\r
+                  BootString,\r
+                  &gEfiGlobalVariableGuid,\r
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+                  BufferSize,\r
+                  Buffer\r
+                  );\r
+\r
+  FreePool (Buffer);\r
+  \r
+  Buffer = NULL;\r
+\r
+  NewBootOrderList = AllocateZeroPool (*BootOrderListSize + sizeof (UINT16));\r
+  if (NULL == NewBootOrderList) {\r
+    FreePool (NewBbsDevPathNode);\r
+    FreePool (CurrentBbsDevPath);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  if (*BootOrderList != NULL) {\r
+    CopyMem (NewBootOrderList, *BootOrderList, *BootOrderListSize);\r
+    FreePool (*BootOrderList);\r
+  }\r
+\r
+  BootOrderLastIndex                    = (UINTN) (*BootOrderListSize / sizeof (UINT16));\r
+  NewBootOrderList[BootOrderLastIndex]  = CurrentBootOptionNo;\r
+  *BootOrderListSize += sizeof (UINT16);\r
+  *BootOrderList = NewBootOrderList;\r
+\r
+  FreePool (NewBbsDevPathNode);\r
+  FreePool (CurrentBbsDevPath);\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Check if the boot option is a legacy one.\r
+\r
+  @param BootOptionVar   The boot option data payload.\r
+  @param BbsEntry        The BBS Table.\r
+  @param BbsIndex        The table index.\r
+\r
+  @retval TRUE           It is a legacy boot option.\r
+  @retval FALSE          It is not a legacy boot option.\r
+\r
+**/\r
+BOOLEAN\r
+BdsIsLegacyBootOption (\r
+  IN UINT8                 *BootOptionVar,\r
+  OUT BBS_TABLE            **BbsEntry,\r
+  OUT UINT16               *BbsIndex\r
+  )\r
+{\r
+  UINT8                     *Ptr;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+  BOOLEAN                   Ret;\r
+  UINT16                    DevPathLen;\r
+\r
+  Ptr = BootOptionVar;\r
+  Ptr += sizeof (UINT32);\r
+  DevPathLen = *(UINT16 *) Ptr;\r
+  Ptr += sizeof (UINT16);\r
+  Ptr += StrSize ((UINT16 *) Ptr);\r
+  DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;\r
+  if ((BBS_DEVICE_PATH == DevicePath->Type) && (BBS_BBS_DP == DevicePath->SubType)) {\r
+    Ptr += DevPathLen;\r
+    *BbsEntry = (BBS_TABLE *) Ptr;\r
+    Ptr += sizeof (BBS_TABLE);\r
+    *BbsIndex = *(UINT16 *) Ptr;\r
+    Ret       = TRUE;\r
+  } else {\r
+    *BbsEntry = NULL;\r
+    Ret       = FALSE;\r
+  }\r
+\r
+  return Ret;\r
+}\r
+\r
+/**\r
+  Delete all the invalid legacy boot options.\r
+\r
+  @retval EFI_SUCCESS             All invalide legacy boot options are deleted.\r
+  @retval EFI_OUT_OF_RESOURCES    Fail to allocate necessary memory.\r
+  @retval EFI_NOT_FOUND           Fail to retrive variable of boot order.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BdsDeleteAllInvalidLegacyBootOptions (\r
+  VOID\r
+  )\r
+{\r
+  UINT16                    *BootOrder;\r
+  UINT8                     *BootOptionVar;\r
+  UINTN                     BootOrderSize;\r
+  UINTN                     BootOptionSize;\r
+  EFI_STATUS                Status;\r
+  UINT16                    HddCount;\r
+  UINT16                    BbsCount;\r
+  HDD_INFO                  *LocalHddInfo;\r
+  BBS_TABLE                 *LocalBbsTable;\r
+  BBS_TABLE                 *BbsEntry;\r
+  UINT16                    BbsIndex;\r
+  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;\r
+  UINTN                     Index;\r
+  UINT16                    BootOption[10];\r
+  UINT16                    BootDesc[100];\r
+  BOOLEAN                   DescStringMatch;\r
+\r
+  Status        = EFI_SUCCESS;\r
+  BootOrder     = NULL;\r
+  BootOrderSize = 0;\r
+  HddCount      = 0;\r
+  BbsCount      = 0;\r
+  LocalHddInfo  = NULL;\r
+  LocalBbsTable = NULL;\r
+  BbsEntry      = NULL;\r
+\r
+  Status        = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  LegacyBios->GetBbsInfo (\r
+                LegacyBios,\r
+                &HddCount,\r
+                &LocalHddInfo,\r
+                &BbsCount,\r
+                &LocalBbsTable\r
+                );\r
+\r
+  BootOrder = BdsLibGetVariableAndSize (\r
+                L"BootOrder",\r
+                &gEfiGlobalVariableGuid,\r
+                &BootOrderSize\r
+                );\r
+  if (BootOrder == NULL) {\r
+    BootOrderSize = 0;\r
+  }\r
+\r
+  Index = 0;\r
+  while (Index < BootOrderSize / sizeof (UINT16)) {\r
+    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);\r
+    BootOptionVar = BdsLibGetVariableAndSize (\r
+                      BootOption,\r
+                      &gEfiGlobalVariableGuid,\r
+                      &BootOptionSize\r
+                      );\r
+    if (NULL == BootOptionVar) {\r
+      BootOptionSize = 0;\r
+      Status = gRT->GetVariable (\r
+                      BootOption,\r
+                      &gEfiGlobalVariableGuid,\r
+                      NULL,\r
+                      &BootOptionSize,\r
+                      BootOptionVar\r
+                      );\r
+      if (Status == EFI_NOT_FOUND) {\r
+        //\r
+        // Update BootOrder\r
+        //\r
+        BdsDeleteBootOption (\r
+          BootOrder[Index],\r
+          BootOrder,\r
+          &BootOrderSize\r
+          );\r
+        continue;\r
+      } else {\r
+        FreePool (BootOrder);\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+    }\r
+  \r
+    //\r
+    // Skip Non-Legacy boot option\r
+    // \r
+    if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, &BbsIndex)) {\r
+      if (BootOptionVar!= NULL) {\r
+        FreePool (BootOptionVar);\r
+      }\r
+      Index++;\r
+      continue;\r
+    }\r
+\r
+    if (BbsIndex < BbsCount) {\r
+      //\r
+      // Check if BBS Description String is changed\r
+      //\r
+      DescStringMatch = FALSE;\r
+      BdsBuildLegacyDevNameString (\r
+        &LocalBbsTable[BbsIndex],\r
+        BbsIndex,\r
+        sizeof (BootDesc),\r
+        BootDesc\r
+        );\r
+\r
+      if (StrCmp (BootDesc, (UINT16*)(BootOptionVar + sizeof (UINT32) + sizeof (UINT16))) == 0) {\r
+        DescStringMatch = TRUE;\r
+      }\r
+\r
+      if (!((LocalBbsTable[BbsIndex].BootPriority == BBS_IGNORE_ENTRY) ||\r
+            (LocalBbsTable[BbsIndex].BootPriority == BBS_DO_NOT_BOOT_FROM)) &&\r
+          (LocalBbsTable[BbsIndex].DeviceType == BbsEntry->DeviceType) &&\r
+          DescStringMatch) {\r
+        Index++;\r
+        continue;\r
+      }\r
+    }\r
+\r
+    if (BootOptionVar != NULL) {\r
+      FreePool (BootOptionVar);\r
+    }\r
+    //\r
+    // should delete\r
+    //\r
+    BdsDeleteBootOption (\r
+      BootOrder[Index],\r
+      BootOrder,\r
+      &BootOrderSize\r
+      );\r
+  }\r
+\r
+  //\r
+  // Adjust the number of boot options.\r
+  //\r
+  Status = gRT->SetVariable (\r
+                  L"BootOrder",\r
+                  &gEfiGlobalVariableGuid,\r
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+                  BootOrderSize,\r
+                  BootOrder\r
+                  );\r
+  if (BootOrder != NULL) {\r
+    FreePool (BootOrder);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Find all legacy boot option by device type.\r
+\r
+  @param BootOrder       The boot order array.\r
+  @param BootOptionNum   The number of boot option.\r
+  @param DevType         Device type.\r
+  @param DevName         Device name.\r
+  @param Attribute       The boot option attribute.\r
+  @param BbsIndex        The BBS table index.\r
+  @param OptionNumber    The boot option index.\r
+\r
+  @retval TRUE           The Legacy boot option is found.\r
+  @retval FALSE          The legacy boot option is not found.\r
+\r
+**/\r
+BOOLEAN\r
+BdsFindLegacyBootOptionByDevTypeAndName (\r
+  IN UINT16                 *BootOrder,\r
+  IN UINTN                  BootOptionNum,\r
+  IN UINT16                 DevType,\r
+  IN CHAR16                 *DevName,\r
+  OUT UINT32                *Attribute,\r
+  OUT UINT16                *BbsIndex,\r
+  OUT UINT16                *OptionNumber\r
+  )\r
+{\r
+  UINTN     Index;\r
+  CHAR16    BootOption[9];\r
+  UINTN     BootOptionSize;\r
+  UINT8     *BootOptionVar;\r
+  BBS_TABLE *BbsEntry;\r
+  BOOLEAN   Found;\r
+\r
+  BbsEntry  = NULL;\r
+  Found     = FALSE;\r
+\r
+  if (NULL == BootOrder) {\r
+    return Found;\r
+  }\r
+\r
+  //\r
+  // Loop all boot option from variable\r
+  //\r
+  for (Index = 0; Index < BootOptionNum; Index++) {\r
+    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", (UINTN) BootOrder[Index]);\r
+    BootOptionVar = BdsLibGetVariableAndSize (\r
+                      BootOption,\r
+                      &gEfiGlobalVariableGuid,\r
+                      &BootOptionSize\r
+                      );\r
+    if (NULL == BootOptionVar) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Skip Non-legacy boot option\r
+    //\r
+    if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, BbsIndex)) {\r
+      FreePool (BootOptionVar);\r
+      continue;\r
+    }\r
+\r
+    if (\r
+        (BbsEntry->DeviceType != DevType) ||\r
+        (StrCmp (DevName, (CHAR16*)(BootOptionVar + sizeof (UINT32) + sizeof (UINT16))) != 0)\r
+       ) {\r
+      FreePool (BootOptionVar);\r
+      continue;\r
+    }\r
+\r
+    *Attribute    = *(UINT32 *) BootOptionVar;\r
+    *OptionNumber = BootOrder[Index];\r
+    Found         = TRUE;\r
+    FreePool (BootOptionVar);\r
+    break;\r
+  }\r
+\r
+  return Found;\r
+}\r
+\r
+/**\r
+  Create a legacy boot option.\r
+\r
+  @param BbsItem         The BBS Table entry.\r
+  @param Index           Index of the specified entry in BBS table.\r
+  @param BootOrderList   The boot order list.\r
+  @param BootOrderListSize The size of boot order list.\r
+\r
+  @retval EFI_OUT_OF_RESOURCE  No enough memory.\r
+  @retval EFI_SUCCESS          The function complete successfully.\r
+  @return Other value if the legacy boot option is not created.\r
+\r
+**/\r
+EFI_STATUS\r
+BdsCreateOneLegacyBootOption (\r
+  IN BBS_TABLE              *BbsItem,\r
+  IN UINTN                  Index,\r
+  IN OUT UINT16             **BootOrderList,\r
+  IN OUT UINTN              *BootOrderListSize\r
+  )\r
+{\r
+  BBS_BBS_DEVICE_PATH       BbsDevPathNode;\r
+  EFI_STATUS                Status;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevPath;\r
+\r
+  DevPath                       = NULL;\r
+\r
+  //\r
+  // Create device path node.\r
+  //\r
+  BbsDevPathNode.Header.Type    = BBS_DEVICE_PATH;\r
+  BbsDevPathNode.Header.SubType = BBS_BBS_DP;\r
+  SetDevicePathNodeLength (&BbsDevPathNode.Header, sizeof (BBS_BBS_DEVICE_PATH));\r
+  BbsDevPathNode.DeviceType = BbsItem->DeviceType;\r
+  CopyMem (&BbsDevPathNode.StatusFlag, &BbsItem->StatusFlags, sizeof (UINT16));\r
+\r
+  DevPath = AppendDevicePathNode (\r
+              NULL,\r
+              (EFI_DEVICE_PATH_PROTOCOL *) &BbsDevPathNode\r
+              );\r
+  if (NULL == DevPath) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  Status = BdsCreateLegacyBootOption (\r
+            BbsItem,\r
+            DevPath,\r
+            Index,\r
+            BootOrderList,\r
+            BootOrderListSize\r
+            );\r
+  BbsItem->BootPriority = 0x00;\r
+\r
+  FreePool (DevPath);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Add the legacy boot options from BBS table if they do not exist.\r
+\r
+  @retval EFI_SUCCESS          The boot options are added successfully \r
+                               or they are already in boot options.\r
+  @retval EFI_NOT_FOUND        No legacy boot options is found.\r
+  @retval EFI_OUT_OF_RESOURCE  No enough memory.\r
+  @return Other value          LegacyBoot options are not added.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BdsAddNonExistingLegacyBootOptions (\r
+  VOID\r
+  )\r
+{\r
+  UINT16                    *BootOrder;\r
+  UINTN                     BootOrderSize;\r
+  EFI_STATUS                Status;\r
+  CHAR16                    Desc[100];\r
+  UINT16                    HddCount;\r
+  UINT16                    BbsCount;\r
+  HDD_INFO                  *LocalHddInfo;\r
+  BBS_TABLE                 *LocalBbsTable;\r
+  UINT16                    BbsIndex;\r
+  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;\r
+  UINT16                    Index;\r
+  UINT32                    Attribute;\r
+  UINT16                    OptionNumber;\r
+  BOOLEAN                   Exist;\r
+\r
+  HddCount      = 0;\r
+  BbsCount      = 0;\r
+  LocalHddInfo  = NULL;\r
+  LocalBbsTable = NULL;\r
+\r
+  Status        = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  LegacyBios->GetBbsInfo (\r
+                LegacyBios,\r
+                &HddCount,\r
+                &LocalHddInfo,\r
+                &BbsCount,\r
+                &LocalBbsTable\r
+                );\r
+\r
+  BootOrder = BdsLibGetVariableAndSize (\r
+                L"BootOrder",\r
+                &gEfiGlobalVariableGuid,\r
+                &BootOrderSize\r
+                );\r
+  if (BootOrder == NULL) {\r
+    BootOrderSize = 0;\r
+  }\r
+\r
+  for (Index = 0; Index < BbsCount; Index++) {\r
+    if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||\r
+        (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)\r
+        ) {\r
+      continue;\r
+    }\r
+\r
+    BdsBuildLegacyDevNameString (&LocalBbsTable[Index], Index, sizeof (Desc), Desc);\r
+\r
+    Exist = BdsFindLegacyBootOptionByDevTypeAndName (\r
+              BootOrder,\r
+              BootOrderSize / sizeof (UINT16),\r
+              LocalBbsTable[Index].DeviceType,\r
+              Desc,\r
+              &Attribute,\r
+              &BbsIndex,\r
+              &OptionNumber\r
+              );\r
+    if (!Exist) {\r
+      //\r
+      // Not found such type of legacy device in boot options or we found but it's disabled\r
+      // so we have to create one and put it to the tail of boot order list\r
+      //\r
+      Status = BdsCreateOneLegacyBootOption (\r
+                &LocalBbsTable[Index],\r
+                Index,\r
+                &BootOrder,\r
+                &BootOrderSize\r
+                );\r
+      if (EFI_ERROR (Status)) {\r
+        break;\r
+      }\r
+      BbsIndex     = Index;\r
+      OptionNumber = BootOrder[BootOrderSize / sizeof (UINT16) - 1];\r
+    }\r
+\r
+    ASSERT (BbsIndex == Index);\r
+  }\r
+\r
+  Status = gRT->SetVariable (\r
+                  L"BootOrder",\r
+                  &gEfiGlobalVariableGuid,\r
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+                  BootOrderSize,\r
+                  BootOrder\r
+                  );\r
+  if (BootOrder != NULL) {\r
+    FreePool (BootOrder);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Fill the device order buffer.\r
+\r
+  @param BbsTable        The BBS table.\r
+  @param BbsType         The BBS Type.\r
+  @param BbsCount        The BBS Count.\r
+  @param Buf             device order buffer.\r
+\r
+  @return The device order buffer.\r
+\r
+**/\r
+UINT16 *\r
+BdsFillDevOrderBuf (\r
+  IN BBS_TABLE                    *BbsTable,\r
+  IN BBS_TYPE                     BbsType,\r
+  IN UINTN                        BbsCount,\r
+  OUT UINT16                      *Buf\r
+  )\r
+{\r
+  UINTN Index;\r
+\r
+  for (Index = 0; Index < BbsCount; Index++) {\r
+    if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {\r
+      continue;\r
+    }\r
+\r
+    if (BbsTable[Index].DeviceType != BbsType) {\r
+      continue;\r
+    }\r
+\r
+    *Buf = (UINT16) (Index & 0xFF);\r
+    Buf++;\r
+  }\r
+\r
+  return Buf;\r
+}\r
+\r
+/**\r
+  Create the device order buffer.\r
+\r
+  @param BbsTable        The BBS table.\r
+  @param BbsCount        The BBS Count.\r
+\r
+  @retval EFI_SUCCES             The buffer is created and the EFI variable named \r
+                                 VAR_LEGACY_DEV_ORDER and gEfiLegacyDevOrderVariableGuid is\r
+                                 set correctly.\r
+  @retval EFI_OUT_OF_RESOURCES   Memmory or storage is not enough.\r
+  @retval EFI_DEVICE_ERROR       Fail to add the device order into EFI variable fail\r
+                                 because of hardware error.\r
+**/\r
+EFI_STATUS\r
+BdsCreateDevOrder (\r
+  IN BBS_TABLE                  *BbsTable,\r
+  IN UINT16                     BbsCount\r
+  )\r
+{\r
+  UINTN                       Index;\r
+  UINTN                       FDCount;\r
+  UINTN                       HDCount;\r
+  UINTN                       CDCount;\r
+  UINTN                       NETCount;\r
+  UINTN                       BEVCount;\r
+  UINTN                       TotalSize;\r
+  UINTN                       HeaderSize;\r
+  LEGACY_DEV_ORDER_ENTRY      *DevOrder;\r
+  LEGACY_DEV_ORDER_ENTRY      *DevOrderPtr;\r
+  EFI_STATUS                  Status;\r
+\r
+  FDCount     = 0;\r
+  HDCount     = 0;\r
+  CDCount     = 0;\r
+  NETCount    = 0;\r
+  BEVCount    = 0;\r
+  TotalSize   = 0;\r
+  HeaderSize  = sizeof (BBS_TYPE) + sizeof (UINT16);\r
+  DevOrder    = NULL;\r
+  Status      = EFI_SUCCESS;\r
+\r
+  //\r
+  // Count all boot devices\r
+  //\r
+  for (Index = 0; Index < BbsCount; Index++) {\r
+    if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {\r
+      continue;\r
+    }\r
+\r
+    switch (BbsTable[Index].DeviceType) {\r
+    case BBS_FLOPPY:\r
+      FDCount++;\r
+      break;\r
+\r
+    case BBS_HARDDISK:\r
+      HDCount++;\r
+      break;\r
+\r
+    case BBS_CDROM:\r
+      CDCount++;\r
+      break;\r
+\r
+    case BBS_EMBED_NETWORK:\r
+      NETCount++;\r
+      break;\r
+\r
+    case BBS_BEV_DEVICE:\r
+      BEVCount++;\r
+      break;\r
+\r
+    default:\r
+      break;\r
+    }\r
+  }\r
+\r
+  TotalSize += (HeaderSize + sizeof (UINT16) * FDCount);\r
+  TotalSize += (HeaderSize + sizeof (UINT16) * HDCount);\r
+  TotalSize += (HeaderSize + sizeof (UINT16) * CDCount);\r
+  TotalSize += (HeaderSize + sizeof (UINT16) * NETCount);\r
+  TotalSize += (HeaderSize + sizeof (UINT16) * BEVCount);\r
+\r
+  //\r
+  // Create buffer to hold all boot device order\r
+  //\r
+  DevOrder = AllocateZeroPool (TotalSize);\r
+  if (NULL == DevOrder) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  DevOrderPtr          = DevOrder;\r
+\r
+  DevOrderPtr->BbsType = BBS_FLOPPY;\r
+  DevOrderPtr->Length  = (UINT16) (sizeof (DevOrderPtr->Length) + FDCount * sizeof (UINT16));\r
+  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_FLOPPY, BbsCount, DevOrderPtr->Data);\r
 \r
+  DevOrderPtr->BbsType = BBS_HARDDISK;\r
+  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));\r
+  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_HARDDISK, BbsCount, DevOrderPtr->Data);\r
+  \r
+  DevOrderPtr->BbsType = BBS_CDROM;\r
+  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));\r
+  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_CDROM, BbsCount, DevOrderPtr->Data);\r
+  \r
+  DevOrderPtr->BbsType = BBS_EMBED_NETWORK;\r
+  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));\r
+  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_EMBED_NETWORK, BbsCount, DevOrderPtr->Data);\r
+\r
+  DevOrderPtr->BbsType = BBS_BEV_DEVICE;\r
+  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));\r
+  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_BEV_DEVICE, BbsCount, DevOrderPtr->Data);\r
+\r
+  ASSERT (TotalSize == (UINTN) ((UINT8 *) DevOrderPtr - (UINT8 *) DevOrder));\r
+\r
+  //\r
+  // Save device order for legacy boot device to variable.\r
+  //\r
+  Status = gRT->SetVariable (\r
+                  VAR_LEGACY_DEV_ORDER,\r
+                  &gEfiLegacyDevOrderVariableGuid,\r
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+                  TotalSize,\r
+                  DevOrder\r
+                  );\r
+  FreePool (DevOrder);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Add the legacy boot devices from BBS table into \r
+  the legacy device boot order.\r
+\r
+  @retval EFI_SUCCESS           The boot devices are added successfully.\r
+  @retval EFI_NOT_FOUND         The legacy boot devices are not found.\r
+  @retval EFI_OUT_OF_RESOURCES  Memmory or storage is not enough.\r
+  @retval EFI_DEVICE_ERROR      Fail to add the legacy device boot order into EFI variable\r
+                                because of hardware error.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BdsUpdateLegacyDevOrder (\r
+  VOID\r
+  )\r
+{\r
+  LEGACY_DEV_ORDER_ENTRY      *DevOrder;\r
+  LEGACY_DEV_ORDER_ENTRY      *NewDevOrder;\r
+  LEGACY_DEV_ORDER_ENTRY      *Ptr;\r
+  LEGACY_DEV_ORDER_ENTRY      *NewPtr;\r
+  UINTN                       DevOrderSize;\r
+  EFI_LEGACY_BIOS_PROTOCOL    *LegacyBios;\r
+  EFI_STATUS                  Status;\r
+  UINT16                      HddCount;\r
+  UINT16                      BbsCount;\r
+  HDD_INFO                    *LocalHddInfo;\r
+  BBS_TABLE                   *LocalBbsTable;\r
+  UINTN                       Index;\r
+  UINTN                       Index2;\r
+  UINTN                       *Idx;\r
+  UINTN                       FDCount;\r
+  UINTN                       HDCount;\r
+  UINTN                       CDCount;\r
+  UINTN                       NETCount;\r
+  UINTN                       BEVCount;\r
+  UINTN                       TotalSize;\r
+  UINTN                       HeaderSize;\r
+  UINT16                      *NewFDPtr;\r
+  UINT16                      *NewHDPtr;\r
+  UINT16                      *NewCDPtr;\r
+  UINT16                      *NewNETPtr;\r
+  UINT16                      *NewBEVPtr;\r
+  UINT16                      *NewDevPtr;\r
+  UINTN                       FDIndex;\r
+  UINTN                       HDIndex;\r
+  UINTN                       CDIndex;\r
+  UINTN                       NETIndex;\r
+  UINTN                       BEVIndex;\r
+\r
+  Idx           = NULL;\r
+  FDCount       = 0;\r
+  HDCount       = 0;\r
+  CDCount       = 0;\r
+  NETCount      = 0;\r
+  BEVCount      = 0;\r
+  TotalSize     = 0;\r
+  HeaderSize    = sizeof (BBS_TYPE) + sizeof (UINT16);\r
+  FDIndex       = 0;\r
+  HDIndex       = 0;\r
+  CDIndex       = 0;\r
+  NETIndex      = 0;\r
+  BEVIndex      = 0;\r
+  NewDevPtr     = NULL;\r
+\r
+  Status        = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = LegacyBios->GetBbsInfo (\r
+                         LegacyBios,\r
+                         &HddCount,\r
+                         &LocalHddInfo,\r
+                         &BbsCount,\r
+                         &LocalBbsTable\r
+                         );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  DevOrder = BdsLibGetVariableAndSize (\r
+               VAR_LEGACY_DEV_ORDER,\r
+               &gEfiLegacyDevOrderVariableGuid,\r
+               &DevOrderSize\r
+               );\r
+  if (NULL == DevOrder) {\r
+    return BdsCreateDevOrder (LocalBbsTable, BbsCount);\r
+  }\r
+  //\r
+  // First we figure out how many boot devices with same device type respectively\r
+  //\r
+  for (Index = 0; Index < BbsCount; Index++) {\r
+    if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||\r
+        (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)\r
+        ) {\r
+      continue;\r
+    }\r
+\r
+    switch (LocalBbsTable[Index].DeviceType) {\r
+    case BBS_FLOPPY:\r
+      FDCount++;\r
+      break;\r
+\r
+    case BBS_HARDDISK:\r
+      HDCount++;\r
+      break;\r
+\r
+    case BBS_CDROM:\r
+      CDCount++;\r
+      break;\r
+\r
+    case BBS_EMBED_NETWORK:\r
+      NETCount++;\r
+      break;\r
+\r
+    case BBS_BEV_DEVICE:\r
+      BEVCount++;\r
+      break;\r
+\r
+    default:\r
+      break;\r
+    }\r
+  }\r
+\r
+  TotalSize += (HeaderSize + FDCount * sizeof (UINT16));\r
+  TotalSize += (HeaderSize + HDCount * sizeof (UINT16));\r
+  TotalSize += (HeaderSize + CDCount * sizeof (UINT16));\r
+  TotalSize += (HeaderSize + NETCount * sizeof (UINT16));\r
+  TotalSize += (HeaderSize + BEVCount * sizeof (UINT16));\r
+\r
+  NewDevOrder = AllocateZeroPool (TotalSize);\r
+  if (NULL == NewDevOrder) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+\r
+\r
+  //\r
+  // copy FD\r
+  //\r
+  Ptr             = DevOrder;\r
+  NewPtr          = NewDevOrder;\r
+  NewPtr->BbsType = Ptr->BbsType;\r
+  NewPtr->Length  = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16));\r
+  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {\r
+    if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||\r
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_FLOPPY\r
+        ) {\r
+      continue;\r
+    }\r
+\r
+    NewPtr->Data[FDIndex] = Ptr->Data[Index];\r
+    FDIndex++;\r
+  }\r
+  NewFDPtr = NewPtr->Data;\r
+\r
+  //\r
+  // copy HD\r
+  //\r
+  Ptr             = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);\r
+  NewPtr          = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);\r
+  NewPtr->BbsType = Ptr->BbsType;\r
+  NewPtr->Length  = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));\r
+  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {\r
+    if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||\r
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||\r
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_HARDDISK\r
+        ) {\r
+      continue;\r
+    }\r
+\r
+    NewPtr->Data[HDIndex] = Ptr->Data[Index];\r
+    HDIndex++;\r
+  }\r
+  NewHDPtr = NewPtr->Data;\r
+\r
+  //\r
+  // copy CD\r
+  //\r
+  Ptr    = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);\r
+  NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);\r
+  NewPtr->BbsType = Ptr->BbsType;\r
+  NewPtr->Length  = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));\r
+  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {\r
+    if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||\r
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||\r
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_CDROM\r
+        ) {\r
+      continue;\r
+    }\r
+\r
+    NewPtr->Data[CDIndex] = Ptr->Data[Index];\r
+    CDIndex++;\r
+  }\r
+  NewCDPtr = NewPtr->Data;\r
+\r
+  //\r
+  // copy NET\r
+  //\r
+  Ptr    = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);\r
+  NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);\r
+  NewPtr->BbsType = Ptr->BbsType;\r
+  NewPtr->Length  = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));\r
+  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {\r
+    if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||\r
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||\r
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_EMBED_NETWORK\r
+        ) {\r
+      continue;\r
+    }\r
+\r
+    NewPtr->Data[NETIndex] = Ptr->Data[Index];\r
+    NETIndex++;\r
+  }\r
+  NewNETPtr = NewPtr->Data;\r
+  \r
+  //\r
+  // copy BEV\r
+  //\r
+  Ptr    = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);\r
+  NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);\r
+  NewPtr->BbsType = Ptr->BbsType;\r
+  NewPtr->Length  = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));\r
+  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {\r
+    if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||\r
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||\r
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_BEV_DEVICE\r
+        ) {\r
+      continue;\r
+    }\r
+\r
+    NewPtr->Data[BEVIndex] = Ptr->Data[Index];\r
+    BEVIndex++;\r
+  }\r
+  NewBEVPtr = NewPtr->Data;\r
+\r
+  for (Index = 0; Index < BbsCount; Index++) {\r
+    if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||\r
+        (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)\r
+        ) {\r
+      continue;\r
+    }\r
+\r
+    switch (LocalBbsTable[Index].DeviceType) {\r
+    case BBS_FLOPPY:\r
+      Idx       = &FDIndex;\r
+      NewDevPtr = NewFDPtr;\r
+      break;\r
+\r
+    case BBS_HARDDISK:\r
+      Idx       = &HDIndex;\r
+      NewDevPtr = NewHDPtr;\r
+      break;\r
+\r
+    case BBS_CDROM:\r
+      Idx       = &CDIndex;\r
+      NewDevPtr = NewCDPtr;\r
+      break;\r
+\r
+    case BBS_EMBED_NETWORK:\r
+      Idx       = &NETIndex;\r
+      NewDevPtr = NewNETPtr;\r
+      break;\r
+\r
+    case BBS_BEV_DEVICE:\r
+      Idx       = &BEVIndex;\r
+      NewDevPtr = NewBEVPtr;\r
+      break;\r
+\r
+    default:\r
+      Idx = NULL;\r
+      break;\r
+    }\r
+    //\r
+    // at this point we have copied those valid indexes to new buffer\r
+    // and we should check if there is any new appeared boot device\r
+    //\r
+    if (Idx != NULL) {\r
+      for (Index2 = 0; Index2 < *Idx; Index2++) {\r
+        if ((NewDevPtr[Index2] & 0xFF) == (UINT16) Index) {\r
+          break;\r
+        }\r
+      }\r
+\r
+      if (Index2 == *Idx) {\r
+        //\r
+        // Index2 == *Idx means we didn't find Index\r
+        // so Index is a new appeared device's index in BBS table\r
+        // insert it before disabled indexes.\r
+        //\r
+        for (Index2 = 0; Index2 < *Idx; Index2++) {\r
+          if ((NewDevPtr[Index2] & 0xFF00) == 0xFF00) {\r
+            break;\r
+          }\r
+        }\r
+        CopyMem (&NewDevPtr[Index2 + 1], &NewDevPtr[Index2], (*Idx - Index2) * sizeof (UINT16));\r
+        NewDevPtr[Index2] = (UINT16) (Index & 0xFF);\r
+        (*Idx)++;\r
+      }\r
+    }\r
+  }\r
+\r
+  FreePool (DevOrder);\r
+\r
+  Status = gRT->SetVariable (\r
+                  VAR_LEGACY_DEV_ORDER,\r
+                  &gEfiLegacyDevOrderVariableGuid,\r
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+                  TotalSize,\r
+                  NewDevOrder\r
+                  );\r
+  FreePool (NewDevOrder);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Set Boot Priority for specified device type.\r
+\r
+  @param DeviceType      The device type.\r
+  @param BbsIndex        The BBS index to set the highest priority. Ignore when -1.\r
+  @param LocalBbsTable   The BBS table.\r
+  @param Priority        The prority table.\r
+\r
+  @retval EFI_SUCCESS           The function completes successfully.\r
+  @retval EFI_NOT_FOUND         Failed to find device.\r
+  @retval EFI_OUT_OF_RESOURCES  Failed to get the efi variable of device order.\r
+\r
+**/\r
+EFI_STATUS\r
+BdsSetBootPriority4SameTypeDev (\r
+  IN UINT16                                              DeviceType,\r
+  IN UINTN                                               BbsIndex,\r
+  IN OUT BBS_TABLE                                       *LocalBbsTable,\r
+  IN OUT UINT16                                          *Priority\r
+  )\r
+{\r
+  LEGACY_DEV_ORDER_ENTRY      *DevOrder;\r
+  LEGACY_DEV_ORDER_ENTRY      *DevOrderPtr;\r
+  UINTN                       DevOrderSize;\r
+  UINTN                       Index;\r
+\r
+  DevOrder = BdsLibGetVariableAndSize (\r
+               VAR_LEGACY_DEV_ORDER,\r
+               &gEfiLegacyDevOrderVariableGuid,\r
+               &DevOrderSize\r
+               );\r
+  if (NULL == DevOrder) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  DevOrderPtr = DevOrder;\r
+  while ((UINT8 *) DevOrderPtr < (UINT8 *) DevOrder + DevOrderSize) {\r
+    if (DevOrderPtr->BbsType == DeviceType) {\r
+      break;\r
+    }\r
+\r
+    DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) ((UINT8 *) DevOrderPtr + sizeof (BBS_TYPE) + DevOrderPtr->Length);\r
+  }\r
+\r
+  if ((UINT8 *) DevOrderPtr >= (UINT8 *) DevOrder + DevOrderSize) {\r
+    FreePool (DevOrder);\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  if (BbsIndex != (UINTN) -1) {\r
+    LocalBbsTable[BbsIndex].BootPriority = *Priority;\r
+    (*Priority)++;\r
+  }\r
+  //\r
+  // If the high byte of the DevIndex is 0xFF, it indicates that this device has been disabled.\r
+  //\r
+  for (Index = 0; Index < DevOrderPtr->Length / sizeof (UINT16) - 1; Index++) {\r
+    if ((DevOrderPtr->Data[Index] & 0xFF00) == 0xFF00) {\r
+      //\r
+      // LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = BBS_DISABLED_ENTRY;\r
+      //\r
+    } else if (DevOrderPtr->Data[Index] != BbsIndex) {\r
+      LocalBbsTable[DevOrderPtr->Data[Index]].BootPriority = *Priority;\r
+      (*Priority)++;\r
+    }\r
+  }\r
+\r
+  FreePool (DevOrder);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Print the BBS Table.\r
+\r
+  @param LocalBbsTable   The BBS table.\r
+  @param BbsCount        The count of entry in BBS table.\r
+**/\r
+VOID\r
+PrintBbsTable (\r
+  IN BBS_TABLE  *LocalBbsTable,\r
+  IN UINT16     BbsCount\r
+  )\r
+{\r
+  UINT16  Idx;\r
+\r
+  DEBUG ((DEBUG_ERROR, "\n"));\r
+  DEBUG ((DEBUG_ERROR, " NO  Prio bb/dd/ff cl/sc Type Stat segm:offs\n"));\r
+  DEBUG ((DEBUG_ERROR, "=============================================\n"));\r
+  for (Idx = 0; Idx < BbsCount; Idx++) {\r
+    if ((LocalBbsTable[Idx].BootPriority == BBS_IGNORE_ENTRY) ||\r
+        (LocalBbsTable[Idx].BootPriority == BBS_DO_NOT_BOOT_FROM) ||\r
+        (LocalBbsTable[Idx].BootPriority == BBS_LOWEST_PRIORITY)\r
+        ) {\r
+      continue;\r
+    }\r
+\r
+    DEBUG (\r
+      (DEBUG_ERROR,\r
+      " %02x: %04x %02x/%02x/%02x %02x/%02x %04x %04x %04x:%04x\n",\r
+      (UINTN) Idx,\r
+      (UINTN) LocalBbsTable[Idx].BootPriority,\r
+      (UINTN) LocalBbsTable[Idx].Bus,\r
+      (UINTN) LocalBbsTable[Idx].Device,\r
+      (UINTN) LocalBbsTable[Idx].Function,\r
+      (UINTN) LocalBbsTable[Idx].Class,\r
+      (UINTN) LocalBbsTable[Idx].SubClass,\r
+      (UINTN) LocalBbsTable[Idx].DeviceType,\r
+      (UINTN) * (UINT16 *) &LocalBbsTable[Idx].StatusFlags,\r
+      (UINTN) LocalBbsTable[Idx].BootHandlerSegment,\r
+      (UINTN) LocalBbsTable[Idx].BootHandlerOffset,\r
+      (UINTN) ((LocalBbsTable[Idx].MfgStringSegment << 4) + LocalBbsTable[Idx].MfgStringOffset),\r
+      (UINTN) ((LocalBbsTable[Idx].DescStringSegment << 4) + LocalBbsTable[Idx].DescStringOffset))\r
+      );\r
+  }\r
+\r
+  DEBUG ((DEBUG_ERROR, "\n"));\r
+}\r
+\r
+/**\r
+  Set the boot priority for BBS entries based on boot option entry and boot order.\r
+\r
+  @param  Entry             The boot option is to be checked for refresh BBS table.\r
+  \r
+  @retval EFI_SUCCESS           The boot priority for BBS entries is refreshed successfully.\r
+  @retval EFI_NOT_FOUND         BBS entries can't be found.\r
+  @retval EFI_OUT_OF_RESOURCES  Failed to get the legacy device boot order.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BdsRefreshBbsTableForBoot (\r
+  IN BDS_COMMON_OPTION        *Entry\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  UINT16                    BbsIndex;\r
+  UINT16                    HddCount;\r
+  UINT16                    BbsCount;\r
+  HDD_INFO                  *LocalHddInfo;\r
+  BBS_TABLE                 *LocalBbsTable;\r
+  UINT16                    DevType;\r
+  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;\r
+  UINTN                     Index;\r
+  UINT16                    Priority;\r
+  UINT16                    *BootOrder;\r
+  UINTN                     BootOrderSize;\r
+  UINT8                     *BootOptionVar;\r
+  UINTN                     BootOptionSize;\r
+  CHAR16                    BootOption[9];\r
+  UINT8                     *Ptr;\r
+  UINT16                    DevPathLen;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevPath;\r
+  UINT16                    *DeviceType;\r
+  UINTN                     DeviceTypeCount;\r
+  UINTN                     DeviceTypeIndex;\r
+\r
+  HddCount      = 0;\r
+  BbsCount      = 0;\r
+  LocalHddInfo  = NULL;\r
+  LocalBbsTable = NULL;\r
+  DevType       = BBS_UNKNOWN;\r
+\r
+  Status        = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  LegacyBios->GetBbsInfo (\r
+                LegacyBios,\r
+                &HddCount,\r
+                &LocalHddInfo,\r
+                &BbsCount,\r
+                &LocalBbsTable\r
+                );\r
+  //\r
+  // First, set all the present devices' boot priority to BBS_UNPRIORITIZED_ENTRY\r
+  // We will set them according to the settings setup by user\r
+  //\r
+  for (Index = 0; Index < BbsCount; Index++) {\r
+    if (!((BBS_IGNORE_ENTRY == LocalBbsTable[Index].BootPriority) ||\r
+        (BBS_DO_NOT_BOOT_FROM == LocalBbsTable[Index].BootPriority) ||\r
+         (BBS_LOWEST_PRIORITY == LocalBbsTable[Index].BootPriority))) {\r
+      LocalBbsTable[Index].BootPriority = BBS_UNPRIORITIZED_ENTRY;\r
+    }\r
+  }\r
+  //\r
+  // boot priority always starts at 0\r
+  //\r
+  Priority = 0;\r
+  if (Entry->LoadOptionsSize == sizeof (BBS_TABLE) + sizeof (UINT16)) {\r
+    //\r
+    // If Entry stands for a legacy boot option, we prioritize the devices with the same type first.\r
+    //\r
+    DevType  = ((BBS_TABLE *) Entry->LoadOptions)->DeviceType;\r
+    BbsIndex = *(UINT16 *) ((BBS_TABLE *) Entry->LoadOptions + 1);\r
+    Status = BdsSetBootPriority4SameTypeDev (\r
+              DevType,\r
+              BbsIndex,\r
+              LocalBbsTable,\r
+              &Priority\r
+              );\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+  //\r
+  // we have to set the boot priority for other BBS entries with different device types\r
+  //\r
+  BootOrder = BdsLibGetVariableAndSize (\r
+                L"BootOrder",\r
+                &gEfiGlobalVariableGuid,\r
+                &BootOrderSize\r
+                );\r
+  DeviceType = AllocatePool (BootOrderSize + sizeof (UINT16));\r
+  ASSERT (DeviceType != NULL);\r
+\r
+  DeviceType[0]   = DevType;\r
+  DeviceTypeCount = 1;\r
+  for (Index = 0; ((BootOrder != NULL) && (Index < BootOrderSize / sizeof (UINT16))); Index++) {\r
+    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);\r
+    BootOptionVar = BdsLibGetVariableAndSize (\r
+                      BootOption,\r
+                      &gEfiGlobalVariableGuid,\r
+                      &BootOptionSize\r
+                      );\r
+    if (NULL == BootOptionVar) {\r
+      continue;\r
+    }\r
+\r
+    Ptr = BootOptionVar;\r
+\r
+    Ptr += sizeof (UINT32);\r
+    DevPathLen = *(UINT16 *) Ptr;\r
+    Ptr += sizeof (UINT16);\r
+    Ptr += StrSize ((UINT16 *) Ptr);\r
+    DevPath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;\r
+    if (BBS_DEVICE_PATH != DevPath->Type || BBS_BBS_DP != DevPath->SubType) {\r
+      FreePool (BootOptionVar);\r
+      continue;\r
+    }\r
+\r
+    Ptr += DevPathLen;\r
+    DevType = ((BBS_TABLE *) Ptr)->DeviceType;\r
+    for (DeviceTypeIndex = 0; DeviceTypeIndex < DeviceTypeCount; DeviceTypeIndex++) {\r
+      if (DeviceType[DeviceTypeIndex] == DevType) {\r
+        break;\r
+      }\r
+    }\r
+    if (DeviceTypeIndex < DeviceTypeCount) {\r
+      //\r
+      // We don't want to process twice for a device type\r
+      //\r
+      FreePool (BootOptionVar);\r
+      continue;\r
+    }\r
+\r
+    DeviceType[DeviceTypeCount] = DevType;\r
+    DeviceTypeCount++;\r
+\r
+    Status = BdsSetBootPriority4SameTypeDev (\r
+              DevType,\r
+              (UINTN) -1,\r
+              LocalBbsTable,\r
+              &Priority\r
+              );\r
+    FreePool (BootOptionVar);\r
+    if (EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (BootOrder != NULL) {\r
+    FreePool (BootOrder);\r
+  }\r
+\r
+  DEBUG_CODE_BEGIN();\r
+    PrintBbsTable (LocalBbsTable, BbsCount);\r
+  DEBUG_CODE_END();\r
+\r
+  return Status;\r
+}\r
 \r
 /**\r
   Boot the legacy system with the boot option\r
index 5841756c4343907dcd1ad386e91c8d22a09117ab..3d1ccf9dc2c5ffd3872a85e26733d01696742c39 100644 (file)
@@ -701,21 +701,9 @@ BdsLibVariableToOption (
                + (UINT16) (CharToUint (VariableName[NumOff+2]) * 0x10)\r
                + (UINT16) (CharToUint (VariableName[NumOff+3]) * 0x1);\r
   }\r
-  //\r
-  // Insert active entry to BdsDeviceList\r
-  //\r
-  if ((Option->Attribute & LOAD_OPTION_ACTIVE) == LOAD_OPTION_ACTIVE) {\r
-    InsertTailList (BdsCommonOptionList, &Option->Link);\r
-    FreePool (Variable);\r
-    return Option;\r
-  }\r
-\r
+  InsertTailList (BdsCommonOptionList, &Option->Link);\r
   FreePool (Variable);\r
-  FreePool (Option->Description);\r
-  FreePool (Option->DevicePath);\r
-  FreePool (Option->LoadOptions);\r
-  FreePool (Option);\r
-  return NULL;\r
+  return Option;\r
 }\r
 \r
 /**\r
index 039747df0fa880feb60df790d27c63d5f1684d3d..0eea67933a71c2bc62b66ef28240dc361993d4c1 100644 (file)
@@ -51,6 +51,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Guid/BdsLibHii.h>\r
 #include <Guid/HdBootVariable.h>\r
 #include <Guid/LastEnumLang.h>\r
+#include <Guid/LegacyDevOrder.h>\r
 \r
 #include <Library/PrintLib.h>\r
 #include <Library/DebugLib.h>\r
index a4b6b53a06e4689d810aa723900d368965db8efb..7879e18a4120b6d8abf388aee6baa88539f9f058 100644 (file)
@@ -3,7 +3,7 @@
   and manage the legacy boot option, all legacy boot option is getting from\r
   the legacy BBS table.\r
 \r
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2012, 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
@@ -16,385 +16,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "BBSsupport.h"\r
 \r
-BOOT_OPTION_BBS_MAPPING  *mBootOptionBbsMapping     = NULL;\r
-UINTN                    mBootOptionBbsMappingCount = 0;\r
-\r
-/**\r
-\r
-  Translate the first n characters of an Ascii string to\r
-  Unicode characters. The count n is indicated by parameter\r
-  Size. If Size is greater than the length of string, then\r
-  the entire string is translated.\r
-\r
-\r
-  @param AStr               Pointer to input Ascii string.\r
-  @param Size               The number of characters to translate.\r
-  @param UStr               Pointer to output Unicode string buffer.\r
-\r
-**/\r
-VOID\r
-AsciiToUnicodeSize (\r
-  IN UINT8              *AStr,\r
-  IN UINTN              Size,\r
-  OUT UINT16            *UStr\r
-  )\r
-{\r
-  UINTN Idx;\r
-\r
-  Idx = 0;\r
-  while (AStr[Idx] != 0) {\r
-    UStr[Idx] = (CHAR16) AStr[Idx];\r
-    if (Idx == Size) {\r
-      break;\r
-    }\r
-\r
-    Idx++;\r
-  }\r
-  UStr[Idx] = 0;\r
-}\r
-\r
-/**\r
-  Build Legacy Device Name String according.\r
-\r
-  @param CurBBSEntry     BBS Table.\r
-  @param Index           Index.\r
-  @param BufSize         The buffer size.\r
-  @param BootString      The output string.\r
-\r
-**/\r
-VOID\r
-BdsBuildLegacyDevNameString (\r
-  IN  BBS_TABLE                 *CurBBSEntry,\r
-  IN  UINTN                     Index,\r
-  IN  UINTN                     BufSize,\r
-  OUT CHAR16                    *BootString\r
-  )\r
-{\r
-  CHAR16  *Fmt;\r
-  CHAR16  *Type;\r
-  UINT8   *StringDesc;\r
-  CHAR16  Temp[80];\r
-\r
-  switch (Index) {\r
-  //\r
-  // Primary Master\r
-  //\r
-  case 1:\r
-    Fmt = L"Primary Master %s";\r
-    break;\r
-\r
- //\r
- // Primary Slave\r
- //\r
-  case 2:\r
-    Fmt = L"Primary Slave %s";\r
-    break;\r
-\r
-  //\r
-  // Secondary Master\r
-  //\r
-  case 3:\r
-    Fmt = L"Secondary Master %s";\r
-    break;\r
-\r
-  //\r
-  // Secondary Slave\r
-  //\r
-  case 4:\r
-    Fmt = L"Secondary Slave %s";\r
-    break;\r
-\r
-  default:\r
-    Fmt = L"%s";\r
-    break;\r
-  }\r
-\r
-  switch (CurBBSEntry->DeviceType) {\r
-  case BBS_FLOPPY:\r
-    Type = L"Floppy";\r
-    break;\r
-\r
-  case BBS_HARDDISK:\r
-    Type = L"Harddisk";\r
-    break;\r
-\r
-  case BBS_CDROM:\r
-    Type = L"CDROM";\r
-    break;\r
-\r
-  case BBS_PCMCIA:\r
-    Type = L"PCMCIAe";\r
-    break;\r
-\r
-  case BBS_USB:\r
-    Type = L"USB";\r
-    break;\r
-\r
-  case BBS_EMBED_NETWORK:\r
-    Type = L"Network";\r
-    break;\r
-\r
-  case BBS_BEV_DEVICE:\r
-    Type = L"BEVe";\r
-    break;\r
-\r
-  case BBS_UNKNOWN:\r
-  default:\r
-    Type = L"Unknown";\r
-    break;\r
-  }\r
-  //\r
-  // If current BBS entry has its description then use it.\r
-  //\r
-  StringDesc = (UINT8 *) (UINTN) ((CurBBSEntry->DescStringSegment << 4) + CurBBSEntry->DescStringOffset);\r
-  if (NULL != StringDesc) {\r
-    //\r
-    // Only get fisrt 32 characters, this is suggested by BBS spec\r
-    //\r
-    AsciiToUnicodeSize (StringDesc, 32, Temp);\r
-    Fmt   = L"%s";\r
-    Type  = Temp;\r
-  }\r
-\r
-  //\r
-  // BbsTable 16 entries are for onboard IDE.\r
-  // Set description string for SATA harddisks, Harddisk 0 ~ Harddisk 11\r
-  //\r
-  if (Index >= 5 && Index <= 16 && (CurBBSEntry->DeviceType == BBS_HARDDISK || CurBBSEntry->DeviceType == BBS_CDROM)) {\r
-    Fmt = L"%s %d";\r
-    UnicodeSPrint (BootString, BufSize, Fmt, Type, Index - 5);\r
-  } else {\r
-    UnicodeSPrint (BootString, BufSize, Fmt, Type);\r
-  }\r
-}\r
-\r
-/**\r
-\r
-  Create a legacy boot option for the specified entry of\r
-  BBS table, save it as variable, and append it to the boot\r
-  order list.\r
-\r
-\r
-  @param CurrentBbsEntry    Pointer to current BBS table.\r
-  @param CurrentBbsDevPath  Pointer to the Device Path Protocol instance of BBS\r
-  @param Index              Index of the specified entry in BBS table.\r
-  @param BootOrderList      On input, the original boot order list.\r
-                            On output, the new boot order list attached with the\r
-                            created node.\r
-  @param BootOrderListSize  On input, the original size of boot order list.\r
-                            On output, the size of new boot order list.\r
-\r
-  @retval  EFI_SUCCESS             Boot Option successfully created.\r
-  @retval  EFI_OUT_OF_RESOURCES    Fail to allocate necessary memory.\r
-  @retval  Other                   Error occurs while setting variable.\r
-\r
-**/\r
-EFI_STATUS\r
-BdsCreateLegacyBootOption (\r
-  IN BBS_TABLE                        *CurrentBbsEntry,\r
-  IN EFI_DEVICE_PATH_PROTOCOL         *CurrentBbsDevPath,\r
-  IN UINTN                            Index,\r
-  IN OUT UINT16                       **BootOrderList,\r
-  IN OUT UINTN                        *BootOrderListSize\r
-  )\r
-{\r
-  EFI_STATUS           Status;\r
-  UINT16               CurrentBootOptionNo;\r
-  UINT16               BootString[10];\r
-  CHAR16               BootDesc[100];\r
-  CHAR8                HelpString[100];\r
-  UINT16               *NewBootOrderList;\r
-  UINTN                BufferSize;\r
-  UINTN                StringLen;\r
-  VOID                 *Buffer;\r
-  UINT8                *Ptr;\r
-  UINT16               CurrentBbsDevPathSize;\r
-  UINTN                BootOrderIndex;\r
-  UINTN                BootOrderLastIndex;\r
-  UINTN                ArrayIndex;\r
-  BOOLEAN              IndexNotFound;\r
-  BBS_BBS_DEVICE_PATH  *NewBbsDevPathNode;\r
-\r
-  if ((*BootOrderList) == NULL) {\r
-    CurrentBootOptionNo = 0;\r
-  } else {\r
-    for (ArrayIndex = 0; ArrayIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); ArrayIndex++) {\r
-      IndexNotFound = TRUE;\r
-      for (BootOrderIndex = 0; BootOrderIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); BootOrderIndex++) {\r
-        if ((*BootOrderList)[BootOrderIndex] == ArrayIndex) {\r
-          IndexNotFound = FALSE;\r
-          break;\r
-        }\r
-      }\r
-\r
-      if (!IndexNotFound) {\r
-        continue;\r
-      } else {\r
-        break;\r
-      }\r
-    }\r
-\r
-    CurrentBootOptionNo = (UINT16) ArrayIndex;\r
-  }\r
-\r
-  UnicodeSPrint (\r
-    BootString,\r
-    sizeof (BootString),\r
-    L"Boot%04x",\r
-    CurrentBootOptionNo\r
-    );\r
-\r
-  BdsBuildLegacyDevNameString (CurrentBbsEntry, Index, sizeof (BootDesc), BootDesc);\r
-\r
-  //\r
-  // Create new BBS device path node with description string\r
-  //\r
-  UnicodeStrToAsciiStr (BootDesc, HelpString);\r
-\r
-  StringLen = AsciiStrLen (HelpString);\r
-  NewBbsDevPathNode = AllocateZeroPool (sizeof (BBS_BBS_DEVICE_PATH) + StringLen);\r
-  if (NewBbsDevPathNode == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  CopyMem (NewBbsDevPathNode, CurrentBbsDevPath, sizeof (BBS_BBS_DEVICE_PATH));\r
-  CopyMem (NewBbsDevPathNode->String, HelpString, StringLen + 1);\r
-  SetDevicePathNodeLength (&(NewBbsDevPathNode->Header), sizeof (BBS_BBS_DEVICE_PATH) + StringLen);\r
-\r
-  //\r
-  // Create entire new CurrentBbsDevPath with end node\r
-  //\r
-  CurrentBbsDevPath = AppendDevicePathNode (\r
-                        EndDevicePath,\r
-                        (EFI_DEVICE_PATH_PROTOCOL *) NewBbsDevPathNode\r
-                        );\r
-   if (CurrentBbsDevPath == NULL) {\r
-    FreePool (NewBbsDevPathNode);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  CurrentBbsDevPathSize = (UINT16) (GetDevicePathSize (CurrentBbsDevPath));\r
-\r
-  BufferSize = sizeof (UINT32) +\r
-    sizeof (UINT16) +\r
-    StrSize (BootDesc) +\r
-    CurrentBbsDevPathSize +\r
-    sizeof (BBS_TABLE) +\r
-    sizeof (UINT16);\r
-\r
-  Buffer = AllocateZeroPool (BufferSize);\r
-  if (Buffer == NULL) {\r
-    FreePool (NewBbsDevPathNode);\r
-    FreePool (CurrentBbsDevPath);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Ptr               = (UINT8 *) Buffer;\r
-\r
-  *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE;\r
-  Ptr += sizeof (UINT32);\r
-\r
-  *((UINT16 *) Ptr) = CurrentBbsDevPathSize;\r
-  Ptr += sizeof (UINT16);\r
-\r
-  CopyMem (\r
-    Ptr,\r
-    BootDesc,\r
-    StrSize (BootDesc)\r
-    );\r
-  Ptr += StrSize (BootDesc);\r
-\r
-  CopyMem (\r
-    Ptr,\r
-    CurrentBbsDevPath,\r
-    CurrentBbsDevPathSize\r
-    );\r
-  Ptr += CurrentBbsDevPathSize;\r
-\r
-  CopyMem (\r
-    Ptr,\r
-    CurrentBbsEntry,\r
-    sizeof (BBS_TABLE)\r
-    );\r
-\r
-  Ptr += sizeof (BBS_TABLE);\r
-  *((UINT16 *) Ptr) = (UINT16) Index;\r
-\r
-  Status = gRT->SetVariable (\r
-                  BootString,\r
-                  &gEfiGlobalVariableGuid,\r
-                  VAR_FLAG,\r
-                  BufferSize,\r
-                  Buffer\r
-                  );\r
-\r
-  FreePool (Buffer);\r
-  \r
-  Buffer = NULL;\r
-\r
-  NewBootOrderList = AllocateZeroPool (*BootOrderListSize + sizeof (UINT16));\r
-  if (NULL == NewBootOrderList) {\r
-    FreePool (NewBbsDevPathNode);\r
-    FreePool (CurrentBbsDevPath);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  if (*BootOrderList != NULL) {\r
-    CopyMem (NewBootOrderList, *BootOrderList, *BootOrderListSize);\r
-    FreePool (*BootOrderList);\r
-  }\r
-\r
-  BootOrderLastIndex                    = (UINTN) (*BootOrderListSize / sizeof (UINT16));\r
-  NewBootOrderList[BootOrderLastIndex]  = CurrentBootOptionNo;\r
-  *BootOrderListSize += sizeof (UINT16);\r
-  *BootOrderList = NewBootOrderList;\r
-\r
-  FreePool (NewBbsDevPathNode);\r
-  FreePool (CurrentBbsDevPath);\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Check if the boot option is a legacy one.\r
-\r
-  @param BootOptionVar   The boot option data payload.\r
-  @param BbsEntry        The BBS Table.\r
-  @param BbsIndex        The table index.\r
-\r
-  @retval TRUE           It is a legacy boot option.\r
-  @retval FALSE          It is not a legacy boot option.\r
-\r
-**/\r
-BOOLEAN\r
-BdsIsLegacyBootOption (\r
-  IN UINT8                 *BootOptionVar,\r
-  OUT BBS_TABLE            **BbsEntry,\r
-  OUT UINT16               *BbsIndex\r
-  )\r
-{\r
-  UINT8                     *Ptr;\r
-  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
-  BOOLEAN                   Ret;\r
-  UINT16                    DevPathLen;\r
-\r
-  Ptr = BootOptionVar;\r
-  Ptr += sizeof (UINT32);\r
-  DevPathLen = *(UINT16 *) Ptr;\r
-  Ptr += sizeof (UINT16);\r
-  Ptr += StrSize ((UINT16 *) Ptr);\r
-  DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;\r
-  if ((BBS_DEVICE_PATH == DevicePath->Type) && (BBS_BBS_DP == DevicePath->SubType)) {\r
-    Ptr += DevPathLen;\r
-    *BbsEntry = (BBS_TABLE *) Ptr;\r
-    Ptr += sizeof (BBS_TABLE);\r
-    *BbsIndex = *(UINT16 *) Ptr;\r
-    Ret       = TRUE;\r
-  } else {\r
-    *BbsEntry = NULL;\r
-    Ret       = FALSE;\r
-  }\r
-\r
-  return Ret;\r
-}\r
+#pragma pack(1)\r
+typedef struct {\r
+  BBS_TABLE BbsEntry;\r
+  UINT16    BbsIndex;\r
+} LEGACY_BOOT_OPTION_BBS_DATA;\r
+#pragma pack()\r
 \r
 /**\r
   Re-order the Boot Option according to the DevOrder.\r
@@ -402,55 +29,99 @@ BdsIsLegacyBootOption (
   The routine re-orders the Boot Option in BootOption array according to\r
   the order specified by DevOrder.\r
 \r
-  @param BootOption         Pointer to buffer containing the Boot Option Numbers\r
-  @param BootOptionCount    Count of the Boot Option Numbers\r
   @param DevOrder           Pointer to buffer containing the BBS Index,\r
                             high 8-bit value 0xFF indicating a disabled boot option\r
   @param DevOrderCount      Count of the BBS Index\r
-  @param EnBootOption       Pointer to buffer receiving the enabled Boot Option Numbers\r
+  @param EnBootOption       Callee allocated buffer containing the enabled Boot Option Numbers\r
   @param EnBootOptionCount  Count of the enabled Boot Option Numbers\r
-  @param DisBootOption      Pointer to buffer receiving the disabled Boot Option Numbers\r
+  @param DisBootOption      Callee allocated buffer containing the disabled Boot Option Numbers\r
   @param DisBootOptionCount Count of the disabled Boot Option Numbers\r
 **/\r
 VOID\r
 OrderLegacyBootOption4SameType (\r
-  UINT16                   *BootOption,\r
-  UINTN                    BootOptionCount,\r
   UINT16                   *DevOrder,\r
   UINTN                    DevOrderCount,\r
-  UINT16                   *EnBootOption,\r
+  UINT16                   **EnBootOption,\r
   UINTN                    *EnBootOptionCount,\r
-  UINT16                   *DisBootOption,\r
+  UINT16                   **DisBootOption,\r
   UINTN                    *DisBootOptionCount\r
   )\r
 {\r
-  UINTN                    Index;\r
-  UINTN                    MappingIndex;\r
+  EFI_STATUS               Status;\r
   UINT16                   *NewBootOption;\r
-  UINT16                   BbsType;\r
+  UINT16                   *BootOrder;\r
+  UINTN                    BootOrderSize;\r
+  UINTN                    Index;\r
+  UINTN                    StartPosition;\r
+  \r
+  BDS_COMMON_OPTION        *BootOption;\r
   \r
+  CHAR16                   OptionName[sizeof ("Boot####")];\r
+  UINT16                   *BbsIndexArray;\r
+  UINT16                   *DeviceTypeArray;\r
+  LIST_ENTRY               List;\r
+\r
+  BootOrder = BdsLibGetVariableAndSize (\r
+                L"BootOrder",\r
+                &gEfiGlobalVariableGuid,\r
+                &BootOrderSize\r
+                );\r
+  ASSERT (BootOrder != NULL);\r
+\r
+  BbsIndexArray       = AllocatePool (BootOrderSize);\r
+  DeviceTypeArray     = AllocatePool (BootOrderSize);\r
+  *EnBootOption       = AllocatePool (BootOrderSize);\r
+  *DisBootOption      = AllocatePool (BootOrderSize);\r
   *DisBootOptionCount = 0;\r
   *EnBootOptionCount  = 0;\r
-  BbsType             = 0;\r
+  Index               = 0;\r
+\r
+  ASSERT (*EnBootOption != NULL);\r
+  ASSERT (*DisBootOption != NULL);\r
+\r
+  for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
+  \r
+    UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]);\r
+    InitializeListHead (&List);\r
+    BootOption = BdsLibVariableToOption (&List, OptionName);\r
+    ASSERT_EFI_ERROR (BootOption != NULL);\r
+    \r
+    if ((DevicePathType (BootOption->DevicePath) == BBS_DEVICE_PATH) &&\r
+        (DevicePathSubType (BootOption->DevicePath) == BBS_BBS_DP)) {\r
+      //\r
+      // Legacy Boot Option\r
+      //\r
+      ASSERT (BootOption->LoadOptionsSize == sizeof (LEGACY_BOOT_OPTION_BBS_DATA));\r
+\r
+      DeviceTypeArray[Index] = ((BBS_BBS_DEVICE_PATH *) BootOption->DevicePath)->DeviceType;\r
+      BbsIndexArray  [Index] = ((LEGACY_BOOT_OPTION_BBS_DATA *) BootOption->LoadOptions)->BbsIndex;\r
+    } else {\r
+      DeviceTypeArray[Index] = BBS_TYPE_UNKNOWN;\r
+      BbsIndexArray  [Index] = 0xFFFF;\r
+    }\r
+    FreePool (BootOption->DevicePath);\r
+    FreePool (BootOption->Description);\r
+    FreePool (BootOption->LoadOptions);\r
+    FreePool (BootOption);\r
+  }\r
 \r
   //\r
   // Record the corresponding Boot Option Numbers according to the DevOrder\r
   // Record the EnBootOption and DisBootOption according to the DevOrder\r
   //\r
+  StartPosition = BootOrderSize / sizeof (UINT16);\r
   NewBootOption = AllocatePool (DevOrderCount * sizeof (UINT16));\r
-  ASSERT (NewBootOption != NULL);\r
-\r
   while (DevOrderCount-- != 0) {\r
-    for (Index = 0; Index < mBootOptionBbsMappingCount; Index++) {\r
-      if (mBootOptionBbsMapping[Index].BbsIndex == (DevOrder[DevOrderCount] & 0xFF)) {\r
-        BbsType = mBootOptionBbsMapping[Index].BbsType;\r
-        NewBootOption[DevOrderCount] = mBootOptionBbsMapping[Index].BootOptionNumber;\r
+    for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
+      if (BbsIndexArray[Index] == (DevOrder[DevOrderCount] & 0xFF)) {\r
+        StartPosition = MIN (StartPosition, Index);\r
+        NewBootOption[DevOrderCount] = BootOrder[Index];\r
         \r
         if ((DevOrder[DevOrderCount] & 0xFF00) == 0xFF00) {\r
-          DisBootOption[*DisBootOptionCount] = NewBootOption[DevOrderCount];\r
+          (*DisBootOption)[*DisBootOptionCount] = BootOrder[Index];\r
           (*DisBootOptionCount)++;\r
         } else {\r
-          EnBootOption[*EnBootOptionCount] = NewBootOption[DevOrderCount];\r
+          (*EnBootOption)[*EnBootOptionCount] = BootOrder[Index];\r
           (*EnBootOptionCount)++;\r
         }\r
         break;\r
@@ -458,24 +129,22 @@ OrderLegacyBootOption4SameType (
     }\r
   }\r
 \r
-  for (Index = 0; Index < BootOptionCount; Index++) {\r
-    //\r
-    // Find the start position for the BbsType in BootOption\r
-    //\r
-    for (MappingIndex = 0; MappingIndex < mBootOptionBbsMappingCount; MappingIndex++) {\r
-      if (mBootOptionBbsMapping[MappingIndex].BbsType == BbsType && mBootOptionBbsMapping[MappingIndex].BootOptionNumber == BootOption[Index]) {\r
-        break;\r
-      }\r
-    }\r
+  //\r
+  // Overwrite the old BootOption\r
+  //\r
+  CopyMem (&BootOrder[StartPosition], NewBootOption, (*DisBootOptionCount + *EnBootOptionCount) * sizeof (UINT16));\r
+  Status = gRT->SetVariable (\r
+                  L"BootOrder",\r
+                  &gEfiGlobalVariableGuid,\r
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+                  BootOrderSize,\r
+                  BootOrder\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
-    //\r
-    // Overwrite the old BootOption\r
-    //\r
-    if (MappingIndex < mBootOptionBbsMappingCount) {\r
-      CopyMem (&BootOption[Index], NewBootOption, (*DisBootOptionCount + *EnBootOptionCount) * sizeof (UINT16));\r
-      break;\r
-    }\r
-  }\r
+  FreePool (NewBootOption);\r
+  FreePool (DeviceTypeArray);\r
+  FreePool (BbsIndexArray);\r
 }\r
 \r
 /**\r
@@ -493,1277 +162,81 @@ OrderLegacyBootOption4SameType (
      Assuming [Efi1 Efi0 CdRom1 Harddisk0] is ordered properly\r
      Output = [Efi1 Efi0 CdRom1 CdRom0 CdRom2 Harddisk0 Harddisk1 Harddisk2]\r
 \r
-  @param BootOption      Pointer to buffer containing Boot Option Numbers\r
-  @param BootOptionCount Count of the Boot Option Numbers\r
 **/\r
 VOID\r
 GroupMultipleLegacyBootOption4SameType (\r
-  UINT16                   *BootOption,\r
-  UINTN                    BootOptionCount\r
-  )\r
-{\r
-  UINTN                    DeviceTypeIndex[7];\r
-  UINTN                    Index;\r
-  UINTN                    MappingIndex;\r
-  UINTN                    *NextIndex;\r
-  UINT16                   OptionNumber;\r
-  UINTN                    DeviceIndex;\r
-\r
-  SetMem (DeviceTypeIndex, sizeof (DeviceTypeIndex), 0xFF);\r
-\r
-  for (Index = 0; Index < BootOptionCount; Index++) {\r
-\r
-    //\r
-    // Find the DeviceType\r
-    //\r
-    for (MappingIndex = 0; MappingIndex < mBootOptionBbsMappingCount; MappingIndex++) {\r
-      if (mBootOptionBbsMapping[MappingIndex].BootOptionNumber == BootOption[Index]) {\r
-        break;\r
-      }\r
-    }\r
-    if (MappingIndex == mBootOptionBbsMappingCount) {\r
-      //\r
-      // Is not a legacy boot option\r
-      //\r
-      continue;\r
-    }\r
-\r
-    ASSERT ((mBootOptionBbsMapping[MappingIndex].BbsType & 0xF) < \r
-             sizeof (DeviceTypeIndex) / sizeof (DeviceTypeIndex[0]));\r
-    NextIndex = &DeviceTypeIndex[mBootOptionBbsMapping[MappingIndex].BbsType & 0xF];\r
-    if (*NextIndex == (UINTN) -1) {\r
-      //\r
-      // *NextIndex is the index in BootOption to put the next Option Number for the same type\r
-      //\r
-      *NextIndex = Index + 1;\r
-    } else {\r
-      //\r
-      // insert the current boot option before *NextIndex, causing [*Next .. Index] shift right one position\r
-      //\r
-      OptionNumber = BootOption[Index];\r
-      CopyMem (&BootOption[*NextIndex + 1], &BootOption[*NextIndex], (Index - *NextIndex) * sizeof (UINT16));\r
-      BootOption[*NextIndex] = OptionNumber;\r
-\r
-      //\r
-      // Update the DeviceTypeIndex array to reflect the right shift operation\r
-      //\r
-      for (DeviceIndex = 0; DeviceIndex < sizeof (DeviceTypeIndex) / sizeof (DeviceTypeIndex[0]); DeviceIndex++) {\r
-        if (DeviceTypeIndex[DeviceIndex] != (UINTN) -1 && DeviceTypeIndex[DeviceIndex] >= *NextIndex) {\r
-          DeviceTypeIndex[DeviceIndex]++;\r
-        }\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-/**\r
-  Delete all the invalid legacy boot options.\r
-\r
-  @retval EFI_SUCCESS             All invalide legacy boot options are deleted.\r
-  @retval EFI_OUT_OF_RESOURCES    Fail to allocate necessary memory.\r
-  @retval EFI_NOT_FOUND           Fail to retrive variable of boot order.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BdsDeleteAllInvalidLegacyBootOptions (\r
-  VOID\r
-  )\r
-{\r
-  UINT16                    *BootOrder;\r
-  UINT8                     *BootOptionVar;\r
-  UINTN                     BootOrderSize;\r
-  UINTN                     BootOptionSize;\r
-  EFI_STATUS                Status;\r
-  UINT16                    HddCount;\r
-  UINT16                    BbsCount;\r
-  HDD_INFO                  *LocalHddInfo;\r
-  BBS_TABLE                 *LocalBbsTable;\r
-  BBS_TABLE                 *BbsEntry;\r
-  UINT16                    BbsIndex;\r
-  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;\r
-  UINTN                     Index;\r
-  UINT16                    BootOption[10];\r
-  UINT16                    BootDesc[100];\r
-  BOOLEAN                   DescStringMatch;\r
-\r
-  Status        = EFI_SUCCESS;\r
-  BootOrder     = NULL;\r
-  BootOrderSize = 0;\r
-  HddCount      = 0;\r
-  BbsCount      = 0;\r
-  LocalHddInfo  = NULL;\r
-  LocalBbsTable = NULL;\r
-  BbsEntry      = NULL;\r
-\r
-  Status        = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  LegacyBios->GetBbsInfo (\r
-                LegacyBios,\r
-                &HddCount,\r
-                &LocalHddInfo,\r
-                &BbsCount,\r
-                &LocalBbsTable\r
-                );\r
-\r
-  BootOrder = BdsLibGetVariableAndSize (\r
-                L"BootOrder",\r
-                &gEfiGlobalVariableGuid,\r
-                &BootOrderSize\r
-                );\r
-  if (BootOrder == NULL) {\r
-    BootOrderSize = 0;\r
-  }\r
-\r
-  Index = 0;\r
-  while (Index < BootOrderSize / sizeof (UINT16)) {\r
-    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);\r
-    BootOptionVar = BdsLibGetVariableAndSize (\r
-                      BootOption,\r
-                      &gEfiGlobalVariableGuid,\r
-                      &BootOptionSize\r
-                      );\r
-    if (NULL == BootOptionVar) {\r
-      BootOptionSize = 0;\r
-      Status = gRT->GetVariable (\r
-                      BootOption,\r
-                      &gEfiGlobalVariableGuid,\r
-                      NULL,\r
-                      &BootOptionSize,\r
-                      BootOptionVar\r
-                      );\r
-      if (Status == EFI_NOT_FOUND) {\r
-        //\r
-        // Update BootOrder\r
-        //\r
-        BdsDeleteBootOption (\r
-          BootOrder[Index],\r
-          BootOrder,\r
-          &BootOrderSize\r
-          );\r
-        continue;\r
-      } else {\r
-        FreePool (BootOrder);\r
-        return EFI_OUT_OF_RESOURCES;\r
-      }\r
-    }\r
-  \r
-    //\r
-    // Skip Non-Legacy boot option\r
-    // \r
-    if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, &BbsIndex)) {\r
-      if (BootOptionVar!= NULL) {\r
-        FreePool (BootOptionVar);\r
-      }\r
-      Index++;\r
-      continue;\r
-    }\r
-\r
-    if (BbsIndex < BbsCount) {\r
-      //\r
-      // Check if BBS Description String is changed\r
-      //\r
-      DescStringMatch = FALSE;\r
-      BdsBuildLegacyDevNameString (\r
-        &LocalBbsTable[BbsIndex],\r
-        BbsIndex,\r
-        sizeof (BootDesc),\r
-        BootDesc\r
-        );\r
-\r
-      if (StrCmp (BootDesc, (UINT16*)(BootOptionVar + sizeof (UINT32) + sizeof (UINT16))) == 0) {\r
-        DescStringMatch = TRUE;\r
-      }\r
-\r
-      if (!((LocalBbsTable[BbsIndex].BootPriority == BBS_IGNORE_ENTRY) ||\r
-            (LocalBbsTable[BbsIndex].BootPriority == BBS_DO_NOT_BOOT_FROM)) &&\r
-          (LocalBbsTable[BbsIndex].DeviceType == BbsEntry->DeviceType) &&\r
-          DescStringMatch) {\r
-        Index++;\r
-        continue;\r
-      }\r
-    }\r
-\r
-    if (BootOptionVar != NULL) {\r
-      FreePool (BootOptionVar);\r
-    }\r
-    //\r
-    // should delete\r
-    //\r
-    BdsDeleteBootOption (\r
-      BootOrder[Index],\r
-      BootOrder,\r
-      &BootOrderSize\r
-      );\r
-  }\r
-\r
-  //\r
-  // Adjust the number of boot options.\r
-  //\r
-  if (BootOrderSize != 0) {\r
-    Status = gRT->SetVariable (\r
-                    L"BootOrder",\r
-                    &gEfiGlobalVariableGuid,\r
-                    VAR_FLAG,\r
-                    BootOrderSize,\r
-                    BootOrder\r
-                    );\r
-  } else {\r
-    EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);\r
-  }\r
-\r
-  if (BootOrder != NULL) {\r
-    FreePool (BootOrder);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Find all legacy boot option by device type.\r
-\r
-  @param BootOrder       The boot order array.\r
-  @param BootOptionNum   The number of boot option.\r
-  @param DevType         Device type.\r
-  @param DevName         Device name.\r
-  @param Attribute       The boot option attribute.\r
-  @param BbsIndex        The BBS table index.\r
-  @param OptionNumber    The boot option index.\r
-\r
-  @retval TRUE           The Legacy boot option is found.\r
-  @retval FALSE          The legacy boot option is not found.\r
-\r
-**/\r
-BOOLEAN\r
-BdsFindLegacyBootOptionByDevTypeAndName (\r
-  IN UINT16                 *BootOrder,\r
-  IN UINTN                  BootOptionNum,\r
-  IN UINT16                 DevType,\r
-  IN CHAR16                 *DevName,\r
-  OUT UINT32                *Attribute,\r
-  OUT UINT16                *BbsIndex,\r
-  OUT UINT16                *OptionNumber\r
-  )\r
-{\r
-  UINTN     Index;\r
-  CHAR16    BootOption[9];\r
-  UINTN     BootOptionSize;\r
-  UINT8     *BootOptionVar;\r
-  BBS_TABLE *BbsEntry;\r
-  BOOLEAN   Found;\r
-\r
-  BbsEntry  = NULL;\r
-  Found     = FALSE;\r
-\r
-  if (NULL == BootOrder) {\r
-    return Found;\r
-  }\r
-\r
-  //\r
-  // Loop all boot option from variable\r
-  //\r
-  for (Index = 0; Index < BootOptionNum; Index++) {\r
-    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", (UINTN) BootOrder[Index]);\r
-    BootOptionVar = BdsLibGetVariableAndSize (\r
-                      BootOption,\r
-                      &gEfiGlobalVariableGuid,\r
-                      &BootOptionSize\r
-                      );\r
-    if (NULL == BootOptionVar) {\r
-      continue;\r
-    }\r
-\r
-    //\r
-    // Skip Non-legacy boot option\r
-    //\r
-    if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, BbsIndex)) {\r
-      FreePool (BootOptionVar);\r
-      continue;\r
-    }\r
-\r
-    if (\r
-        (BbsEntry->DeviceType != DevType) ||\r
-        (StrCmp (DevName, (CHAR16*)(BootOptionVar + sizeof (UINT32) + sizeof (UINT16))) != 0)\r
-       ) {\r
-      FreePool (BootOptionVar);\r
-      continue;\r
-    }\r
-\r
-    *Attribute    = *(UINT32 *) BootOptionVar;\r
-    *OptionNumber = BootOrder[Index];\r
-    Found         = TRUE;\r
-    FreePool (BootOptionVar);\r
-    break;\r
-  }\r
-\r
-  return Found;\r
-}\r
-\r
-/**\r
-  Create a legacy boot option.\r
-\r
-  @param BbsItem         The BBS Table entry.\r
-  @param Index           Index of the specified entry in BBS table.\r
-  @param BootOrderList   The boot order list.\r
-  @param BootOrderListSize The size of boot order list.\r
-\r
-  @retval EFI_OUT_OF_RESOURCE  No enough memory.\r
-  @retval EFI_SUCCESS          The function complete successfully.\r
-  @return Other value if the legacy boot option is not created.\r
-\r
-**/\r
-EFI_STATUS\r
-BdsCreateOneLegacyBootOption (\r
-  IN BBS_TABLE              *BbsItem,\r
-  IN UINTN                  Index,\r
-  IN OUT UINT16             **BootOrderList,\r
-  IN OUT UINTN              *BootOrderListSize\r
-  )\r
-{\r
-  BBS_BBS_DEVICE_PATH       BbsDevPathNode;\r
-  EFI_STATUS                Status;\r
-  EFI_DEVICE_PATH_PROTOCOL  *DevPath;\r
-\r
-  DevPath                       = NULL;\r
-\r
-  //\r
-  // Create device path node.\r
-  //\r
-  BbsDevPathNode.Header.Type    = BBS_DEVICE_PATH;\r
-  BbsDevPathNode.Header.SubType = BBS_BBS_DP;\r
-  SetDevicePathNodeLength (&BbsDevPathNode.Header, sizeof (BBS_BBS_DEVICE_PATH));\r
-  BbsDevPathNode.DeviceType = BbsItem->DeviceType;\r
-  CopyMem (&BbsDevPathNode.StatusFlag, &BbsItem->StatusFlags, sizeof (UINT16));\r
-\r
-  DevPath = AppendDevicePathNode (\r
-              EndDevicePath,\r
-              (EFI_DEVICE_PATH_PROTOCOL *) &BbsDevPathNode\r
-              );\r
-  if (NULL == DevPath) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Status = BdsCreateLegacyBootOption (\r
-            BbsItem,\r
-            DevPath,\r
-            Index,\r
-            BootOrderList,\r
-            BootOrderListSize\r
-            );\r
-  BbsItem->BootPriority = 0x00;\r
-\r
-  FreePool (DevPath);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Add the legacy boot options from BBS table if they do not exist.\r
-\r
-  @retval EFI_SUCCESS          The boot options are added successfully \r
-                               or they are already in boot options.\r
-  @retval EFI_NOT_FOUND        No legacy boot options is found.\r
-  @retval EFI_OUT_OF_RESOURCE  No enough memory.\r
-  @return Other value          LegacyBoot options are not added.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BdsAddNonExistingLegacyBootOptions (\r
   VOID\r
   )\r
 {\r
-  UINT16                    *BootOrder;\r
-  UINTN                     BootOrderSize;\r
-  EFI_STATUS                Status;\r
-  CHAR16                    Desc[100];\r
-  UINT16                    HddCount;\r
-  UINT16                    BbsCount;\r
-  HDD_INFO                  *LocalHddInfo;\r
-  BBS_TABLE                 *LocalBbsTable;\r
-  UINT16                    BbsIndex;\r
-  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;\r
-  UINT16                    Index;\r
-  UINT32                    Attribute;\r
-  UINT16                    OptionNumber;\r
-  BOOLEAN                   Exist;\r
-\r
-  HddCount      = 0;\r
-  BbsCount      = 0;\r
-  LocalHddInfo  = NULL;\r
-  LocalBbsTable = NULL;\r
-\r
-  Status        = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  if (mBootOptionBbsMapping != NULL) {\r
-    FreePool (mBootOptionBbsMapping);\r
-\r
-    mBootOptionBbsMapping      = NULL;\r
-    mBootOptionBbsMappingCount = 0;\r
-  }\r
+  UINTN                        Index;\r
+  UINTN                        DeviceIndex;\r
+  UINTN                        DeviceTypeIndex[7];\r
+  UINTN                        *NextIndex;\r
+  UINT16                       OptionNumber;\r
+  UINT16                       *BootOrder;\r
+  UINTN                        BootOrderSize;\r
+  CHAR16                       OptionName[sizeof ("Boot####")];\r
+  BDS_COMMON_OPTION            *BootOption;\r
+  LIST_ENTRY                   List;\r
 \r
-  LegacyBios->GetBbsInfo (\r
-                LegacyBios,\r
-                &HddCount,\r
-                &LocalHddInfo,\r
-                &BbsCount,\r
-                &LocalBbsTable\r
-                );\r
+  SetMem (DeviceTypeIndex, sizeof (DeviceTypeIndex), 0xff);\r
 \r
   BootOrder = BdsLibGetVariableAndSize (\r
                 L"BootOrder",\r
                 &gEfiGlobalVariableGuid,\r
                 &BootOrderSize\r
                 );\r
-  if (BootOrder == NULL) {\r
-    BootOrderSize = 0;\r
-  }\r
-\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||\r
-        (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)\r
-        ) {\r
-      continue;\r
-    }\r
 \r
-    BdsBuildLegacyDevNameString (&LocalBbsTable[Index], Index, sizeof (Desc), Desc);\r
+  for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
+    UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]);\r
+    InitializeListHead (&List);\r
+    BootOption = BdsLibVariableToOption (&List, OptionName);\r
+    ASSERT_EFI_ERROR (BootOption != NULL);\r
 \r
-    Exist = BdsFindLegacyBootOptionByDevTypeAndName (\r
-              BootOrder,\r
-              BootOrderSize / sizeof (UINT16),\r
-              LocalBbsTable[Index].DeviceType,\r
-              Desc,\r
-              &Attribute,\r
-              &BbsIndex,\r
-              &OptionNumber\r
-              );\r
-    if (!Exist) {\r
+    if ((DevicePathType (BootOption->DevicePath) == BBS_DEVICE_PATH) &&\r
+        (DevicePathSubType (BootOption->DevicePath) == BBS_BBS_DP)) {\r
       //\r
-      // Not found such type of legacy device in boot options or we found but it's disabled\r
-      // so we have to create one and put it to the tail of boot order list\r
+      // Legacy Boot Option\r
       //\r
-      Status = BdsCreateOneLegacyBootOption (\r
-                &LocalBbsTable[Index],\r
-                Index,\r
-                &BootOrder,\r
-                &BootOrderSize\r
-                );\r
-      if (EFI_ERROR (Status)) {\r
-        break;\r
-      }\r
-      BbsIndex     = Index;\r
-      OptionNumber = BootOrder[BootOrderSize / sizeof (UINT16) - 1];\r
-    }\r
-\r
-    ASSERT (BbsIndex == Index);\r
-    //\r
-    // Save the BbsIndex\r
-    //\r
-    mBootOptionBbsMapping = ReallocatePool (\r
-                              mBootOptionBbsMappingCount * sizeof (BOOT_OPTION_BBS_MAPPING),\r
-                              (mBootOptionBbsMappingCount + 1) * sizeof (BOOT_OPTION_BBS_MAPPING),\r
-                              mBootOptionBbsMapping\r
-                              );\r
-    ASSERT (mBootOptionBbsMapping != NULL);\r
-    mBootOptionBbsMapping[mBootOptionBbsMappingCount].BootOptionNumber = OptionNumber;\r
-    mBootOptionBbsMapping[mBootOptionBbsMappingCount].BbsIndex         = Index;\r
-    mBootOptionBbsMapping[mBootOptionBbsMappingCount].BbsType          = LocalBbsTable[Index].DeviceType;\r
-    mBootOptionBbsMappingCount ++;\r
-  }\r
-\r
-  //\r
-  // Group the Boot Option Number in BootOrder for the same type devices\r
-  //\r
-  GroupMultipleLegacyBootOption4SameType (\r
-    BootOrder,\r
-    BootOrderSize / sizeof (UINT16)\r
-    );\r
-\r
-  if (BootOrderSize > 0) {\r
-    Status = gRT->SetVariable (\r
-                    L"BootOrder",\r
-                    &gEfiGlobalVariableGuid,\r
-                    VAR_FLAG,\r
-                    BootOrderSize,\r
-                    BootOrder\r
-                    );\r
-  } else {\r
-    EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);\r
-  }\r
-\r
-  if (BootOrder != NULL) {\r
-    FreePool (BootOrder);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Fill the device order buffer.\r
-\r
-  @param BbsTable        The BBS table.\r
-  @param BbsType         The BBS Type.\r
-  @param BbsCount        The BBS Count.\r
-  @param Buf             device order buffer.\r
-\r
-  @return The device order buffer.\r
-\r
-**/\r
-UINT16 *\r
-BdsFillDevOrderBuf (\r
-  IN BBS_TABLE                    *BbsTable,\r
-  IN BBS_TYPE                     BbsType,\r
-  IN UINTN                        BbsCount,\r
-  OUT UINT16                      *Buf\r
-  )\r
-{\r
-  UINTN Index;\r
-\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {\r
-      continue;\r
-    }\r
-\r
-    if (BbsTable[Index].DeviceType != BbsType) {\r
-      continue;\r
-    }\r
-\r
-    *Buf = (UINT16) (Index & 0xFF);\r
-    Buf++;\r
-  }\r
-\r
-  return Buf;\r
-}\r
-\r
-/**\r
-  Create the device order buffer.\r
-\r
-  @param BbsTable        The BBS table.\r
-  @param BbsCount        The BBS Count.\r
-\r
-  @retval EFI_SUCCES             The buffer is created and the EFI variable named \r
-                                 VAR_LEGACY_DEV_ORDER and gEfiLegacyDevOrderVariableGuid is\r
-                                 set correctly.\r
-  @retval EFI_OUT_OF_RESOURCES   Memmory or storage is not enough.\r
-  @retval EFI_DEVICE_ERROR       Fail to add the device order into EFI variable fail\r
-                                 because of hardware error.\r
-**/\r
-EFI_STATUS\r
-BdsCreateDevOrder (\r
-  IN BBS_TABLE                  *BbsTable,\r
-  IN UINT16                     BbsCount\r
-  )\r
-{\r
-  UINTN                       Index;\r
-  UINTN                       FDCount;\r
-  UINTN                       HDCount;\r
-  UINTN                       CDCount;\r
-  UINTN                       NETCount;\r
-  UINTN                       BEVCount;\r
-  UINTN                       TotalSize;\r
-  UINTN                       HeaderSize;\r
-  LEGACY_DEV_ORDER_ENTRY      *DevOrder;\r
-  LEGACY_DEV_ORDER_ENTRY      *DevOrderPtr;\r
-  EFI_STATUS                  Status;\r
-\r
-  FDCount     = 0;\r
-  HDCount     = 0;\r
-  CDCount     = 0;\r
-  NETCount    = 0;\r
-  BEVCount    = 0;\r
-  TotalSize   = 0;\r
-  HeaderSize  = sizeof (BBS_TYPE) + sizeof (UINT16);\r
-  DevOrder    = NULL;\r
-  Status      = EFI_SUCCESS;\r
-\r
-  //\r
-  // Count all boot devices\r
-  //\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {\r
-      continue;\r
-    }\r
-\r
-    switch (BbsTable[Index].DeviceType) {\r
-    case BBS_FLOPPY:\r
-      FDCount++;\r
-      break;\r
-\r
-    case BBS_HARDDISK:\r
-      HDCount++;\r
-      break;\r
-\r
-    case BBS_CDROM:\r
-      CDCount++;\r
-      break;\r
-\r
-    case BBS_EMBED_NETWORK:\r
-      NETCount++;\r
-      break;\r
-\r
-    case BBS_BEV_DEVICE:\r
-      BEVCount++;\r
-      break;\r
-\r
-    default:\r
-      break;\r
-    }\r
-  }\r
-\r
-  TotalSize += (HeaderSize + sizeof (UINT16) * FDCount);\r
-  TotalSize += (HeaderSize + sizeof (UINT16) * HDCount);\r
-  TotalSize += (HeaderSize + sizeof (UINT16) * CDCount);\r
-  TotalSize += (HeaderSize + sizeof (UINT16) * NETCount);\r
-  TotalSize += (HeaderSize + sizeof (UINT16) * BEVCount);\r
-\r
-  //\r
-  // Create buffer to hold all boot device order\r
-  //\r
-  DevOrder = AllocateZeroPool (TotalSize);\r
-  if (NULL == DevOrder) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  DevOrderPtr          = DevOrder;\r
-\r
-  DevOrderPtr->BbsType = BBS_FLOPPY;\r
-  DevOrderPtr->Length  = (UINT16) (sizeof (DevOrderPtr->Length) + FDCount * sizeof (UINT16));\r
-  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_FLOPPY, BbsCount, DevOrderPtr->Data);\r
-\r
-  DevOrderPtr->BbsType = BBS_HARDDISK;\r
-  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));\r
-  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_HARDDISK, BbsCount, DevOrderPtr->Data);\r
-  \r
-  DevOrderPtr->BbsType = BBS_CDROM;\r
-  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));\r
-  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_CDROM, BbsCount, DevOrderPtr->Data);\r
-  \r
-  DevOrderPtr->BbsType = BBS_EMBED_NETWORK;\r
-  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));\r
-  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_EMBED_NETWORK, BbsCount, DevOrderPtr->Data);\r
-\r
-  DevOrderPtr->BbsType = BBS_BEV_DEVICE;\r
-  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));\r
-  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_BEV_DEVICE, BbsCount, DevOrderPtr->Data);\r
-\r
-  ASSERT (TotalSize == (UINTN) ((UINT8 *) DevOrderPtr - (UINT8 *) DevOrder));\r
-\r
-  //\r
-  // Save device order for legacy boot device to variable.\r
-  //\r
-  Status = gRT->SetVariable (\r
-                  VAR_LEGACY_DEV_ORDER,\r
-                  &gEfiLegacyDevOrderVariableGuid,\r
-                  VAR_FLAG,\r
-                  TotalSize,\r
-                  DevOrder\r
-                  );\r
-  FreePool (DevOrder);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Add the legacy boot devices from BBS table into \r
-  the legacy device boot order.\r
-\r
-  @retval EFI_SUCCESS           The boot devices are added successfully.\r
-  @retval EFI_NOT_FOUND         The legacy boot devices are not found.\r
-  @retval EFI_OUT_OF_RESOURCES  Memmory or storage is not enough.\r
-  @retval EFI_DEVICE_ERROR      Fail to add the legacy device boot order into EFI variable\r
-                                because of hardware error.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BdsUpdateLegacyDevOrder (\r
-  VOID\r
-  )\r
-{\r
-  LEGACY_DEV_ORDER_ENTRY      *DevOrder;\r
-  LEGACY_DEV_ORDER_ENTRY      *NewDevOrder;\r
-  LEGACY_DEV_ORDER_ENTRY      *Ptr;\r
-  LEGACY_DEV_ORDER_ENTRY      *NewPtr;\r
-  UINTN                       DevOrderSize;\r
-  EFI_LEGACY_BIOS_PROTOCOL    *LegacyBios;\r
-  EFI_STATUS                  Status;\r
-  UINT16                      HddCount;\r
-  UINT16                      BbsCount;\r
-  HDD_INFO                    *LocalHddInfo;\r
-  BBS_TABLE                   *LocalBbsTable;\r
-  UINTN                       Index;\r
-  UINTN                       Index2;\r
-  UINTN                       *Idx;\r
-  UINTN                       FDCount;\r
-  UINTN                       HDCount;\r
-  UINTN                       CDCount;\r
-  UINTN                       NETCount;\r
-  UINTN                       BEVCount;\r
-  UINTN                       TotalSize;\r
-  UINTN                       HeaderSize;\r
-  UINT16                      *NewFDPtr;\r
-  UINT16                      *NewHDPtr;\r
-  UINT16                      *NewCDPtr;\r
-  UINT16                      *NewNETPtr;\r
-  UINT16                      *NewBEVPtr;\r
-  UINT16                      *NewDevPtr;\r
-  UINTN                       FDIndex;\r
-  UINTN                       HDIndex;\r
-  UINTN                       CDIndex;\r
-  UINTN                       NETIndex;\r
-  UINTN                       BEVIndex;\r
-\r
-  Idx           = NULL;\r
-  FDCount       = 0;\r
-  HDCount       = 0;\r
-  CDCount       = 0;\r
-  NETCount      = 0;\r
-  BEVCount      = 0;\r
-  TotalSize     = 0;\r
-  HeaderSize    = sizeof (BBS_TYPE) + sizeof (UINT16);\r
-  FDIndex       = 0;\r
-  HDIndex       = 0;\r
-  CDIndex       = 0;\r
-  NETIndex      = 0;\r
-  BEVIndex      = 0;\r
-  NewDevPtr     = NULL;\r
-\r
-  Status        = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  Status = LegacyBios->GetBbsInfo (\r
-                         LegacyBios,\r
-                         &HddCount,\r
-                         &LocalHddInfo,\r
-                         &BbsCount,\r
-                         &LocalBbsTable\r
-                         );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  DevOrder = BdsLibGetVariableAndSize (\r
-               VAR_LEGACY_DEV_ORDER,\r
-               &gEfiLegacyDevOrderVariableGuid,\r
-               &DevOrderSize\r
-               );\r
-  if (NULL == DevOrder) {\r
-    return BdsCreateDevOrder (LocalBbsTable, BbsCount);\r
-  }\r
-  //\r
-  // First we figure out how many boot devices with same device type respectively\r
-  //\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||\r
-        (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)\r
-        ) {\r
-      continue;\r
-    }\r
-\r
-    switch (LocalBbsTable[Index].DeviceType) {\r
-    case BBS_FLOPPY:\r
-      FDCount++;\r
-      break;\r
-\r
-    case BBS_HARDDISK:\r
-      HDCount++;\r
-      break;\r
-\r
-    case BBS_CDROM:\r
-      CDCount++;\r
-      break;\r
-\r
-    case BBS_EMBED_NETWORK:\r
-      NETCount++;\r
-      break;\r
-\r
-    case BBS_BEV_DEVICE:\r
-      BEVCount++;\r
-      break;\r
-\r
-    default:\r
-      break;\r
-    }\r
-  }\r
-\r
-  TotalSize += (HeaderSize + FDCount * sizeof (UINT16));\r
-  TotalSize += (HeaderSize + HDCount * sizeof (UINT16));\r
-  TotalSize += (HeaderSize + CDCount * sizeof (UINT16));\r
-  TotalSize += (HeaderSize + NETCount * sizeof (UINT16));\r
-  TotalSize += (HeaderSize + BEVCount * sizeof (UINT16));\r
-\r
-  NewDevOrder = AllocateZeroPool (TotalSize);\r
-  if (NULL == NewDevOrder) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-\r
-\r
-  //\r
-  // copy FD\r
-  //\r
-  Ptr             = DevOrder;\r
-  NewPtr          = NewDevOrder;\r
-  NewPtr->BbsType = Ptr->BbsType;\r
-  NewPtr->Length  = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16));\r
-  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {\r
-    if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||\r
-        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
-        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_FLOPPY\r
-        ) {\r
-      continue;\r
-    }\r
-\r
-    NewPtr->Data[FDIndex] = Ptr->Data[Index];\r
-    FDIndex++;\r
-  }\r
-  NewFDPtr = NewPtr->Data;\r
-\r
-  //\r
-  // copy HD\r
-  //\r
-  Ptr             = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);\r
-  NewPtr          = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);\r
-  NewPtr->BbsType = Ptr->BbsType;\r
-  NewPtr->Length  = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));\r
-  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {\r
-    if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||\r
-        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
-        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||\r
-        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_HARDDISK\r
-        ) {\r
-      continue;\r
-    }\r
-\r
-    NewPtr->Data[HDIndex] = Ptr->Data[Index];\r
-    HDIndex++;\r
-  }\r
-  NewHDPtr = NewPtr->Data;\r
-\r
-  //\r
-  // copy CD\r
-  //\r
-  Ptr    = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);\r
-  NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);\r
-  NewPtr->BbsType = Ptr->BbsType;\r
-  NewPtr->Length  = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));\r
-  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {\r
-    if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||\r
-        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
-        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||\r
-        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_CDROM\r
-        ) {\r
-      continue;\r
-    }\r
-\r
-    NewPtr->Data[CDIndex] = Ptr->Data[Index];\r
-    CDIndex++;\r
-  }\r
-  NewCDPtr = NewPtr->Data;\r
-\r
-  //\r
-  // copy NET\r
-  //\r
-  Ptr    = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);\r
-  NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);\r
-  NewPtr->BbsType = Ptr->BbsType;\r
-  NewPtr->Length  = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));\r
-  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {\r
-    if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||\r
-        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
-        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||\r
-        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_EMBED_NETWORK\r
-        ) {\r
-      continue;\r
-    }\r
-\r
-    NewPtr->Data[NETIndex] = Ptr->Data[Index];\r
-    NETIndex++;\r
-  }\r
-  NewNETPtr = NewPtr->Data;\r
-  \r
-  //\r
-  // copy BEV\r
-  //\r
-  Ptr    = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);\r
-  NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);\r
-  NewPtr->BbsType = Ptr->BbsType;\r
-  NewPtr->Length  = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));\r
-  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {\r
-    if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||\r
-        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
-        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||\r
-        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_BEV_DEVICE\r
-        ) {\r
-      continue;\r
-    }\r
-\r
-    NewPtr->Data[BEVIndex] = Ptr->Data[Index];\r
-    BEVIndex++;\r
-  }\r
-  NewBEVPtr = NewPtr->Data;\r
-\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||\r
-        (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)\r
-        ) {\r
-      continue;\r
-    }\r
-\r
-    switch (LocalBbsTable[Index].DeviceType) {\r
-    case BBS_FLOPPY:\r
-      Idx       = &FDIndex;\r
-      NewDevPtr = NewFDPtr;\r
-      break;\r
-\r
-    case BBS_HARDDISK:\r
-      Idx       = &HDIndex;\r
-      NewDevPtr = NewHDPtr;\r
-      break;\r
-\r
-    case BBS_CDROM:\r
-      Idx       = &CDIndex;\r
-      NewDevPtr = NewCDPtr;\r
-      break;\r
+      ASSERT ((((BBS_BBS_DEVICE_PATH *) BootOption->DevicePath)->DeviceType & 0xF) < sizeof (DeviceTypeIndex) / sizeof (DeviceTypeIndex[0]));\r
+      NextIndex = &DeviceTypeIndex[((BBS_BBS_DEVICE_PATH *) BootOption->DevicePath)->DeviceType & 0xF];\r
 \r
-    case BBS_EMBED_NETWORK:\r
-      Idx       = &NETIndex;\r
-      NewDevPtr = NewNETPtr;\r
-      break;\r
-\r
-    case BBS_BEV_DEVICE:\r
-      Idx       = &BEVIndex;\r
-      NewDevPtr = NewBEVPtr;\r
-      break;\r
-\r
-    default:\r
-      Idx = NULL;\r
-      break;\r
-    }\r
-    //\r
-    // at this point we have copied those valid indexes to new buffer\r
-    // and we should check if there is any new appeared boot device\r
-    //\r
-    if (Idx != NULL) {\r
-      for (Index2 = 0; Index2 < *Idx; Index2++) {\r
-        if ((NewDevPtr[Index2] & 0xFF) == (UINT16) Index) {\r
-          break;\r
-        }\r
-      }\r
+      if (*NextIndex == (UINTN) -1) {\r
+        //\r
+        // *NextIndex is the Index in BootOrder to put the next Option Number for the same type\r
+        //\r
+        *NextIndex = Index + 1;\r
+      } else {\r
+        //\r
+        // insert the current boot option before *NextIndex, causing [*Next .. Index] shift right one position\r
+        //\r
+        OptionNumber = BootOrder[Index];\r
+        CopyMem (&BootOrder[*NextIndex + 1], &BootOrder[*NextIndex], (Index - *NextIndex) * sizeof (UINT16));\r
+        BootOrder[*NextIndex] = OptionNumber;\r
 \r
-      if (Index2 == *Idx) {\r
         //\r
-        // Index2 == *Idx means we didn't find Index\r
-        // so Index is a new appeared device's index in BBS table\r
-        // insert it before disabled indexes.\r
+        // Update the DeviceTypeIndex array to reflect the right shift operation\r
         //\r
-        for (Index2 = 0; Index2 < *Idx; Index2++) {\r
-          if ((NewDevPtr[Index2] & 0xFF00) == 0xFF00) {\r
-            break;\r
+        for (DeviceIndex = 0; DeviceIndex < sizeof (DeviceTypeIndex) / sizeof (DeviceTypeIndex[0]); DeviceIndex++) {\r
+          if (DeviceTypeIndex[DeviceIndex] != (UINTN) -1 && DeviceTypeIndex[DeviceIndex] >= *NextIndex) {\r
+            DeviceTypeIndex[DeviceIndex]++;\r
           }\r
         }\r
-        CopyMem (&NewDevPtr[Index2 + 1], &NewDevPtr[Index2], (*Idx - Index2) * sizeof (UINT16));\r
-        NewDevPtr[Index2] = (UINT16) (Index & 0xFF);\r
-        (*Idx)++;\r
       }\r
     }\r
+    FreePool (BootOption->DevicePath);\r
+    FreePool (BootOption->Description);\r
+    FreePool (BootOption->LoadOptions);\r
+    FreePool (BootOption);\r
   }\r
 \r
-  FreePool (DevOrder);\r
-\r
-  Status = gRT->SetVariable (\r
-                  VAR_LEGACY_DEV_ORDER,\r
-                  &gEfiLegacyDevOrderVariableGuid,\r
-                  VAR_FLAG,\r
-                  TotalSize,\r
-                  NewDevOrder\r
-                  );\r
-  FreePool (NewDevOrder);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Set Boot Priority for specified device type.\r
-\r
-  @param DeviceType      The device type.\r
-  @param BbsIndex        The BBS index to set the highest priority. Ignore when -1.\r
-  @param LocalBbsTable   The BBS table.\r
-  @param Priority        The prority table.\r
-\r
-  @retval EFI_SUCCESS           The function completes successfully.\r
-  @retval EFI_NOT_FOUND         Failed to find device.\r
-  @retval EFI_OUT_OF_RESOURCES  Failed to get the efi variable of device order.\r
-\r
-**/\r
-EFI_STATUS\r
-BdsSetBootPriority4SameTypeDev (\r
-  IN UINT16                                              DeviceType,\r
-  IN UINTN                                               BbsIndex,\r
-  IN OUT BBS_TABLE                                       *LocalBbsTable,\r
-  IN OUT UINT16                                          *Priority\r
-  )\r
-{\r
-  LEGACY_DEV_ORDER_ENTRY      *DevOrder;\r
-  LEGACY_DEV_ORDER_ENTRY      *DevOrderPtr;\r
-  UINTN                       DevOrderSize;\r
-  UINTN                       Index;\r
-\r
-  DevOrder = BdsLibGetVariableAndSize (\r
-               VAR_LEGACY_DEV_ORDER,\r
-               &gEfiLegacyDevOrderVariableGuid,\r
-               &DevOrderSize\r
-               );\r
-  if (NULL == DevOrder) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  DevOrderPtr = DevOrder;\r
-  while ((UINT8 *) DevOrderPtr < (UINT8 *) DevOrder + DevOrderSize) {\r
-    if (DevOrderPtr->BbsType == DeviceType) {\r
-      break;\r
-    }\r
-\r
-    DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) ((UINT8 *) DevOrderPtr + sizeof (BBS_TYPE) + DevOrderPtr->Length);\r
-  }\r
-\r
-  if ((UINT8 *) DevOrderPtr >= (UINT8 *) DevOrder + DevOrderSize) {\r
-    FreePool (DevOrder);\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  if (BbsIndex != (UINTN) -1) {\r
-    LocalBbsTable[BbsIndex].BootPriority = *Priority;\r
-    (*Priority)++;\r
-  }\r
-  //\r
-  // If the high byte of the DevIndex is 0xFF, it indicates that this device has been disabled.\r
-  //\r
-  for (Index = 0; Index < DevOrderPtr->Length / sizeof (UINT16) - 1; Index++) {\r
-    if ((DevOrderPtr->Data[Index] & 0xFF00) == 0xFF00) {\r
-      //\r
-      // LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = BBS_DISABLED_ENTRY;\r
-      //\r
-    } else if (DevOrderPtr->Data[Index] != BbsIndex) {\r
-      LocalBbsTable[DevOrderPtr->Data[Index]].BootPriority = *Priority;\r
-      (*Priority)++;\r
-    }\r
-  }\r
-\r
-  FreePool (DevOrder);\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Print the BBS Table.\r
-\r
-  @param LocalBbsTable   The BBS table.\r
-  @param BbsCount        The count of entry in BBS table.\r
-**/\r
-VOID\r
-PrintBbsTable (\r
-  IN BBS_TABLE  *LocalBbsTable,\r
-  IN UINT16     BbsCount\r
-  )\r
-{\r
-  UINT16  Idx;\r
-\r
-  DEBUG ((DEBUG_ERROR, "\n"));\r
-  DEBUG ((DEBUG_ERROR, " NO  Prio bb/dd/ff cl/sc Type Stat segm:offs\n"));\r
-  DEBUG ((DEBUG_ERROR, "=============================================\n"));\r
-  for (Idx = 0; Idx < BbsCount; Idx++) {\r
-    if ((LocalBbsTable[Idx].BootPriority == BBS_IGNORE_ENTRY) ||\r
-        (LocalBbsTable[Idx].BootPriority == BBS_DO_NOT_BOOT_FROM) ||\r
-        (LocalBbsTable[Idx].BootPriority == BBS_LOWEST_PRIORITY)\r
-        ) {\r
-      continue;\r
-    }\r
-\r
-    DEBUG (\r
-      (DEBUG_ERROR,\r
-      " %02x: %04x %02x/%02x/%02x %02x/%02x %04x %04x %04x:%04x\n",\r
-      (UINTN) Idx,\r
-      (UINTN) LocalBbsTable[Idx].BootPriority,\r
-      (UINTN) LocalBbsTable[Idx].Bus,\r
-      (UINTN) LocalBbsTable[Idx].Device,\r
-      (UINTN) LocalBbsTable[Idx].Function,\r
-      (UINTN) LocalBbsTable[Idx].Class,\r
-      (UINTN) LocalBbsTable[Idx].SubClass,\r
-      (UINTN) LocalBbsTable[Idx].DeviceType,\r
-      (UINTN) * (UINT16 *) &LocalBbsTable[Idx].StatusFlags,\r
-      (UINTN) LocalBbsTable[Idx].BootHandlerSegment,\r
-      (UINTN) LocalBbsTable[Idx].BootHandlerOffset,\r
-      (UINTN) ((LocalBbsTable[Idx].MfgStringSegment << 4) + LocalBbsTable[Idx].MfgStringOffset),\r
-      (UINTN) ((LocalBbsTable[Idx].DescStringSegment << 4) + LocalBbsTable[Idx].DescStringOffset))\r
-      );\r
-  }\r
-\r
-  DEBUG ((DEBUG_ERROR, "\n"));\r
+  gRT->SetVariable (\r
+         L"BootOrder",\r
+         &gEfiGlobalVariableGuid,\r
+         EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+         BootOrderSize,\r
+         BootOrder\r
+         );\r
+  FreePool (BootOrder);\r
 }\r
 \r
-/**\r
-  Set the boot priority for BBS entries based on boot option entry and boot order.\r
-\r
-  @param  Entry             The boot option is to be checked for refresh BBS table.\r
-  \r
-  @retval EFI_SUCCESS           The boot priority for BBS entries is refreshed successfully.\r
-  @retval EFI_NOT_FOUND         BBS entries can't be found.\r
-  @retval EFI_OUT_OF_RESOURCES  Failed to get the legacy device boot order.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BdsRefreshBbsTableForBoot (\r
-  IN BDS_COMMON_OPTION        *Entry\r
-  )\r
-{\r
-  EFI_STATUS                Status;\r
-  UINT16                    BbsIndex;\r
-  UINT16                    HddCount;\r
-  UINT16                    BbsCount;\r
-  HDD_INFO                  *LocalHddInfo;\r
-  BBS_TABLE                 *LocalBbsTable;\r
-  UINT16                    DevType;\r
-  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;\r
-  UINTN                     Index;\r
-  UINT16                    Priority;\r
-  UINT16                    *BootOrder;\r
-  UINTN                     BootOrderSize;\r
-  UINT8                     *BootOptionVar;\r
-  UINTN                     BootOptionSize;\r
-  CHAR16                    BootOption[9];\r
-  UINT8                     *Ptr;\r
-  UINT16                    DevPathLen;\r
-  EFI_DEVICE_PATH_PROTOCOL  *DevPath;\r
-  UINT16                    *DeviceType;\r
-  UINTN                     DeviceTypeCount;\r
-  UINTN                     DeviceTypeIndex;\r
-\r
-  HddCount      = 0;\r
-  BbsCount      = 0;\r
-  LocalHddInfo  = NULL;\r
-  LocalBbsTable = NULL;\r
-  DevType       = BBS_UNKNOWN;\r
-\r
-  Status        = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  LegacyBios->GetBbsInfo (\r
-                LegacyBios,\r
-                &HddCount,\r
-                &LocalHddInfo,\r
-                &BbsCount,\r
-                &LocalBbsTable\r
-                );\r
-  //\r
-  // First, set all the present devices' boot priority to BBS_UNPRIORITIZED_ENTRY\r
-  // We will set them according to the settings setup by user\r
-  //\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if (!((BBS_IGNORE_ENTRY == LocalBbsTable[Index].BootPriority) ||\r
-        (BBS_DO_NOT_BOOT_FROM == LocalBbsTable[Index].BootPriority) ||\r
-         (BBS_LOWEST_PRIORITY == LocalBbsTable[Index].BootPriority))) {\r
-      LocalBbsTable[Index].BootPriority = BBS_UNPRIORITIZED_ENTRY;\r
-    }\r
-  }\r
-  //\r
-  // boot priority always starts at 0\r
-  //\r
-  Priority = 0;\r
-  if (Entry->LoadOptionsSize == sizeof (BBS_TABLE) + sizeof (UINT16)) {\r
-    //\r
-    // If Entry stands for a legacy boot option, we prioritize the devices with the same type first.\r
-    //\r
-    DevType  = ((BBS_TABLE *) Entry->LoadOptions)->DeviceType;\r
-    BbsIndex = *(UINT16 *) ((BBS_TABLE *) Entry->LoadOptions + 1);\r
-    Status = BdsSetBootPriority4SameTypeDev (\r
-              DevType,\r
-              BbsIndex,\r
-              LocalBbsTable,\r
-              &Priority\r
-              );\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-  //\r
-  // we have to set the boot priority for other BBS entries with different device types\r
-  //\r
-  BootOrder = BdsLibGetVariableAndSize (\r
-                L"BootOrder",\r
-                &gEfiGlobalVariableGuid,\r
-                &BootOrderSize\r
-                );\r
-  DeviceType = AllocatePool (BootOrderSize + sizeof (UINT16));\r
-  ASSERT (DeviceType != NULL);\r
-\r
-  DeviceType[0]   = DevType;\r
-  DeviceTypeCount = 1;\r
-  for (Index = 0; ((BootOrder != NULL) && (Index < BootOrderSize / sizeof (UINT16))); Index++) {\r
-    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);\r
-    BootOptionVar = BdsLibGetVariableAndSize (\r
-                      BootOption,\r
-                      &gEfiGlobalVariableGuid,\r
-                      &BootOptionSize\r
-                      );\r
-    if (NULL == BootOptionVar) {\r
-      continue;\r
-    }\r
-\r
-    Ptr = BootOptionVar;\r
-\r
-    Ptr += sizeof (UINT32);\r
-    DevPathLen = *(UINT16 *) Ptr;\r
-    Ptr += sizeof (UINT16);\r
-    Ptr += StrSize ((UINT16 *) Ptr);\r
-    DevPath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;\r
-    if (BBS_DEVICE_PATH != DevPath->Type || BBS_BBS_DP != DevPath->SubType) {\r
-      FreePool (BootOptionVar);\r
-      continue;\r
-    }\r
-\r
-    Ptr += DevPathLen;\r
-    DevType = ((BBS_TABLE *) Ptr)->DeviceType;\r
-    for (DeviceTypeIndex = 0; DeviceTypeIndex < DeviceTypeCount; DeviceTypeIndex++) {\r
-      if (DeviceType[DeviceTypeIndex] == DevType) {\r
-        break;\r
-      }\r
-    }\r
-    if (DeviceTypeIndex < DeviceTypeCount) {\r
-      //\r
-      // We don't want to process twice for a device type\r
-      //\r
-      FreePool (BootOptionVar);\r
-      continue;\r
-    }\r
-\r
-    DeviceType[DeviceTypeCount] = DevType;\r
-    DeviceTypeCount++;\r
-\r
-    Status = BdsSetBootPriority4SameTypeDev (\r
-              DevType,\r
-              (UINTN) -1,\r
-              LocalBbsTable,\r
-              &Priority\r
-              );\r
-    FreePool (BootOptionVar);\r
-    if (EFI_ERROR (Status)) {\r
-      break;\r
-    }\r
-  }\r
-\r
-  if (BootOrder != NULL) {\r
-    FreePool (BootOrder);\r
-  }\r
-\r
-  DEBUG_CODE_BEGIN();\r
-    PrintBbsTable (LocalBbsTable, BbsCount);\r
-  DEBUG_CODE_END();\r
-  \r
-  return Status;\r
-}\r
index 26d6cb26373d5323127fdd89d56e215fba6c98f9..e73dc859959cfbe275bb3bb7d34fe007446b815b 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   declares interface functions\r
 \r
-Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2012, 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
@@ -50,14 +50,10 @@ BdsBuildLegacyDevNameString (
   2. Input  = [Efi1 Efi0 CdRom1 Harddisk0 Harddisk1 Harddisk2 CdRom0 CdRom2]\r
      Assuming [Efi1 Efi0 CdRom1 Harddisk0] is ordered properly\r
      Output = [Efi1 Efi0 CdRom1 CdRom0 CdRom2 Harddisk0 Harddisk1 Harddisk2]\r
-\r
-  @param BootOption      Pointer to buffer containing Boot Option Numbers\r
-  @param BootOptionCount Count of the Boot Option Numbers\r
 **/\r
 VOID\r
 GroupMultipleLegacyBootOption4SameType (\r
-  UINT16                   *BootOption,\r
-  UINTN                    BootOptionCount\r
+  VOID\r
   );\r
 \r
 /**\r
@@ -66,25 +62,21 @@ GroupMultipleLegacyBootOption4SameType (
   The routine re-orders the Boot Option in BootOption array according to\r
   the order specified by DevOrder.\r
 \r
-  @param BootOption         Pointer to buffer containing the Boot Option Numbers\r
-  @param BootOptionCount    Count of the Boot Option Numbers\r
   @param DevOrder           Pointer to buffer containing the BBS Index,\r
                             high 8-bit value 0xFF indicating a disabled boot option\r
   @param DevOrderCount      Count of the BBS Index\r
-  @param EnBootOption       Pointer to buffer receiving the enabled Boot Option Numbers\r
+  @param EnBootOption       Callee allocated buffer containing the enabled Boot Option Numbers\r
   @param EnBootOptionCount  Count of the enabled Boot Option Numbers\r
-  @param DisBootOption      Pointer to buffer receiving the disabled Boot Option Numbers\r
+  @param DisBootOption      Callee allocated buffer containing the disabled Boot Option Numbers\r
   @param DisBootOptionCount Count of the disabled Boot Option Numbers\r
 **/\r
 VOID\r
 OrderLegacyBootOption4SameType (\r
-  UINT16                   *BootOption,\r
-  UINTN                    BootOptionCount,\r
   UINT16                   *DevOrder,\r
   UINTN                    DevOrderCount,\r
-  UINT16                   *EnBootOption,\r
+  UINT16                   **EnBootOption,\r
   UINTN                    *EnBootOptionCount,\r
-  UINT16                   *DisBootOption,\r
+  UINT16                   **DisBootOption,\r
   UINTN                    *DisBootOptionCount\r
   );\r
 #endif\r
index e267935c7f71006f9616af76510c2803d87864b6..d00d0978b0c0eaebf0609d47db97bb34db84aed5 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Utility routines used by boot maintenance modules.\r
 \r
-Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2012, 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
@@ -14,36 +14,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "BootMaint.h"\r
 \r
-/**\r
-\r
-  Find the first instance of this Protocol\r
-  in the system and return it's interface.\r
-\r
-\r
-  @param ProtocolGuid    Provides the protocol to search for\r
-  @param Interface       On return, a pointer to the first interface\r
-                         that matches ProtocolGuid\r
-\r
-  @retval  EFI_SUCCESS      A protocol instance matching ProtocolGuid was found\r
-  @retval  EFI_NOT_FOUND    No protocol instances were found that match ProtocolGuid\r
-\r
-**/\r
-EFI_STATUS\r
-EfiLibLocateProtocol (\r
-  IN  EFI_GUID    *ProtocolGuid,\r
-  OUT VOID        **Interface\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-\r
-  Status = gBS->LocateProtocol (\r
-                  ProtocolGuid,\r
-                  NULL,\r
-                  (VOID **) Interface\r
-                  );\r
-  return Status;\r
-}\r
-\r
 /**\r
 \r
   Function opens and returns a file handle to the root directory of a volume.\r
@@ -201,7 +171,13 @@ EfiLibDeleteVariable (
     //\r
     // Delete variable from Storage\r
     //\r
-    Status = gRT->SetVariable (VarName, VarGuid, VAR_FLAG, 0, NULL);\r
+    Status = gRT->SetVariable (\r
+                    VarName,\r
+                    VarGuid,\r
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+                    0,\r
+                    NULL\r
+                    );\r
     ASSERT (!EFI_ERROR (Status));\r
     FreePool (VarBuf);\r
   }\r
index 1186c0cb1907dc915fa490a673f023727d929ddc..d1705a0b9cec59a9d4389fa98e4a3904d9eb03bf 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   The functions for Boot Maintainence Main menu.\r
 \r
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2012, 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
@@ -1016,7 +1016,7 @@ InitializeBM (
     UpdateTerminalPage (BmmCallbackInfo);\r
   }\r
 \r
-  Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);\r
+  Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);\r
   if (!EFI_ERROR (Status)) {\r
     RefreshUpdateData ();\r
     mStartLabel->Number = FORM_BOOT_LEGACY_DEVICE_ID;\r
@@ -1327,6 +1327,11 @@ BdsStartBootMaint (
   //\r
   BdsLibEnumerateAllBootOption (&BdsBootOptionList);\r
 \r
+  //\r
+  // Group the legacy boot options for the same device type\r
+  //\r
+  GroupMultipleLegacyBootOption4SameType ();\r
+\r
   //\r
   // Init the BMM\r
   //\r
@@ -1404,60 +1409,3 @@ FormSetDispatcher (
   return Status;\r
 }\r
 \r
-\r
-/**\r
-  Deletete the Boot Option from EFI Variable. The Boot Order Arrray\r
-  is also updated.\r
-\r
-  @param OptionNumber    The number of Boot option want to be deleted.\r
-  @param BootOrder       The Boot Order array.\r
-  @param BootOrderSize   The size of the Boot Order Array.\r
-\r
-  @retval  EFI_SUCCESS           The Boot Option Variable was found and removed\r
-  @retval  EFI_UNSUPPORTED       The Boot Option Variable store was inaccessible\r
-  @retval  EFI_NOT_FOUND         The Boot Option Variable was not found\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BdsDeleteBootOption (\r
-  IN UINTN                       OptionNumber,\r
-  IN OUT UINT16                  *BootOrder,\r
-  IN OUT UINTN                   *BootOrderSize\r
-  )\r
-{\r
-  UINT16      BootOption[100];\r
-  UINTN       Index;\r
-  EFI_STATUS  Status;\r
-  UINTN       Index2Del;\r
-\r
-  Status    = EFI_SUCCESS;\r
-  Index2Del = 0;\r
-\r
-  UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", OptionNumber);\r
-  Status = EfiLibDeleteVariable (BootOption, &gEfiGlobalVariableGuid);\r
-  \r
-  //\r
-  // adjust boot order array\r
-  //\r
-  for (Index = 0; Index < *BootOrderSize / sizeof (UINT16); Index++) {\r
-    if (BootOrder[Index] == OptionNumber) {\r
-      Index2Del = Index;\r
-      break;\r
-    }\r
-  }\r
-\r
-  if (Index != *BootOrderSize / sizeof (UINT16)) {\r
-    for (Index = 0; Index < *BootOrderSize / sizeof (UINT16) - 1; Index++) {\r
-      if (Index >= Index2Del) {\r
-        BootOrder[Index] = BootOrder[Index + 1];\r
-      }\r
-    }\r
-\r
-    *BootOrderSize -= sizeof (UINT16);\r
-  }\r
-\r
-  return Status;\r
-\r
-}\r
-\r
-\r
index 57acf8554157b4262d44d0687ef4e59244d77fab..d5016043cb73daecf68fb94a18b4edf3d22c88c3 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Header file for boot maintenance module.\r
 \r
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2012, 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
@@ -39,11 +39,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #define STR_NET_HELP      L"NET Drive #%02x"\r
 #define STR_BEV_HELP      L"BEV Drive #%02x"\r
 \r
-//\r
-// Variable created with this flag will be "Efi:...."\r
-//\r
-#define VAR_FLAG  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE\r
-\r
 extern CHAR16   mFileExplorerStorageName[];\r
 extern CHAR16   mBootMaintStorageName[];\r
 //\r
@@ -238,18 +233,6 @@ typedef struct {
   UINT16  StringToken;\r
 } COM_ATTR;\r
 \r
-#pragma pack(1)\r
-///\r
-/// For each legacy boot option in BBS table, a corresponding Boot#### variables is created.\r
-/// The structure saves the mapping relationship between #### and the index in the BBS table.\r
-///\r
-typedef struct {\r
-  UINT16    BootOptionNumber;\r
-  UINT16    BbsIndex;\r
-  UINT16    BbsType;\r
-} BOOT_OPTION_BBS_MAPPING;\r
-#pragma pack()\r
-\r
 typedef struct {\r
   UINT64                    BaudRate;\r
   UINT8                     DataBits;\r
@@ -1160,23 +1143,6 @@ EfiLibFileInfo (
   IN EFI_FILE_HANDLE      FHand\r
   );\r
 \r
-/**\r
-  Find the first instance of this Protocol in the system and return it's interface.\r
-\r
-  @param ProtocolGuid    Provides the protocol to search for\r
-  @param Interface       On return, a pointer to the first interface\r
-                         that matches ProtocolGuid\r
-\r
-  @retval  EFI_SUCCESS      A protocol instance matching ProtocolGuid was found\r
-  @retval  EFI_NOT_FOUND    No protocol instances were found that match ProtocolGuid\r
-\r
-**/\r
-EFI_STATUS\r
-EfiLibLocateProtocol (\r
-  IN  EFI_GUID        *ProtocolGuid,\r
-  OUT VOID            **Interface\r
-  );\r
-\r
 /**\r
   Adjusts the size of a previously allocated buffer.\r
 \r
index c4b83ba0ffa4476d6c2d17a09e9fdb2d45cd9a31..ef36ae2dc81b39122e62a6c8d55de76c46470df7 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Variable operation that will be used by bootmaint\r
 \r
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2012, 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
@@ -161,7 +161,7 @@ Var_ChangeBootOrder (
     Status = gRT->SetVariable (\r
                     L"BootOrder",\r
                     &gEfiGlobalVariableGuid,\r
-                    VAR_FLAG,\r
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
                     BootOrderListSize * sizeof (UINT16),\r
                     BootOrderList\r
                     );\r
@@ -299,7 +299,7 @@ Var_ChangeDriverOrder (
     Status = gRT->SetVariable (\r
                     L"DriverOrder",\r
                     &gEfiGlobalVariableGuid,\r
-                    VAR_FLAG,\r
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
                     DriverOrderListSize * sizeof (UINT16),\r
                     DriverOrderList\r
                     );\r
@@ -334,7 +334,7 @@ Var_UpdateAllConsoleOption (
     Status = gRT->SetVariable (\r
                     L"ConOut",\r
                     &gEfiGlobalVariableGuid,\r
-                    VAR_FLAG,\r
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
                     GetDevicePathSize (OutDevicePath),\r
                     OutDevicePath\r
                     );\r
@@ -346,7 +346,7 @@ Var_UpdateAllConsoleOption (
     Status = gRT->SetVariable (\r
                     L"ConIn",\r
                     &gEfiGlobalVariableGuid,\r
-                    VAR_FLAG,\r
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
                     GetDevicePathSize (InpDevicePath),\r
                     InpDevicePath\r
                     );\r
@@ -358,7 +358,7 @@ Var_UpdateAllConsoleOption (
     Status = gRT->SetVariable (\r
                     L"ErrOut",\r
                     &gEfiGlobalVariableGuid,\r
-                    VAR_FLAG,\r
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
                     GetDevicePathSize (ErrDevicePath),\r
                     ErrDevicePath\r
                     );\r
@@ -461,7 +461,7 @@ Var_UpdateConsoleOption (
     Status = gRT->SetVariable (\r
                     ConsoleName,\r
                     &gEfiGlobalVariableGuid,\r
-                    VAR_FLAG,\r
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
                     GetDevicePathSize (ConDevicePath),\r
                     ConDevicePath\r
                     );\r
@@ -663,7 +663,7 @@ Var_UpdateDriverOption (
   Status = gRT->SetVariable (\r
                   DriverString,\r
                   &gEfiGlobalVariableGuid,\r
-                  VAR_FLAG,\r
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
                   BufferSize,\r
                   Buffer\r
                   );\r
@@ -684,7 +684,7 @@ Var_UpdateDriverOption (
   Status = gRT->SetVariable (\r
                   L"DriverOrder",\r
                   &gEfiGlobalVariableGuid,\r
-                  VAR_FLAG,\r
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
                   DriverOrderListSize + sizeof (UINT16),\r
                   NewDriverOrderList\r
                   );\r
@@ -831,7 +831,7 @@ Var_UpdateBootOption (
   Status = gRT->SetVariable (\r
                   BootString,\r
                   &gEfiGlobalVariableGuid,\r
-                  VAR_FLAG,\r
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
                   BufferSize,\r
                   Buffer\r
                   );\r
@@ -855,7 +855,7 @@ Var_UpdateBootOption (
   Status = gRT->SetVariable (\r
                   L"BootOrder",\r
                   &gEfiGlobalVariableGuid,\r
-                  VAR_FLAG,\r
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
                   BootOrderListSize + sizeof (UINT16),\r
                   NewBootOrderList\r
                   );\r
@@ -920,7 +920,7 @@ Var_UpdateBootNext (
   Status = gRT->SetVariable (\r
                   L"BootNext",\r
                   &gEfiGlobalVariableGuid,\r
-                  VAR_FLAG,\r
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
                   sizeof (UINT16),\r
                   &NewMenuEntry->OptionNumber\r
                   );\r
@@ -980,20 +980,17 @@ Var_UpdateBootOrder (
     }\r
   }\r
 \r
-  GroupMultipleLegacyBootOption4SameType (\r
-    BootOrderList,\r
-    BootOrderListSize / sizeof (UINT16)\r
-    );\r
-\r
   Status = gRT->SetVariable (\r
                   L"BootOrder",\r
                   &gEfiGlobalVariableGuid,\r
-                  VAR_FLAG,\r
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
                   BootOrderListSize,\r
                   BootOrderList\r
                   );\r
   FreePool (BootOrderList);\r
 \r
+  GroupMultipleLegacyBootOption4SameType ();\r
+\r
   BOpt_FreeMenu (&BootOptionMenu);\r
   BOpt_GetBootOptions (CallbackData);\r
 \r
@@ -1057,7 +1054,7 @@ Var_UpdateDriverOrder (
   Status = gRT->SetVariable (\r
                   L"DriverOrder",\r
                   &gEfiGlobalVariableGuid,\r
-                  VAR_FLAG,\r
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
                   DriverOrderListSize,\r
                   NewDriverOrderList\r
                   );\r
@@ -1108,7 +1105,6 @@ Var_UpdateBBSOption (
   UINTN                       EnBootOptionCount;\r
   UINT16                      *DisBootOption;\r
   UINTN                       DisBootOptionCount;\r
-  UINT16                      *BootOrder;\r
 \r
   DisMap              = NULL;\r
   NewOrder            = NULL;\r
@@ -1219,7 +1215,7 @@ Var_UpdateBBSOption (
   Status = gRT->SetVariable (\r
                   VAR_LEGACY_DEV_ORDER,\r
                   &gEfiLegacyDevOrderVariableGuid,\r
-                  VAR_FLAG,\r
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
                   VarSize,\r
                   OriginalPtr\r
                   );\r
@@ -1231,39 +1227,15 @@ Var_UpdateBBSOption (
   // 1. Re-order the Option Number in BootOrder according to Legacy Dev Order\r
   //\r
   ASSERT (OptionMenu->MenuNumber == DevOrder->Length / sizeof (UINT16) - 1);\r
-  BootOrder = BdsLibGetVariableAndSize (\r
-                L"BootOrder",\r
-                &gEfiGlobalVariableGuid,\r
-                &VarSize\r
-                );\r
-  ASSERT (BootOrder != NULL);\r
-\r
-  DisBootOption = AllocatePool (VarSize);\r
-  ASSERT (DisBootOption != NULL);\r
-  EnBootOption  = AllocatePool (VarSize);\r
-  ASSERT (EnBootOption  != NULL);\r
-  \r
+\r
   OrderLegacyBootOption4SameType (\r
-    BootOrder,\r
-    VarSize / sizeof (UINT16),\r
     DevOrder->Data,\r
     DevOrder->Length / sizeof (UINT16) - 1,\r
-    EnBootOption,\r
+    &EnBootOption,\r
     &EnBootOptionCount,\r
-    DisBootOption,\r
+    &DisBootOption,\r
     &DisBootOptionCount\r
     );\r
-  \r
-  Status = gRT->SetVariable (\r
-                    L"BootOrder",\r
-                    &gEfiGlobalVariableGuid,\r
-                    VAR_FLAG,\r
-                    VarSize,\r
-                    BootOrder\r
-                    );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  FreePool (BootOrder);\r
 \r
   //\r
   // 2. Deactivate the DisBootOption and activate the EnBootOption\r
@@ -1282,7 +1254,7 @@ Var_UpdateBBSOption (
       Status = gRT->SetVariable (\r
                       VarName,\r
                       &gEfiGlobalVariableGuid,\r
-                      VAR_FLAG,\r
+                      EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
                       OptionSize,\r
                       BootOptionVar\r
                       );\r
@@ -1305,7 +1277,7 @@ Var_UpdateBBSOption (
       Status = gRT->SetVariable (\r
                       VarName,\r
                       &gEfiGlobalVariableGuid,\r
-                      VAR_FLAG,\r
+                      EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
                       OptionSize,\r
                       BootOptionVar\r
                       );\r
index a838c2ff7eca0b7d3fc70adc3d38efd28e557ff0..dc1364899ea3b0f7187a5814de60ebd51f52849c 100644 (file)
@@ -232,6 +232,14 @@ CallBootManager (
 \r
   BdsLibEnumerateAllBootOption (&mBootOptionsList);\r
 \r
+  //\r
+  // Group the legacy boot options for the same device type\r
+  //\r
+  GroupMultipleLegacyBootOption4SameType ();\r
+\r
+  InitializeListHead (&mBootOptionsList);\r
+  BdsLibBuildOptionFromVar (&mBootOptionsList, L"BootOrder");\r
+\r
   HiiHandle = gBootManagerPrivate.HiiHandle;\r
 \r
   //\r
@@ -268,9 +276,9 @@ CallBootManager (
     mKeyInput++;\r
 \r
     //\r
-    // Don't display the boot option marked as LOAD_OPTION_HIDDEN\r
+    // Don't display the hidden/inactive boot option\r
     //\r
-    if ((Option->Attribute & LOAD_OPTION_HIDDEN) != 0) {\r
+    if (((Option->Attribute & LOAD_OPTION_HIDDEN) != 0) || ((Option->Attribute & LOAD_OPTION_ACTIVE) == 0)) {\r
       continue;\r
     }\r
 \r