]> git.proxmox.com Git - mirror_edk2.git/commitdiff
BDS enhancement: enumerate & show all legacy boot options in Boot Manager so that...
authorniruiyu <niruiyu@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 28 Jan 2011 02:36:26 +0000 (02:36 +0000)
committerniruiyu <niruiyu@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 28 Jan 2011 02:36:26 +0000 (02:36 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11279 6f19259b-4bc3-4df7-8a09-765794883524

IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.c
IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.h
IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c
IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootMaint.h
IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootOption.c
IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/UpdatePage.c
IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/Variable.c
IntelFrameworkModulePkg/Universal/BdsDxe/BootMngr/BootManager.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
index 7418bb2b61724e17cf36dcafdbf256d6ce02f6c3..26d6cb26373d5323127fdd89d56e215fba6c98f9 100644 (file)
@@ -36,4 +36,55 @@ BdsBuildLegacyDevNameString (
   OUT CHAR16                       *BootString\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
+/**\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
 #endif\r
index 6e15e096a68fd33d2635f30f69f68f7c6eda9750..ac09201fb4b415702e71341dc199c199b9a7b8f5 100644 (file)
@@ -1441,59 +1441,3 @@ FormSetDispatcher (
 }\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 bd74fd2a6b622b962104ef12bbe9b778ec18c862..5b3da67d804526551b05c12ea8951e91d36f6ef9 100644 (file)
@@ -252,13 +252,23 @@ typedef struct {
 } 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
+\r
 typedef struct {\r
   BBS_TYPE  BbsType;\r
   ///\r
   /// Length = sizeof (UINT16) + SIZEOF (Data)\r
   ///\r
   UINT16    Length;\r
-  UINT16    *Data;\r
+  UINT16    Data[1];\r
 } BM_LEGACY_DEV_ORDER_CONTEXT;\r
 #pragma pack()\r
 \r
@@ -304,10 +314,10 @@ typedef struct {
 } BM_LOAD_CONTEXT;\r
 \r
 typedef struct {\r
-  BBS_TABLE *BbsTable;\r
-  UINTN     Index;\r
-  UINT    BbsCount;\r
-  UINT16    *Description;\r
+  BBS_TABLE *BbsEntry;\r
+  UINT16    BbsIndex;\r
+  UINT16    BbsCount;\r
+  CHAR16    *Description;\r
 } BM_LEGACY_DEVICE_CONTEXT;\r
 \r
 typedef struct {\r
index 2cfc3b817ae61feb4a6746d4273e1f021046cdc8..37d2350d563753a5839cc468a9224cdec34c55e5 100644 (file)
@@ -5,7 +5,7 @@
 \r
   Boot option manipulation\r
 \r
-Copyright (c) 2004 - 2010, 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
@@ -529,6 +529,7 @@ BOpt_FreeMenu (
     RemoveEntryList (&MenuEntry->Link);\r
     BOpt_DestroyMenuEntry (MenuEntry);\r
   }\r
+  FreeMenu->MenuNumber = 0;\r
 }\r
 \r
 /**\r
@@ -707,7 +708,7 @@ BOpt_GetLegacyOptions (
   HDD_INFO                  *HddInfo;\r
   UINT16                    BbsCount;\r
   BBS_TABLE                 *BbsTable;\r
-  UINT                    Index;\r
+  UINT16                    Index;\r
   CHAR16                    DescString[100];\r
   UINTN                     FDNum;\r
   UINTN                     HDNum;\r
@@ -766,8 +767,8 @@ BOpt_GetLegacyOptions (
     }\r
 \r
     NewLegacyDevContext           = (BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext;\r
-    NewLegacyDevContext->BbsTable = &BbsTable[Index];\r
-    NewLegacyDevContext->Index    = Index;\r
+    NewLegacyDevContext->BbsEntry = &BbsTable[Index];\r
+    NewLegacyDevContext->BbsIndex = Index;\r
     NewLegacyDevContext->BbsCount = BbsCount;\r
     BdsBuildLegacyDevNameString (\r
       &BbsTable[Index],\r
@@ -775,12 +776,11 @@ BOpt_GetLegacyOptions (
       sizeof (DescString),\r
       DescString\r
       );\r
-    NewLegacyDevContext->Description = AllocateZeroPool (StrSize (DescString));\r
+    NewLegacyDevContext->Description = AllocateCopyPool (StrSize (DescString), DescString);\r
     if (NULL == NewLegacyDevContext->Description) {\r
       break;\r
     }\r
 \r
-    CopyMem (NewLegacyDevContext->Description, DescString, StrSize (DescString));\r
     NewMenuEntry->DisplayString = NewLegacyDevContext->Description;\r
     NewMenuEntry->HelpString    = NULL;\r
 \r
index 24a444d24f9576e7167798b97165d9784950e9ab..aaa33600426bc36aa83690ca647c46414b98983a 100644 (file)
@@ -535,10 +535,14 @@ UpdateOrderPage (
   IN BMM_CALLBACK_DATA                *CallbackData\r
   )\r
 {\r
-  BM_MENU_ENTRY *NewMenuEntry;\r
-  UINT16        Index;\r
-  VOID          *OptionsOpCodeHandle;\r
+  BM_MENU_ENTRY   *NewMenuEntry;\r
+  UINT16          Index;\r
+  UINT16          OptionOrderIndex;\r
+  VOID            *OptionsOpCodeHandle;\r
+  UINTN           DeviceType;\r
+  BM_LOAD_CONTEXT *NewLoadContext;\r
 \r
+  DeviceType                    = (UINTN) -1;\r
   CallbackData->BmmAskSaveOrNot = TRUE;\r
 \r
   UpdatePageStart (CallbackData);\r
@@ -551,10 +555,10 @@ UpdateOrderPage (
   ASSERT (OptionsOpCodeHandle != NULL);\r
   \r
   for (\r
-        Index = 0;\r
+        Index = 0, OptionOrderIndex = 0;\r
         (\r
           (Index < OptionMenu->MenuNumber) &&\r
-          (Index <\r
+          (OptionOrderIndex <\r
             (\r
               sizeof (CallbackData->BmmFakeNvData.OptionOrder) /\r
               sizeof (CallbackData->BmmFakeNvData.OptionOrder[0])\r
@@ -563,7 +567,20 @@ UpdateOrderPage (
         );\r
         Index++\r
       ) {\r
-    NewMenuEntry = BOpt_GetMenuEntry (OptionMenu, Index);\r
+    NewMenuEntry   = BOpt_GetMenuEntry (OptionMenu, Index);\r
+    NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
+\r
+    if (NewLoadContext->IsLegacy) {\r
+      if (((BBS_BBS_DEVICE_PATH *) NewLoadContext->FilePathList)->DeviceType != DeviceType) {\r
+        DeviceType = ((BBS_BBS_DEVICE_PATH *) NewLoadContext->FilePathList)->DeviceType;\r
+      } else {\r
+        //\r
+        // Only show one legacy boot option for the same device type\r
+        // assuming the boot options are grouped by the device type\r
+        //\r
+        continue;\r
+      }\r
+    }\r
     HiiCreateOneOfOptionOpCode (\r
       OptionsOpCodeHandle,\r
       NewMenuEntry->DisplayStringToken,\r
@@ -571,7 +588,7 @@ UpdateOrderPage (
       EFI_IFR_TYPE_NUM_SIZE_32,\r
       (UINT32) (NewMenuEntry->OptionNumber + 1)\r
       );\r
-    CallbackData->BmmFakeNvData.OptionOrder[Index] = (UINT32) (NewMenuEntry->OptionNumber + 1);\r
+    CallbackData->BmmFakeNvData.OptionOrder[OptionOrderIndex++] = (UINT32) (NewMenuEntry->OptionNumber + 1);\r
   }\r
 \r
   if (OptionMenu->MenuNumber > 0) {\r
@@ -1241,9 +1258,8 @@ UpdateSetLegacyDeviceOrderPage (
   CallbackData->BmmAskSaveOrNot = TRUE;\r
   UpdatePageStart (CallbackData);\r
 \r
-  DisMap = CallbackData->BmmOldFakeNVData.DisableMap;\r
+  DisMap = ZeroMem (CallbackData->BmmOldFakeNVData.DisableMap, sizeof (CallbackData->BmmOldFakeNVData.DisableMap));\r
 \r
-  SetMem (DisMap, 32, 0);\r
   //\r
   // Create oneof option list\r
   //\r
@@ -1311,19 +1327,19 @@ UpdateSetLegacyDeviceOrderPage (
   for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {\r
     NewMenuEntry                = BOpt_GetMenuEntry (OptionMenu, Index);\r
     //\r
-    // Create OneOf for each legacy device, select the first one by default\r
+    // Create OneOf for each legacy device\r
     //\r
     HiiCreateOneOfOptionOpCode (\r
       OptionsOpCodeHandle,\r
       NewMenuEntry->DisplayStringToken,\r
-      (UINT8) ((Index == 0) ? EFI_IFR_OPTION_DEFAULT : 0),\r
+      0,\r
       EFI_IFR_TYPE_NUM_SIZE_8,\r
-      (UINT8) ((BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext)->Index\r
+      (UINT8) ((BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext)->BbsIndex\r
       );\r
   }\r
 \r
   //\r
-  // for item "Disabled"\r
+  // Create OneOf for item "Disabled"\r
   //\r
   HiiCreateOneOfOptionOpCode (\r
     OptionsOpCodeHandle,\r
index f476b40803efe531a7a981e5eee7bd146be660db..579036fff3028a2a11f5880c39f68f65beda0e23 100644 (file)
@@ -849,7 +849,6 @@ Var_UpdateBootOption (
   NewBootOrderList[BootOrderListSize / sizeof (UINT16)] = Index;\r
 \r
   if (BootOrderList != NULL) {\r
-    EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);\r
     FreePool (BootOrderList);\r
   }\r
 \r
@@ -949,9 +948,10 @@ Var_UpdateBootOrder (
 {\r
   EFI_STATUS  Status;\r
   UINT16      Index;\r
+  UINT16      OrderIndex;\r
   UINT16      *BootOrderList;\r
-  UINT16      *NewBootOrderList;\r
   UINTN       BootOrderListSize;\r
+  UINT16      OptionNumber;\r
 \r
   BootOrderList     = NULL;\r
   BootOrderListSize = 0;\r
@@ -964,41 +964,40 @@ Var_UpdateBootOrder (
                     &gEfiGlobalVariableGuid,\r
                     &BootOrderListSize\r
                     );\r
-\r
-  NewBootOrderList = AllocateZeroPool (BootOrderListSize);\r
-  if (NewBootOrderList == NULL) {\r
+  if (BootOrderList == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  //\r
-  // If exists, delete it to hold new BootOrder\r
-  //\r
-  if (BootOrderList != NULL) {\r
-    EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);\r
-    FreePool (BootOrderList);\r
-  }\r
-\r
   ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.OptionOrder) / sizeof (CallbackData->BmmFakeNvData.OptionOrder[0])));\r
-  for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
-    NewBootOrderList[Index] = (UINT16) (CallbackData->BmmFakeNvData.OptionOrder[Index] - 1);\r
+\r
+  for (OrderIndex = 0; (OrderIndex < BootOptionMenu.MenuNumber) && (CallbackData->BmmFakeNvData.OptionOrder[OrderIndex] != 0); OrderIndex++) {\r
+    for (Index = OrderIndex; Index < BootOrderListSize / sizeof (UINT16); Index++) {\r
+      if ((BootOrderList[Index] == (UINT16) (CallbackData->BmmFakeNvData.OptionOrder[OrderIndex] - 1)) && (OrderIndex != Index)) {\r
+        OptionNumber = BootOrderList[Index];\r
+        CopyMem (&BootOrderList[OrderIndex + 1], &BootOrderList[OrderIndex], (Index - OrderIndex) * sizeof (UINT16));\r
+        BootOrderList[OrderIndex] = OptionNumber;\r
+      }\r
+    }\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
                   BootOrderListSize,\r
-                  NewBootOrderList\r
+                  BootOrderList\r
                   );\r
-  FreePool (NewBootOrderList);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
+  FreePool (BootOrderList);\r
 \r
   BOpt_FreeMenu (&BootOptionMenu);\r
   BOpt_GetBootOptions (CallbackData);\r
 \r
-  return EFI_SUCCESS;\r
+  return Status;\r
 \r
 }\r
 \r
@@ -1092,20 +1091,12 @@ Var_UpdateBBSOption (
   VOID                        *BootOptionVar;\r
   CHAR16                      VarName[100];\r
   UINTN                       OptionSize;\r
-  UINT8                       *Ptr;\r
   EFI_STATUS                  Status;\r
-  CHAR16                      DescString[100];\r
-  CHAR8                       DescAsciiString[100];\r
-  UINTN                       NewOptionSize;\r
-  UINT8                       *NewOptionPtr;\r
-  UINT8                       *TempPtr;\r
   UINT32                      *Attribute;\r
   BM_MENU_OPTION              *OptionMenu;\r
-  BM_LEGACY_DEVICE_CONTEXT    *LegacyDeviceContext;\r
   UINT8                       *LegacyDev;\r
   UINT8                       *VarData;\r
   UINTN                       VarSize;\r
-  BM_MENU_ENTRY               *NewMenuEntry;\r
   BM_LEGACY_DEV_ORDER_CONTEXT *DevOrder;\r
   UINT8                       *OriginalPtr;\r
   UINT8                       *DisMap;\r
@@ -1113,56 +1104,51 @@ Var_UpdateBBSOption (
   UINTN                       Bit;\r
   UINT16                      *NewOrder;\r
   UINT16                      Tmp;\r
+  UINT16                      *EnBootOption;\r
+  UINTN                       EnBootOptionCount;\r
+  UINT16                      *DisBootOption;\r
+  UINTN                       DisBootOptionCount;\r
+  UINT16                      *BootOrder;\r
 \r
-  LegacyDeviceContext = NULL;\r
   DisMap              = NULL;\r
   NewOrder            = NULL;\r
 \r
-  if (FORM_SET_FD_ORDER_ID == CallbackData->BmmPreviousPageId) {\r
-    OptionMenu            = (BM_MENU_OPTION *) &LegacyFDMenu;\r
-    LegacyDev             = CallbackData->BmmFakeNvData.LegacyFD;\r
-    CallbackData->BbsType = BBS_FLOPPY;\r
-  } else {\r
-    if (FORM_SET_HD_ORDER_ID == CallbackData->BmmPreviousPageId) {\r
+  switch (CallbackData->BmmPreviousPageId) {\r
+    case FORM_SET_FD_ORDER_ID:\r
+      OptionMenu            = (BM_MENU_OPTION *) &LegacyFDMenu;\r
+      LegacyDev             = CallbackData->BmmFakeNvData.LegacyFD;\r
+      CallbackData->BbsType = BBS_FLOPPY;\r
+      break;\r
+\r
+    case FORM_SET_HD_ORDER_ID:\r
       OptionMenu            = (BM_MENU_OPTION *) &LegacyHDMenu;\r
       LegacyDev             = CallbackData->BmmFakeNvData.LegacyHD;\r
       CallbackData->BbsType = BBS_HARDDISK;\r
-    } else {\r
-      if (FORM_SET_CD_ORDER_ID == CallbackData->BmmPreviousPageId) {\r
-        OptionMenu            = (BM_MENU_OPTION *) &LegacyCDMenu;\r
-        LegacyDev             = CallbackData->BmmFakeNvData.LegacyCD;\r
-        CallbackData->BbsType = BBS_CDROM;\r
-      } else {\r
-        if (FORM_SET_NET_ORDER_ID == CallbackData->BmmPreviousPageId) {\r
-          OptionMenu            = (BM_MENU_OPTION *) &LegacyNETMenu;\r
-          LegacyDev             = CallbackData->BmmFakeNvData.LegacyNET;\r
-          CallbackData->BbsType = BBS_EMBED_NETWORK;\r
-        } else {\r
-          OptionMenu            = (BM_MENU_OPTION *) &LegacyBEVMenu;\r
-          LegacyDev             = CallbackData->BmmFakeNvData.LegacyBEV;\r
-          CallbackData->BbsType = BBS_BEV_DEVICE;\r
-        }\r
-      }\r
-    }\r
+      break;\r
+\r
+    case FORM_SET_CD_ORDER_ID:\r
+      OptionMenu            = (BM_MENU_OPTION *) &LegacyCDMenu;\r
+      LegacyDev             = CallbackData->BmmFakeNvData.LegacyCD;\r
+      CallbackData->BbsType = BBS_CDROM;\r
+      break;\r
+\r
+    case FORM_SET_NET_ORDER_ID:\r
+      OptionMenu            = (BM_MENU_OPTION *) &LegacyNETMenu;\r
+      LegacyDev             = CallbackData->BmmFakeNvData.LegacyNET;\r
+      CallbackData->BbsType = BBS_EMBED_NETWORK;\r
+      break;\r
+\r
+    default:\r
+      ASSERT (FORM_SET_BEV_ORDER_ID == CallbackData->BmmPreviousPageId);\r
+      OptionMenu            = (BM_MENU_OPTION *) &LegacyBEVMenu;\r
+      LegacyDev             = CallbackData->BmmFakeNvData.LegacyBEV;\r
+      CallbackData->BbsType = BBS_BEV_DEVICE;\r
+      break;\r
   }\r
 \r
   DisMap  = CallbackData->BmmOldFakeNVData.DisableMap;\r
   Status  = EFI_SUCCESS;\r
 \r
-  //\r
-  // Find the first device's context\r
-  // If all devices are disabled( 0xFF == LegacyDev[0]), LegacyDeviceContext can be set to any VariableContext\r
-  // because we just use it to fill the desc string, and user can not see the string in UI\r
-  //\r
-  for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {\r
-    NewMenuEntry        = BOpt_GetMenuEntry (OptionMenu, Index);\r
-    LegacyDeviceContext = (BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext;\r
-    if (0xFF != LegacyDev[0] && LegacyDev[0] == LegacyDeviceContext->Index) {\r
-      DEBUG ((DEBUG_ERROR, "DescStr: %s\n", LegacyDeviceContext->Description));\r
-      break;\r
-    }\r
-  }\r
-  ASSERT (LegacyDeviceContext != NULL);\r
 \r
   //\r
   // Update the Variable "LegacyDevOrder"\r
@@ -1180,24 +1166,23 @@ Var_UpdateBBSOption (
   OriginalPtr = VarData;\r
   DevOrder    = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;\r
 \r
-  while (VarData < VarData + VarSize) {\r
+  while (VarData < OriginalPtr + VarSize) {\r
     if (DevOrder->BbsType == CallbackData->BbsType) {\r
       break;\r
     }\r
 \r
-    VarData += sizeof (BBS_TYPE);\r
-    VarData += *(UINT16 *) VarData;\r
+    VarData += sizeof (BBS_TYPE) + DevOrder->Length;\r
     DevOrder = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;\r
   }\r
 \r
-  if (VarData >= VarData + VarSize) {\r
+  if (VarData >= OriginalPtr + VarSize) {\r
     FreePool (OriginalPtr);\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
-  NewOrder = (UINT16 *) AllocateZeroPool (DevOrder->Length - sizeof (UINT16));\r
+  NewOrder = AllocateZeroPool (DevOrder->Length - sizeof (DevOrder->Length));\r
   if (NewOrder == NULL) {\r
-    FreePool (VarData);\r
+    FreePool (OriginalPtr);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
@@ -1215,8 +1200,7 @@ Var_UpdateBBSOption (
   // so we use DisMap to set en/dis state of each item in NewOrder array\r
   //\r
   for (Index2 = 0; Index2 < OptionMenu->MenuNumber; Index2++) {\r
-    Tmp = *(UINT16 *) ((UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16) + Index2 * sizeof (UINT16));\r
-    Tmp &= 0xFF;\r
+    Tmp = (UINT16) (DevOrder->Data[Index2] & 0xFF);\r
     Pos = Tmp / 8;\r
     Bit = 7 - (Tmp % 8);\r
     if ((DisMap[Pos] & (1 << Bit)) != 0) {\r
@@ -1226,9 +1210,9 @@ Var_UpdateBBSOption (
   }\r
 \r
   CopyMem (\r
-    (UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16),\r
+    DevOrder->Data,\r
     NewOrder,\r
-    DevOrder->Length - sizeof (UINT16)\r
+    DevOrder->Length - sizeof (DevOrder->Length)\r
     );\r
   FreePool (NewOrder);\r
 \r
@@ -1240,143 +1224,101 @@ Var_UpdateBBSOption (
                   OriginalPtr\r
                   );\r
 \r
-  FreePool (OriginalPtr);\r
 \r
   //\r
-  // Update Optional Data of Boot####\r
+  // Update BootOrder and Boot####.Attribute\r
   //\r
-  BootOptionVar = GetLegacyBootOptionVar (CallbackData->BbsType, &Index, &OptionSize);\r
-\r
-  if (BootOptionVar != NULL) {\r
-    CopyMem (\r
-      DescString,\r
-      LegacyDeviceContext->Description,\r
-      StrSize (LegacyDeviceContext->Description)\r
-      );\r
-\r
-       UnicodeStrToAsciiStr((CONST CHAR16*)&DescString, (CHAR8 *)&DescAsciiString);\r
-\r
-    NewOptionSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (DescString) +\r
-                    sizeof (BBS_BBS_DEVICE_PATH);\r
-    NewOptionSize += AsciiStrLen (DescAsciiString) +\r
-                    END_DEVICE_PATH_LENGTH + sizeof (BBS_TABLE) + sizeof (UINT16);\r
-\r
-    UnicodeSPrint (VarName, 100, L"Boot%04x", Index);\r
+  // 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
+  OrderLegacyBootOption4SameType (\r
+    BootOrder,\r
+    VarSize / sizeof (UINT16),\r
+    DevOrder->Data,\r
+    DevOrder->Length / sizeof (UINT16) - 1,\r
+    EnBootOption,\r
+    &EnBootOptionCount,\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
-    Ptr       = BootOptionVar;\r
+  FreePool (BootOrder);\r
 \r
-    Attribute = (UINT32 *) Ptr;\r
-    *Attribute |= LOAD_OPTION_ACTIVE;\r
-    if (LegacyDev[0] == 0xFF) {\r
-      //\r
-      // Disable this legacy boot option\r
-      //\r
+  //\r
+  // 2. Deactivate the DisBootOption and activate the EnBootOption\r
+  //\r
+  for (Index = 0; Index < DisBootOptionCount; Index++) {\r
+    UnicodeSPrint (VarName, sizeof (VarName), L"Boot%04x", DisBootOption[Index]);\r
+    BootOptionVar = BdsLibGetVariableAndSize (\r
+                      VarName,\r
+                      &gEfiGlobalVariableGuid,\r
+                      &OptionSize\r
+                      );\r
+    if (BootOptionVar != NULL) {\r
+      Attribute   = (UINT32 *) BootOptionVar;\r
       *Attribute &= ~LOAD_OPTION_ACTIVE;\r
-    }\r
 \r
-    Ptr += sizeof (UINT32);\r
-\r
-    Ptr += sizeof (UINT16);\r
-    Ptr += StrSize ((CHAR16 *) Ptr);\r
+      Status = gRT->SetVariable (\r
+                      VarName,\r
+                      &gEfiGlobalVariableGuid,\r
+                      VAR_FLAG,\r
+                      OptionSize,\r
+                      BootOptionVar\r
+                      );\r
 \r
-    NewOptionPtr = AllocateZeroPool (NewOptionSize);\r
-    if (NewOptionPtr == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
+      FreePool (BootOptionVar);\r
     }\r
+  }\r
 \r
-    TempPtr = NewOptionPtr;\r
-\r
-    //\r
-    // Attribute\r
-    //\r
-    CopyMem (\r
-      TempPtr,\r
-      BootOptionVar,\r
-      sizeof (UINT32)\r
-      );\r
-\r
-    TempPtr += sizeof (UINT32);\r
-\r
-    //\r
-    // BBS device path Length\r
-    //\r
-    *((UINT16 *) TempPtr) = (UINT16) (sizeof (BBS_BBS_DEVICE_PATH) +\r
-                         AsciiStrLen (DescAsciiString) +\r
-                         END_DEVICE_PATH_LENGTH);\r
-\r
-    TempPtr += sizeof (UINT16);\r
-\r
-    //\r
-    // Description string\r
-    //\r
-    CopyMem (\r
-      TempPtr,\r
-      DescString,\r
-      StrSize (DescString)\r
-      );\r
-\r
-    TempPtr += StrSize (DescString);\r
-\r
-    //\r
-    // BBS device path\r
-    //\r
-    CopyMem (\r
-      TempPtr,\r
-      Ptr,\r
-      sizeof (BBS_BBS_DEVICE_PATH)\r
-      );\r
-\r
-    CopyMem (\r
-      ((BBS_BBS_DEVICE_PATH*) TempPtr)->String,\r
-      DescAsciiString,\r
-      AsciiStrSize (DescAsciiString)\r
-      );\r
-\r
-    SetDevicePathNodeLength (\r
-          (EFI_DEVICE_PATH_PROTOCOL *) TempPtr,\r
-          sizeof (BBS_BBS_DEVICE_PATH) + AsciiStrLen (DescAsciiString)\r
-          );\r
-\r
-    TempPtr += sizeof (BBS_BBS_DEVICE_PATH) + AsciiStrLen (DescAsciiString);\r
-\r
-    //\r
-    // End node\r
-    //\r
-    CopyMem (\r
-      TempPtr,\r
-      EndDevicePath,\r
-      END_DEVICE_PATH_LENGTH\r
-      );\r
-    TempPtr += END_DEVICE_PATH_LENGTH;\r
-\r
-    //\r
-    // Now TempPtr point to optional data, i.e. Bbs Table\r
-    //\r
-    CopyMem (\r
-      TempPtr,\r
-      LegacyDeviceContext->BbsTable,\r
-      sizeof (BBS_TABLE)\r
-      );\r
-\r
-    //\r
-    // Now TempPtr point to BBS index\r
-    //\r
-    TempPtr += sizeof (BBS_TABLE);\r
-    *((UINT16 *) TempPtr) = (UINT16) LegacyDeviceContext->Index;\r
+  for (Index = 0; Index < EnBootOptionCount; Index++) {\r
+    UnicodeSPrint (VarName, sizeof (VarName), L"Boot%04x", EnBootOption[Index]);\r
+    BootOptionVar = BdsLibGetVariableAndSize (\r
+                      VarName,\r
+                      &gEfiGlobalVariableGuid,\r
+                      &OptionSize\r
+                      );\r
+    if (BootOptionVar != NULL) {\r
+      Attribute   = (UINT32 *) BootOptionVar;\r
+      *Attribute |= LOAD_OPTION_ACTIVE;\r
 \r
-    Status = gRT->SetVariable (\r
-                    VarName,\r
-                    &gEfiGlobalVariableGuid,\r
-                    VAR_FLAG,\r
-                    NewOptionSize,\r
-                    NewOptionPtr\r
-                    );\r
+      Status = gRT->SetVariable (\r
+                      VarName,\r
+                      &gEfiGlobalVariableGuid,\r
+                      VAR_FLAG,\r
+                      OptionSize,\r
+                      BootOptionVar\r
+                      );\r
 \r
-    FreePool (NewOptionPtr);\r
-    FreePool (BootOptionVar);\r
+      FreePool (BootOptionVar);\r
+    }\r
   }\r
 \r
   BOpt_GetBootOptions (CallbackData);\r
+\r
+  FreePool (OriginalPtr);\r
+  FreePool (EnBootOption);\r
+  FreePool (DisBootOption);\r
   return Status;\r
 }\r
 \r
index b22d0982aebf8cef9580a45ac45ba2a5f0a9c8ae..bf65ea092b534035a5aaec068eb04643b7f83ccb 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   The platform boot manager reference implementation\r
 \r
-Copyright (c) 2004 - 2010, 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
@@ -18,6 +18,17 @@ UINT16             mKeyInput;
 EFI_GUID           mBootManagerGuid = BOOT_MANAGER_FORMSET_GUID;\r
 LIST_ENTRY         mBootOptionsList;\r
 BDS_COMMON_OPTION  *gOption;\r
+CHAR16             *mDeviceTypeStr[] = {\r
+  L"Legacy BEV",\r
+  L"Legacy Floppy",\r
+  L"Legacy Hard Drive",\r
+  L"Legacy CD ROM",\r
+  L"Legacy PCMCIA",\r
+  L"Legacy USB",\r
+  L"Legacy Embedded Network",\r
+  L"Legacy Unknown Device"\r
+};\r
+\r
 \r
 HII_VENDOR_DEVICE_PATH  mBootManagerHiiVendorDevicePath = {\r
   {\r
@@ -207,8 +218,12 @@ CallBootManager (
   VOID                        *EndOpCodeHandle;\r
   EFI_IFR_GUID_LABEL          *StartLabel;\r
   EFI_IFR_GUID_LABEL          *EndLabel;\r
+  UINT16                      DeviceType;\r
+  BOOLEAN                     IsLegacyOption;\r
+  BOOLEAN                     NeedEndOp;\r
 \r
-  gOption = NULL;\r
+  DeviceType = (UINT16) -1;\r
+  gOption    = NULL;\r
   InitializeListHead (&mBootOptionsList);\r
 \r
   //\r
@@ -247,7 +262,7 @@ CallBootManager (
   EndLabel->Number       = LABEL_BOOT_OPTION_END;\r
 \r
   mKeyInput = 0;\r
-\r
+  NeedEndOp = FALSE;\r
   for (Link = GetFirstNode (&mBootOptionsList); !IsNull (&mBootOptionsList, Link); Link = GetNextNode (&mBootOptionsList, Link)) {\r
     Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
 \r
@@ -262,7 +277,38 @@ CallBootManager (
     if ((Option->Attribute & LOAD_OPTION_HIDDEN) != 0) {\r
       continue;\r
     }\r
-      \r
+\r
+    //\r
+    // Group the legacy boot option in the sub title created dynamically\r
+    //\r
+    IsLegacyOption = (BOOLEAN) (\r
+                       (DevicePathType (Option->DevicePath) == BBS_DEVICE_PATH) &&\r
+                       (DevicePathSubType (Option->DevicePath) == BBS_BBS_DP)\r
+                       );\r
+\r
+    if (!IsLegacyOption && NeedEndOp) {\r
+      NeedEndOp = FALSE;\r
+      HiiCreateEndOpCode (StartOpCodeHandle);\r
+    }\r
+    \r
+    if (IsLegacyOption && DeviceType != ((BBS_BBS_DEVICE_PATH *) Option->DevicePath)->DeviceType) {\r
+      if (NeedEndOp) {\r
+        HiiCreateEndOpCode (StartOpCodeHandle);\r
+      }\r
+\r
+      DeviceType = ((BBS_BBS_DEVICE_PATH *) Option->DevicePath)->DeviceType;\r
+      Token      = HiiSetString (\r
+                     HiiHandle,\r
+                     0,\r
+                     mDeviceTypeStr[\r
+                       MIN (DeviceType & 0xF, sizeof (mDeviceTypeStr) / sizeof (mDeviceTypeStr[0]) - 1)\r
+                       ],\r
+                     NULL\r
+                     );\r
+      HiiCreateSubTitleOpCode (StartOpCodeHandle, Token, 0, 0, 1);\r
+      NeedEndOp = TRUE;\r
+    }\r
+\r
     ASSERT (Option->Description != NULL);\r
     \r
     Token = HiiSetString (HiiHandle, 0, Option->Description, NULL);\r
@@ -286,6 +332,10 @@ CallBootManager (
       );\r
   }\r
 \r
+  if (NeedEndOp) {\r
+    HiiCreateEndOpCode (StartOpCodeHandle);\r
+  }\r
+\r
   HiiUpdateForm (\r
     HiiHandle,\r
     &mBootManagerGuid,\r