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