]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/UefiBootManagerLib/BmConsole.c
MdeModulePkg: Fix EOL to be DOS format.
[mirror_edk2.git] / MdeModulePkg / Library / UefiBootManagerLib / BmConsole.c
index 4f5c8b04c2106e4bdcd5d00874e37a87bdc19595..86b4fac4241e33bf754fd42465ea7c330e2458c8 100644 (file)
-/** @file
-  Library functions which contain all the code to connect console device.
-
-Copyright (c) 2011 - 2015, 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 "InternalBm.h"
-
-CHAR16       *mConVarName[] = {
-  L"ConIn",
-  L"ConOut",
-  L"ErrOut",
-  L"ConInDev",
-  L"ConOutDev",
-  L"ErrOutDev"
-};
-
-/**
-  Search out the video controller.
-
-  @return  PCI device path of the video controller.
-**/
-EFI_HANDLE
-BmGetVideoController (
-  VOID
-  )
-{
-  EFI_STATUS                Status;
-  UINTN                     RootBridgeHandleCount;
-  EFI_HANDLE                *RootBridgeHandleBuffer;
-  UINTN                     HandleCount;
-  EFI_HANDLE                *HandleBuffer;
-  UINTN                     RootBridgeIndex;
-  UINTN                     Index;
-  EFI_HANDLE                VideoController;
-  EFI_PCI_IO_PROTOCOL       *PciIo;
-  PCI_TYPE00                Pci;
-
-  //
-  // Make all the PCI_IO protocols show up
-  //
-  Status = gBS->LocateHandleBuffer (
-                  ByProtocol,
-                  &gEfiPciRootBridgeIoProtocolGuid,
-                  NULL,
-                  &RootBridgeHandleCount,
-                  &RootBridgeHandleBuffer
-                  );
-  if (EFI_ERROR (Status) || (RootBridgeHandleCount == 0)) {
-    return NULL;
-  }
-
-  VideoController = NULL;
-  for (RootBridgeIndex = 0; RootBridgeIndex < RootBridgeHandleCount; RootBridgeIndex++) {
-    gBS->ConnectController (RootBridgeHandleBuffer[RootBridgeIndex], NULL, NULL, FALSE);
-
-    //
-    // Start to check all the pci io to find the first video controller
-    //
-    Status = gBS->LocateHandleBuffer (
-                    ByProtocol,
-                    &gEfiPciIoProtocolGuid,
-                    NULL,
-                    &HandleCount,
-                    &HandleBuffer
-                    );
-    if (EFI_ERROR (Status)) {
-      continue;
-    }
-
-    for (Index = 0; Index < HandleCount; Index++) {
-      Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID **) &PciIo);
-      if (!EFI_ERROR (Status)) {
-        //
-        // Check for all video controller
-        //
-        Status = PciIo->Pci.Read (
-                          PciIo,
-                          EfiPciIoWidthUint32,
-                          0,
-                          sizeof (Pci) / sizeof (UINT32),
-                          &Pci
-                          );
-        if (!EFI_ERROR (Status) && IS_PCI_VGA (&Pci)) {
-          // TODO: use IS_PCI_DISPLAY??
-          VideoController = HandleBuffer[Index];
-          break;
-        }
-      }
-    }
-    FreePool (HandleBuffer);
-
-    if (VideoController != NULL) {
-      break;
-    }
-  }
-  FreePool (RootBridgeHandleBuffer);
-  
-  return VideoController;
-}
-
-/**
-  Query all the children of VideoController and return the device paths of all the 
-  children that support GraphicsOutput protocol.
-
-  @param VideoController       PCI handle of video controller.
-
-  @return  Device paths of all the children that support GraphicsOutput protocol.
-**/
-EFI_DEVICE_PATH_PROTOCOL *
-EFIAPI
-EfiBootManagerGetGopDevicePath (
-  IN  EFI_HANDLE                       VideoController
-  )
-{
-  UINTN                                Index;
-  EFI_STATUS                           Status;
-  EFI_GUID                             **ProtocolBuffer;
-  UINTN                                ProtocolBufferCount;
-  UINTN                                ProtocolIndex;
-  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY  *OpenInfoBuffer;
-  UINTN                                EntryCount;
-  EFI_DEVICE_PATH_PROTOCOL             *DevicePath;
-  EFI_DEVICE_PATH_PROTOCOL             *Next;
-  EFI_DEVICE_PATH_PROTOCOL             *Previous;
-  EFI_DEVICE_PATH_PROTOCOL             *TempDevicePath;
-  EFI_DEVICE_PATH_PROTOCOL             *GopPool;
-  EFI_DEVICE_PATH_PROTOCOL             *ReturnDevicePath;
-
-
-  Status = gBS->ProtocolsPerHandle (
-                  VideoController,
-                  &ProtocolBuffer,
-                  &ProtocolBufferCount
-                  );
-  if (EFI_ERROR (Status)) {
-    return NULL;
-  }
-
-  GopPool = NULL;
-
-  for (ProtocolIndex = 0; ProtocolIndex < ProtocolBufferCount; ProtocolIndex++) {
-    Status = gBS->OpenProtocolInformation (
-                    VideoController,
-                    ProtocolBuffer[ProtocolIndex],
-                    &OpenInfoBuffer,
-                    &EntryCount
-                    );
-    if (EFI_ERROR (Status)) {
-      continue;
-    }
-
-    for (Index = 0; Index < EntryCount; Index++) {
-      //
-      // Query all the children
-      //
-      if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
-        Status = gBS->OpenProtocol (
-                        OpenInfoBuffer[Index].ControllerHandle,
-                        &gEfiDevicePathProtocolGuid,
-                        (VOID **) &DevicePath,
-                        NULL,
-                        NULL,
-                        EFI_OPEN_PROTOCOL_GET_PROTOCOL
-                        );
-        if (EFI_ERROR (Status)) {
-          continue;
-        }
-
-        Previous = NULL;
-        for (Next = DevicePath; !IsDevicePathEnd (Next); Next = NextDevicePathNode (Next)) {
-          Previous = Next;
-        }
-        ASSERT (Previous != NULL);
-
-        if (DevicePathType (Previous) == ACPI_DEVICE_PATH && DevicePathSubType (Previous) == ACPI_ADR_DP) {
-          Status = gBS->OpenProtocol (
-                          OpenInfoBuffer[Index].ControllerHandle,
-                          &gEfiGraphicsOutputProtocolGuid,
-                          NULL,
-                          NULL,
-                          NULL,
-                          EFI_OPEN_PROTOCOL_TEST_PROTOCOL
-                          );
-          if (!EFI_ERROR (Status)) {
-            //
-            // Append the device path to GOP pool when there is GOP protocol installed.
-            //
-            TempDevicePath = GopPool;
-            GopPool = AppendDevicePathInstance (GopPool, DevicePath);
-            gBS->FreePool (TempDevicePath);
-          }
-        }
-
-        if (DevicePathType (Previous) == HARDWARE_DEVICE_PATH && DevicePathSubType (Previous) == HW_CONTROLLER_DP) {
-          //
-          // Recursively look for GOP child in this frame buffer handle
-          //
-          DEBUG ((EFI_D_INFO, "[Bds] Looking for GOP child deeper ... \n"));
-          TempDevicePath = GopPool;
-          ReturnDevicePath = EfiBootManagerGetGopDevicePath (OpenInfoBuffer[Index].ControllerHandle);
-          GopPool = AppendDevicePathInstance (GopPool, ReturnDevicePath);
-          gBS->FreePool (ReturnDevicePath);
-          gBS->FreePool (TempDevicePath);
-        }
-      }
-    }
-
-    FreePool (OpenInfoBuffer);
-  }
-
-  FreePool (ProtocolBuffer);
-
-  return GopPool;
-}
-
-/**
-  Connect the platform active active video controller.
-
-  @param VideoController       PCI handle of video controller.
-
-  @retval EFI_NOT_FOUND There is no active video controller.
-  @retval EFI_SUCCESS   The video controller is connected.
-**/
-EFI_STATUS
-EFIAPI
-EfiBootManagerConnectVideoController (
-  EFI_HANDLE                 VideoController  OPTIONAL
-  )
-{
-  EFI_DEVICE_PATH_PROTOCOL   *Gop;
-  
-  if (VideoController == NULL) {
-    //
-    // Get the platform vga device
-    //
-    VideoController = BmGetVideoController ();
-  }
-  if (VideoController == NULL) {
-    return EFI_NOT_FOUND;
-  }
-
-  //
-  // Try to connect the PCI device path, so that GOP dirver could start on this 
-  // device and create child handles with GraphicsOutput Protocol installed
-  // on them, then we get device paths of these child handles and select 
-  // them as possible console device.
-  //
-  gBS->ConnectController (VideoController, NULL, NULL, FALSE);
-
-  Gop = EfiBootManagerGetGopDevicePath (VideoController);
-  if (Gop == NULL) {
-    return EFI_NOT_FOUND;
-  }
-
-  EfiBootManagerUpdateConsoleVariable (ConOut, Gop, NULL);
-  FreePool (Gop);
-
-  //
-  // Necessary for ConPlatform and ConSplitter driver to start up again after ConOut is updated.
-  //
-  return gBS->ConnectController (VideoController, NULL, NULL, TRUE);
-}
-
-/**
-  Fill console handle in System Table if there are no valid console handle in.
-
-  Firstly, check the validation of console handle in System Table. If it is invalid,
-  update it by the first console device handle from EFI console variable. 
-
-  @param  VarName            The name of the EFI console variable.
-  @param  ConsoleGuid        Specified Console protocol GUID.
-  @param  ConsoleHandle      On IN,  console handle in System Table to be checked. 
-                             On OUT, new console handle in system table.
-  @param  ProtocolInterface  On IN,  console protocol on console handle in System Table to be checked. 
-                             On OUT, new console protocol on new console handle in system table.
-
-  @retval TRUE               System Table has been updated.
-  @retval FALSE              System Table hasn't been updated.
-
-**/
-BOOLEAN 
-BmUpdateSystemTableConsole (
-  IN     CHAR16                   *VarName,
-  IN     EFI_GUID                 *ConsoleGuid,
-  IN OUT EFI_HANDLE               *ConsoleHandle,
-  IN OUT VOID                     **ProtocolInterface
-  )
-{
-  EFI_STATUS                      Status;
-  UINTN                           DevicePathSize;
-  EFI_DEVICE_PATH_PROTOCOL        *FullDevicePath;
-  EFI_DEVICE_PATH_PROTOCOL        *VarConsole;
-  EFI_DEVICE_PATH_PROTOCOL        *Instance;
-  VOID                            *Interface;
-  EFI_HANDLE                      NewHandle;
-  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;
-
-  ASSERT (VarName != NULL);
-  ASSERT (ConsoleHandle != NULL);
-  ASSERT (ConsoleGuid != NULL);
-  ASSERT (ProtocolInterface != NULL);
-
-  if (*ConsoleHandle != NULL) {
-    Status = gBS->HandleProtocol (
-                   *ConsoleHandle,
-                   ConsoleGuid,
-                   &Interface
-                   );
-    if (Status == EFI_SUCCESS && Interface == *ProtocolInterface) {
-      //
-      // If ConsoleHandle is valid and console protocol on this handle also
-      // also matched, just return.
-      //
-      return FALSE;
-    }
-  }
-  
-  //
-  // Get all possible consoles device path from EFI variable
-  //
-  GetEfiGlobalVariable2 (VarName, (VOID **) &VarConsole, NULL);
-  if (VarConsole == NULL) {
-    //
-    // If there is no any console device, just return.
-    //
-    return FALSE;
-  }
-
-  FullDevicePath = VarConsole;
-
-  do {
-    //
-    // Check every instance of the console variable
-    //
-    Instance  = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);
-    if (Instance == NULL) {
-      DEBUG ((EFI_D_ERROR, "[Bds] No valid console instance is found for %s!\n", VarName));
-      // We should not ASSERT when all the console devices are removed.
-      // ASSERT_EFI_ERROR (EFI_NOT_FOUND);
-      FreePool (FullDevicePath);
-      return FALSE;
-    }
-    
-    //
-    // Find console device handle by device path instance
-    //
-    Status = gBS->LocateDevicePath (
-                    ConsoleGuid,
-                    &Instance,
-                    &NewHandle
-                    );
-    if (!EFI_ERROR (Status)) {
-      //
-      // Get the console protocol on this console device handle
-      //
-      Status = gBS->HandleProtocol (
-                      NewHandle,
-                      ConsoleGuid,
-                      &Interface
-                      );
-      if (!EFI_ERROR (Status)) {
-        //
-        // Update new console handle in System Table.
-        //
-        *ConsoleHandle     = NewHandle;
-        *ProtocolInterface = Interface;
-        if (CompareGuid (ConsoleGuid, &gEfiSimpleTextOutProtocolGuid)) {
-          //
-          // If it is console out device, set console mode 80x25 if current mode is invalid.
-          //
-          TextOut = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *) Interface;
-          if (TextOut->Mode->Mode == -1) {
-            TextOut->SetMode (TextOut, 0);
-          }
-        }
-        return TRUE;
-      }
-    }
-
-  } while (Instance != NULL);
-
-  //
-  // No any available console devcie found.
-  //
-  return FALSE;
-}
-
-/**
-  This function updates the console variable based on ConVarName. It can
-  add or remove one specific console device path from the variable
-
-  @param  ConsoleType              ConIn, ConOut, ErrOut, ConInDev, ConOutDev or ErrOutDev.
-  @param  CustomizedConDevicePath  The console device path to be added to
-                                   the console variable. Cannot be multi-instance.
-  @param  ExclusiveDevicePath      The console device path to be removed
-                                   from the console variable. Cannot be multi-instance.
-
-  @retval EFI_UNSUPPORTED          The added device path is the same as a removed one.
-  @retval EFI_SUCCESS              Successfully added or removed the device path from the
-                                   console variable.
-  @retval others                   Return status of RT->SetVariable().
-
-**/
-EFI_STATUS
-EFIAPI
-EfiBootManagerUpdateConsoleVariable (
-  IN  CONSOLE_TYPE              ConsoleType,
-  IN  EFI_DEVICE_PATH_PROTOCOL  *CustomizedConDevicePath,
-  IN  EFI_DEVICE_PATH_PROTOCOL  *ExclusiveDevicePath
-  )
-{
-  EFI_STATUS                Status;
-  EFI_DEVICE_PATH_PROTOCOL  *VarConsole;
-  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;
-  EFI_DEVICE_PATH_PROTOCOL  *TempNewDevicePath;
-
-  if (ConsoleType >= sizeof (mConVarName) / sizeof (mConVarName[0])) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Notes: check the device path point, here should check
-  // with compare memory
-  //
-  if (CustomizedConDevicePath == ExclusiveDevicePath) {
-    return EFI_UNSUPPORTED;
-  }
-  //
-  // Delete the ExclusiveDevicePath from current default console
-  //
-  GetEfiGlobalVariable2 (mConVarName[ConsoleType], (VOID **) &VarConsole, NULL);
-  //
-  // Initialize NewDevicePath
-  //
-  NewDevicePath = VarConsole;
-
-  //
-  // If ExclusiveDevicePath is even the part of the instance in VarConsole, delete it.
-  // In the end, NewDevicePath is the final device path.
-  //
-  if (ExclusiveDevicePath != NULL && VarConsole != NULL) {
-      NewDevicePath = BmDelPartMatchInstance (VarConsole, ExclusiveDevicePath);
-  }
-  //
-  // Try to append customized device path to NewDevicePath.
-  //
-  if (CustomizedConDevicePath != NULL) {
-    if (!BmMatchDevicePaths (NewDevicePath, CustomizedConDevicePath)) {
-      //
-      // Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.
-      //
-      NewDevicePath = BmDelPartMatchInstance (NewDevicePath, CustomizedConDevicePath);
-      //
-      // In the first check, the default console variable will be _ModuleEntryPoint,
-      // just append current customized device path
-      //
-      TempNewDevicePath = NewDevicePath;
-      NewDevicePath = AppendDevicePathInstance (NewDevicePath, CustomizedConDevicePath);
-      if (TempNewDevicePath != NULL) {
-        FreePool(TempNewDevicePath);
-      }
-    }
-  }
-
-  //
-  // Finally, Update the variable of the default console by NewDevicePath
-  //
-  Status = gRT->SetVariable (
-                  mConVarName[ConsoleType],
-                  &gEfiGlobalVariableGuid,
-                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS
-                                                  | ((ConsoleType < ConInDev) ? EFI_VARIABLE_NON_VOLATILE : 0),
-                  GetDevicePathSize (NewDevicePath),
-                  NewDevicePath
-                  );
-
-  if (VarConsole == NewDevicePath) {
-    if (VarConsole != NULL) {
-      FreePool(VarConsole);
-    }
-  } else {
-    if (VarConsole != NULL) {
-      FreePool(VarConsole);
-    }
-    if (NewDevicePath != NULL) {
-      FreePool(NewDevicePath);
-    }
-  }
-
-  return Status;
-}
-
-
-/**
-  Connect the console device base on the variable ConsoleType.
-
-  @param  ConsoleType              ConIn, ConOut or ErrOut.
-
-  @retval EFI_NOT_FOUND            There is not any console devices connected
-                                   success
-  @retval EFI_SUCCESS              Success connect any one instance of the console
-                                   device path base on the variable ConVarName.
-
-**/
-EFI_STATUS
-EFIAPI
-EfiBootManagerConnectConsoleVariable (
-  IN  CONSOLE_TYPE              ConsoleType
-  )
-{
-  EFI_STATUS                Status;
-  EFI_DEVICE_PATH_PROTOCOL  *StartDevicePath;
-  EFI_DEVICE_PATH_PROTOCOL  *Instance;
-  EFI_DEVICE_PATH_PROTOCOL  *Next;
-  EFI_DEVICE_PATH_PROTOCOL  *CopyOfDevicePath;
-  UINTN                     Size;
-  BOOLEAN                   DeviceExist;
-  EFI_HANDLE                Handle;
-
-  if ((ConsoleType != ConIn) && (ConsoleType != ConOut) && (ConsoleType != ErrOut)) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  Status      = EFI_SUCCESS;
-  DeviceExist = FALSE;
-  Handle      = NULL;
-
-  //
-  // Check if the console variable exist
-  //
-  GetEfiGlobalVariable2 (mConVarName[ConsoleType], (VOID **) &StartDevicePath, NULL);
-  if (StartDevicePath == NULL) {
-    return EFI_UNSUPPORTED;
-  }
-
-  CopyOfDevicePath = StartDevicePath;
-  do {
-    //
-    // Check every instance of the console variable
-    //
-    Instance  = GetNextDevicePathInstance (&CopyOfDevicePath, &Size);
-    if (Instance == NULL) {
-      FreePool (StartDevicePath);
-      return EFI_UNSUPPORTED;
-    }
-    
-    Next      = Instance;
-    while (!IsDevicePathEndType (Next)) {
-      Next = NextDevicePathNode (Next);
-    }
-
-    SetDevicePathEndNode (Next);
-    //
-    // Connect the USB console
-    // USB console device path is a short-form device path that 
-    //  starts with the first element being a USB WWID
-    //  or a USB Class device path
-    //
-    if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&
-        ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP) || (DevicePathSubType (Instance) == MSG_USB_WWID_DP))
-       ) {
-      Status = BmConnectUsbShortFormDevicePath (Instance);
-      if (!EFI_ERROR (Status)) {
-        DeviceExist = TRUE;
-      }
-    } else {
-      for (Next = Instance; !IsDevicePathEnd (Next); Next = NextDevicePathNode (Next)) {
-        if (DevicePathType (Next) == ACPI_DEVICE_PATH && DevicePathSubType (Next) == ACPI_ADR_DP) {
-          break;
-        } else if (DevicePathType (Next) == HARDWARE_DEVICE_PATH && 
-                   DevicePathSubType (Next) == HW_CONTROLLER_DP &&
-                   DevicePathType (NextDevicePathNode (Next)) == ACPI_DEVICE_PATH &&
-                   DevicePathSubType (NextDevicePathNode (Next)) == ACPI_ADR_DP
-                   ) {
-          break;
-        }
-      }
-      if (!IsDevicePathEnd (Next)) {
-        //
-        // For GOP device path, start the video driver with NULL remaining device path
-        //
-        SetDevicePathEndNode (Next);
-        Status = EfiBootManagerConnectDevicePath (Instance, &Handle);
-        if (!EFI_ERROR (Status)) {
-          gBS->ConnectController (Handle, NULL, NULL, TRUE);
-        }
-      } else {
-        Status = EfiBootManagerConnectDevicePath (Instance, NULL);
-      }
-      if (EFI_ERROR (Status)) {
-        //
-        // Delete the instance from the console varialbe
-        //
-        EfiBootManagerUpdateConsoleVariable (ConsoleType, NULL, Instance);
-      } else {
-        DeviceExist = TRUE;
-      }
-    }
-    FreePool(Instance);
-  } while (CopyOfDevicePath != NULL);
-
-  FreePool (StartDevicePath);
-
-  if (!DeviceExist) {
-    return EFI_NOT_FOUND;
-  }
-
-  return EFI_SUCCESS;
-}
-
-
-/**
-  This function will search every input/output device in current system,
-  and make every input/output device as potential console device.
-**/
-VOID
-EFIAPI
-EfiBootManagerConnectAllConsoles (
-  VOID
-  )
-{
-  UINTN                     Index;
-  EFI_DEVICE_PATH_PROTOCOL  *ConDevicePath;
-  UINTN                     HandleCount;
-  EFI_HANDLE                *HandleBuffer;
-
-  Index         = 0;
-  HandleCount   = 0;
-  HandleBuffer  = NULL;
-  ConDevicePath = NULL;
-
-  //
-  // Update all the console variables
-  //
-  gBS->LocateHandleBuffer (
-          ByProtocol,
-          &gEfiSimpleTextInProtocolGuid,
-          NULL,
-          &HandleCount,
-          &HandleBuffer
-          );
-
-  for (Index = 0; Index < HandleCount; Index++) {
-    gBS->HandleProtocol (
-            HandleBuffer[Index],
-            &gEfiDevicePathProtocolGuid,
-            (VOID **) &ConDevicePath
-            );
-    EfiBootManagerUpdateConsoleVariable (ConIn, ConDevicePath, NULL);
-  }
-
-  if (HandleBuffer != NULL) {
-    FreePool(HandleBuffer);
-    HandleBuffer = NULL;
-  }
-
-  gBS->LocateHandleBuffer (
-          ByProtocol,
-          &gEfiSimpleTextOutProtocolGuid,
-          NULL,
-          &HandleCount,
-          &HandleBuffer
-          );
-  for (Index = 0; Index < HandleCount; Index++) {
-    gBS->HandleProtocol (
-            HandleBuffer[Index],
-            &gEfiDevicePathProtocolGuid,
-            (VOID **) &ConDevicePath
-            );
-    EfiBootManagerUpdateConsoleVariable (ConOut, ConDevicePath, NULL);
-    EfiBootManagerUpdateConsoleVariable (ErrOut, ConDevicePath, NULL);
-  }
-
-  if (HandleBuffer != NULL) {
-    FreePool(HandleBuffer);
-  }
-
-  //
-  // Connect all console variables
-  //
-  EfiBootManagerConnectAllDefaultConsoles ();
-}
-
-
-/**
-  This function will connect all the console devices base on the console
-  device variable ConIn, ConOut and ErrOut.
-
-  @retval EFI_DEVICE_ERROR         All the consoles were not connected due to an error.
-  @retval EFI_SUCCESS              Success connect any one instance of the console
-                                   device path base on the variable ConVarName.
-**/
-EFI_STATUS
-EFIAPI
-EfiBootManagerConnectAllDefaultConsoles (
-  VOID
-  )
-{
-  EFI_STATUS                Status;
-  BOOLEAN                   OneConnected;
-  BOOLEAN                   SystemTableUpdated;
-
-  OneConnected = FALSE;
-
-  Status = EfiBootManagerConnectConsoleVariable (ConOut);
-  if (!EFI_ERROR (Status)) {
-    OneConnected = TRUE;
-  }
-  PERF_START (NULL, "ConOutReady", "BDS", 1);
-  PERF_END   (NULL, "ConOutReady", "BDS", 0);
-
-  
-  Status = EfiBootManagerConnectConsoleVariable (ConIn);
-  if (!EFI_ERROR (Status)) {
-    OneConnected = TRUE;
-  }
-  PERF_START (NULL, "ConInReady", "BDS", 1);
-  PERF_END   (NULL, "ConInReady", "BDS", 0);
-
-  Status = EfiBootManagerConnectConsoleVariable (ErrOut);
-  if (!EFI_ERROR (Status)) {
-    OneConnected = TRUE;
-  }
-  PERF_START (NULL, "ErrOutReady", "BDS", 1);
-  PERF_END   (NULL, "ErrOutReady", "BDS", 0);
-
-  SystemTableUpdated = FALSE;
-  //
-  // Fill console handles in System Table if no console device assignd.
-  //
-  if (BmUpdateSystemTableConsole (L"ConIn", &gEfiSimpleTextInProtocolGuid, &gST->ConsoleInHandle, (VOID **) &gST->ConIn)) {
-    SystemTableUpdated = TRUE;
-  }
-  if (BmUpdateSystemTableConsole (L"ConOut", &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **) &gST->ConOut)) {
-    SystemTableUpdated = TRUE;
-  }
-  if (BmUpdateSystemTableConsole (L"ErrOut", &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **) &gST->StdErr)) {
-    SystemTableUpdated = TRUE;
-  }
-
-  if (SystemTableUpdated) {
-    //
-    // Update the CRC32 in the EFI System Table header
-    //
-    gST->Hdr.CRC32 = 0;
-    gBS->CalculateCrc32 (
-          (UINT8 *) &gST->Hdr,
-          gST->Hdr.HeaderSize,
-          &gST->Hdr.CRC32
-          );
-  }
-
-  return OneConnected ? EFI_SUCCESS : EFI_DEVICE_ERROR;
-}
+/** @file\r
+  Library functions which contain all the code to connect console device.\r
+\r
+Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalBm.h"\r
+\r
+CHAR16       *mConVarName[] = {\r
+  L"ConIn",\r
+  L"ConOut",\r
+  L"ErrOut",\r
+  L"ConInDev",\r
+  L"ConOutDev",\r
+  L"ErrOutDev"\r
+};\r
+\r
+/**\r
+  Search out the video controller.\r
+\r
+  @return  PCI device path of the video controller.\r
+**/\r
+EFI_HANDLE\r
+BmGetVideoController (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  UINTN                     RootBridgeHandleCount;\r
+  EFI_HANDLE                *RootBridgeHandleBuffer;\r
+  UINTN                     HandleCount;\r
+  EFI_HANDLE                *HandleBuffer;\r
+  UINTN                     RootBridgeIndex;\r
+  UINTN                     Index;\r
+  EFI_HANDLE                VideoController;\r
+  EFI_PCI_IO_PROTOCOL       *PciIo;\r
+  PCI_TYPE00                Pci;\r
+\r
+  //\r
+  // Make all the PCI_IO protocols show up\r
+  //\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiPciRootBridgeIoProtocolGuid,\r
+                  NULL,\r
+                  &RootBridgeHandleCount,\r
+                  &RootBridgeHandleBuffer\r
+                  );\r
+  if (EFI_ERROR (Status) || (RootBridgeHandleCount == 0)) {\r
+    return NULL;\r
+  }\r
+\r
+  VideoController = NULL;\r
+  for (RootBridgeIndex = 0; RootBridgeIndex < RootBridgeHandleCount; RootBridgeIndex++) {\r
+    gBS->ConnectController (RootBridgeHandleBuffer[RootBridgeIndex], NULL, NULL, FALSE);\r
+\r
+    //\r
+    // Start to check all the pci io to find the first video controller\r
+    //\r
+    Status = gBS->LocateHandleBuffer (\r
+                    ByProtocol,\r
+                    &gEfiPciIoProtocolGuid,\r
+                    NULL,\r
+                    &HandleCount,\r
+                    &HandleBuffer\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
+\r
+    for (Index = 0; Index < HandleCount; Index++) {\r
+      Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID **) &PciIo);\r
+      if (!EFI_ERROR (Status)) {\r
+        //\r
+        // Check for all video controller\r
+        //\r
+        Status = PciIo->Pci.Read (\r
+                          PciIo,\r
+                          EfiPciIoWidthUint32,\r
+                          0,\r
+                          sizeof (Pci) / sizeof (UINT32),\r
+                          &Pci\r
+                          );\r
+        if (!EFI_ERROR (Status) && IS_PCI_VGA (&Pci)) {\r
+          // TODO: use IS_PCI_DISPLAY??\r
+          VideoController = HandleBuffer[Index];\r
+          break;\r
+        }\r
+      }\r
+    }\r
+    FreePool (HandleBuffer);\r
+\r
+    if (VideoController != NULL) {\r
+      break;\r
+    }\r
+  }\r
+  FreePool (RootBridgeHandleBuffer);\r
+  \r
+  return VideoController;\r
+}\r
+\r
+/**\r
+  Query all the children of VideoController and return the device paths of all the \r
+  children that support GraphicsOutput protocol.\r
+\r
+  @param VideoController       PCI handle of video controller.\r
+\r
+  @return  Device paths of all the children that support GraphicsOutput protocol.\r
+**/\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+EFIAPI\r
+EfiBootManagerGetGopDevicePath (\r
+  IN  EFI_HANDLE                       VideoController\r
+  )\r
+{\r
+  UINTN                                Index;\r
+  EFI_STATUS                           Status;\r
+  EFI_GUID                             **ProtocolBuffer;\r
+  UINTN                                ProtocolBufferCount;\r
+  UINTN                                ProtocolIndex;\r
+  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY  *OpenInfoBuffer;\r
+  UINTN                                EntryCount;\r
+  EFI_DEVICE_PATH_PROTOCOL             *DevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL             *Next;\r
+  EFI_DEVICE_PATH_PROTOCOL             *Previous;\r
+  EFI_DEVICE_PATH_PROTOCOL             *TempDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL             *GopPool;\r
+  EFI_DEVICE_PATH_PROTOCOL             *ReturnDevicePath;\r
+\r
+\r
+  Status = gBS->ProtocolsPerHandle (\r
+                  VideoController,\r
+                  &ProtocolBuffer,\r
+                  &ProtocolBufferCount\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return NULL;\r
+  }\r
+\r
+  GopPool = NULL;\r
+\r
+  for (ProtocolIndex = 0; ProtocolIndex < ProtocolBufferCount; ProtocolIndex++) {\r
+    Status = gBS->OpenProtocolInformation (\r
+                    VideoController,\r
+                    ProtocolBuffer[ProtocolIndex],\r
+                    &OpenInfoBuffer,\r
+                    &EntryCount\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
+\r
+    for (Index = 0; Index < EntryCount; Index++) {\r
+      //\r
+      // Query all the children\r
+      //\r
+      if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
+        Status = gBS->OpenProtocol (\r
+                        OpenInfoBuffer[Index].ControllerHandle,\r
+                        &gEfiDevicePathProtocolGuid,\r
+                        (VOID **) &DevicePath,\r
+                        NULL,\r
+                        NULL,\r
+                        EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                        );\r
+        if (EFI_ERROR (Status)) {\r
+          continue;\r
+        }\r
+\r
+        Previous = NULL;\r
+        for (Next = DevicePath; !IsDevicePathEnd (Next); Next = NextDevicePathNode (Next)) {\r
+          Previous = Next;\r
+        }\r
+        ASSERT (Previous != NULL);\r
+\r
+        if (DevicePathType (Previous) == ACPI_DEVICE_PATH && DevicePathSubType (Previous) == ACPI_ADR_DP) {\r
+          Status = gBS->OpenProtocol (\r
+                          OpenInfoBuffer[Index].ControllerHandle,\r
+                          &gEfiGraphicsOutputProtocolGuid,\r
+                          NULL,\r
+                          NULL,\r
+                          NULL,\r
+                          EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+                          );\r
+          if (!EFI_ERROR (Status)) {\r
+            //\r
+            // Append the device path to GOP pool when there is GOP protocol installed.\r
+            //\r
+            TempDevicePath = GopPool;\r
+            GopPool = AppendDevicePathInstance (GopPool, DevicePath);\r
+            gBS->FreePool (TempDevicePath);\r
+          }\r
+        }\r
+\r
+        if (DevicePathType (Previous) == HARDWARE_DEVICE_PATH && DevicePathSubType (Previous) == HW_CONTROLLER_DP) {\r
+          //\r
+          // Recursively look for GOP child in this frame buffer handle\r
+          //\r
+          DEBUG ((EFI_D_INFO, "[Bds] Looking for GOP child deeper ... \n"));\r
+          TempDevicePath = GopPool;\r
+          ReturnDevicePath = EfiBootManagerGetGopDevicePath (OpenInfoBuffer[Index].ControllerHandle);\r
+          GopPool = AppendDevicePathInstance (GopPool, ReturnDevicePath);\r
+          gBS->FreePool (ReturnDevicePath);\r
+          gBS->FreePool (TempDevicePath);\r
+        }\r
+      }\r
+    }\r
+\r
+    FreePool (OpenInfoBuffer);\r
+  }\r
+\r
+  FreePool (ProtocolBuffer);\r
+\r
+  return GopPool;\r
+}\r
+\r
+/**\r
+  Connect the platform active active video controller.\r
+\r
+  @param VideoController       PCI handle of video controller.\r
+\r
+  @retval EFI_NOT_FOUND There is no active video controller.\r
+  @retval EFI_SUCCESS   The video controller is connected.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiBootManagerConnectVideoController (\r
+  EFI_HANDLE                 VideoController  OPTIONAL\r
+  )\r
+{\r
+  EFI_DEVICE_PATH_PROTOCOL   *Gop;\r
+  \r
+  if (VideoController == NULL) {\r
+    //\r
+    // Get the platform vga device\r
+    //\r
+    VideoController = BmGetVideoController ();\r
+  }\r
\r
+  if (VideoController == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // Try to connect the PCI device path, so that GOP dirver could start on this \r
+  // device and create child handles with GraphicsOutput Protocol installed\r
+  // on them, then we get device paths of these child handles and select \r
+  // them as possible console device.\r
+  //\r
+  gBS->ConnectController (VideoController, NULL, NULL, FALSE);\r
+\r
+  Gop = EfiBootManagerGetGopDevicePath (VideoController);\r
+  if (Gop == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  EfiBootManagerUpdateConsoleVariable (ConOut, Gop, NULL);\r
+  FreePool (Gop);\r
+\r
+  //\r
+  // Necessary for ConPlatform and ConSplitter driver to start up again after ConOut is updated.\r
+  //\r
+  return gBS->ConnectController (VideoController, NULL, NULL, TRUE);\r
+}\r
+\r
+/**\r
+  Fill console handle in System Table if there are no valid console handle in.\r
+\r
+  Firstly, check the validation of console handle in System Table. If it is invalid,\r
+  update it by the first console device handle from EFI console variable. \r
+\r
+  @param  VarName            The name of the EFI console variable.\r
+  @param  ConsoleGuid        Specified Console protocol GUID.\r
+  @param  ConsoleHandle      On IN,  console handle in System Table to be checked. \r
+                             On OUT, new console handle in system table.\r
+  @param  ProtocolInterface  On IN,  console protocol on console handle in System Table to be checked. \r
+                             On OUT, new console protocol on new console handle in system table.\r
+\r
+  @retval TRUE               System Table has been updated.\r
+  @retval FALSE              System Table hasn't been updated.\r
+\r
+**/\r
+BOOLEAN \r
+BmUpdateSystemTableConsole (\r
+  IN     CHAR16                   *VarName,\r
+  IN     EFI_GUID                 *ConsoleGuid,\r
+  IN OUT EFI_HANDLE               *ConsoleHandle,\r
+  IN OUT VOID                     **ProtocolInterface\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  UINTN                           DevicePathSize;\r
+  EFI_DEVICE_PATH_PROTOCOL        *FullDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL        *VarConsole;\r
+  EFI_DEVICE_PATH_PROTOCOL        *Instance;\r
+  VOID                            *Interface;\r
+  EFI_HANDLE                      NewHandle;\r
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;\r
+\r
+  ASSERT (VarName != NULL);\r
+  ASSERT (ConsoleHandle != NULL);\r
+  ASSERT (ConsoleGuid != NULL);\r
+  ASSERT (ProtocolInterface != NULL);\r
+\r
+  if (*ConsoleHandle != NULL) {\r
+    Status = gBS->HandleProtocol (\r
+                   *ConsoleHandle,\r
+                   ConsoleGuid,\r
+                   &Interface\r
+                   );\r
+    if (Status == EFI_SUCCESS && Interface == *ProtocolInterface) {\r
+      //\r
+      // If ConsoleHandle is valid and console protocol on this handle also\r
+      // also matched, just return.\r
+      //\r
+      return FALSE;\r
+    }\r
+  }\r
+  \r
+  //\r
+  // Get all possible consoles device path from EFI variable\r
+  //\r
+  GetEfiGlobalVariable2 (VarName, (VOID **) &VarConsole, NULL);\r
+  if (VarConsole == NULL) {\r
+    //\r
+    // If there is no any console device, just return.\r
+    //\r
+    return FALSE;\r
+  }\r
+\r
+  FullDevicePath = VarConsole;\r
+\r
+  do {\r
+    //\r
+    // Check every instance of the console variable\r
+    //\r
+    Instance  = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);\r
+    if (Instance == NULL) {\r
+      DEBUG ((EFI_D_ERROR, "[Bds] No valid console instance is found for %s!\n", VarName));\r
+      // We should not ASSERT when all the console devices are removed.\r
+      // ASSERT_EFI_ERROR (EFI_NOT_FOUND);\r
+      FreePool (FullDevicePath);\r
+      return FALSE;\r
+    }\r
+    \r
+    //\r
+    // Find console device handle by device path instance\r
+    //\r
+    Status = gBS->LocateDevicePath (\r
+                    ConsoleGuid,\r
+                    &Instance,\r
+                    &NewHandle\r
+                    );\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // Get the console protocol on this console device handle\r
+      //\r
+      Status = gBS->HandleProtocol (\r
+                      NewHandle,\r
+                      ConsoleGuid,\r
+                      &Interface\r
+                      );\r
+      if (!EFI_ERROR (Status)) {\r
+        //\r
+        // Update new console handle in System Table.\r
+        //\r
+        *ConsoleHandle     = NewHandle;\r
+        *ProtocolInterface = Interface;\r
+        if (CompareGuid (ConsoleGuid, &gEfiSimpleTextOutProtocolGuid)) {\r
+          //\r
+          // If it is console out device, set console mode 80x25 if current mode is invalid.\r
+          //\r
+          TextOut = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *) Interface;\r
+          if (TextOut->Mode->Mode == -1) {\r
+            TextOut->SetMode (TextOut, 0);\r
+          }\r
+        }\r
+        return TRUE;\r
+      }\r
+    }\r
+\r
+  } while (Instance != NULL);\r
+\r
+  //\r
+  // No any available console devcie found.\r
+  //\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  This function updates the console variable based on ConVarName. It can\r
+  add or remove one specific console device path from the variable\r
+\r
+  @param  ConsoleType              ConIn, ConOut, ErrOut, ConInDev, ConOutDev or ErrOutDev.\r
+  @param  CustomizedConDevicePath  The console device path to be added to\r
+                                   the console variable. Cannot be multi-instance.\r
+  @param  ExclusiveDevicePath      The console device path to be removed\r
+                                   from the console variable. Cannot be multi-instance.\r
+\r
+  @retval EFI_UNSUPPORTED          The added device path is the same as a removed one.\r
+  @retval EFI_SUCCESS              Successfully added or removed the device path from the\r
+                                   console variable.\r
+  @retval others                   Return status of RT->SetVariable().\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiBootManagerUpdateConsoleVariable (\r
+  IN  CONSOLE_TYPE              ConsoleType,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL  *CustomizedConDevicePath,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL  *ExclusiveDevicePath\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_DEVICE_PATH_PROTOCOL  *VarConsole;\r
+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL  *TempNewDevicePath;\r
+\r
+  if (ConsoleType >= sizeof (mConVarName) / sizeof (mConVarName[0])) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Notes: check the device path point, here should check\r
+  // with compare memory\r
+  //\r
+  if (CustomizedConDevicePath == ExclusiveDevicePath) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  //\r
+  // Delete the ExclusiveDevicePath from current default console\r
+  //\r
+  GetEfiGlobalVariable2 (mConVarName[ConsoleType], (VOID **) &VarConsole, NULL);\r
+  //\r
+  // Initialize NewDevicePath\r
+  //\r
+  NewDevicePath = VarConsole;\r
+\r
+  //\r
+  // If ExclusiveDevicePath is even the part of the instance in VarConsole, delete it.\r
+  // In the end, NewDevicePath is the final device path.\r
+  //\r
+  if (ExclusiveDevicePath != NULL && VarConsole != NULL) {\r
+      NewDevicePath = BmDelPartMatchInstance (VarConsole, ExclusiveDevicePath);\r
+  }\r
+  //\r
+  // Try to append customized device path to NewDevicePath.\r
+  //\r
+  if (CustomizedConDevicePath != NULL) {\r
+    if (!BmMatchDevicePaths (NewDevicePath, CustomizedConDevicePath)) {\r
+      //\r
+      // Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.\r
+      //\r
+      NewDevicePath = BmDelPartMatchInstance (NewDevicePath, CustomizedConDevicePath);\r
+      //\r
+      // In the first check, the default console variable will be _ModuleEntryPoint,\r
+      // just append current customized device path\r
+      //\r
+      TempNewDevicePath = NewDevicePath;\r
+      NewDevicePath = AppendDevicePathInstance (NewDevicePath, CustomizedConDevicePath);\r
+      if (TempNewDevicePath != NULL) {\r
+        FreePool(TempNewDevicePath);\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // Finally, Update the variable of the default console by NewDevicePath\r
+  //\r
+  Status = gRT->SetVariable (\r
+                  mConVarName[ConsoleType],\r
+                  &gEfiGlobalVariableGuid,\r
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS\r
+                                                  | ((ConsoleType < ConInDev) ? EFI_VARIABLE_NON_VOLATILE : 0),\r
+                  GetDevicePathSize (NewDevicePath),\r
+                  NewDevicePath\r
+                  );\r
+\r
+  if (VarConsole == NewDevicePath) {\r
+    if (VarConsole != NULL) {\r
+      FreePool(VarConsole);\r
+    }\r
+  } else {\r
+    if (VarConsole != NULL) {\r
+      FreePool(VarConsole);\r
+    }\r
+    if (NewDevicePath != NULL) {\r
+      FreePool(NewDevicePath);\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Connect the console device base on the variable ConsoleType.\r
+\r
+  @param  ConsoleType              ConIn, ConOut or ErrOut.\r
+\r
+  @retval EFI_NOT_FOUND            There is not any console devices connected\r
+                                   success\r
+  @retval EFI_SUCCESS              Success connect any one instance of the console\r
+                                   device path base on the variable ConVarName.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiBootManagerConnectConsoleVariable (\r
+  IN  CONSOLE_TYPE              ConsoleType\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_DEVICE_PATH_PROTOCOL  *StartDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL  *Instance;\r
+  EFI_DEVICE_PATH_PROTOCOL  *Next;\r
+  EFI_DEVICE_PATH_PROTOCOL  *CopyOfDevicePath;\r
+  UINTN                     Size;\r
+  BOOLEAN                   DeviceExist;\r
+  EFI_HANDLE                Handle;\r
+\r
+  if ((ConsoleType != ConIn) && (ConsoleType != ConOut) && (ConsoleType != ErrOut)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status      = EFI_SUCCESS;\r
+  DeviceExist = FALSE;\r
+  Handle      = NULL;\r
+\r
+  //\r
+  // Check if the console variable exist\r
+  //\r
+  GetEfiGlobalVariable2 (mConVarName[ConsoleType], (VOID **) &StartDevicePath, NULL);\r
+  if (StartDevicePath == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  CopyOfDevicePath = StartDevicePath;\r
+  do {\r
+    //\r
+    // Check every instance of the console variable\r
+    //\r
+    Instance  = GetNextDevicePathInstance (&CopyOfDevicePath, &Size);\r
+    if (Instance == NULL) {\r
+      FreePool (StartDevicePath);\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+    \r
+    Next      = Instance;\r
+    while (!IsDevicePathEndType (Next)) {\r
+      Next = NextDevicePathNode (Next);\r
+    }\r
+\r
+    SetDevicePathEndNode (Next);\r
+    //\r
+    // Connect the USB console\r
+    // USB console device path is a short-form device path that \r
+    //  starts with the first element being a USB WWID\r
+    //  or a USB Class device path\r
+    //\r
+    if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&\r
+        ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP) || (DevicePathSubType (Instance) == MSG_USB_WWID_DP))\r
+       ) {\r
+      Status = BmConnectUsbShortFormDevicePath (Instance);\r
+      if (!EFI_ERROR (Status)) {\r
+        DeviceExist = TRUE;\r
+      }\r
+    } else {\r
+      for (Next = Instance; !IsDevicePathEnd (Next); Next = NextDevicePathNode (Next)) {\r
+        if (DevicePathType (Next) == ACPI_DEVICE_PATH && DevicePathSubType (Next) == ACPI_ADR_DP) {\r
+          break;\r
+        } else if (DevicePathType (Next) == HARDWARE_DEVICE_PATH && \r
+                   DevicePathSubType (Next) == HW_CONTROLLER_DP &&\r
+                   DevicePathType (NextDevicePathNode (Next)) == ACPI_DEVICE_PATH &&\r
+                   DevicePathSubType (NextDevicePathNode (Next)) == ACPI_ADR_DP\r
+                   ) {\r
+          break;\r
+        }\r
+      }\r
+      if (!IsDevicePathEnd (Next)) {\r
+        //\r
+        // For GOP device path, start the video driver with NULL remaining device path\r
+        //\r
+        SetDevicePathEndNode (Next);\r
+        Status = EfiBootManagerConnectDevicePath (Instance, &Handle);\r
+        if (!EFI_ERROR (Status)) {\r
+          gBS->ConnectController (Handle, NULL, NULL, TRUE);\r
+        }\r
+      } else {\r
+        Status = EfiBootManagerConnectDevicePath (Instance, NULL);\r
+      }\r
+      if (EFI_ERROR (Status)) {\r
+        //\r
+        // Delete the instance from the console varialbe\r
+        //\r
+        EfiBootManagerUpdateConsoleVariable (ConsoleType, NULL, Instance);\r
+      } else {\r
+        DeviceExist = TRUE;\r
+      }\r
+    }\r
+    FreePool(Instance);\r
+  } while (CopyOfDevicePath != NULL);\r
+\r
+  FreePool (StartDevicePath);\r
+\r
+  if (!DeviceExist) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  This function will search every input/output device in current system,\r
+  and make every input/output device as potential console device.\r
+**/\r
+VOID\r
+EFIAPI\r
+EfiBootManagerConnectAllConsoles (\r
+  VOID\r
+  )\r
+{\r
+  UINTN                     Index;\r
+  EFI_DEVICE_PATH_PROTOCOL  *ConDevicePath;\r
+  UINTN                     HandleCount;\r
+  EFI_HANDLE                *HandleBuffer;\r
+\r
+  Index         = 0;\r
+  HandleCount   = 0;\r
+  HandleBuffer  = NULL;\r
+  ConDevicePath = NULL;\r
+\r
+  //\r
+  // Update all the console variables\r
+  //\r
+  gBS->LocateHandleBuffer (\r
+          ByProtocol,\r
+          &gEfiSimpleTextInProtocolGuid,\r
+          NULL,\r
+          &HandleCount,\r
+          &HandleBuffer\r
+          );\r
+\r
+  for (Index = 0; Index < HandleCount; Index++) {\r
+    gBS->HandleProtocol (\r
+            HandleBuffer[Index],\r
+            &gEfiDevicePathProtocolGuid,\r
+            (VOID **) &ConDevicePath\r
+            );\r
+    EfiBootManagerUpdateConsoleVariable (ConIn, ConDevicePath, NULL);\r
+  }\r
+\r
+  if (HandleBuffer != NULL) {\r
+    FreePool(HandleBuffer);\r
+    HandleBuffer = NULL;\r
+  }\r
+\r
+  gBS->LocateHandleBuffer (\r
+          ByProtocol,\r
+          &gEfiSimpleTextOutProtocolGuid,\r
+          NULL,\r
+          &HandleCount,\r
+          &HandleBuffer\r
+          );\r
+  for (Index = 0; Index < HandleCount; Index++) {\r
+    gBS->HandleProtocol (\r
+            HandleBuffer[Index],\r
+            &gEfiDevicePathProtocolGuid,\r
+            (VOID **) &ConDevicePath\r
+            );\r
+    EfiBootManagerUpdateConsoleVariable (ConOut, ConDevicePath, NULL);\r
+    EfiBootManagerUpdateConsoleVariable (ErrOut, ConDevicePath, NULL);\r
+  }\r
+\r
+  if (HandleBuffer != NULL) {\r
+    FreePool(HandleBuffer);\r
+  }\r
+\r
+  //\r
+  // Connect all console variables\r
+  //\r
+  EfiBootManagerConnectAllDefaultConsoles ();\r
+}\r
+\r
+\r
+/**\r
+  This function will connect all the console devices base on the console\r
+  device variable ConIn, ConOut and ErrOut.\r
+\r
+  @retval EFI_DEVICE_ERROR         All the consoles were not connected due to an error.\r
+  @retval EFI_SUCCESS              Success connect any one instance of the console\r
+                                   device path base on the variable ConVarName.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiBootManagerConnectAllDefaultConsoles (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  BOOLEAN                   OneConnected;\r
+  BOOLEAN                   SystemTableUpdated;\r
+\r
+  OneConnected = FALSE;\r
+\r
+  Status = EfiBootManagerConnectConsoleVariable (ConOut);\r
+  if (!EFI_ERROR (Status)) {\r
+    OneConnected = TRUE;\r
+  }\r
+  PERF_START (NULL, "ConOutReady", "BDS", 1);\r
+  PERF_END   (NULL, "ConOutReady", "BDS", 0);\r
+\r
+  \r
+  Status = EfiBootManagerConnectConsoleVariable (ConIn);\r
+  if (!EFI_ERROR (Status)) {\r
+    OneConnected = TRUE;\r
+  }\r
+  PERF_START (NULL, "ConInReady", "BDS", 1);\r
+  PERF_END   (NULL, "ConInReady", "BDS", 0);\r
+\r
+  Status = EfiBootManagerConnectConsoleVariable (ErrOut);\r
+  if (!EFI_ERROR (Status)) {\r
+    OneConnected = TRUE;\r
+  }\r
+  PERF_START (NULL, "ErrOutReady", "BDS", 1);\r
+  PERF_END   (NULL, "ErrOutReady", "BDS", 0);\r
+\r
+  SystemTableUpdated = FALSE;\r
+  //\r
+  // Fill console handles in System Table if no console device assignd.\r
+  //\r
+  if (BmUpdateSystemTableConsole (L"ConIn", &gEfiSimpleTextInProtocolGuid, &gST->ConsoleInHandle, (VOID **) &gST->ConIn)) {\r
+    SystemTableUpdated = TRUE;\r
+  }\r
+  if (BmUpdateSystemTableConsole (L"ConOut", &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **) &gST->ConOut)) {\r
+    SystemTableUpdated = TRUE;\r
+  }\r
+  if (BmUpdateSystemTableConsole (L"ErrOut", &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **) &gST->StdErr)) {\r
+    SystemTableUpdated = TRUE;\r
+  }\r
+\r
+  if (SystemTableUpdated) {\r
+    //\r
+    // Update the CRC32 in the EFI System Table header\r
+    //\r
+    gST->Hdr.CRC32 = 0;\r
+    gBS->CalculateCrc32 (\r
+          (UINT8 *) &gST->Hdr,\r
+          gST->Hdr.HeaderSize,\r
+          &gST->Hdr.CRC32\r
+          );\r
+  }\r
+\r
+  return OneConnected ? EFI_SUCCESS : EFI_DEVICE_ERROR;\r
+}\r