diff options
author | Ruiyu Ni <ruiyu.ni@intel.com> | 2015-05-13 02:23:44 +0000 |
---|---|---|
committer | niruiyu <niruiyu@Edk2> | 2015-05-13 02:23:44 +0000 |
commit | 067ed98a734eabd311b8c2c8ebd48b67e0242afa (patch) | |
tree | de29bfd3aa457cc7b13cb2b2d7806421f2950ec5 /MdeModulePkg/Library/UefiBootManagerLib/BmConsole.c | |
parent | 30cfc3d0ee0e5d8c425e1a1556fccf3b382dd61a (diff) | |
download | edk2-platforms-067ed98a734eabd311b8c2c8ebd48b67e0242afa.tar.xz |
MdeModulePkg: Fix EOL to be DOS format.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17421 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Library/UefiBootManagerLib/BmConsole.c')
-rw-r--r-- | MdeModulePkg/Library/UefiBootManagerLib/BmConsole.c | 1528 |
1 files changed, 764 insertions, 764 deletions
diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmConsole.c b/MdeModulePkg/Library/UefiBootManagerLib/BmConsole.c index 4f5c8b04c2..86b4fac424 100644 --- a/MdeModulePkg/Library/UefiBootManagerLib/BmConsole.c +++ b/MdeModulePkg/Library/UefiBootManagerLib/BmConsole.c @@ -1,764 +1,764 @@ -/** @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
+ 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;
+}
|