/** @file
handles console redirection from boot manager

Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "BootMaintenanceManager.h"

/**
  Function compares a device path data structure to that of all the nodes of a
  second device path instance.

  @param  Multi                 A pointer to a multi-instance device path data
                                structure.
  @param  Single                A pointer to a single-instance device path data
                                structure.

  @retval TRUE                  If the Single device path is contained within Multi device path.
  @retval FALSE                 The Single device path is not match within Multi device path.

**/
BOOLEAN
MatchDevicePaths (
  IN  EFI_DEVICE_PATH_PROTOCOL  *Multi,
  IN  EFI_DEVICE_PATH_PROTOCOL  *Single
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInst;
  UINTN                     Size;

  if ((Multi == NULL) || (Single  == NULL)) {
    return FALSE;
  }

  DevicePath     = Multi;
  DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);

  //
  // Search for the match of 'Single' in 'Multi'
  //
  while (DevicePathInst != NULL) {
    //
    // If the single device path is found in multiple device paths,
    // return success
    //
    if (CompareMem (Single, DevicePathInst, Size) == 0) {
      FreePool (DevicePathInst);
      return TRUE;
    }

    FreePool (DevicePathInst);
    DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
  }

  return FALSE;
}

/**
  Check whether the device path node is ISA Serial Node.

  @param Acpi           Device path node to be checked

  @retval TRUE          It's ISA Serial Node.
  @retval FALSE         It's NOT ISA Serial Node.

**/
BOOLEAN
IsIsaSerialNode (
  IN ACPI_HID_DEVICE_PATH  *Acpi
  )
{
  return (BOOLEAN)(
                   (DevicePathType (Acpi) == ACPI_DEVICE_PATH) &&
                   (DevicePathSubType (Acpi) == ACPI_DP) &&
                   (ReadUnaligned32 (&Acpi->HID) == EISA_PNP_ID (0x0501))
                   );
}

/**
  Update Com Ports attributes from DevicePath

  @param DevicePath      DevicePath that contains Com ports

  @retval EFI_SUCCESS   The update is successful.

**/
EFI_STATUS
UpdateComAttributeFromVariable (
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath
  );

/**
  Update the multi-instance device path of Terminal Device based on
  the global TerminalMenu. If ChangeTernimal is TRUE, the terminal
  device path in the Terminal Device in TerminalMenu is also updated.

  @param DevicePath      The multi-instance device path.
  @param ChangeTerminal  TRUE, then device path in the Terminal Device
                         in TerminalMenu is also updated; FALSE, no update.

  @return EFI_SUCCESS    The function completes successfully.

**/
EFI_STATUS
ChangeTerminalDevicePath (
  IN OUT    EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
  IN        BOOLEAN                   ChangeTerminal
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *Node;
  EFI_DEVICE_PATH_PROTOCOL  *Node1;
  ACPI_HID_DEVICE_PATH      *Acpi;
  UART_DEVICE_PATH          *Uart;
  UART_DEVICE_PATH          *Uart1;
  UINTN                     Com;
  BM_TERMINAL_CONTEXT       *NewTerminalContext;
  BM_MENU_ENTRY             *NewMenuEntry;

  Node = DevicePath;
  Node = NextDevicePathNode (Node);
  Com  = 0;
  while (!IsDevicePathEnd (Node)) {
    Acpi = (ACPI_HID_DEVICE_PATH *)Node;
    if (IsIsaSerialNode (Acpi)) {
      CopyMem (&Com, &Acpi->UID, sizeof (UINT32));
    }

    NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Com);

    NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;
    if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {
      Uart = (UART_DEVICE_PATH *)Node;
      CopyMem (
        &Uart->BaudRate,
        &NewTerminalContext->BaudRate,
        sizeof (UINT64)
        );

      CopyMem (
        &Uart->DataBits,
        &NewTerminalContext->DataBits,
        sizeof (UINT8)
        );

      CopyMem (
        &Uart->Parity,
        &NewTerminalContext->Parity,
        sizeof (UINT8)
        );

      CopyMem (
        &Uart->StopBits,
        &NewTerminalContext->StopBits,
        sizeof (UINT8)
        );
      //
      // Change the device path in the ComPort
      //
      if (ChangeTerminal) {
        Node1 = NewTerminalContext->DevicePath;
        Node1 = NextDevicePathNode (Node1);
        while (!IsDevicePathEnd (Node1)) {
          if ((DevicePathType (Node1) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node1) == MSG_UART_DP)) {
            Uart1 = (UART_DEVICE_PATH *)Node1;
            CopyMem (
              &Uart1->BaudRate,
              &NewTerminalContext->BaudRate,
              sizeof (UINT64)
              );

            CopyMem (
              &Uart1->DataBits,
              &NewTerminalContext->DataBits,
              sizeof (UINT8)
              );

            CopyMem (
              &Uart1->Parity,
              &NewTerminalContext->Parity,
              sizeof (UINT8)
              );

            CopyMem (
              &Uart1->StopBits,
              &NewTerminalContext->StopBits,
              sizeof (UINT8)
              );
            break;
          }

          //
          // end if
          //
          Node1 = NextDevicePathNode (Node1);
        }

        //
        // end while
        //
        break;
      }
    }

    Node = NextDevicePathNode (Node);
  }

  return EFI_SUCCESS;
}

/**
  Update the device path that describing a terminal device
  based on the new BaudRate, Data Bits, parity and Stop Bits
  set.

  @param DevicePath terminal device's path

**/
VOID
ChangeVariableDevicePath (
  IN OUT EFI_DEVICE_PATH_PROTOCOL  *DevicePath
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *Node;
  ACPI_HID_DEVICE_PATH      *Acpi;
  UART_DEVICE_PATH          *Uart;
  UINTN                     Com;
  BM_TERMINAL_CONTEXT       *NewTerminalContext;
  BM_MENU_ENTRY             *NewMenuEntry;

  Node = DevicePath;
  Node = NextDevicePathNode (Node);
  Com  = 0;
  while (!IsDevicePathEnd (Node)) {
    Acpi = (ACPI_HID_DEVICE_PATH *)Node;
    if (IsIsaSerialNode (Acpi)) {
      CopyMem (&Com, &Acpi->UID, sizeof (UINT32));
    }

    if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {
      NewMenuEntry = BOpt_GetMenuEntry (
                       &TerminalMenu,
                       Com
                       );
      ASSERT (NewMenuEntry != NULL);
      NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;
      Uart               = (UART_DEVICE_PATH *)Node;
      CopyMem (
        &Uart->BaudRate,
        &NewTerminalContext->BaudRate,
        sizeof (UINT64)
        );

      CopyMem (
        &Uart->DataBits,
        &NewTerminalContext->DataBits,
        sizeof (UINT8)
        );

      CopyMem (
        &Uart->Parity,
        &NewTerminalContext->Parity,
        sizeof (UINT8)
        );

      CopyMem (
        &Uart->StopBits,
        &NewTerminalContext->StopBits,
        sizeof (UINT8)
        );
    }

    Node = NextDevicePathNode (Node);
  }
}

/**
  Retrieve ACPI UID of UART from device path

  @param Handle          The handle for the UART device.
  @param AcpiUid         The ACPI UID on output.

  @retval  TRUE   Find valid UID from device path
  @retval  FALSE  Can't find

**/
BOOLEAN
RetrieveUartUid (
  IN EFI_HANDLE  Handle,
  IN OUT UINT32  *AcpiUid
  )
{
  EFI_STATUS                Status;
  ACPI_HID_DEVICE_PATH      *Acpi;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

  Status = gBS->HandleProtocol (
                  Handle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&DevicePath
                  );
  if (EFI_ERROR (Status)) {
    return FALSE;
  }

  Acpi = NULL;
  for ( ; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {
    if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (DevicePath) == MSG_UART_DP)) {
      break;
    }

    //
    // Acpi points to the node before the Uart node
    //
    Acpi = (ACPI_HID_DEVICE_PATH *)DevicePath;
  }

  if ((Acpi != NULL) && IsIsaSerialNode (Acpi)) {
    if (AcpiUid != NULL) {
      CopyMem (AcpiUid, &Acpi->UID, sizeof (UINT32));
    }

    return TRUE;
  } else {
    return FALSE;
  }
}

/**
  Sort Uart handles array with Acpi->UID from low to high.

  @param Handles         EFI_SERIAL_IO_PROTOCOL handle buffer
  @param NoHandles       EFI_SERIAL_IO_PROTOCOL handle count
**/
VOID
SortedUartHandle (
  IN  EFI_HANDLE  *Handles,
  IN  UINTN       NoHandles
  )
{
  UINTN       Index1;
  UINTN       Index2;
  UINTN       Position;
  UINT32      AcpiUid1;
  UINT32      AcpiUid2;
  UINT32      TempAcpiUid;
  EFI_HANDLE  TempHandle;

  for (Index1 = 0; Index1 < NoHandles-1; Index1++) {
    if (!RetrieveUartUid (Handles[Index1], &AcpiUid1)) {
      continue;
    }

    TempHandle  = Handles[Index1];
    Position    = Index1;
    TempAcpiUid = AcpiUid1;

    for (Index2 = Index1+1; Index2 < NoHandles; Index2++) {
      if (!RetrieveUartUid (Handles[Index2], &AcpiUid2)) {
        continue;
      }

      if (AcpiUid2 < TempAcpiUid) {
        TempAcpiUid = AcpiUid2;
        TempHandle  = Handles[Index2];
        Position    = Index2;
      }
    }

    Handles[Position] = Handles[Index1];
    Handles[Index1]   = TempHandle;
  }
}

/**
  Test whether DevicePath is a valid Terminal


  @param DevicePath      DevicePath to be checked
  @param Termi           If DevicePath is valid Terminal, terminal type is returned.
  @param Com             If DevicePath is valid Terminal, Com Port type is returned.

  @retval  TRUE         If DevicePath point to a Terminal.
  @retval  FALSE        If DevicePath does not point to a Terminal.

**/
BOOLEAN
IsTerminalDevicePath (
  IN  EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
  OUT TYPE_OF_TERMINAL          *Termi,
  OUT UINTN                     *Com
  );

/**
  Build a list containing all serial devices.


  @retval EFI_SUCCESS The function complete successfully.
  @retval EFI_UNSUPPORTED No serial ports present.

**/
EFI_STATUS
LocateSerialIo (
  VOID
  )
{
  UINTN                     Index;
  UINTN                     Index2;
  UINTN                     NoHandles;
  EFI_HANDLE                *Handles;
  EFI_STATUS                Status;
  ACPI_HID_DEVICE_PATH      *Acpi;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_SERIAL_IO_PROTOCOL    *SerialIo;
  EFI_DEVICE_PATH_PROTOCOL  *Node;
  EFI_DEVICE_PATH_PROTOCOL  *OutDevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *InpDevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *ErrDevicePath;
  BM_MENU_ENTRY             *NewMenuEntry;
  BM_TERMINAL_CONTEXT       *NewTerminalContext;
  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;
  VENDOR_DEVICE_PATH        Vendor;

  //
  // Get all handles that have SerialIo protocol installed
  //
  InitializeListHead (&TerminalMenu.Head);
  TerminalMenu.MenuNumber = 0;
  Status                  = gBS->LocateHandleBuffer (
                                   ByProtocol,
                                   &gEfiSerialIoProtocolGuid,
                                   NULL,
                                   &NoHandles,
                                   &Handles
                                   );
  if (EFI_ERROR (Status)) {
    //
    // No serial ports present
    //
    return EFI_UNSUPPORTED;
  }

  //
  // Sort Uart handles array with Acpi->UID from low to high
  // then Terminal menu can be built from low Acpi->UID to high Acpi->UID
  //
  SortedUartHandle (Handles, NoHandles);

  for (Index = 0; Index < NoHandles; Index++) {
    //
    // Check to see whether the handle has DevicePath Protocol installed
    //
    gBS->HandleProtocol (
           Handles[Index],
           &gEfiDevicePathProtocolGuid,
           (VOID **)&DevicePath
           );

    Acpi = NULL;
    for (Node = DevicePath; !IsDevicePathEnd (Node); Node = NextDevicePathNode (Node)) {
      if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {
        break;
      }

      //
      // Acpi points to the node before Uart node
      //
      Acpi = (ACPI_HID_DEVICE_PATH *)Node;
    }

    if ((Acpi != NULL) && IsIsaSerialNode (Acpi)) {
      NewMenuEntry = BOpt_CreateMenuEntry (BM_TERMINAL_CONTEXT_SELECT);
      if (NewMenuEntry == NULL) {
        FreePool (Handles);
        return EFI_OUT_OF_RESOURCES;
      }

      NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;
      CopyMem (&NewMenuEntry->OptionNumber, &Acpi->UID, sizeof (UINT32));
      NewTerminalContext->DevicePath = DuplicateDevicePath (DevicePath);
      //
      // BugBug: I have no choice, calling EfiLibStrFromDatahub will hang the system!
      // coz' the misc data for each platform is not correct, actually it's the device path stored in
      // datahub which is not completed, so a searching for end of device path will enter a
      // dead-loop.
      //
      NewMenuEntry->DisplayString = EfiLibStrFromDatahub (DevicePath);
      if (NULL == NewMenuEntry->DisplayString) {
        NewMenuEntry->DisplayString = UiDevicePathToStr (DevicePath);
      }

      NewMenuEntry->HelpString = NULL;

      NewMenuEntry->DisplayStringToken = HiiSetString (mBmmCallbackInfo->BmmHiiHandle, 0, NewMenuEntry->DisplayString, NULL);

      NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;

      gBS->HandleProtocol (
             Handles[Index],
             &gEfiSerialIoProtocolGuid,
             (VOID **)&SerialIo
             );

      CopyMem (
        &NewTerminalContext->BaudRate,
        &SerialIo->Mode->BaudRate,
        sizeof (UINT64)
        );

      CopyMem (
        &NewTerminalContext->DataBits,
        &SerialIo->Mode->DataBits,
        sizeof (UINT8)
        );

      CopyMem (
        &NewTerminalContext->Parity,
        &SerialIo->Mode->Parity,
        sizeof (UINT8)
        );

      CopyMem (
        &NewTerminalContext->StopBits,
        &SerialIo->Mode->StopBits,
        sizeof (UINT8)
        );
      InsertTailList (&TerminalMenu.Head, &NewMenuEntry->Link);
      TerminalMenu.MenuNumber++;
    }
  }

  if (Handles != NULL) {
    FreePool (Handles);
  }

  //
  // Get L"ConOut", L"ConIn" and L"ErrOut" from the Var
  //
  GetEfiGlobalVariable2 (L"ConOut", (VOID **)&OutDevicePath, NULL);
  GetEfiGlobalVariable2 (L"ConIn", (VOID **)&InpDevicePath, NULL);
  GetEfiGlobalVariable2 (L"ErrOut", (VOID **)&ErrDevicePath, NULL);
  if (OutDevicePath != NULL) {
    UpdateComAttributeFromVariable (OutDevicePath);
  }

  if (InpDevicePath != NULL) {
    UpdateComAttributeFromVariable (InpDevicePath);
  }

  if (ErrDevicePath != NULL) {
    UpdateComAttributeFromVariable (ErrDevicePath);
  }

  for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
    NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
    if (NULL == NewMenuEntry) {
      return EFI_NOT_FOUND;
    }

    NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;

    NewTerminalContext->TerminalType = 0;
    NewTerminalContext->IsConIn      = FALSE;
    NewTerminalContext->IsConOut     = FALSE;
    NewTerminalContext->IsStdErr     = FALSE;

    Vendor.Header.Type    = MESSAGING_DEVICE_PATH;
    Vendor.Header.SubType = MSG_VENDOR_DP;

    for (Index2 = 0; Index2 < (ARRAY_SIZE (TerminalTypeGuid)); Index2++) {
      CopyMem (&Vendor.Guid, &TerminalTypeGuid[Index2], sizeof (EFI_GUID));
      SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));
      NewDevicePath = AppendDevicePathNode (
                        NewTerminalContext->DevicePath,
                        (EFI_DEVICE_PATH_PROTOCOL *)&Vendor
                        );
      if (NewMenuEntry->HelpString != NULL) {
        FreePool (NewMenuEntry->HelpString);
      }

      //
      // NewMenuEntry->HelpString = UiDevicePathToStr (NewDevicePath);
      // NewMenuEntry->DisplayString = NewMenuEntry->HelpString;
      //
      NewMenuEntry->HelpString = NULL;

      NewMenuEntry->DisplayStringToken = HiiSetString (mBmmCallbackInfo->BmmHiiHandle, 0, NewMenuEntry->DisplayString, NULL);

      NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;

      if (MatchDevicePaths (OutDevicePath, NewDevicePath)) {
        NewTerminalContext->IsConOut     = TRUE;
        NewTerminalContext->TerminalType = (UINT8)Index2;
      }

      if (MatchDevicePaths (InpDevicePath, NewDevicePath)) {
        NewTerminalContext->IsConIn      = TRUE;
        NewTerminalContext->TerminalType = (UINT8)Index2;
      }

      if (MatchDevicePaths (ErrDevicePath, NewDevicePath)) {
        NewTerminalContext->IsStdErr     = TRUE;
        NewTerminalContext->TerminalType = (UINT8)Index2;
      }
    }
  }

  return EFI_SUCCESS;
}

/**
  Update Com Ports attributes from DevicePath

  @param DevicePath      DevicePath that contains Com ports

  @retval EFI_SUCCESS   The update is successful.
  @retval EFI_NOT_FOUND Can not find specific menu entry
**/
EFI_STATUS
UpdateComAttributeFromVariable (
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *Node;
  EFI_DEVICE_PATH_PROTOCOL  *SerialNode;
  ACPI_HID_DEVICE_PATH      *Acpi;
  UART_DEVICE_PATH          *Uart;
  UART_DEVICE_PATH          *Uart1;
  UINTN                     TerminalNumber;
  BM_MENU_ENTRY             *NewMenuEntry;
  BM_TERMINAL_CONTEXT       *NewTerminalContext;
  UINTN                     Index;

  Node           = DevicePath;
  Node           = NextDevicePathNode (Node);
  TerminalNumber = 0;
  for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
    while (!IsDevicePathEnd (Node)) {
      Acpi = (ACPI_HID_DEVICE_PATH *)Node;
      if (IsIsaSerialNode (Acpi)) {
        CopyMem (&TerminalNumber, &Acpi->UID, sizeof (UINT32));
      }

      if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {
        Uart         = (UART_DEVICE_PATH *)Node;
        NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, TerminalNumber);
        if (NULL == NewMenuEntry) {
          return EFI_NOT_FOUND;
        }

        NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;
        CopyMem (
          &NewTerminalContext->BaudRate,
          &Uart->BaudRate,
          sizeof (UINT64)
          );

        CopyMem (
          &NewTerminalContext->DataBits,
          &Uart->DataBits,
          sizeof (UINT8)
          );

        CopyMem (
          &NewTerminalContext->Parity,
          &Uart->Parity,
          sizeof (UINT8)
          );

        CopyMem (
          &NewTerminalContext->StopBits,
          &Uart->StopBits,
          sizeof (UINT8)
          );

        SerialNode = NewTerminalContext->DevicePath;
        SerialNode = NextDevicePathNode (SerialNode);
        while (!IsDevicePathEnd (SerialNode)) {
          if ((DevicePathType (SerialNode) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (SerialNode) == MSG_UART_DP)) {
            //
            // Update following device paths according to
            // previous acquired uart attributes
            //
            Uart1 = (UART_DEVICE_PATH *)SerialNode;
            CopyMem (
              &Uart1->BaudRate,
              &NewTerminalContext->BaudRate,
              sizeof (UINT64)
              );

            CopyMem (
              &Uart1->DataBits,
              &NewTerminalContext->DataBits,
              sizeof (UINT8)
              );
            CopyMem (
              &Uart1->Parity,
              &NewTerminalContext->Parity,
              sizeof (UINT8)
              );
            CopyMem (
              &Uart1->StopBits,
              &NewTerminalContext->StopBits,
              sizeof (UINT8)
              );

            break;
          }

          SerialNode = NextDevicePathNode (SerialNode);
        }

        //
        // end while
        //
      }

      Node = NextDevicePathNode (Node);
    }

    //
    // end while
    //
  }

  return EFI_SUCCESS;
}

/**
  Build up Console Menu based on types passed in. The type can
  be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT
  and BM_CONSOLE_ERR_CONTEXT_SELECT.

  @param ConsoleMenuType Can be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT
                         and BM_CONSOLE_ERR_CONTEXT_SELECT.

  @retval EFI_UNSUPPORTED The type passed in is not in the 3 types defined.
  @retval EFI_NOT_FOUND   If the EFI Variable defined in UEFI spec with name "ConOutDev",
                          "ConInDev" or "ConErrDev" doesn't exists.
  @retval EFI_OUT_OF_RESOURCES Not enough resource to complete the operations.
  @retval EFI_SUCCESS          Function completes successfully.

**/
EFI_STATUS
GetConsoleMenu (
  IN UINTN  ConsoleMenuType
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *AllDevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *MultiDevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInst;
  UINTN                     Size;
  UINTN                     AllCount;
  UINTN                     Index;
  UINTN                     Index2;
  BM_MENU_ENTRY             *NewMenuEntry;
  BM_CONSOLE_CONTEXT        *NewConsoleContext;
  TYPE_OF_TERMINAL          Terminal;
  UINTN                     Com;
  BM_MENU_OPTION            *ConsoleMenu;

  DevicePath    = NULL;
  AllDevicePath = NULL;
  AllCount      = 0;
  switch (ConsoleMenuType) {
    case BM_CONSOLE_IN_CONTEXT_SELECT:
      ConsoleMenu = &ConsoleInpMenu;
      GetEfiGlobalVariable2 (L"ConIn", (VOID **)&DevicePath, NULL);
      GetEfiGlobalVariable2 (L"ConInDev", (VOID **)&AllDevicePath, NULL);
      break;

    case BM_CONSOLE_OUT_CONTEXT_SELECT:
      ConsoleMenu = &ConsoleOutMenu;
      GetEfiGlobalVariable2 (L"ConOut", (VOID **)&DevicePath, NULL);
      GetEfiGlobalVariable2 (L"ConOutDev", (VOID **)&AllDevicePath, NULL);
      break;

    case BM_CONSOLE_ERR_CONTEXT_SELECT:
      ConsoleMenu = &ConsoleErrMenu;
      GetEfiGlobalVariable2 (L"ErrOut", (VOID **)&DevicePath, NULL);
      GetEfiGlobalVariable2 (L"ErrOutDev", (VOID **)&AllDevicePath, NULL);
      break;

    default:
      return EFI_UNSUPPORTED;
  }

  if (NULL == AllDevicePath) {
    return EFI_NOT_FOUND;
  }

  InitializeListHead (&ConsoleMenu->Head);

  AllCount                = EfiDevicePathInstanceCount (AllDevicePath);
  ConsoleMenu->MenuNumber = 0;
  //
  // Following is menu building up for Console Devices selected.
  //
  MultiDevicePath = AllDevicePath;
  Index2          = 0;
  for (Index = 0; Index < AllCount; Index++) {
    DevicePathInst = GetNextDevicePathInstance (&MultiDevicePath, &Size);
    if (DevicePathInst == NULL) {
      ASSERT (DevicePathInst != NULL);
      continue;
    }

    NewMenuEntry = BOpt_CreateMenuEntry (BM_CONSOLE_CONTEXT_SELECT);
    if (NULL == NewMenuEntry) {
      return EFI_OUT_OF_RESOURCES;
    }

    NewConsoleContext          = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;
    NewMenuEntry->OptionNumber = Index2;

    NewConsoleContext->DevicePath = DuplicateDevicePath (DevicePathInst);
    if (NewConsoleContext->DevicePath == NULL) {
      ASSERT (NewConsoleContext->DevicePath != NULL);
      return EFI_OUT_OF_RESOURCES;
    }

    NewMenuEntry->DisplayString = EfiLibStrFromDatahub (NewConsoleContext->DevicePath);
    if (NULL == NewMenuEntry->DisplayString) {
      NewMenuEntry->DisplayString = UiDevicePathToStr (NewConsoleContext->DevicePath);
    }

    NewMenuEntry->DisplayStringToken = HiiSetString (mBmmCallbackInfo->BmmHiiHandle, 0, NewMenuEntry->DisplayString, NULL);

    if (NULL == NewMenuEntry->HelpString) {
      NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;
    } else {
      NewMenuEntry->HelpStringToken = HiiSetString (mBmmCallbackInfo->BmmHiiHandle, 0, NewMenuEntry->HelpString, NULL);
    }

    NewConsoleContext->IsTerminal = IsTerminalDevicePath (
                                      NewConsoleContext->DevicePath,
                                      &Terminal,
                                      &Com
                                      );

    NewConsoleContext->IsActive = MatchDevicePaths (
                                    DevicePath,
                                    NewConsoleContext->DevicePath
                                    );

    if (NewConsoleContext->IsTerminal) {
      BOpt_DestroyMenuEntry (NewMenuEntry);
    } else {
      Index2++;
      ConsoleMenu->MenuNumber++;
      InsertTailList (&ConsoleMenu->Head, &NewMenuEntry->Link);
    }
  }

  return EFI_SUCCESS;
}

/**
  Build up ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu

  @retval EFI_SUCCESS    The function always complete successfully.

**/
EFI_STATUS
GetAllConsoles (
  VOID
  )
{
  GetConsoleMenu (BM_CONSOLE_IN_CONTEXT_SELECT);
  GetConsoleMenu (BM_CONSOLE_OUT_CONTEXT_SELECT);
  GetConsoleMenu (BM_CONSOLE_ERR_CONTEXT_SELECT);
  return EFI_SUCCESS;
}

/**
  Free ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu

  @retval EFI_SUCCESS    The function always complete successfully.
**/
EFI_STATUS
FreeAllConsoles (
  VOID
  )
{
  BOpt_FreeMenu (&ConsoleOutMenu);
  BOpt_FreeMenu (&ConsoleInpMenu);
  BOpt_FreeMenu (&ConsoleErrMenu);
  BOpt_FreeMenu (&TerminalMenu);
  return EFI_SUCCESS;
}

/**
  Test whether DevicePath is a valid Terminal


  @param DevicePath      DevicePath to be checked
  @param Termi           If DevicePath is valid Terminal, terminal type is returned.
  @param Com             If DevicePath is valid Terminal, Com Port type is returned.

  @retval  TRUE         If DevicePath point to a Terminal.
  @retval  FALSE        If DevicePath does not point to a Terminal.

**/
BOOLEAN
IsTerminalDevicePath (
  IN  EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
  OUT TYPE_OF_TERMINAL          *Termi,
  OUT UINTN                     *Com
  )
{
  BOOLEAN                   IsTerminal;
  EFI_DEVICE_PATH_PROTOCOL  *Node;
  VENDOR_DEVICE_PATH        *Vendor;
  UART_DEVICE_PATH          *Uart;
  ACPI_HID_DEVICE_PATH      *Acpi;
  UINTN                     Index;

  IsTerminal = FALSE;

  Uart   = NULL;
  Vendor = NULL;
  Acpi   = NULL;
  for (Node = DevicePath; !IsDevicePathEnd (Node); Node = NextDevicePathNode (Node)) {
    //
    // Vendor points to the node before the End node
    //
    Vendor = (VENDOR_DEVICE_PATH *)Node;

    if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {
      Uart = (UART_DEVICE_PATH *)Node;
    }

    if (Uart == NULL) {
      //
      // Acpi points to the node before the UART node
      //
      Acpi = (ACPI_HID_DEVICE_PATH *)Node;
    }
  }

  if ((Vendor == NULL) ||
      (DevicePathType (Vendor) != MESSAGING_DEVICE_PATH) ||
      (DevicePathSubType (Vendor) != MSG_VENDOR_DP) ||
      (Uart == NULL))
  {
    return FALSE;
  }

  //
  // There are 9 kinds of Terminal types
  // check to see whether this devicepath
  // is one of that type
  //
  for (Index = 0; Index < ARRAY_SIZE (TerminalTypeGuid); Index++) {
    if (CompareGuid (&Vendor->Guid, &TerminalTypeGuid[Index])) {
      *Termi     = Index;
      IsTerminal = TRUE;
      break;
    }
  }

  if (Index == ARRAY_SIZE (TerminalTypeGuid)) {
    IsTerminal = FALSE;
  }

  if (!IsTerminal) {
    return FALSE;
  }

  if ((Acpi != NULL) && IsIsaSerialNode (Acpi)) {
    CopyMem (Com, &Acpi->UID, sizeof (UINT32));
  } else {
    return FALSE;
  }

  return TRUE;
}

/**
  Get mode number according to column and row

  @param CallbackData    The BMM context data.
**/
VOID
GetConsoleOutMode (
  IN  BMM_CALLBACK_DATA  *CallbackData
  )
{
  UINTN                            Col;
  UINTN                            Row;
  UINTN                            CurrentCol;
  UINTN                            CurrentRow;
  UINTN                            Mode;
  UINTN                            MaxMode;
  EFI_STATUS                       Status;
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *ConOut;

  ConOut  = gST->ConOut;
  MaxMode = (UINTN)(ConOut->Mode->MaxMode);

  CurrentCol = PcdGet32 (PcdSetupConOutColumn);
  CurrentRow = PcdGet32 (PcdSetupConOutRow);
  for (Mode = 0; Mode < MaxMode; Mode++) {
    Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row);
    if (!EFI_ERROR (Status)) {
      if ((CurrentCol == Col) && (CurrentRow == Row)) {
        CallbackData->BmmFakeNvData.ConsoleOutMode = (UINT16)Mode;
        break;
      }
    }
  }
}

/**

  Initialize console input device check box to ConsoleInCheck[MAX_MENU_NUMBER]
  in BMM_FAKE_NV_DATA structure.

  @param CallbackData    The BMM context data.

**/
VOID
GetConsoleInCheck (
  IN  BMM_CALLBACK_DATA  *CallbackData
  )
{
  UINTN                Index;
  BM_MENU_ENTRY        *NewMenuEntry;
  UINT8                *ConInCheck;
  BM_CONSOLE_CONTEXT   *NewConsoleContext;
  BM_TERMINAL_CONTEXT  *NewTerminalContext;

  ASSERT (CallbackData != NULL);

  ConInCheck = &CallbackData->BmmFakeNvData.ConsoleInCheck[0];
  for (Index = 0; ((Index < ConsoleInpMenu.MenuNumber) && \
                   (Index < MAX_MENU_NUMBER)); Index++)
  {
    NewMenuEntry      = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);
    NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;
    ConInCheck[Index] = NewConsoleContext->IsActive;
  }

  for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
    NewMenuEntry       = BOpt_GetMenuEntry (&TerminalMenu, Index);
    NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;
    ASSERT (Index + ConsoleInpMenu.MenuNumber < MAX_MENU_NUMBER);
    ConInCheck[Index + ConsoleInpMenu.MenuNumber] = NewTerminalContext->IsConIn;
  }
}

/**

  Initialize console output device check box to ConsoleOutCheck[MAX_MENU_NUMBER]
  in BMM_FAKE_NV_DATA structure.

  @param CallbackData    The BMM context data.

**/
VOID
GetConsoleOutCheck (
  IN  BMM_CALLBACK_DATA  *CallbackData
  )
{
  UINTN                Index;
  BM_MENU_ENTRY        *NewMenuEntry;
  UINT8                *ConOutCheck;
  BM_CONSOLE_CONTEXT   *NewConsoleContext;
  BM_TERMINAL_CONTEXT  *NewTerminalContext;

  ASSERT (CallbackData != NULL);
  ConOutCheck = &CallbackData->BmmFakeNvData.ConsoleOutCheck[0];
  for (Index = 0; ((Index < ConsoleOutMenu.MenuNumber) && \
                   (Index < MAX_MENU_NUMBER)); Index++)
  {
    NewMenuEntry       = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);
    NewConsoleContext  = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;
    ConOutCheck[Index] = NewConsoleContext->IsActive;
  }

  for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
    NewMenuEntry       = BOpt_GetMenuEntry (&TerminalMenu, Index);
    NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;
    ASSERT (Index + ConsoleOutMenu.MenuNumber < MAX_MENU_NUMBER);
    ConOutCheck[Index + ConsoleOutMenu.MenuNumber] = NewTerminalContext->IsConOut;
  }
}

/**

  Initialize standard error output device check box to ConsoleErrCheck[MAX_MENU_NUMBER]
  in BMM_FAKE_NV_DATA structure.

  @param CallbackData    The BMM context data.

**/
VOID
GetConsoleErrCheck (
  IN  BMM_CALLBACK_DATA  *CallbackData
  )
{
  UINTN                Index;
  BM_MENU_ENTRY        *NewMenuEntry;
  UINT8                *ConErrCheck;
  BM_CONSOLE_CONTEXT   *NewConsoleContext;
  BM_TERMINAL_CONTEXT  *NewTerminalContext;

  ASSERT (CallbackData != NULL);
  ConErrCheck = &CallbackData->BmmFakeNvData.ConsoleErrCheck[0];
  for (Index = 0; ((Index < ConsoleErrMenu.MenuNumber) && \
                   (Index < MAX_MENU_NUMBER)); Index++)
  {
    NewMenuEntry       = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);
    NewConsoleContext  = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;
    ConErrCheck[Index] = NewConsoleContext->IsActive;
  }

  for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
    NewMenuEntry       = BOpt_GetMenuEntry (&TerminalMenu, Index);
    NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;
    ASSERT (Index + ConsoleErrMenu.MenuNumber < MAX_MENU_NUMBER);
    ConErrCheck[Index + ConsoleErrMenu.MenuNumber] = NewTerminalContext->IsStdErr;
  }
}

/**

  Initialize terminal attributes (baudrate, data rate, stop bits, parity and terminal type)
  to BMM_FAKE_NV_DATA structure.

  @param CallbackData    The BMM context data.

**/
VOID
GetTerminalAttribute (
  IN  BMM_CALLBACK_DATA  *CallbackData
  )
{
  BMM_FAKE_NV_DATA     *CurrentFakeNVMap;
  BM_MENU_ENTRY        *NewMenuEntry;
  BM_TERMINAL_CONTEXT  *NewTerminalContext;
  UINTN                TerminalIndex;
  UINT8                AttributeIndex;

  ASSERT (CallbackData != NULL);

  CurrentFakeNVMap = &CallbackData->BmmFakeNvData;
  for (TerminalIndex = 0; ((TerminalIndex < TerminalMenu.MenuNumber) && \
                           (TerminalIndex < MAX_MENU_NUMBER)); TerminalIndex++)
  {
    NewMenuEntry       = BOpt_GetMenuEntry (&TerminalMenu, TerminalIndex);
    NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;
    for (AttributeIndex = 0; AttributeIndex < sizeof (BaudRateList) / sizeof (BaudRateList[0]); AttributeIndex++) {
      if (NewTerminalContext->BaudRate == (UINT64)(BaudRateList[AttributeIndex].Value)) {
        NewTerminalContext->BaudRateIndex = AttributeIndex;
        break;
      }
    }

    for (AttributeIndex = 0; AttributeIndex < ARRAY_SIZE (DataBitsList); AttributeIndex++) {
      if (NewTerminalContext->DataBits == (UINT64)(DataBitsList[AttributeIndex].Value)) {
        NewTerminalContext->DataBitsIndex = AttributeIndex;
        break;
      }
    }

    for (AttributeIndex = 0; AttributeIndex < ARRAY_SIZE (ParityList); AttributeIndex++) {
      if (NewTerminalContext->Parity == (UINT64)(ParityList[AttributeIndex].Value)) {
        NewTerminalContext->ParityIndex = AttributeIndex;
        break;
      }
    }

    for (AttributeIndex = 0; AttributeIndex < ARRAY_SIZE (StopBitsList); AttributeIndex++) {
      if (NewTerminalContext->StopBits == (UINT64)(StopBitsList[AttributeIndex].Value)) {
        NewTerminalContext->StopBitsIndex = AttributeIndex;
        break;
      }
    }

    CurrentFakeNVMap->COMBaudRate[TerminalIndex]     = NewTerminalContext->BaudRateIndex;
    CurrentFakeNVMap->COMDataRate[TerminalIndex]     = NewTerminalContext->DataBitsIndex;
    CurrentFakeNVMap->COMStopBits[TerminalIndex]     = NewTerminalContext->StopBitsIndex;
    CurrentFakeNVMap->COMParity[TerminalIndex]       = NewTerminalContext->ParityIndex;
    CurrentFakeNVMap->COMTerminalType[TerminalIndex] = NewTerminalContext->TerminalType;
    CurrentFakeNVMap->COMFlowControl[TerminalIndex]  = NewTerminalContext->FlowControl;
  }
}
