]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.c
BDS enhancement: enumerate & show all legacy boot options in Boot Manager so that...
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMaint / BBSsupport.c
index b70c2c36bc4f7059626ebbb9d0dadc1aefe98f6c..4a3fc46acf15be149c79a886c3bbfc3137339cff 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 - 2009, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2011, 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,6 +16,9 @@ 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
@@ -157,7 +160,7 @@ BdsBuildLegacyDevNameString (
   // 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) {\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
@@ -198,7 +201,7 @@ BdsCreateLegacyBootOption (
   EFI_STATUS           Status;\r
   UINT16               CurrentBootOptionNo;\r
   UINT16               BootString[10];\r
-  UINT16               BootDesc[100];\r
+  CHAR16               BootDesc[100];\r
   CHAR8                HelpString[100];\r
   UINT16               *NewBootOrderList;\r
   UINTN                BufferSize;\r
@@ -246,7 +249,7 @@ BdsCreateLegacyBootOption (
   //\r
   // Create new BBS device path node with description string\r
   //\r
-  UnicodeStrToAsciiStr ((CONST CHAR16*)&BootDesc, (CHAR8*)&HelpString);\r
+  UnicodeStrToAsciiStr (BootDesc, HelpString);\r
 \r
   StringLen = AsciiStrLen (HelpString);\r
   NewBbsDevPathNode = AllocateZeroPool (sizeof (BBS_BBS_DEVICE_PATH) + StringLen);\r
@@ -393,6 +396,164 @@ BdsIsLegacyBootOption (
   return Ret;\r
 }\r
 \r
+/**\r
+  Re-order the Boot Option according to the DevOrder.\r
+\r
+  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 EnBootOptionCount  Count of the enabled Boot Option Numbers\r
+  @param DisBootOption      Pointer to buffer receiving 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
+  UINTN                    *EnBootOptionCount,\r
+  UINT16                   *DisBootOption,\r
+  UINTN                    *DisBootOptionCount\r
+  )\r
+{\r
+  UINTN                    Index;\r
+  UINTN                    MappingIndex;\r
+  UINT16                   *NewBootOption;\r
+  UINT16                   BbsType;\r
+  \r
+  *DisBootOptionCount = 0;\r
+  *EnBootOptionCount  = 0;\r
+  BbsType             = 0;\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
+  NewBootOption = AllocatePool (DevOrderCount * sizeof (UINT16));\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
+        \r
+        if ((DevOrder[DevOrderCount] & 0xFF00) == 0xFF00) {\r
+          DisBootOption[*DisBootOptionCount] = NewBootOption[DevOrderCount];\r
+          (*DisBootOptionCount)++;\r
+        } else {\r
+          EnBootOption[*EnBootOptionCount] = NewBootOption[DevOrderCount];\r
+          (*EnBootOptionCount)++;\r
+        }\r
+        break;\r
+      }\r
+    }\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
+    //\r
+    // Overwrite the old BootOption\r
+    //\r
+    if (MappingIndex < mBootOptionBbsMappingCount) {\r
+      CopyMem (&BootOption[Index], NewBootOption, (*DisBootOptionCount + *EnBootOptionCount) * sizeof (UINT16));\r
+      break;\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Group the legacy boot options in the BootOption.\r
+\r
+  The routine assumes the boot options in the beginning that covers all the device \r
+  types are ordered properly and re-position the following boot options just after\r
+  the corresponding boot options with the same device type.\r
+  For example:\r
+  1. Input  = [Harddisk1 CdRom2 Efi1 Harddisk0 CdRom0 CdRom1 Harddisk2 Efi0]\r
+     Assuming [Harddisk1 CdRom2 Efi1] is ordered properly\r
+     Output = [Harddisk1 Harddisk0 Harddisk2 CdRom2 CdRom0 CdRom1 Efi1 Efi0]\r
+\r
+  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
+  )\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
@@ -450,8 +611,8 @@ BdsDeleteAllInvalidLegacyBootOptions (
                 &gEfiGlobalVariableGuid,\r
                 &BootOrderSize\r
                 );\r
-  if (NULL == BootOrder) {\r
-    return EFI_NOT_FOUND;\r
+  if (BootOrder == NULL) {\r
+    BootOrderSize = 0;\r
   }\r
 \r
   Index = 0;\r
@@ -463,14 +624,32 @@ BdsDeleteAllInvalidLegacyBootOptions (
                       &BootOptionSize\r
                       );\r
     if (NULL == BootOptionVar) {\r
-      if (BootOrder != NULL) {\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
-      return EFI_OUT_OF_RESOURCES;\r
     }\r
   \r
     //\r
-    // Skip Non-Legacy boot options\r
+    // Skip Non-Legacy boot option\r
     // \r
     if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, &BbsIndex)) {\r
       if (BootOptionVar!= NULL) {\r
@@ -480,28 +659,29 @@ BdsDeleteAllInvalidLegacyBootOptions (
       continue;\r
     }\r
 \r
-    //\r
-    // Check if BBS Description String is changed\r
-    //\r
-    DescStringMatch = FALSE;\r
-\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
+    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
+      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
@@ -545,6 +725,7 @@ BdsDeleteAllInvalidLegacyBootOptions (
   @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
@@ -554,18 +735,18 @@ BdsDeleteAllInvalidLegacyBootOptions (
 \r
 **/\r
 BOOLEAN\r
-BdsFindLegacyBootOptionByDevType (\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 UINT                *OptionNumber\r
+  OUT UINT16                *OptionNumber\r
   )\r
 {\r
   UINTN     Index;\r
-  UINTN     BootOrderIndex;\r
-  UINT16    BootOption[100];\r
+  CHAR16    BootOption[9];\r
   UINTN     BootOptionSize;\r
   UINT8     *BootOptionVar;\r
   BBS_TABLE *BbsEntry;\r
@@ -581,9 +762,8 @@ BdsFindLegacyBootOptionByDevType (
   //\r
   // Loop all boot option from variable\r
   //\r
-  for (BootOrderIndex = 0; BootOrderIndex < BootOptionNum; BootOrderIndex++) {\r
-    Index = (UINTN) BootOrder[BootOrderIndex];\r
-    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", Index);\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
@@ -601,13 +781,16 @@ BdsFindLegacyBootOptionByDevType (
       continue;\r
     }\r
 \r
-    if (BbsEntry->DeviceType != DevType) {\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 = Index;\r
+    *OptionNumber = BootOrder[Index];\r
     Found         = TRUE;\r
     FreePool (BootOptionVar);\r
     break;\r
@@ -692,18 +875,18 @@ BdsAddNonExistingLegacyBootOptions (
   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
-  UINT                    Index;\r
+  UINT16                    Index;\r
   UINT32                    Attribute;\r
-  UINT                    OptionNumber;\r
-  BOOLEAN                   Ret;\r
+  UINT16                    OptionNumber;\r
+  BOOLEAN                   Exist;\r
 \r
-  BootOrder     = NULL;\r
   HddCount      = 0;\r
   BbsCount      = 0;\r
   LocalHddInfo  = NULL;\r
@@ -714,6 +897,13 @@ BdsAddNonExistingLegacyBootOptions (
     return Status;\r
   }\r
 \r
+  if (mBootOptionBbsMapping != NULL) {\r
+    FreePool (mBootOptionBbsMapping);\r
+\r
+    mBootOptionBbsMapping      = NULL;\r
+    mBootOptionBbsMappingCount = 0;\r
+  }\r
+\r
   LegacyBios->GetBbsInfo (\r
                 LegacyBios,\r
                 &HddCount,\r
@@ -727,7 +917,7 @@ BdsAddNonExistingLegacyBootOptions (
                 &gEfiGlobalVariableGuid,\r
                 &BootOrderSize\r
                 );\r
-  if (NULL == BootOrder) {\r
+  if (BootOrder == NULL) {\r
     BootOrderSize = 0;\r
   }\r
 \r
@@ -738,33 +928,59 @@ BdsAddNonExistingLegacyBootOptions (
       continue;\r
     }\r
 \r
-    Ret = BdsFindLegacyBootOptionByDevType (\r
-            BootOrder,\r
-            BootOrderSize / sizeof (UINT16),\r
-            LocalBbsTable[Index].DeviceType,\r
-            &Attribute,\r
-            &BbsIndex,\r
-            &OptionNumber\r
-            );\r
-    if (Ret) {\r
-      continue;\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
-    // 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
+    // Save the BbsIndex\r
     //\r
-    Status = BdsCreateOneLegacyBootOption (\r
-              &LocalBbsTable[Index],\r
-              Index,\r
-              &BootOrder,\r
-              &BootOrderSize\r
-              );\r
-    if (EFI_ERROR (Status)) {\r
-      break;\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
@@ -800,7 +1016,7 @@ BdsFillDevOrderBuf (
   IN BBS_TABLE                    *BbsTable,\r
   IN BBS_TYPE                     BbsType,\r
   IN UINTN                        BbsCount,\r
-  OUT UINT16                       *Buf\r
+  OUT UINT16                      *Buf\r
   )\r
 {\r
   UINTN Index;\r
@@ -840,17 +1056,17 @@ BdsCreateDevOrder (
   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
-  UINT8       *DevOrder;\r
-  UINT8       *Ptr;\r
-  EFI_STATUS  Status;\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
+  BM_LEGACY_DEV_ORDER_CONTEXT *DevOrder;\r
+  BM_LEGACY_DEV_ORDER_CONTEXT *DevOrderPtr;\r
+  EFI_STATUS                  Status;\r
 \r
   FDCount     = 0;\r
   HDCount     = 0;\r
@@ -860,7 +1076,6 @@ BdsCreateDevOrder (
   TotalSize   = 0;\r
   HeaderSize  = sizeof (BBS_TYPE) + sizeof (UINT16);\r
   DevOrder    = NULL;\r
-  Ptr         = NULL;\r
   Status      = EFI_SUCCESS;\r
 \r
   //\r
@@ -910,48 +1125,29 @@ BdsCreateDevOrder (
   if (NULL == DevOrder) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
+  DevOrderPtr          = DevOrder;\r
 \r
-  Ptr                 = DevOrder;\r
-\r
-  *((BBS_TYPE *) Ptr) = BBS_FLOPPY;\r
-  Ptr += sizeof (BBS_TYPE);\r
-  *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16));\r
-  Ptr += sizeof (UINT16);\r
-  if (FDCount != 0) {\r
-    Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_FLOPPY, BbsCount, (UINT16 *) Ptr);\r
-  }\r
-\r
-  *((BBS_TYPE *) Ptr) = BBS_HARDDISK;\r
-  Ptr += sizeof (BBS_TYPE);\r
-  *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));\r
-  Ptr += sizeof (UINT16);\r
-  if (HDCount != 0) {\r
-    Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_HARDDISK, BbsCount, (UINT16 *) Ptr);\r
-  }\r
+  DevOrderPtr->BbsType = BBS_FLOPPY;\r
+  DevOrderPtr->Length  = (UINT16) (sizeof (DevOrderPtr->Length) + FDCount * sizeof (UINT16));\r
+  DevOrderPtr          = (BM_LEGACY_DEV_ORDER_CONTEXT *) BdsFillDevOrderBuf (BbsTable, BBS_FLOPPY, BbsCount, DevOrderPtr->Data);\r
 \r
-  *((BBS_TYPE *) Ptr) = BBS_CDROM;\r
-  Ptr += sizeof (BBS_TYPE);\r
-  *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));\r
-  Ptr += sizeof (UINT16);\r
-  if (CDCount != 0) {\r
-    Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_CDROM, BbsCount, (UINT16 *) Ptr);\r
-  }\r
+  DevOrderPtr->BbsType = BBS_HARDDISK;\r
+  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));\r
+  DevOrderPtr          = (BM_LEGACY_DEV_ORDER_CONTEXT *) BdsFillDevOrderBuf (BbsTable, BBS_HARDDISK, BbsCount, DevOrderPtr->Data);\r
+  \r
+  DevOrderPtr->BbsType = BBS_CDROM;\r
+  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));\r
+  DevOrderPtr          = (BM_LEGACY_DEV_ORDER_CONTEXT *) 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          = (BM_LEGACY_DEV_ORDER_CONTEXT *) BdsFillDevOrderBuf (BbsTable, BBS_EMBED_NETWORK, BbsCount, DevOrderPtr->Data);\r
 \r
-  *((BBS_TYPE *) Ptr) = BBS_EMBED_NETWORK;\r
-  Ptr += sizeof (BBS_TYPE);\r
-  *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));\r
-  Ptr += sizeof (UINT16);\r
-  if (NETCount != 0) {\r
-    Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_EMBED_NETWORK, BbsCount, (UINT16 *) Ptr);\r
-  }\r
+  DevOrderPtr->BbsType = BBS_BEV_DEVICE;\r
+  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));\r
+  DevOrderPtr          = (BM_LEGACY_DEV_ORDER_CONTEXT *) BdsFillDevOrderBuf (BbsTable, BBS_BEV_DEVICE, BbsCount, DevOrderPtr->Data);\r
 \r
-  *((BBS_TYPE *) Ptr) = BBS_BEV_DEVICE;\r
-  Ptr += sizeof (BBS_TYPE);\r
-  *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));\r
-  Ptr += sizeof (UINT16);\r
-  if (BEVCount != 0) {\r
-    Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_BEV_DEVICE, BbsCount, (UINT16 *) Ptr);\r
-  }\r
+  ASSERT (TotalSize == (UINTN) ((UINT8 *) DevOrderPtr - (UINT8 *) DevOrder));\r
 \r
   //\r
   // Save device order for legacy boot device to variable.\r
@@ -984,43 +1180,39 @@ BdsUpdateLegacyDevOrder (
   VOID\r
   )\r
 {\r
-  UINT8                     *DevOrder;\r
-  UINT8                     *NewDevOrder;\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
-  UINT8                     *Ptr;\r
-  UINT8                     *NewPtr;\r
-  UINT16                    *NewFDPtr;\r
-  UINT16                    *NewHDPtr;\r
-  UINT16                    *NewCDPtr;\r
-  UINT16                    *NewNETPtr;\r
-  UINT16                    *NewBEVPtr;\r
-  UINT16                    *NewDevPtr;\r
-  UINT16                    Length;\r
-  UINT16                    Tmp;\r
-  UINTN                     FDIndex;\r
-  UINTN                     HDIndex;\r
-  UINTN                     CDIndex;\r
-  UINTN                     NETIndex;\r
-  UINTN                     BEVIndex;\r
+  BM_LEGACY_DEV_ORDER_CONTEXT *DevOrder;\r
+  BM_LEGACY_DEV_ORDER_CONTEXT *NewDevOrder;\r
+  BM_LEGACY_DEV_ORDER_CONTEXT *Ptr;\r
+  BM_LEGACY_DEV_ORDER_CONTEXT *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
-  LocalHddInfo  = NULL;\r
-  LocalBbsTable = NULL;\r
   Idx           = NULL;\r
   FDCount       = 0;\r
   HDCount       = 0;\r
@@ -1041,19 +1233,22 @@ BdsUpdateLegacyDevOrder (
     return Status;\r
   }\r
 \r
-  LegacyBios->GetBbsInfo (\r
-                LegacyBios,\r
-                &HddCount,\r
-                &LocalHddInfo,\r
-                &BbsCount,\r
-                &LocalBbsTable\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 = (UINT8 *) BdsLibGetVariableAndSize (\r
-                        VAR_LEGACY_DEV_ORDER,\r
-                        &EfiLegacyDevOrderGuid,\r
-                        &DevOrderSize\r
-                        );\r
+  DevOrder = BdsLibGetVariableAndSize (\r
+               VAR_LEGACY_DEV_ORDER,\r
+               &EfiLegacyDevOrderGuid,\r
+               &DevOrderSize\r
+               );\r
   if (NULL == DevOrder) {\r
     return BdsCreateDevOrder (LocalBbsTable, BbsCount);\r
   }\r
@@ -1104,137 +1299,111 @@ BdsUpdateLegacyDevOrder (
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  NewFDPtr  = (UINT16 *) (NewDevOrder + HeaderSize);\r
-  NewHDPtr  = (UINT16 *) ((UINT8 *) NewFDPtr + FDCount * sizeof (UINT16) + HeaderSize);\r
-  NewCDPtr  = (UINT16 *) ((UINT8 *) NewHDPtr + HDCount * sizeof (UINT16) + HeaderSize);\r
-  NewNETPtr = (UINT16 *) ((UINT8 *) NewCDPtr + CDCount * sizeof (UINT16) + HeaderSize);\r
-  NewBEVPtr = (UINT16 *) ((UINT8 *) NewNETPtr + NETCount * sizeof (UINT16) + HeaderSize);\r
+\r
 \r
   //\r
   // copy FD\r
   //\r
-  Ptr                     = DevOrder;\r
-  NewPtr                  = NewDevOrder;\r
-  *((BBS_TYPE *) NewPtr)  = *((BBS_TYPE *) Ptr);\r
-  Ptr += sizeof (BBS_TYPE);\r
-  NewPtr += sizeof (BBS_TYPE);\r
-  Length                = *((UINT16 *) Ptr);\r
-  *((UINT16 *) NewPtr)  = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16));\r
-  Ptr += sizeof (UINT16);\r
-\r
-  for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {\r
-    if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||\r
-        LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
-        LocalBbsTable[*Ptr].DeviceType != BBS_FLOPPY\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
-      Ptr += sizeof (UINT16);\r
       continue;\r
     }\r
 \r
-    NewFDPtr[FDIndex] = *(UINT16 *) Ptr;\r
+    NewPtr->Data[FDIndex] = Ptr->Data[Index];\r
     FDIndex++;\r
-    Ptr += sizeof (UINT16);\r
   }\r
+  NewFDPtr = NewPtr->Data;\r
+\r
   //\r
   // copy HD\r
   //\r
-  NewPtr                  = (UINT8 *) NewHDPtr - HeaderSize;\r
-  *((BBS_TYPE *) NewPtr)  = *((BBS_TYPE *) Ptr);\r
-  Ptr += sizeof (BBS_TYPE);\r
-  NewPtr += sizeof (BBS_TYPE);\r
-  Length                = *((UINT16 *) Ptr);\r
-  *((UINT16 *) NewPtr)  = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));\r
-  Ptr += sizeof (UINT16);\r
-\r
-  for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {\r
-    if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||\r
-        LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
-        LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||\r
-        LocalBbsTable[*Ptr].DeviceType != BBS_HARDDISK\r
+  Ptr             = (BM_LEGACY_DEV_ORDER_CONTEXT *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);\r
+  NewPtr          = (BM_LEGACY_DEV_ORDER_CONTEXT *) (&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
-      Ptr += sizeof (UINT16);\r
       continue;\r
     }\r
 \r
-    NewHDPtr[HDIndex] = *(UINT16 *) Ptr;\r
+    NewPtr->Data[HDIndex] = Ptr->Data[Index];\r
     HDIndex++;\r
-    Ptr += sizeof (UINT16);\r
   }\r
+  NewHDPtr = NewPtr->Data;\r
+\r
   //\r
   // copy CD\r
   //\r
-  NewPtr                  = (UINT8 *) NewCDPtr - HeaderSize;\r
-  *((BBS_TYPE *) NewPtr)  = *((BBS_TYPE *) Ptr);\r
-  Ptr += sizeof (BBS_TYPE);\r
-  NewPtr += sizeof (BBS_TYPE);\r
-  Length                = *((UINT16 *) Ptr);\r
-  *((UINT16 *) NewPtr)  = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));\r
-  Ptr += sizeof (UINT16);\r
-\r
-  for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {\r
-    if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||\r
-        LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
-        LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||\r
-        LocalBbsTable[*Ptr].DeviceType != BBS_CDROM\r
+  Ptr    = (BM_LEGACY_DEV_ORDER_CONTEXT *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);\r
+  NewPtr = (BM_LEGACY_DEV_ORDER_CONTEXT *) (&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
-      Ptr += sizeof (UINT16);\r
       continue;\r
     }\r
 \r
-    NewCDPtr[CDIndex] = *(UINT16 *) Ptr;\r
+    NewPtr->Data[CDIndex] = Ptr->Data[Index];\r
     CDIndex++;\r
-    Ptr += sizeof (UINT16);\r
   }\r
+  NewCDPtr = NewPtr->Data;\r
+\r
   //\r
   // copy NET\r
   //\r
-  NewPtr                  = (UINT8 *) NewNETPtr - HeaderSize;\r
-  *((BBS_TYPE *) NewPtr)  = *((BBS_TYPE *) Ptr);\r
-  Ptr += sizeof (BBS_TYPE);\r
-  NewPtr += sizeof (BBS_TYPE);\r
-  Length                = *((UINT16 *) Ptr);\r
-  *((UINT16 *) NewPtr)  = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));\r
-  Ptr += sizeof (UINT16);\r
-\r
-  for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {\r
-    if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||\r
-        LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
-        LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||\r
-        LocalBbsTable[*Ptr].DeviceType != BBS_EMBED_NETWORK\r
+  Ptr    = (BM_LEGACY_DEV_ORDER_CONTEXT *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);\r
+  NewPtr = (BM_LEGACY_DEV_ORDER_CONTEXT *) (&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
-      Ptr += sizeof (UINT16);\r
       continue;\r
     }\r
 \r
-    NewNETPtr[NETIndex] = *(UINT16 *) Ptr;\r
+    NewPtr->Data[NETIndex] = Ptr->Data[Index];\r
     NETIndex++;\r
-    Ptr += sizeof (UINT16);\r
   }\r
+  NewNETPtr = NewPtr->Data;\r
+  \r
   //\r
   // copy BEV\r
   //\r
-  NewPtr                  = (UINT8 *) NewBEVPtr - HeaderSize;\r
-  *((BBS_TYPE *) NewPtr)  = *((BBS_TYPE *) Ptr);\r
-  Ptr += sizeof (BBS_TYPE);\r
-  NewPtr += sizeof (BBS_TYPE);\r
-  Length                = *((UINT16 *) Ptr);\r
-  *((UINT16 *) NewPtr)  = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));\r
-  Ptr += sizeof (UINT16);\r
-\r
-  for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {\r
-    if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||\r
-        LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
-        LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||\r
-        LocalBbsTable[*Ptr].DeviceType != BBS_BEV_DEVICE\r
+  Ptr    = (BM_LEGACY_DEV_ORDER_CONTEXT *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);\r
+  NewPtr = (BM_LEGACY_DEV_ORDER_CONTEXT *) (&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
-      Ptr += sizeof (UINT16);\r
       continue;\r
     }\r
 \r
-    NewBEVPtr[BEVIndex] = *(UINT16 *) Ptr;\r
+    NewPtr->Data[BEVIndex] = Ptr->Data[Index];\r
     BEVIndex++;\r
-    Ptr += sizeof (UINT16);\r
   }\r
+  NewBEVPtr = NewPtr->Data;\r
 \r
   for (Index = 0; Index < BbsCount; Index++) {\r
     if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||\r
@@ -1277,7 +1446,7 @@ BdsUpdateLegacyDevOrder (
     // 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 != 0) {\r
+    if (Idx != NULL) {\r
       for (Index2 = 0; Index2 < *Idx; Index2++) {\r
         if ((NewDevPtr[Index2] & 0xFF) == (UINT16) Index) {\r
           break;\r
@@ -1288,110 +1457,16 @@ BdsUpdateLegacyDevOrder (
         //\r
         // Index2 == *Idx means we didn't find Index\r
         // so Index is a new appeared device's index in BBS table\r
-        // save it.\r
+        // insert it before disabled indexes.\r
         //\r
-        NewDevPtr[*Idx] = (UINT16) (Index & 0xFF);\r
-        (*Idx)++;\r
-      }\r
-    }\r
-  }\r
-\r
-  if (FDCount != 0) {\r
-    //\r
-    // Just to make sure that disabled indexes are all at the end of the array\r
-    //\r
-    for (Index = 0; Index < FDIndex - 1; Index++) {\r
-      if (0xFF00 != (NewFDPtr[Index] & 0xFF00)) {\r
-        continue;\r
-      }\r
-\r
-      for (Index2 = Index + 1; Index2 < FDIndex; Index2++) {\r
-        if (0 == (NewFDPtr[Index2] & 0xFF00)) {\r
-          Tmp               = NewFDPtr[Index];\r
-          NewFDPtr[Index]   = NewFDPtr[Index2];\r
-          NewFDPtr[Index2]  = Tmp;\r
-          break;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  if (HDCount != 0) {\r
-    //\r
-    // Just to make sure that disabled indexes are all at the end of the array\r
-    //\r
-    for (Index = 0; Index < HDIndex - 1; Index++) {\r
-      if (0xFF00 != (NewHDPtr[Index] & 0xFF00)) {\r
-        continue;\r
-      }\r
-\r
-      for (Index2 = Index + 1; Index2 < HDIndex; Index2++) {\r
-        if (0 == (NewHDPtr[Index2] & 0xFF00)) {\r
-          Tmp               = NewHDPtr[Index];\r
-          NewHDPtr[Index]   = NewHDPtr[Index2];\r
-          NewHDPtr[Index2]  = Tmp;\r
-          break;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  if (CDCount != 0) {\r
-    //\r
-    // Just to make sure that disabled indexes are all at the end of the array\r
-    //\r
-    for (Index = 0; Index < CDIndex - 1; Index++) {\r
-      if (0xFF00 != (NewCDPtr[Index] & 0xFF00)) {\r
-        continue;\r
-      }\r
-\r
-      for (Index2 = Index + 1; Index2 < CDIndex; Index2++) {\r
-        if (0 == (NewCDPtr[Index2] & 0xFF00)) {\r
-          Tmp               = NewCDPtr[Index];\r
-          NewCDPtr[Index]   = NewCDPtr[Index2];\r
-          NewCDPtr[Index2]  = Tmp;\r
-          break;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  if (NETCount != 0) {\r
-    //\r
-    // Just to make sure that disabled indexes are all at the end of the array\r
-    //\r
-    for (Index = 0; Index < NETIndex - 1; Index++) {\r
-      if (0xFF00 != (NewNETPtr[Index] & 0xFF00)) {\r
-        continue;\r
-      }\r
-\r
-      for (Index2 = Index + 1; Index2 < NETIndex; Index2++) {\r
-        if (0 == (NewNETPtr[Index2] & 0xFF00)) {\r
-          Tmp               = NewNETPtr[Index];\r
-          NewNETPtr[Index]  = NewNETPtr[Index2];\r
-          NewNETPtr[Index2] = Tmp;\r
-          break;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  if (BEVCount!= 0) {\r
-    //\r
-    // Just to make sure that disabled indexes are all at the end of the array\r
-    //\r
-    for (Index = 0; Index < BEVIndex - 1; Index++) {\r
-      if (0xFF00 != (NewBEVPtr[Index] & 0xFF00)) {\r
-        continue;\r
-      }\r
-\r
-      for (Index2 = Index + 1; Index2 < BEVIndex; Index2++) {\r
-        if (0 == (NewBEVPtr[Index2] & 0xFF00)) {\r
-          Tmp               = NewBEVPtr[Index];\r
-          NewBEVPtr[Index]  = NewBEVPtr[Index2];\r
-          NewBEVPtr[Index2] = Tmp;\r
-          break;\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
@@ -1414,6 +1489,7 @@ BdsUpdateLegacyDevOrder (
   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
@@ -1425,60 +1501,58 @@ BdsUpdateLegacyDevOrder (
 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
-  UINT8   *DevOrder;\r
-\r
-  UINT8   *OrigBuffer;\r
-  UINT16  *DevIndex;\r
-  UINTN   DevOrderSize;\r
-  UINTN   DevCount;\r
-  UINTN   Index;\r
+  BM_LEGACY_DEV_ORDER_CONTEXT *DevOrder;\r
+  BM_LEGACY_DEV_ORDER_CONTEXT *DevOrderPtr;\r
+  UINTN                       DevOrderSize;\r
+  UINTN                       Index;\r
 \r
   DevOrder = BdsLibGetVariableAndSize (\r
-              VAR_LEGACY_DEV_ORDER,\r
-              &EfiLegacyDevOrderGuid,\r
-              &DevOrderSize\r
-              );\r
+               VAR_LEGACY_DEV_ORDER,\r
+               &EfiLegacyDevOrderGuid,\r
+               &DevOrderSize\r
+               );\r
   if (NULL == DevOrder) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  OrigBuffer = DevOrder;\r
-  while (DevOrder < OrigBuffer + DevOrderSize) {\r
-    if (DeviceType == * (BBS_TYPE *) DevOrder) {\r
+  DevOrderPtr = DevOrder;\r
+  while ((UINT8 *) DevOrderPtr < (UINT8 *) DevOrder + DevOrderSize) {\r
+    if (DevOrderPtr->BbsType == DeviceType) {\r
       break;\r
     }\r
 \r
-    DevOrder += sizeof (BBS_TYPE);\r
-    DevOrder += *(UINT16 *) DevOrder;\r
+    DevOrderPtr = (BM_LEGACY_DEV_ORDER_CONTEXT *) ((UINT8 *) DevOrderPtr + sizeof (BBS_TYPE) + DevOrderPtr->Length);\r
   }\r
 \r
-  if (DevOrder >= OrigBuffer + DevOrderSize) {\r
-    FreePool (OrigBuffer);\r
+  if ((UINT8 *) DevOrderPtr >= (UINT8 *) DevOrder + DevOrderSize) {\r
+    FreePool (DevOrder);\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
-  DevOrder += sizeof (BBS_TYPE);\r
-  DevCount  = (*((UINT16 *) DevOrder) - sizeof (UINT16)) / sizeof (UINT16);\r
-  DevIndex  = (UINT16 *) (DevOrder + sizeof (UINT16));\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 < DevCount; Index++) {\r
-    if ((DevIndex[Index] & 0xFF00) == 0xFF00) {\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 {\r
-      LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = *Priority;\r
+    } else if (DevOrderPtr->Data[Index] != BbsIndex) {\r
+      LocalBbsTable[DevOrderPtr->Data[Index]].BootPriority = *Priority;\r
       (*Priority)++;\r
     }\r
   }\r
 \r
-  FreePool (OrigBuffer);\r
+  FreePool (DevOrder);\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -1545,6 +1619,7 @@ BdsRefreshBbsTableForBoot (
   )\r
 {\r
   EFI_STATUS                Status;\r
+  UINT16                    BbsIndex;\r
   UINT16                    HddCount;\r
   UINT16                    BbsCount;\r
   HDD_INFO                  *LocalHddInfo;\r
@@ -1557,10 +1632,13 @@ BdsRefreshBbsTableForBoot (
   UINTN                     BootOrderSize;\r
   UINT8                     *BootOptionVar;\r
   UINTN                     BootOptionSize;\r
-  UINT16                    BootOption[100];\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
@@ -1599,9 +1677,11 @@ BdsRefreshBbsTableForBoot (
     //\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
+    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
@@ -1612,11 +1692,16 @@ BdsRefreshBbsTableForBoot (
   //\r
   // we have to set the boot priority for other BBS entries with different device types\r
   //\r
-  BootOrder = (UINT16 *) BdsLibGetVariableAndSize (\r
-                          L"BootOrder",\r
-                          &gEfiGlobalVariableGuid,\r
-                          &BootOrderSize\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
@@ -1641,7 +1726,13 @@ BdsRefreshBbsTableForBoot (
     }\r
 \r
     Ptr += DevPathLen;\r
-    if (DevType == ((BBS_TABLE *) Ptr)->DeviceType) {\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
@@ -1649,8 +1740,12 @@ BdsRefreshBbsTableForBoot (
       continue;\r
     }\r
 \r
+    DeviceType[DeviceTypeCount] = DevType;\r
+    DeviceTypeCount++;\r
+\r
     Status = BdsSetBootPriority4SameTypeDev (\r
-              ((BBS_TABLE *) Ptr)->DeviceType,\r
+              DevType,\r
+              (UINTN) -1,\r
               LocalBbsTable,\r
               &Priority\r
               );\r