]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/UefiBootManagerLib/BmConsole.c
MdeModulePkg: Add UefiBootManagerLib
[mirror_edk2.git] / MdeModulePkg / Library / UefiBootManagerLib / BmConsole.c
diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmConsole.c b/MdeModulePkg/Library/UefiBootManagerLib/BmConsole.c
new file mode 100644 (file)
index 0000000..49b9995
--- /dev/null
@@ -0,0 +1,748 @@
+/** @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.
+**/
+VOID
+EFIAPI
+EfiBootManagerConnectAllDefaultConsoles (
+  VOID
+  )
+{
+  BOOLEAN                   SystemTableUpdated;
+
+  EfiBootManagerConnectConsoleVariable (ConOut);
+  PERF_START (NULL, "ConOutReady", "BDS", 1);
+  PERF_END   (NULL, "ConOutReady", "BDS", 0);
+
+  
+  EfiBootManagerConnectConsoleVariable (ConIn);
+  PERF_START (NULL, "ConInReady", "BDS", 1);
+  PERF_END   (NULL, "ConInReady", "BDS", 0);
+
+  //
+  // The _ModuleEntryPoint err out var is legal.
+  //
+  EfiBootManagerConnectConsoleVariable (ErrOut);
+  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
+          );
+  }
+}