]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Library/LegacyBootManagerLib/LegacyBm.c
Remove IntelFrameworkModulePkg
[mirror_edk2.git] / IntelFrameworkModulePkg / Library / LegacyBootManagerLib / LegacyBm.c
diff --git a/IntelFrameworkModulePkg/Library/LegacyBootManagerLib/LegacyBm.c b/IntelFrameworkModulePkg/Library/LegacyBootManagerLib/LegacyBm.c
deleted file mode 100644 (file)
index 6138a32..0000000
+++ /dev/null
@@ -1,1530 +0,0 @@
-/** @file\r
-  This function deal with the legacy boot option, it create, delete\r
-  and manage the legacy boot option, all legacy boot option is getting from\r
-  the legacy BBS table.\r
-\r
-Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "InternalLegacyBm.h"\r
-\r
-#define  LEGACY_BM_BOOT_DESCRIPTION_LENGTH  32\r
-\r
-/**\r
-  Initialize legacy boot manager library by call EfiBootManagerRegisterLegacyBootSupport\r
-  function to export two function pointer.\r
-\r
-  @param ImageHandle     The image handle.\r
-  @param SystemTable     The system table.\r
-\r
-  @retval EFI_SUCCESS    The legacy boot manager library is initialized correctly.\r
-  @return Other value if failed to initialize the legacy boot manager library.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-LegacyBootManagerLibConstructor (\r
-  IN EFI_HANDLE                            ImageHandle,\r
-  IN EFI_SYSTEM_TABLE                      *SystemTable\r
-)\r
-{\r
-  EfiBootManagerRegisterLegacyBootSupport (\r
-    LegacyBmRefreshAllBootOption,\r
-    LegacyBmBoot\r
-    );\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Get the device type from the input legacy device path.\r
-\r
-  @param DevicePath     The legacy device path.\r
-\r
-  @retval               The legacy device type.\r
-**/\r
-UINT16\r
-LegacyBmDeviceType (\r
-  EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
-  )\r
-{\r
-  ASSERT ((DevicePathType (DevicePath) == BBS_DEVICE_PATH) &&\r
-          (DevicePathSubType (DevicePath) == BBS_BBS_DP));\r
-  return ((BBS_BBS_DEVICE_PATH *) DevicePath)->DeviceType;\r
-}\r
-\r
-/**\r
-  Validate the BbsEntry base on the Boot Priority info in the BbsEntry.\r
-\r
-  @param BbsEntry       The input bbs entry info.\r
-\r
-  @retval TRUE          The BbsEntry is valid.\r
-  @retval FALSE         The BbsEntry is invalid.\r
-**/\r
-BOOLEAN\r
-LegacyBmValidBbsEntry (\r
-  IN BBS_TABLE   *BbsEntry\r
-  )\r
-{\r
-  switch (BbsEntry->BootPriority) {\r
-    case BBS_IGNORE_ENTRY:\r
-    case BBS_DO_NOT_BOOT_FROM:\r
-    case BBS_LOWEST_PRIORITY:\r
-      return FALSE;\r
-    default:\r
-      return TRUE;\r
-  }\r
-}\r
-\r
-/**\r
-  Build Legacy Device Name String according.\r
-\r
-  @param CurBBSEntry     BBS Table.\r
-  @param Index           Index.\r
-  @param BufSize         The buffer size.\r
-  @param BootString      The output string.\r
-\r
-**/\r
-VOID\r
-LegacyBmBuildLegacyDevNameString (\r
-  IN  BBS_TABLE                 *CurBBSEntry,\r
-  IN  UINTN                     Index,\r
-  IN  UINTN                     BufSize,\r
-  OUT CHAR16                    *BootString\r
-  )\r
-{\r
-  CHAR16  *Fmt;\r
-  CHAR16  *Type;\r
-  CHAR8   *StringDesc;\r
-  CHAR8   StringBufferA[LEGACY_BM_BOOT_DESCRIPTION_LENGTH + 1];\r
-  CHAR16  StringBufferU[LEGACY_BM_BOOT_DESCRIPTION_LENGTH + 1];\r
-\r
-  switch (Index) {\r
-  //\r
-  // Primary Master\r
-  //\r
-  case 1:\r
-    Fmt = L"Primary Master %s";\r
-    break;\r
-\r
- //\r
- // Primary Slave\r
- //\r
-  case 2:\r
-    Fmt = L"Primary Slave %s";\r
-    break;\r
-\r
-  //\r
-  // Secondary Master\r
-  //\r
-  case 3:\r
-    Fmt = L"Secondary Master %s";\r
-    break;\r
-\r
-  //\r
-  // Secondary Slave\r
-  //\r
-  case 4:\r
-    Fmt = L"Secondary Slave %s";\r
-    break;\r
-\r
-  default:\r
-    Fmt = L"%s";\r
-    break;\r
-  }\r
-\r
-  switch (CurBBSEntry->DeviceType) {\r
-  case BBS_FLOPPY:\r
-    Type = L"Floppy";\r
-    break;\r
-\r
-  case BBS_HARDDISK:\r
-    Type = L"Harddisk";\r
-    break;\r
-\r
-  case BBS_CDROM:\r
-    Type = L"CDROM";\r
-    break;\r
-\r
-  case BBS_PCMCIA:\r
-    Type = L"PCMCIAe";\r
-    break;\r
-\r
-  case BBS_USB:\r
-    Type = L"USB";\r
-    break;\r
-\r
-  case BBS_EMBED_NETWORK:\r
-    Type = L"Network";\r
-    break;\r
-\r
-  case BBS_BEV_DEVICE:\r
-    Type = L"BEVe";\r
-    break;\r
-\r
-  case BBS_UNKNOWN:\r
-  default:\r
-    Type = L"Unknown";\r
-    break;\r
-  }\r
-  //\r
-  // If current BBS entry has its description then use it.\r
-  //\r
-  StringDesc = (CHAR8 *) (((UINTN) CurBBSEntry->DescStringSegment << 4) + CurBBSEntry->DescStringOffset);\r
-  if (NULL != StringDesc) {\r
-    //\r
-    // Only get fisrt 32 characters, this is suggested by BBS spec\r
-    //\r
-    CopyMem (StringBufferA, StringDesc, LEGACY_BM_BOOT_DESCRIPTION_LENGTH);\r
-    StringBufferA[LEGACY_BM_BOOT_DESCRIPTION_LENGTH] = 0;\r
-    AsciiStrToUnicodeStrS (StringBufferA, StringBufferU, ARRAY_SIZE (StringBufferU));\r
-    Fmt   = L"%s";\r
-    Type  = StringBufferU;\r
-  }\r
-\r
-  //\r
-  // BbsTable 16 entries are for onboard IDE.\r
-  // Set description string for SATA harddisks, Harddisk 0 ~ Harddisk 11\r
-  //\r
-  if (Index >= 5 && Index <= 16 && (CurBBSEntry->DeviceType == BBS_HARDDISK || CurBBSEntry->DeviceType == BBS_CDROM)) {\r
-    Fmt = L"%s %d";\r
-    UnicodeSPrint (BootString, BufSize, Fmt, Type, Index - 5);\r
-  } else {\r
-    UnicodeSPrint (BootString, BufSize, Fmt, Type);\r
-  }\r
-}\r
-\r
-/**\r
-  Get the Bbs index for the input boot option.\r
-\r
-  @param BootOption     The input boot option info.\r
-  @param BbsTable       The input Bbs table.\r
-  @param BbsCount       The input total bbs entry number.\r
-  @param BbsIndexUsed   The array shows how many BBS table indexs have been used.\r
-\r
-  @retval The index for the input boot option.\r
-**/\r
-UINT16\r
-LegacyBmFuzzyMatch (\r
-  EFI_BOOT_MANAGER_LOAD_OPTION   *BootOption,\r
-  BBS_TABLE                      *BbsTable,\r
-  UINT16                         BbsCount,\r
-  BOOLEAN                        *BbsIndexUsed\r
-  )\r
-{\r
-  UINT16                         Index;\r
-  LEGACY_BM_BOOT_OPTION_BBS_DATA *BbsData;\r
-  CHAR16                         Description[LEGACY_BM_BOOT_DESCRIPTION_LENGTH + 1];\r
-\r
-  BbsData = (LEGACY_BM_BOOT_OPTION_BBS_DATA *) BootOption->OptionalData;\r
-\r
-  //\r
-  // Directly check the BBS index stored in BootOption\r
-  //\r
-  if ((BbsData->BbsIndex < BbsCount) &&\r
-      (LegacyBmDeviceType (BootOption->FilePath) == BbsTable[BbsData->BbsIndex].DeviceType)) {\r
-    LegacyBmBuildLegacyDevNameString (\r
-      &BbsTable[BbsData->BbsIndex],\r
-      BbsData->BbsIndex,\r
-      sizeof (Description),\r
-      Description\r
-      );\r
-    if ((StrCmp (Description, BootOption->Description) == 0) && !BbsIndexUsed[BbsData->BbsIndex]) {\r
-      //\r
-      // If devices with the same description string are connected,\r
-      // the BbsIndex of the first device is returned for the other device also.\r
-      // So, check if the BbsIndex is already being used, before assigning the BbsIndex.\r
-      //\r
-      BbsIndexUsed[BbsData->BbsIndex] = TRUE;\r
-      return BbsData->BbsIndex;\r
-    }\r
-  }\r
-\r
-  //\r
-  // BBS table could be changed (entry removed/moved)\r
-  // find the correct BBS index\r
-  //\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if (!LegacyBmValidBbsEntry (&BbsTable[Index]) ||\r
-        (BbsTable[Index].DeviceType != LegacyBmDeviceType (BootOption->FilePath))) {\r
-      continue;\r
-    }\r
-\r
-    LegacyBmBuildLegacyDevNameString (\r
-      &BbsTable[Index],\r
-      Index,\r
-      sizeof (Description),\r
-      Description\r
-      );\r
-    if ((StrCmp (Description, BootOption->Description) == 0) && !BbsIndexUsed[Index]) {\r
-      //\r
-      // If devices with the same description string are connected,\r
-      // the BbsIndex of the first device is assigned for the other device also.\r
-      // So, check if the BbsIndex is already being used, before assigning the corrected BbsIndex.\r
-      //\r
-      break;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Add the corrected BbsIndex in the UsedBbsIndex Buffer\r
-  //\r
-  if (Index != BbsCount) {\r
-    BbsIndexUsed[Index] = TRUE;\r
-  }\r
-\r
-  return Index;\r
-}\r
-\r
-/**\r
-\r
-  Update legacy device order base on the input info.\r
-\r
-  @param   LegacyDevOrder     Legacy device order data buffer.\r
-  @param   LegacyDevOrderSize Legacy device order data buffer size.\r
-  @param   DeviceType         Device type which need to check.\r
-  @param   OldBbsIndex        Old Bds Index.\r
-  @param   NewBbsIndex        New Bds Index, if it is -1,means remove this option.\r
-\r
-**/\r
-VOID\r
-LegacyBmUpdateBbsIndex (\r
-  LEGACY_DEV_ORDER_ENTRY   *LegacyDevOrder,\r
-  UINTN                    *LegacyDevOrderSize,\r
-  UINT16                   DeviceType,\r
-  UINT16                   OldBbsIndex,\r
-  UINT16                   NewBbsIndex // Delete entry if -1\r
-  )\r
-{\r
-  LEGACY_DEV_ORDER_ENTRY   *Entry;\r
-  UINTN                    Index;\r
-\r
-  ASSERT (((LegacyDevOrder == NULL) && (*LegacyDevOrderSize == 0)) ||\r
-          ((LegacyDevOrder != NULL) && (*LegacyDevOrderSize != 0))\r
-         );\r
-\r
-  for (Entry = LegacyDevOrder;\r
-       Entry < (LEGACY_DEV_ORDER_ENTRY *) ((UINT8 *) LegacyDevOrder + *LegacyDevOrderSize);\r
-       Entry = (LEGACY_DEV_ORDER_ENTRY *) ((UINTN) Entry + sizeof (BBS_TYPE) + Entry->Length)\r
-       ) {\r
-    if (Entry->BbsType == DeviceType) {\r
-      for (Index = 0; Index < Entry->Length / sizeof (UINT16) - 1; Index++) {\r
-        if (Entry->Data[Index] == OldBbsIndex) {\r
-          if (NewBbsIndex == (UINT16) -1) {\r
-            //\r
-            // Delete the old entry\r
-            //\r
-            CopyMem (\r
-              &Entry->Data[Index],\r
-              &Entry->Data[Index + 1],\r
-              (UINT8 *) LegacyDevOrder + *LegacyDevOrderSize - (UINT8 *) &Entry->Data[Index + 1]\r
-              );\r
-            Entry->Length       -= sizeof (UINT16);\r
-            *LegacyDevOrderSize -= sizeof(UINT16);\r
-          } else {\r
-            Entry->Data[Index]   = NewBbsIndex;\r
-          }\r
-          break;\r
-        }\r
-      }\r
-      break;\r
-    }\r
-  }\r
-}\r
-\r
-/**\r
-  Delete all the legacy boot options.\r
-\r
-  @retval EFI_SUCCESS            All legacy boot options are deleted.\r
-**/\r
-EFI_STATUS\r
-LegacyBmDeleteAllBootOptions (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS                    Status;\r
-  UINTN                         Index;\r
-  EFI_BOOT_MANAGER_LOAD_OPTION  *BootOption;\r
-  UINTN                         BootOptionCount;\r
-\r
-  BootOption = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);\r
-  for (Index = 0; Index < BootOptionCount; Index++) {\r
-    if ((DevicePathType (BootOption[Index].FilePath) == BBS_DEVICE_PATH) &&\r
-        (DevicePathSubType (BootOption[Index].FilePath) == BBS_BBS_DP)) {\r
-      Status = EfiBootManagerDeleteLoadOptionVariable (BootOption[Index].OptionNumber, BootOption[Index].OptionType);\r
-      //\r
-      // Deleting variable with current variable implementation shouldn't fail.\r
-      //\r
-      ASSERT_EFI_ERROR (Status);\r
-    }\r
-  }\r
-\r
-  Status = gRT->SetVariable (\r
-                  VAR_LEGACY_DEV_ORDER,\r
-                  &gEfiLegacyDevOrderVariableGuid,\r
-                  0,\r
-                  0,\r
-                  NULL\r
-                  );\r
-  //\r
-  // Deleting variable with current variable implementation shouldn't fail.\r
-  //\r
-  ASSERT (Status == EFI_SUCCESS || Status == EFI_NOT_FOUND);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  Delete all the invalid legacy boot options.\r
-\r
-  @retval EFI_SUCCESS             All invalide legacy boot options are deleted.\r
-  @retval EFI_OUT_OF_RESOURCES    Fail to allocate necessary memory.\r
-  @retval EFI_NOT_FOUND           Fail to retrive variable of boot order.\r
-**/\r
-EFI_STATUS\r
-LegacyBmDeleteAllInvalidBootOptions (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS                    Status;\r
-  UINT16                        HddCount;\r
-  UINT16                        BbsCount;\r
-  HDD_INFO                      *HddInfo;\r
-  BBS_TABLE                     *BbsTable;\r
-  UINT16                        BbsIndex;\r
-  EFI_LEGACY_BIOS_PROTOCOL      *LegacyBios;\r
-  UINTN                         Index;\r
-  EFI_BOOT_MANAGER_LOAD_OPTION  *BootOption;\r
-  UINTN                         BootOptionCount;\r
-  LEGACY_DEV_ORDER_ENTRY        *LegacyDevOrder;\r
-  UINTN                         LegacyDevOrderSize;\r
-  BOOLEAN                       *BbsIndexUsed;\r
-\r
-  HddCount      = 0;\r
-  BbsCount      = 0;\r
-  HddInfo       = NULL;\r
-  BbsTable      = NULL;\r
-\r
-  Status        = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  Status = LegacyBios->GetBbsInfo (\r
-                         LegacyBios,\r
-                         &HddCount,\r
-                         &HddInfo,\r
-                         &BbsCount,\r
-                         &BbsTable\r
-                         );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  GetVariable2 (VAR_LEGACY_DEV_ORDER, &gEfiLegacyDevOrderVariableGuid, (VOID **) &LegacyDevOrder, &LegacyDevOrderSize);\r
-\r
-  BootOption = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);\r
-\r
-  BbsIndexUsed = AllocateZeroPool (BbsCount * sizeof (BOOLEAN));\r
-  ASSERT (BbsIndexUsed != NULL);\r
-\r
-  for (Index = 0; Index < BootOptionCount; Index++) {\r
-    //\r
-    // Skip non legacy boot option\r
-    //\r
-    if ((DevicePathType (BootOption[Index].FilePath) != BBS_DEVICE_PATH) ||\r
-        (DevicePathSubType (BootOption[Index].FilePath) != BBS_BBS_DP)) {\r
-      continue;\r
-    }\r
-\r
-    BbsIndex = LegacyBmFuzzyMatch (&BootOption[Index], BbsTable, BbsCount, BbsIndexUsed);\r
-    if (BbsIndex == BbsCount) {\r
-      DEBUG ((EFI_D_INFO, "[LegacyBds] Delete Boot Option Boot%04x: %s\n", (UINTN) BootOption[Index].OptionNumber, BootOption[Index].Description));\r
-      //\r
-      // Delete entry from LegacyDevOrder\r
-      //\r
-      LegacyBmUpdateBbsIndex (\r
-        LegacyDevOrder,\r
-        &LegacyDevOrderSize,\r
-        LegacyBmDeviceType (BootOption[Index].FilePath),\r
-        ((LEGACY_BM_BOOT_OPTION_BBS_DATA *) BootOption[Index].OptionalData)->BbsIndex,\r
-        (UINT16) -1\r
-        );\r
-      EfiBootManagerDeleteLoadOptionVariable (BootOption[Index].OptionNumber, BootOption[Index].OptionType);\r
-    } else {\r
-      if (((LEGACY_BM_BOOT_OPTION_BBS_DATA *) BootOption[Index].OptionalData)->BbsIndex != BbsIndex) {\r
-        DEBUG ((EFI_D_INFO, "[LegacyBds] Update Boot Option Boot%04x: %s Bbs0x%04x->Bbs0x%04x\n", (UINTN) BootOption[Index].OptionNumber, BootOption[Index].Description,\r
-                (UINTN) ((LEGACY_BM_BOOT_OPTION_BBS_DATA *) BootOption[Index].OptionalData)->BbsIndex, (UINTN) BbsIndex));\r
-        //\r
-        // Update the BBS index in LegacyDevOrder\r
-        //\r
-        LegacyBmUpdateBbsIndex (\r
-          LegacyDevOrder,\r
-          &LegacyDevOrderSize,\r
-          LegacyBmDeviceType (BootOption[Index].FilePath),\r
-          ((LEGACY_BM_BOOT_OPTION_BBS_DATA *) BootOption[Index].OptionalData)->BbsIndex,\r
-          BbsIndex\r
-          );\r
-\r
-        //\r
-        // Update the OptionalData in the Boot#### variable\r
-        //\r
-        ((LEGACY_BM_BOOT_OPTION_BBS_DATA *) BootOption[Index].OptionalData)->BbsIndex = BbsIndex;\r
-        EfiBootManagerLoadOptionToVariable (&BootOption[Index]);\r
-      }\r
-    }\r
-  }\r
-  EfiBootManagerFreeLoadOptions (BootOption, BootOptionCount);\r
-\r
-  if (LegacyDevOrder != NULL) {\r
-    Status = gRT->SetVariable (\r
-                    VAR_LEGACY_DEV_ORDER,\r
-                    &gEfiLegacyDevOrderVariableGuid,\r
-                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
-                    LegacyDevOrderSize,\r
-                    LegacyDevOrder\r
-                    );\r
-    //\r
-    // Shrink variable with current variable implementation shouldn't fail.\r
-    //\r
-    ASSERT_EFI_ERROR (Status);\r
-\r
-    FreePool (LegacyDevOrder);\r
-  }\r
-  FreePool(BbsIndexUsed);\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Create legacy boot option.\r
-\r
-  @param BootOption        Ponter to the boot option which will be crated.\r
-  @param BbsEntry          The input bbs entry info.\r
-  @param BbsIndex          The BBS index.\r
-\r
-  @retval EFI_SUCCESS            Create legacy boot option successfully.\r
-  @retval EFI_INVALID_PARAMETER  Invalid input parameter.\r
-\r
-**/\r
-EFI_STATUS\r
-LegacyBmCreateLegacyBootOption (\r
-  IN OUT EFI_BOOT_MANAGER_LOAD_OPTION  *BootOption,\r
-  IN BBS_TABLE                         *BbsEntry,\r
-  IN UINT16                            BbsIndex\r
-  )\r
-{\r
-  EFI_STATUS                   Status;\r
-  EFI_DEVICE_PATH_PROTOCOL     *DevicePath;\r
-  CHAR16                       Description[LEGACY_BM_BOOT_DESCRIPTION_LENGTH + 1];\r
-  CHAR8                        HelpString[LEGACY_BM_BOOT_DESCRIPTION_LENGTH + 1];\r
-  UINTN                        StringLen;\r
-  LEGACY_BM_BOOT_OPTION_BBS_DATA  *OptionalData;\r
-  BBS_BBS_DEVICE_PATH          *BbsNode;\r
-\r
-  if ((BootOption == NULL) || (BbsEntry == NULL)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  LegacyBmBuildLegacyDevNameString (BbsEntry, BbsIndex, sizeof (Description), Description);\r
-\r
-  //\r
-  // Create the BBS device path with description string\r
-  //\r
-  UnicodeStrToAsciiStrS (Description, HelpString, sizeof (HelpString));\r
-  StringLen = AsciiStrLen (HelpString);\r
-  DevicePath = AllocatePool (sizeof (BBS_BBS_DEVICE_PATH) + StringLen + END_DEVICE_PATH_LENGTH);\r
-  ASSERT (DevicePath != NULL);\r
-\r
-  BbsNode = (BBS_BBS_DEVICE_PATH *) DevicePath;\r
-  SetDevicePathNodeLength (BbsNode, sizeof (BBS_BBS_DEVICE_PATH) + StringLen);\r
-  BbsNode->Header.Type    = BBS_DEVICE_PATH;\r
-  BbsNode->Header.SubType = BBS_BBS_DP;\r
-  BbsNode->DeviceType     = BbsEntry->DeviceType;\r
-  CopyMem (&BbsNode->StatusFlag, &BbsEntry->StatusFlags, sizeof (BBS_STATUS_FLAGS));\r
-  CopyMem (BbsNode->String, HelpString, StringLen + 1);\r
-\r
-  SetDevicePathEndNode (NextDevicePathNode (BbsNode));\r
-\r
-  //\r
-  // Create the OptionalData\r
-  //\r
-  OptionalData = AllocatePool (sizeof (LEGACY_BM_BOOT_OPTION_BBS_DATA));\r
-  ASSERT (OptionalData != NULL);\r
-  OptionalData->BbsIndex = BbsIndex;\r
-\r
-  //\r
-  // Create the BootOption\r
-  //\r
-  Status = EfiBootManagerInitializeLoadOption (\r
-             BootOption,\r
-             LoadOptionNumberUnassigned,\r
-             LoadOptionTypeBoot,\r
-             LOAD_OPTION_ACTIVE,\r
-             Description,\r
-             DevicePath,\r
-             (UINT8 *) OptionalData,\r
-             sizeof (LEGACY_BM_BOOT_OPTION_BBS_DATA)\r
-             );\r
-  FreePool (DevicePath);\r
-  FreePool (OptionalData);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Fill the device order buffer.\r
-\r
-  @param BbsTable        The BBS table.\r
-  @param BbsType         The BBS Type.\r
-  @param BbsCount        The BBS Count.\r
-  @param Buf             device order buffer.\r
-\r
-  @return The device order buffer.\r
-\r
-**/\r
-UINT16 *\r
-LegacyBmFillDevOrderBuf (\r
-  IN BBS_TABLE                    *BbsTable,\r
-  IN BBS_TYPE                     BbsType,\r
-  IN UINTN                        BbsCount,\r
-  OUT UINT16                      *Buf\r
-  )\r
-{\r
-  UINTN Index;\r
-\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if (!LegacyBmValidBbsEntry (&BbsTable[Index])) {\r
-      continue;\r
-    }\r
-\r
-    if (BbsTable[Index].DeviceType != BbsType) {\r
-      continue;\r
-    }\r
-\r
-    *Buf = (UINT16) (Index & 0xFF);\r
-    Buf++;\r
-  }\r
-\r
-  return Buf;\r
-}\r
-\r
-/**\r
-  Create the device order buffer.\r
-\r
-  @param BbsTable        The BBS table.\r
-  @param BbsCount        The BBS Count.\r
-\r
-  @retval EFI_SUCCES             The buffer is created and the EFI variable named\r
-                                 VAR_LEGACY_DEV_ORDER and EfiLegacyDevOrderGuid is\r
-                                 set correctly.\r
-  @retval EFI_OUT_OF_RESOURCES   Memmory or storage is not enough.\r
-  @retval EFI_DEVICE_ERROR       Fail to add the device order into EFI variable fail\r
-                                 because of hardware error.\r
-**/\r
-EFI_STATUS\r
-LegacyBmCreateDevOrder (\r
-  IN BBS_TABLE                  *BbsTable,\r
-  IN UINT16                     BbsCount\r
-  )\r
-{\r
-  UINTN                       Index;\r
-  UINTN                       FDCount;\r
-  UINTN                       HDCount;\r
-  UINTN                       CDCount;\r
-  UINTN                       NETCount;\r
-  UINTN                       BEVCount;\r
-  UINTN                       TotalSize;\r
-  UINTN                       HeaderSize;\r
-  LEGACY_DEV_ORDER_ENTRY      *DevOrder;\r
-  LEGACY_DEV_ORDER_ENTRY      *DevOrderPtr;\r
-  EFI_STATUS                  Status;\r
-\r
-  FDCount     = 0;\r
-  HDCount     = 0;\r
-  CDCount     = 0;\r
-  NETCount    = 0;\r
-  BEVCount    = 0;\r
-  TotalSize   = 0;\r
-  HeaderSize  = sizeof (BBS_TYPE) + sizeof (UINT16);\r
-  DevOrder    = NULL;\r
-  Status      = EFI_SUCCESS;\r
-\r
-  //\r
-  // Count all boot devices\r
-  //\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if (!LegacyBmValidBbsEntry (&BbsTable[Index])) {\r
-      continue;\r
-    }\r
-\r
-    switch (BbsTable[Index].DeviceType) {\r
-    case BBS_FLOPPY:\r
-      FDCount++;\r
-      break;\r
-\r
-    case BBS_HARDDISK:\r
-      HDCount++;\r
-      break;\r
-\r
-    case BBS_CDROM:\r
-      CDCount++;\r
-      break;\r
-\r
-    case BBS_EMBED_NETWORK:\r
-      NETCount++;\r
-      break;\r
-\r
-    case BBS_BEV_DEVICE:\r
-      BEVCount++;\r
-      break;\r
-\r
-    default:\r
-      break;\r
-    }\r
-  }\r
-\r
-  TotalSize += (HeaderSize + sizeof (UINT16) * FDCount);\r
-  TotalSize += (HeaderSize + sizeof (UINT16) * HDCount);\r
-  TotalSize += (HeaderSize + sizeof (UINT16) * CDCount);\r
-  TotalSize += (HeaderSize + sizeof (UINT16) * NETCount);\r
-  TotalSize += (HeaderSize + sizeof (UINT16) * BEVCount);\r
-\r
-  //\r
-  // Create buffer to hold all boot device order\r
-  //\r
-  DevOrder = AllocateZeroPool (TotalSize);\r
-  if (NULL == DevOrder) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  DevOrderPtr          = DevOrder;\r
-\r
-  DevOrderPtr->BbsType = BBS_FLOPPY;\r
-  DevOrderPtr->Length  = (UINT16) (sizeof (DevOrderPtr->Length) + FDCount * sizeof (UINT16));\r
-  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) LegacyBmFillDevOrderBuf (BbsTable, BBS_FLOPPY, BbsCount, DevOrderPtr->Data);\r
-\r
-  DevOrderPtr->BbsType = BBS_HARDDISK;\r
-  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));\r
-  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) LegacyBmFillDevOrderBuf (BbsTable, BBS_HARDDISK, BbsCount, DevOrderPtr->Data);\r
-\r
-  DevOrderPtr->BbsType = BBS_CDROM;\r
-  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));\r
-  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) LegacyBmFillDevOrderBuf (BbsTable, BBS_CDROM, BbsCount, DevOrderPtr->Data);\r
-\r
-  DevOrderPtr->BbsType = BBS_EMBED_NETWORK;\r
-  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));\r
-  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) LegacyBmFillDevOrderBuf (BbsTable, BBS_EMBED_NETWORK, BbsCount, DevOrderPtr->Data);\r
-\r
-  DevOrderPtr->BbsType = BBS_BEV_DEVICE;\r
-  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));\r
-  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) LegacyBmFillDevOrderBuf (BbsTable, BBS_BEV_DEVICE, BbsCount, DevOrderPtr->Data);\r
-\r
-  ASSERT (TotalSize == ((UINTN) DevOrderPtr - (UINTN) DevOrder));\r
-\r
-  //\r
-  // Save device order for legacy boot device to variable.\r
-  //\r
-  Status = gRT->SetVariable (\r
-                  VAR_LEGACY_DEV_ORDER,\r
-                  &gEfiLegacyDevOrderVariableGuid,\r
-                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
-                  TotalSize,\r
-                  DevOrder\r
-                  );\r
-  FreePool (DevOrder);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Add the legacy boot devices from BBS table into\r
-  the legacy device boot order.\r
-\r
-  @retval EFI_SUCCESS           The boot devices are added successfully.\r
-  @retval EFI_NOT_FOUND         The legacy boot devices are not found.\r
-  @retval EFI_OUT_OF_RESOURCES  Memmory or storage is not enough.\r
-  @retval EFI_DEVICE_ERROR      Fail to add the legacy device boot order into EFI variable\r
-                                because of hardware error.\r
-**/\r
-EFI_STATUS\r
-LegacyBmUpdateDevOrder (\r
-  VOID\r
-  )\r
-{\r
-  LEGACY_DEV_ORDER_ENTRY      *DevOrder;\r
-  LEGACY_DEV_ORDER_ENTRY      *NewDevOrder;\r
-  LEGACY_DEV_ORDER_ENTRY      *Ptr;\r
-  LEGACY_DEV_ORDER_ENTRY      *NewPtr;\r
-  EFI_LEGACY_BIOS_PROTOCOL    *LegacyBios;\r
-  EFI_STATUS                  Status;\r
-  UINT16                      HddCount;\r
-  UINT16                      BbsCount;\r
-  HDD_INFO                    *LocalHddInfo;\r
-  BBS_TABLE                   *LocalBbsTable;\r
-  UINTN                       Index;\r
-  UINTN                       Index2;\r
-  UINTN                       *Idx;\r
-  UINTN                       FDCount;\r
-  UINTN                       HDCount;\r
-  UINTN                       CDCount;\r
-  UINTN                       NETCount;\r
-  UINTN                       BEVCount;\r
-  UINTN                       TotalSize;\r
-  UINTN                       HeaderSize;\r
-  UINT16                      *NewFDPtr;\r
-  UINT16                      *NewHDPtr;\r
-  UINT16                      *NewCDPtr;\r
-  UINT16                      *NewNETPtr;\r
-  UINT16                      *NewBEVPtr;\r
-  UINT16                      *NewDevPtr;\r
-  UINTN                       FDIndex;\r
-  UINTN                       HDIndex;\r
-  UINTN                       CDIndex;\r
-  UINTN                       NETIndex;\r
-  UINTN                       BEVIndex;\r
-\r
-  Idx           = NULL;\r
-  FDCount       = 0;\r
-  HDCount       = 0;\r
-  CDCount       = 0;\r
-  NETCount      = 0;\r
-  BEVCount      = 0;\r
-  TotalSize     = 0;\r
-  HeaderSize    = sizeof (BBS_TYPE) + sizeof (UINT16);\r
-  FDIndex       = 0;\r
-  HDIndex       = 0;\r
-  CDIndex       = 0;\r
-  NETIndex      = 0;\r
-  BEVIndex      = 0;\r
-  NewDevPtr     = NULL;\r
-\r
-  Status        = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  Status = LegacyBios->GetBbsInfo (\r
-                         LegacyBios,\r
-                         &HddCount,\r
-                         &LocalHddInfo,\r
-                         &BbsCount,\r
-                         &LocalBbsTable\r
-                         );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  GetVariable2 (VAR_LEGACY_DEV_ORDER, &gEfiLegacyDevOrderVariableGuid, (VOID **) &DevOrder, NULL);\r
-  if (NULL == DevOrder) {\r
-    return LegacyBmCreateDevOrder (LocalBbsTable, BbsCount);\r
-  }\r
-  //\r
-  // First we figure out how many boot devices with same device type respectively\r
-  //\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if (!LegacyBmValidBbsEntry (&LocalBbsTable[Index])) {\r
-      continue;\r
-    }\r
-\r
-    switch (LocalBbsTable[Index].DeviceType) {\r
-    case BBS_FLOPPY:\r
-      FDCount++;\r
-      break;\r
-\r
-    case BBS_HARDDISK:\r
-      HDCount++;\r
-      break;\r
-\r
-    case BBS_CDROM:\r
-      CDCount++;\r
-      break;\r
-\r
-    case BBS_EMBED_NETWORK:\r
-      NETCount++;\r
-      break;\r
-\r
-    case BBS_BEV_DEVICE:\r
-      BEVCount++;\r
-      break;\r
-\r
-    default:\r
-      break;\r
-    }\r
-  }\r
-\r
-  TotalSize += (HeaderSize + FDCount * sizeof (UINT16));\r
-  TotalSize += (HeaderSize + HDCount * sizeof (UINT16));\r
-  TotalSize += (HeaderSize + CDCount * sizeof (UINT16));\r
-  TotalSize += (HeaderSize + NETCount * sizeof (UINT16));\r
-  TotalSize += (HeaderSize + BEVCount * sizeof (UINT16));\r
-\r
-  NewDevOrder = AllocateZeroPool (TotalSize);\r
-  if (NULL == NewDevOrder) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  //\r
-  // copy FD\r
-  //\r
-  Ptr             = DevOrder;\r
-  NewPtr          = NewDevOrder;\r
-  NewPtr->BbsType = Ptr->BbsType;\r
-  NewPtr->Length  = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16));\r
-  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {\r
-    if (!LegacyBmValidBbsEntry (&LocalBbsTable[Ptr->Data[Index] & 0xFF]) ||\r
-        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_FLOPPY\r
-        ) {\r
-      continue;\r
-    }\r
-\r
-    NewPtr->Data[FDIndex] = Ptr->Data[Index];\r
-    FDIndex++;\r
-  }\r
-  NewFDPtr = NewPtr->Data;\r
-\r
-  //\r
-  // copy HD\r
-  //\r
-  Ptr             = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);\r
-  NewPtr          = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);\r
-  NewPtr->BbsType = Ptr->BbsType;\r
-  NewPtr->Length  = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));\r
-  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {\r
-    if (!LegacyBmValidBbsEntry (&LocalBbsTable[Ptr->Data[Index] & 0xFF]) ||\r
-        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_HARDDISK\r
-        ) {\r
-      continue;\r
-    }\r
-\r
-    NewPtr->Data[HDIndex] = Ptr->Data[Index];\r
-    HDIndex++;\r
-  }\r
-  NewHDPtr = NewPtr->Data;\r
-\r
-  //\r
-  // copy CD\r
-  //\r
-  Ptr    = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);\r
-  NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);\r
-  NewPtr->BbsType = Ptr->BbsType;\r
-  NewPtr->Length  = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));\r
-  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {\r
-    if (!LegacyBmValidBbsEntry (&LocalBbsTable[Ptr->Data[Index] & 0xFF]) ||\r
-        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_CDROM\r
-        ) {\r
-      continue;\r
-    }\r
-\r
-    NewPtr->Data[CDIndex] = Ptr->Data[Index];\r
-    CDIndex++;\r
-  }\r
-  NewCDPtr = NewPtr->Data;\r
-\r
-  //\r
-  // copy NET\r
-  //\r
-  Ptr    = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);\r
-  NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);\r
-  NewPtr->BbsType = Ptr->BbsType;\r
-  NewPtr->Length  = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));\r
-  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {\r
-    if (!LegacyBmValidBbsEntry (&LocalBbsTable[Ptr->Data[Index] & 0xFF]) ||\r
-        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_EMBED_NETWORK\r
-        ) {\r
-      continue;\r
-    }\r
-\r
-    NewPtr->Data[NETIndex] = Ptr->Data[Index];\r
-    NETIndex++;\r
-  }\r
-  NewNETPtr = NewPtr->Data;\r
-\r
-  //\r
-  // copy BEV\r
-  //\r
-  Ptr    = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);\r
-  NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);\r
-  NewPtr->BbsType = Ptr->BbsType;\r
-  NewPtr->Length  = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));\r
-  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {\r
-    if (!LegacyBmValidBbsEntry (&LocalBbsTable[Ptr->Data[Index] & 0xFF]) ||\r
-        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_BEV_DEVICE\r
-        ) {\r
-      continue;\r
-    }\r
-\r
-    NewPtr->Data[BEVIndex] = Ptr->Data[Index];\r
-    BEVIndex++;\r
-  }\r
-  NewBEVPtr = NewPtr->Data;\r
-\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if (!LegacyBmValidBbsEntry (&LocalBbsTable[Index])) {\r
-      continue;\r
-    }\r
-\r
-    switch (LocalBbsTable[Index].DeviceType) {\r
-    case BBS_FLOPPY:\r
-      Idx       = &FDIndex;\r
-      NewDevPtr = NewFDPtr;\r
-      break;\r
-\r
-    case BBS_HARDDISK:\r
-      Idx       = &HDIndex;\r
-      NewDevPtr = NewHDPtr;\r
-      break;\r
-\r
-    case BBS_CDROM:\r
-      Idx       = &CDIndex;\r
-      NewDevPtr = NewCDPtr;\r
-      break;\r
-\r
-    case BBS_EMBED_NETWORK:\r
-      Idx       = &NETIndex;\r
-      NewDevPtr = NewNETPtr;\r
-      break;\r
-\r
-    case BBS_BEV_DEVICE:\r
-      Idx       = &BEVIndex;\r
-      NewDevPtr = NewBEVPtr;\r
-      break;\r
-\r
-    default:\r
-      Idx = NULL;\r
-      break;\r
-    }\r
-    //\r
-    // at this point we have copied those valid indexes to new buffer\r
-    // and we should check if there is any new appeared boot device\r
-    //\r
-    if (Idx != NULL) {\r
-      for (Index2 = 0; Index2 < *Idx; Index2++) {\r
-        if ((NewDevPtr[Index2] & 0xFF) == (UINT16) Index) {\r
-          break;\r
-        }\r
-      }\r
-\r
-      if (Index2 == *Idx) {\r
-        //\r
-        // Index2 == *Idx means we didn't find Index\r
-        // so Index is a new appeared device's index in BBS table\r
-        // insert it before disabled indexes.\r
-        //\r
-        for (Index2 = 0; Index2 < *Idx; Index2++) {\r
-          if ((NewDevPtr[Index2] & 0xFF00) == 0xFF00) {\r
-            break;\r
-          }\r
-        }\r
-        CopyMem (&NewDevPtr[Index2 + 1], &NewDevPtr[Index2], (*Idx - Index2) * sizeof (UINT16));\r
-        NewDevPtr[Index2] = (UINT16) (Index & 0xFF);\r
-        (*Idx)++;\r
-      }\r
-    }\r
-  }\r
-\r
-  FreePool (DevOrder);\r
-\r
-  Status = gRT->SetVariable (\r
-                  VAR_LEGACY_DEV_ORDER,\r
-                  &gEfiLegacyDevOrderVariableGuid,\r
-                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
-                  TotalSize,\r
-                  NewDevOrder\r
-                  );\r
-  FreePool (NewDevOrder);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Set Boot Priority for specified device type.\r
-\r
-  @param DeviceType      The device type.\r
-  @param BbsIndex        The BBS index to set the highest priority. Ignore when -1.\r
-  @param LocalBbsTable   The BBS table.\r
-  @param Priority        The prority table.\r
-\r
-  @retval EFI_SUCCESS           The function completes successfully.\r
-  @retval EFI_NOT_FOUND         Failed to find device.\r
-  @retval EFI_OUT_OF_RESOURCES  Failed to get the efi variable of device order.\r
-\r
-**/\r
-EFI_STATUS\r
-LegacyBmSetPriorityForSameTypeDev (\r
-  IN UINT16                                              DeviceType,\r
-  IN UINTN                                               BbsIndex,\r
-  IN OUT BBS_TABLE                                       *LocalBbsTable,\r
-  IN OUT UINT16                                          *Priority\r
-  )\r
-{\r
-  LEGACY_DEV_ORDER_ENTRY      *DevOrder;\r
-  LEGACY_DEV_ORDER_ENTRY      *DevOrderPtr;\r
-  UINTN                       DevOrderSize;\r
-  UINTN                       Index;\r
-\r
-  GetVariable2 (VAR_LEGACY_DEV_ORDER, &gEfiLegacyDevOrderVariableGuid, (VOID **) &DevOrder, &DevOrderSize);\r
-  if (NULL == DevOrder) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  DevOrderPtr = DevOrder;\r
-  while ((UINT8 *) DevOrderPtr < (UINT8 *) DevOrder + DevOrderSize) {\r
-    if (DevOrderPtr->BbsType == DeviceType) {\r
-      break;\r
-    }\r
-\r
-    DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) ((UINTN) DevOrderPtr + sizeof (BBS_TYPE) + DevOrderPtr->Length);\r
-  }\r
-\r
-  if ((UINT8 *) DevOrderPtr >= (UINT8 *) DevOrder + DevOrderSize) {\r
-    FreePool (DevOrder);\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  if (BbsIndex != (UINTN) -1) {\r
-    //\r
-    // In case the BBS entry isn't valid because devices were plugged or removed.\r
-    //\r
-    if (!LegacyBmValidBbsEntry (&LocalBbsTable[BbsIndex]) || (LocalBbsTable[BbsIndex].DeviceType != DeviceType)) {\r
-      FreePool (DevOrder);\r
-      return EFI_NOT_FOUND;\r
-    }\r
-    LocalBbsTable[BbsIndex].BootPriority = *Priority;\r
-    (*Priority)++;\r
-  }\r
-  //\r
-  // If the high byte of the DevIndex is 0xFF, it indicates that this device has been disabled.\r
-  //\r
-  for (Index = 0; Index < DevOrderPtr->Length / sizeof (UINT16) - 1; Index++) {\r
-    if ((DevOrderPtr->Data[Index] & 0xFF00) == 0xFF00) {\r
-      //\r
-      // LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = BBS_DISABLED_ENTRY;\r
-      //\r
-    } else if (DevOrderPtr->Data[Index] != BbsIndex) {\r
-      LocalBbsTable[DevOrderPtr->Data[Index]].BootPriority = *Priority;\r
-      (*Priority)++;\r
-    }\r
-  }\r
-\r
-  FreePool (DevOrder);\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Print the BBS Table.\r
-\r
-  @param LocalBbsTable   The BBS table.\r
-  @param BbsCount        The count of entry in BBS table.\r
-**/\r
-VOID\r
-LegacyBmPrintBbsTable (\r
-  IN BBS_TABLE  *LocalBbsTable,\r
-  IN UINT16     BbsCount\r
-  )\r
-{\r
-  UINT16  Index;\r
-\r
-  DEBUG ((DEBUG_INFO, "\n"));\r
-  DEBUG ((DEBUG_INFO, " NO  Prio bb/dd/ff cl/sc Type Stat segm:offs\n"));\r
-  DEBUG ((DEBUG_INFO, "=============================================\n"));\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if (!LegacyBmValidBbsEntry (&LocalBbsTable[Index])) {\r
-      continue;\r
-    }\r
-\r
-    DEBUG (\r
-      (DEBUG_INFO,\r
-      " %02x: %04x %02x/%02x/%02x %02x/%02x %04x %04x %04x:%04x\n",\r
-      (UINTN) Index,\r
-      (UINTN) LocalBbsTable[Index].BootPriority,\r
-      (UINTN) LocalBbsTable[Index].Bus,\r
-      (UINTN) LocalBbsTable[Index].Device,\r
-      (UINTN) LocalBbsTable[Index].Function,\r
-      (UINTN) LocalBbsTable[Index].Class,\r
-      (UINTN) LocalBbsTable[Index].SubClass,\r
-      (UINTN) LocalBbsTable[Index].DeviceType,\r
-      (UINTN) * (UINT16 *) &LocalBbsTable[Index].StatusFlags,\r
-      (UINTN) LocalBbsTable[Index].BootHandlerSegment,\r
-      (UINTN) LocalBbsTable[Index].BootHandlerOffset,\r
-      (UINTN) ((LocalBbsTable[Index].MfgStringSegment << 4) + LocalBbsTable[Index].MfgStringOffset),\r
-      (UINTN) ((LocalBbsTable[Index].DescStringSegment << 4) + LocalBbsTable[Index].DescStringOffset))\r
-      );\r
-  }\r
-\r
-  DEBUG ((DEBUG_INFO, "\n"));\r
-}\r
-\r
-/**\r
-  Set the boot priority for BBS entries based on boot option entry and boot order.\r
-\r
-  @param  BootOption            The boot option is to be checked for refresh BBS table.\r
-\r
-  @retval EFI_SUCCESS           The boot priority for BBS entries is refreshed successfully.\r
-  @retval EFI_NOT_FOUND         BBS entries can't be found.\r
-  @retval EFI_OUT_OF_RESOURCES  Failed to get the legacy device boot order.\r
-**/\r
-EFI_STATUS\r
-LegacyBmRefreshBbsTableForBoot (\r
-  IN EFI_BOOT_MANAGER_LOAD_OPTION        *BootOption\r
-  )\r
-{\r
-  EFI_STATUS                    Status;\r
-  UINT16                        BbsIndex;\r
-  UINT16                        HddCount;\r
-  UINT16                        BbsCount;\r
-  HDD_INFO                      *LocalHddInfo;\r
-  BBS_TABLE                     *LocalBbsTable;\r
-  UINT16                        DevType;\r
-  EFI_LEGACY_BIOS_PROTOCOL      *LegacyBios;\r
-  UINTN                         Index;\r
-  UINT16                        Priority;\r
-  UINT16                        *DeviceType;\r
-  UINTN                         DeviceTypeCount;\r
-  UINTN                         DeviceTypeIndex;\r
-  EFI_BOOT_MANAGER_LOAD_OPTION  *Option;\r
-  UINTN                         OptionCount;\r
-\r
-  HddCount      = 0;\r
-  BbsCount      = 0;\r
-  LocalHddInfo  = NULL;\r
-  LocalBbsTable = NULL;\r
-  DevType       = BBS_UNKNOWN;\r
-\r
-  Status        = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  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
-  //\r
-  // First, set all the present devices' boot priority to BBS_UNPRIORITIZED_ENTRY\r
-  // We will set them according to the settings setup by user\r
-  //\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if (LegacyBmValidBbsEntry (&LocalBbsTable[Index])) {\r
-      LocalBbsTable[Index].BootPriority = BBS_UNPRIORITIZED_ENTRY;\r
-    }\r
-  }\r
-  //\r
-  // boot priority always starts at 0\r
-  //\r
-  Priority = 0;\r
-  if ((DevicePathType (BootOption->FilePath) == BBS_DEVICE_PATH) &&\r
-      (DevicePathSubType (BootOption->FilePath) == BBS_BBS_DP)) {\r
-    //\r
-    // If BootOption stands for a legacy boot option, we prioritize the devices with the same type first.\r
-    //\r
-    DevType  = LegacyBmDeviceType (BootOption->FilePath);\r
-    BbsIndex = ((LEGACY_BM_BOOT_OPTION_BBS_DATA *) BootOption->OptionalData)->BbsIndex;\r
-    Status = LegacyBmSetPriorityForSameTypeDev (\r
-               DevType,\r
-               BbsIndex,\r
-               LocalBbsTable,\r
-               &Priority\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-  //\r
-  // we have to set the boot priority for other BBS entries with different device types\r
-  //\r
-  Option          = EfiBootManagerGetLoadOptions (&OptionCount, LoadOptionTypeBoot);\r
-  DeviceType      = AllocatePool (sizeof (UINT16) * OptionCount);\r
-  ASSERT (DeviceType != NULL);\r
-  DeviceType[0]   = DevType;\r
-  DeviceTypeCount = 1;\r
-  for (Index = 0; Index < OptionCount; Index++) {\r
-    if ((DevicePathType (Option[Index].FilePath) != BBS_DEVICE_PATH) ||\r
-        (DevicePathSubType (Option[Index].FilePath) != BBS_BBS_DP)) {\r
-      continue;\r
-    }\r
-\r
-    DevType = LegacyBmDeviceType (Option[Index].FilePath);\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
-      continue;\r
-    }\r
-\r
-    DeviceType[DeviceTypeCount] = DevType;\r
-    DeviceTypeCount++;\r
-\r
-    Status = LegacyBmSetPriorityForSameTypeDev (\r
-               DevType,\r
-               (UINTN) -1,\r
-               LocalBbsTable,\r
-               &Priority\r
-               );\r
-  }\r
-  EfiBootManagerFreeLoadOptions (Option, OptionCount);\r
-\r
-  DEBUG_CODE_BEGIN();\r
-    LegacyBmPrintBbsTable (LocalBbsTable, BbsCount);\r
-  DEBUG_CODE_END();\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Boot the legacy system with the boot option.\r
-\r
-  @param  BootOption The legacy boot option which have BBS device path\r
-                     On return, BootOption->Status contains the boot status.\r
-                     EFI_UNSUPPORTED    There is no legacybios protocol, do not support\r
-                                        legacy boot.\r
-                     EFI_STATUS         The status of LegacyBios->LegacyBoot ().\r
-**/\r
-VOID\r
-EFIAPI\r
-LegacyBmBoot (\r
-  IN  EFI_BOOT_MANAGER_LOAD_OPTION           *BootOption\r
-  )\r
-{\r
-  EFI_STATUS                Status;\r
-  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;\r
-\r
-  Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);\r
-  if (EFI_ERROR (Status)) {\r
-    //\r
-    // If no LegacyBios protocol we do not support legacy boot\r
-    //\r
-    BootOption->Status = EFI_UNSUPPORTED;\r
-    return;\r
-  }\r
-  //\r
-  // Notes: if we separate the int 19, then we don't need to refresh BBS\r
-  //\r
-  Status = LegacyBmRefreshBbsTableForBoot (BootOption);\r
-  if (EFI_ERROR (Status)) {\r
-    BootOption->Status = Status;\r
-    return;\r
-  }\r
-\r
-  BootOption->Status = LegacyBios->LegacyBoot (\r
-                                     LegacyBios,\r
-                                     (BBS_BBS_DEVICE_PATH *) BootOption->FilePath,\r
-                                     BootOption->OptionalDataSize,\r
-                                     BootOption->OptionalData\r
-                                     );\r
-}\r
-\r
-/**\r
-  This function enumerates all the legacy boot options.\r
-\r
-  @param BootOptionCount   Return the legacy boot option count.\r
-\r
-  @retval    Pointer to the legacy boot option buffer.\r
-**/\r
-EFI_BOOT_MANAGER_LOAD_OPTION *\r
-LegacyBmEnumerateAllBootOptions (\r
-  UINTN                         *BootOptionCount\r
-  )\r
-{\r
-  EFI_STATUS                    Status;\r
-  UINT16                        HddCount;\r
-  UINT16                        BbsCount;\r
-  HDD_INFO                      *HddInfo;\r
-  BBS_TABLE                     *BbsTable;\r
-  EFI_LEGACY_BIOS_PROTOCOL      *LegacyBios;\r
-  UINT16                        Index;\r
-  EFI_BOOT_MANAGER_LOAD_OPTION  *BootOptions;\r
-\r
-  ASSERT (BootOptionCount != NULL);\r
-\r
-  BootOptions      = NULL;\r
-  *BootOptionCount = 0;\r
-  BbsCount         = 0;\r
-\r
-  Status        = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);\r
-  if (EFI_ERROR (Status)) {\r
-    return NULL;\r
-  }\r
-\r
-  Status = LegacyBios->GetBbsInfo (\r
-                         LegacyBios,\r
-                         &HddCount,\r
-                         &HddInfo,\r
-                         &BbsCount,\r
-                         &BbsTable\r
-                         );\r
-  if (EFI_ERROR (Status)) {\r
-    return NULL;\r
-  }\r
-\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if (!LegacyBmValidBbsEntry (&BbsTable[Index])) {\r
-      continue;\r
-    }\r
-\r
-    BootOptions = ReallocatePool (\r
-                    sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount),\r
-                    sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1),\r
-                    BootOptions\r
-                    );\r
-    ASSERT (BootOptions != NULL);\r
-\r
-    Status = LegacyBmCreateLegacyBootOption (&BootOptions[(*BootOptionCount)++], &BbsTable[Index], Index);\r
-    ASSERT_EFI_ERROR (Status);\r
-  }\r
-\r
-  return BootOptions;\r
-}\r
-\r
-/**\r
-  Return the index of the boot option in the boot option array.\r
-\r
-  The function compares the Description, FilePath, OptionalData.\r
-\r
-  @param Key         The input boot option which is compared with.\r
-  @param Array       The input boot option array.\r
-  @param Count       The count of the input boot options.\r
-\r
-  @retval  The index of the input boot option in the array.\r
-\r
-**/\r
-INTN\r
-LegacyBmFindBootOption (\r
-  IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Key,\r
-  IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Array,\r
-  IN UINTN                              Count\r
-  )\r
-{\r
-  UINTN                             Index;\r
-\r
-  for (Index = 0; Index < Count; Index++) {\r
-    if ((StrCmp (Key->Description, Array[Index].Description) == 0) &&\r
-        (CompareMem (Key->FilePath, Array[Index].FilePath, GetDevicePathSize (Key->FilePath)) == 0) &&\r
-        (Key->OptionalDataSize == Array[Index].OptionalDataSize) &&\r
-        (CompareMem (Key->OptionalData, Array[Index].OptionalData, Key->OptionalDataSize) == 0)) {\r
-      return (INTN) Index;\r
-    }\r
-  }\r
-\r
-  return -1;\r
-}\r
-\r
-/**\r
-  Refresh all legacy boot options.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-LegacyBmRefreshAllBootOption (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS                                 Status;\r
-  EFI_LEGACY_BIOS_PROTOCOL                   *LegacyBios;\r
-  UINTN                                      RootBridgeHandleCount;\r
-  EFI_HANDLE                                 *RootBridgeHandleBuffer;\r
-  UINTN                                      HandleCount;\r
-  EFI_HANDLE                                 *HandleBuffer;\r
-  UINTN                                      RootBridgeIndex;\r
-  UINTN                                      Index;\r
-  UINTN                                      Flags;\r
-  EFI_BOOT_MANAGER_LOAD_OPTION               *BootOptions;\r
-  UINTN                                      BootOptionCount;\r
-  EFI_BOOT_MANAGER_LOAD_OPTION               *ExistingBootOptions;\r
-  UINTN                                      ExistingBootOptionCount;\r
-\r
-  Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);\r
-  if (EFI_ERROR (Status)) {\r
-    LegacyBmDeleteAllBootOptions ();\r
-    return;\r
-  }\r
-  PERF_START (NULL, "LegacyBootOptionEnum", "BDS", 0);\r
-\r
-  //\r
-  // Before enumerating the legacy boot option, we need to dispatch all the legacy option roms\r
-  // to ensure the GetBbsInfo() counts all the legacy devices.\r
-  //\r
-  gBS->LocateHandleBuffer (\r
-         ByProtocol,\r
-         &gEfiPciRootBridgeIoProtocolGuid,\r
-         NULL,\r
-         &RootBridgeHandleCount,\r
-         &RootBridgeHandleBuffer\r
-         );\r
-  for (RootBridgeIndex = 0; RootBridgeIndex < RootBridgeHandleCount; RootBridgeIndex++) {\r
-    gBS->ConnectController (RootBridgeHandleBuffer[RootBridgeIndex], NULL, NULL, FALSE);\r
-    gBS->LocateHandleBuffer (\r
-           ByProtocol,\r
-           &gEfiPciIoProtocolGuid,\r
-           NULL,\r
-           &HandleCount,\r
-           &HandleBuffer\r
-           );\r
-    for (Index = 0; Index < HandleCount; Index++) {\r
-      //\r
-      // Start the thunk driver so that the legacy option rom gets dispatched.\r
-      // Note: We don't directly call InstallPciRom because some thunk drivers\r
-      // (e.g. BlockIo thunk driver) depend on the immediate result after dispatching\r
-      //\r
-      Status = LegacyBios->CheckPciRom (\r
-                             LegacyBios,\r
-                             HandleBuffer[Index],\r
-                             NULL,\r
-                             NULL,\r
-                             &Flags\r
-                             );\r
-      if (!EFI_ERROR (Status)) {\r
-        gBS->ConnectController (HandleBuffer[Index], NULL, NULL, FALSE);\r
-      }\r
-    }\r
-  }\r
-\r
-  //\r
-  // Same algorithm pattern as the EfiBootManagerRefreshAllBootOption\r
-  // Firstly delete the invalid legacy boot options,\r
-  // then enumreate and save the newly appeared legacy boot options\r
-  // the last step is legacy boot option special action to refresh the LegacyDevOrder variable\r
-  //\r
-  LegacyBmDeleteAllInvalidBootOptions ();\r
-\r
-  ExistingBootOptions = EfiBootManagerGetLoadOptions (&ExistingBootOptionCount, LoadOptionTypeBoot);\r
-  BootOptions         = LegacyBmEnumerateAllBootOptions   (&BootOptionCount);\r
-\r
-  for (Index = 0; Index < BootOptionCount; Index++) {\r
-    if (LegacyBmFindBootOption (&BootOptions[Index], ExistingBootOptions, ExistingBootOptionCount) == -1) {\r
-      Status = EfiBootManagerAddLoadOptionVariable (&BootOptions[Index], (UINTN) -1);\r
-      DEBUG ((\r
-        EFI_D_INFO, "[LegacyBds] New Boot Option: Boot%04x Bbs0x%04x %s %r\n",\r
-        (UINTN) BootOptions[Index].OptionNumber,\r
-        (UINTN) ((LEGACY_BM_BOOT_OPTION_BBS_DATA *) BootOptions[Index].OptionalData)->BbsIndex,\r
-        BootOptions[Index].Description,\r
-        Status\r
-        ));\r
-      //\r
-      // Continue upon failure to add boot option.\r
-      //\r
-    }\r
-  }\r
-\r
-  EfiBootManagerFreeLoadOptions (ExistingBootOptions, ExistingBootOptionCount);\r
-  EfiBootManagerFreeLoadOptions (BootOptions,         BootOptionCount);\r
-\r
-  //\r
-  // Failure to create LegacyDevOrder variable only impacts the boot order.\r
-  //\r
-  LegacyBmUpdateDevOrder ();\r
-\r
-  PERF_END   (NULL, "LegacyBootOptionEnum", "BDS", 0);\r
-}\r