-/** @file
-
-Copyright (c) 2004 - 2007, Intel Corporation
-All rights reserved. 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.
-
-Module Name:
-
- BdsConsole.c
-
-Abstract:
-
- BDS Lib functions which contain all the code to connect console device
-
-
-**/
-
-#include "InternalBdsLib.h"
-//@MT:#include "EfiPrintLib.h"
-
-BOOLEAN
-IsNvNeed (
- IN CHAR16 *ConVarName
- )
-{
- CHAR16 *Ptr;
-
- Ptr = ConVarName;
-
- //
- // If the variable includes "Dev" at last, we consider
- // it does not support NV attribute.
- //
- while (*Ptr) {
- Ptr++;
- }
-
- if ((*(Ptr-3) == 'D') && (*(Ptr-2) == 'e') && (*(Ptr-1) == 'v')) {
- return FALSE;
- } else {
- return TRUE;
- }
-}
-
-
-/**
- This function update console variable based on ConVarName, it can
- add or remove one specific console device path from the variable
-
- @param ConVarName Console related variable name, ConIn, ConOut,
- ErrOut.
- @param CustomizedConDevicePath The console device path which will be added to
- the console variable ConVarName, this parameter
- can not be multi-instance.
- @param ExclusiveDevicePath The console device path which will be removed
- from the console variable ConVarName, this
- parameter can not be multi-instance.
-
- @retval EFI_UNSUPPORTED Add or remove the same device path.
- @retval EFI_SUCCESS Success add or remove the device path from the
- console variable.
-
-**/
-EFI_STATUS
-BdsLibUpdateConsoleVariable (
- IN CHAR16 *ConVarName,
- IN EFI_DEVICE_PATH_PROTOCOL *CustomizedConDevicePath,
- IN EFI_DEVICE_PATH_PROTOCOL *ExclusiveDevicePath
- )
-{
- EFI_DEVICE_PATH_PROTOCOL *VarConsole;
- UINTN DevicePathSize;
- EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
- EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;
- UINT32 Attributes;
-
- VarConsole = NULL;
- DevicePathSize = 0;
-
- //
- // 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
- //
- VarConsole = BdsLibGetVariableAndSize (
- ConVarName,
- &gEfiGlobalVariableGuid,
- &DevicePathSize
- );
-
- //
- // 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 = BdsLibDelPartMatchInstance (VarConsole, ExclusiveDevicePath);
- }
- //
- // Try to append customized device path to NewDevicePath.
- //
- if (CustomizedConDevicePath != NULL) {
- if (!BdsLibMatchDevicePaths (NewDevicePath, CustomizedConDevicePath)) {
- //
- // Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.
- //
- NewDevicePath = BdsLibDelPartMatchInstance (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);
- SafeFreePool(TempNewDevicePath);
- }
- }
-
- //
- // The attribute for ConInDev, ConOutDev and ErrOutDev does not include NV.
- //
- if (IsNvNeed(ConVarName)) {
- //
- // ConVarName has NV attribute.
- //
- Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
- } else {
- //
- // ConVarName does not have NV attribute.
- //
- Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
- }
-
- //
- // Finally, Update the variable of the default console by NewDevicePath
- //
- gRT->SetVariable (
- ConVarName,
- &gEfiGlobalVariableGuid,
- Attributes,
- GetDevicePathSize (NewDevicePath),
- NewDevicePath
- );
-
- if (VarConsole == NewDevicePath) {
- SafeFreePool(VarConsole);
- } else {
- SafeFreePool(VarConsole);
- SafeFreePool(NewDevicePath);
- }
-
- return EFI_SUCCESS;
-
-}
-
-
-/**
- Connect the console device base on the variable ConVarName, if
- device path of the ConVarName is multi-instance device path, if
- anyone of the instances is connected success, then this function
- will return success.
-
- @param ConVarName Console related variable name, ConIn, ConOut,
- 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
-BdsLibConnectConsoleVariable (
- IN CHAR16 *ConVarName
- )
-{
- EFI_STATUS Status;
- EFI_DEVICE_PATH_PROTOCOL *StartDevicePath;
- UINTN VariableSize;
- EFI_DEVICE_PATH_PROTOCOL *Instance;
- EFI_DEVICE_PATH_PROTOCOL *Next;
- EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath;
- UINTN Size;
- BOOLEAN DeviceExist;
-
- Status = EFI_SUCCESS;
- DeviceExist = FALSE;
-
- //
- // Check if the console variable exist
- //
- StartDevicePath = BdsLibGetVariableAndSize (
- ConVarName,
- &gEfiGlobalVariableGuid,
- &VariableSize
- );
- if (StartDevicePath == NULL) {
- return EFI_UNSUPPORTED;
- }
-
- CopyOfDevicePath = StartDevicePath;
- do {
- //
- // Check every instance of the console variable
- //
- Instance = GetNextDevicePathInstance (&CopyOfDevicePath, &Size);
- Next = Instance;
- while (!IsDevicePathEndType (Next)) {
- Next = NextDevicePathNode (Next);
- }
-
- SetDevicePathEndNode (Next);
- //
- // Check USB1.1 console
- //
- if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&
- ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP)
-#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
- || (DevicePathSubType (Instance) == MSG_USB_WWID_DP)
-#endif
- )) {
- //
- // Check the Usb console in Usb2.0 bus firstly, then Usb1.1 bus
- //
- Status = BdsLibConnectUsbDevByShortFormDP (PCI_CLASSC_PI_EHCI, Instance);
- if (!EFI_ERROR (Status)) {
- DeviceExist = TRUE;
- }
-
- Status = BdsLibConnectUsbDevByShortFormDP (PCI_CLASSC_PI_UHCI, Instance);
- if (!EFI_ERROR (Status)) {
- DeviceExist = TRUE;
- }
- } else {
- //
- // Connect the instance device path
- //
- Status = BdsLibConnectDevicePath (Instance);
- if (EFI_ERROR (Status)) {
- //
- // Delete the instance from the console varialbe
- //
- BdsLibUpdateConsoleVariable (ConVarName, NULL, Instance);
- } else {
- DeviceExist = TRUE;
- }
- }
- SafeFreePool(Instance);
- } while (CopyOfDevicePath != NULL);
-
- gBS->FreePool (StartDevicePath);
-
- if (DeviceExist == FALSE) {
- return EFI_NOT_FOUND;
- }
-
- return EFI_SUCCESS;
-}
-
-
-/**
- This function will search every simpletxt devive in current system,
- and make every simpletxt device as pertantial console device.
-
- None
-
- @return None
-
-**/
-VOID
-BdsLibConnectAllConsoles (
- 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 varables
- //
- gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiSimpleTextInProtocolGuid,
- NULL,
- &HandleCount,
- &HandleBuffer
- );
-
- for (Index = 0; Index < HandleCount; Index++) {
- gBS->HandleProtocol (
- HandleBuffer[Index],
- &gEfiDevicePathProtocolGuid,
- (VOID **) &ConDevicePath
- );
- BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL);
- }
-
- SafeFreePool(HandleBuffer);
-
- gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiSimpleTextOutProtocolGuid,
- NULL,
- &HandleCount,
- &HandleBuffer
- );
- for (Index = 0; Index < HandleCount; Index++) {
- gBS->HandleProtocol (
- HandleBuffer[Index],
- &gEfiDevicePathProtocolGuid,
- (VOID **) &ConDevicePath
- );
- BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL);
- BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL);
- }
-
- SafeFreePool(HandleBuffer);
-
- //
- // Connect all console variables
- //
- BdsLibConnectAllDefaultConsoles ();
-
-}
-
-
-/**
- This function will connect console device base on the console
- device variable ConIn, ConOut and ErrOut.
-
- None
-
- @retval EFI_SUCCESS At least one of the ConIn and ConOut device have
- been connected success.
- @retval EFI_STATUS Return the status of
- BdsLibConnectConsoleVariable ().
-
-**/
-EFI_STATUS
-BdsLibConnectAllDefaultConsoles (
- VOID
- )
-{
- EFI_STATUS Status;
-
- //
- // Connect all default console variables
- //
-
- //
- // It seems impossible not to have any ConOut device on platform,
- // so we check the status here.
- //
- Status = BdsLibConnectConsoleVariable (L"ConOut");
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Insert the performance probe for Console Out
- //
- PERF_START (NULL, "ConOut", "BDS", 1);
- PERF_END (NULL, "ConOut", "BDS", 0);
-
- //
- // Because possibly the platform is legacy free, in such case,
- // ConIn devices (Serial Port and PS2 Keyboard ) does not exist,
- // so we need not check the status.
- //
- BdsLibConnectConsoleVariable (L"ConIn");
-
- //
- // The _ModuleEntryPoint err out var is legal.
- //
- BdsLibConnectConsoleVariable (L"ErrOut");
-
- return EFI_SUCCESS;
-
-}
+/** @file\r
+ BDS Lib functions which contain all the code to connect console device\r
+\r
+Copyright (c) 2004 - 2008, Intel Corporation. <BR>\r
+All rights reserved. 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 "InternalBdsLib.h"\r
+\r
+/**\r
+ Check if we need to save the EFI variable with "ConVarName" as name\r
+ as NV type\r
+\r
+ @param ConVarName The name of the EFI variable.\r
+\r
+ @retval TRUE Set the EFI variabel as NV type.\r
+ @retval FALSE EFI variabel as NV type can be set NonNV.\r
+**/\r
+BOOLEAN\r
+IsNvNeed (\r
+ IN CHAR16 *ConVarName\r
+ )\r
+{\r
+ CHAR16 *Ptr;\r
+\r
+ Ptr = ConVarName;\r
+\r
+ //\r
+ // If the variable includes "Dev" at last, we consider\r
+ // it does not support NV attribute.\r
+ //\r
+ while (*Ptr != L'\0') {\r
+ Ptr++;\r
+ }\r
+\r
+ if ((*(Ptr - 3) == 'D') && (*(Ptr - 2) == 'e') && (*(Ptr - 1) == 'v')) {\r
+ return FALSE;\r
+ } else {\r
+ return TRUE;\r
+ }\r
+}\r
+\r
+\r
+/**\r
+ This function update console variable based on ConVarName, it can\r
+ add or remove one specific console device path from the variable\r
+\r
+ @param ConVarName Console related variable name, ConIn, ConOut,\r
+ ErrOut.\r
+ @param CustomizedConDevicePath The console device path which will be added to\r
+ the console variable ConVarName, this parameter\r
+ can not be multi-instance.\r
+ @param ExclusiveDevicePath The console device path which will be removed\r
+ from the console variable ConVarName, this\r
+ parameter can not be multi-instance.\r
+\r
+ @retval EFI_UNSUPPORTED Add or remove the same device path.\r
+ @retval EFI_SUCCESS Success add or remove the device path from the\r
+ console variable.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BdsLibUpdateConsoleVariable (\r
+ IN CHAR16 *ConVarName,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *CustomizedConDevicePath,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *ExclusiveDevicePath\r
+ )\r
+{\r
+ EFI_DEVICE_PATH_PROTOCOL *VarConsole;\r
+ UINTN DevicePathSize;\r
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;\r
+ UINT32 Attributes;\r
+\r
+ VarConsole = NULL;\r
+ DevicePathSize = 0;\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
+ VarConsole = BdsLibGetVariableAndSize (\r
+ ConVarName,\r
+ &gEfiGlobalVariableGuid,\r
+ &DevicePathSize\r
+ );\r
+\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 = BdsLibDelPartMatchInstance (VarConsole, ExclusiveDevicePath);\r
+ }\r
+ //\r
+ // Try to append customized device path to NewDevicePath.\r
+ //\r
+ if (CustomizedConDevicePath != NULL) {\r
+ if (!BdsLibMatchDevicePaths (NewDevicePath, CustomizedConDevicePath)) {\r
+ //\r
+ // Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.\r
+ //\r
+ NewDevicePath = BdsLibDelPartMatchInstance (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
+ // The attribute for ConInDev, ConOutDev and ErrOutDev does not include NV.\r
+ //\r
+ if (IsNvNeed(ConVarName)) {\r
+ //\r
+ // ConVarName has NV attribute.\r
+ //\r
+ Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;\r
+ } else {\r
+ //\r
+ // ConVarName does not have NV attribute.\r
+ //\r
+ Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;\r
+ }\r
+\r
+ //\r
+ // Finally, Update the variable of the default console by NewDevicePath\r
+ //\r
+ gRT->SetVariable (\r
+ ConVarName,\r
+ &gEfiGlobalVariableGuid,\r
+ Attributes,\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) {\r
+ FreePool(NewDevicePath);\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+\r
+/**\r
+ Connect the console device base on the variable ConVarName, if\r
+ device path of the ConVarName is multi-instance device path, if\r
+ anyone of the instances is connected success, then this function\r
+ will return success.\r
+\r
+ @param ConVarName Console related variable name, ConIn, ConOut,\r
+ 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
+BdsLibConnectConsoleVariable (\r
+ IN CHAR16 *ConVarName\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *StartDevicePath;\r
+ UINTN VariableSize;\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
+\r
+ Status = EFI_SUCCESS;\r
+ DeviceExist = FALSE;\r
+\r
+ //\r
+ // Check if the console variable exist\r
+ //\r
+ StartDevicePath = BdsLibGetVariableAndSize (\r
+ ConVarName,\r
+ &gEfiGlobalVariableGuid,\r
+ &VariableSize\r
+ );\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
+ Next = Instance;\r
+ while (!IsDevicePathEndType (Next)) {\r
+ Next = NextDevicePathNode (Next);\r
+ }\r
+\r
+ SetDevicePathEndNode (Next);\r
+ //\r
+ // Check USB1.1 console\r
+ //\r
+ if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&\r
+ ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP)\r
+ || (DevicePathSubType (Instance) == MSG_USB_WWID_DP)\r
+ )) {\r
+ //\r
+ // Check the Usb console in Usb2.0 bus firstly, then Usb1.1 bus\r
+ //\r
+ Status = BdsLibConnectUsbDevByShortFormDP (PCI_CLASSC_PI_EHCI, Instance);\r
+ if (!EFI_ERROR (Status)) {\r
+ DeviceExist = TRUE;\r
+ }\r
+\r
+ Status = BdsLibConnectUsbDevByShortFormDP (PCI_CLASSC_PI_UHCI, Instance);\r
+ if (!EFI_ERROR (Status)) {\r
+ DeviceExist = TRUE;\r
+ }\r
+ } else {\r
+ //\r
+ // Connect the instance device path\r
+ //\r
+ Status = BdsLibConnectDevicePath (Instance);\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Delete the instance from the console varialbe\r
+ //\r
+ BdsLibUpdateConsoleVariable (ConVarName, 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 simpletxt devive in current system,\r
+ and make every simpletxt device as pertantial console device.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+BdsLibConnectAllConsoles (\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 varables\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
+ BdsLibUpdateConsoleVariable (L"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
+ BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL);\r
+ BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL);\r
+ }\r
+\r
+ if (HandleBuffer != NULL) {\r
+ FreePool(HandleBuffer);\r
+ }\r
+\r
+ //\r
+ // Connect all console variables\r
+ //\r
+ BdsLibConnectAllDefaultConsoles ();\r
+\r
+}\r
+\r
+/**\r
+ This function will connect console device base on the console\r
+ device variable ConIn, ConOut and ErrOut.\r
+\r
+ @retval EFI_SUCCESS At least one of the ConIn and ConOut device have\r
+ been connected success.\r
+ @retval EFI_STATUS Return the status of\r
+ BdsLibConnectConsoleVariable ().\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BdsLibConnectAllDefaultConsoles (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Connect all default console variables\r
+ //\r
+\r
+ //\r
+ // It seems impossible not to have any ConOut device on platform,\r
+ // so we check the status here.\r
+ //\r
+ Status = BdsLibConnectConsoleVariable (L"ConOut");\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Insert the performance probe for Console Out\r
+ //\r
+ PERF_START (NULL, "ConOut", "BDS", 1);\r
+ PERF_END (NULL, "ConOut", "BDS", 0);\r
+\r
+ //\r
+ // Because possibly the platform is legacy free, in such case,\r
+ // ConIn devices (Serial Port and PS2 Keyboard ) does not exist,\r
+ // so we need not check the status.\r
+ //\r
+ BdsLibConnectConsoleVariable (L"ConIn");\r
+\r
+ //\r
+ // The _ModuleEntryPoint err out var is legal.\r
+ //\r
+ BdsLibConnectConsoleVariable (L"ErrOut");\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+/**\r
+ Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer\r
+ is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt\r
+ buffer is passed in it will be used if it is big enough.\r
+\r
+ @param BmpImage Pointer to BMP file\r
+ @param BmpImageSize Number of bytes in BmpImage\r
+ @param GopBlt Buffer containing GOP version of BmpImage.\r
+ @param GopBltSize Size of GopBlt in bytes.\r
+ @param PixelHeight Height of GopBlt/BmpImage in pixels\r
+ @param PixelWidth Width of GopBlt/BmpImage in pixels\r
+\r
+ @retval EFI_SUCCESS GopBlt and GopBltSize are returned. \r
+ @retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image\r
+ @retval EFI_BUFFER_TOO_SMALL The passed in GopBlt buffer is not big enough.\r
+ GopBltSize will contain the required size.\r
+ @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate.\r
+\r
+**/\r
+EFI_STATUS\r
+ConvertBmpToGopBlt (\r
+ IN VOID *BmpImage,\r
+ IN UINTN BmpImageSize,\r
+ IN OUT VOID **GopBlt,\r
+ IN OUT UINTN *GopBltSize,\r
+ OUT UINTN *PixelHeight,\r
+ OUT UINTN *PixelWidth\r
+ )\r
+{\r
+ UINT8 *Image;\r
+ UINT8 *ImageHeader;\r
+ BMP_IMAGE_HEADER *BmpHeader;\r
+ BMP_COLOR_MAP *BmpColorMap;\r
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
+ UINTN BltBufferSize;\r
+ UINTN Index;\r
+ UINTN Height;\r
+ UINTN Width;\r
+ UINTN ImageIndex;\r
+ BOOLEAN IsAllocated;\r
+\r
+ BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;\r
+\r
+ if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // Doesn't support compress.\r
+ //\r
+ if (BmpHeader->CompressionType != 0) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // Calculate Color Map offset in the image.\r
+ //\r
+ Image = BmpImage;\r
+ BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));\r
+\r
+ //\r
+ // Calculate graphics image data address in the image\r
+ //\r
+ Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;\r
+ ImageHeader = Image;\r
+\r
+ //\r
+ // Calculate the BltBuffer needed size.\r
+ //\r
+ BltBufferSize = BmpHeader->PixelWidth * BmpHeader->PixelHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
+ IsAllocated = FALSE;\r
+ if (*GopBlt == NULL) {\r
+ //\r
+ // GopBlt is not allocated by caller.\r
+ //\r
+ *GopBltSize = BltBufferSize;\r
+ *GopBlt = AllocatePool (*GopBltSize);\r
+ IsAllocated = TRUE;\r
+ if (*GopBlt == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ } else {\r
+ //\r
+ // GopBlt has been allocated by caller.\r
+ //\r
+ if (*GopBltSize < BltBufferSize) {\r
+ *GopBltSize = BltBufferSize;\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+ }\r
+\r
+ *PixelWidth = BmpHeader->PixelWidth;\r
+ *PixelHeight = BmpHeader->PixelHeight;\r
+\r
+ //\r
+ // Convert image from BMP to Blt buffer format\r
+ //\r
+ BltBuffer = *GopBlt;\r
+ for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {\r
+ Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];\r
+ for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {\r
+ switch (BmpHeader->BitPerPixel) {\r
+ case 1:\r
+ //\r
+ // Convert 1-bit (2 colors) BMP to 24-bit color\r
+ //\r
+ for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {\r
+ Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;\r
+ Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;\r
+ Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;\r
+ Blt++;\r
+ Width++;\r
+ }\r
+\r
+ Blt --;\r
+ Width --;\r
+ break;\r
+\r
+ case 4:\r
+ //\r
+ // Convert 4-bit (16 colors) BMP Palette to 24-bit color\r
+ //\r
+ Index = (*Image) >> 4;\r
+ Blt->Red = BmpColorMap[Index].Red;\r
+ Blt->Green = BmpColorMap[Index].Green;\r
+ Blt->Blue = BmpColorMap[Index].Blue;\r
+ if (Width < (BmpHeader->PixelWidth - 1)) {\r
+ Blt++;\r
+ Width++;\r
+ Index = (*Image) & 0x0f;\r
+ Blt->Red = BmpColorMap[Index].Red;\r
+ Blt->Green = BmpColorMap[Index].Green;\r
+ Blt->Blue = BmpColorMap[Index].Blue;\r
+ }\r
+ break;\r
+\r
+ case 8:\r
+ //\r
+ // Convert 8-bit (256 colors) BMP Palette to 24-bit color\r
+ //\r
+ Blt->Red = BmpColorMap[*Image].Red;\r
+ Blt->Green = BmpColorMap[*Image].Green;\r
+ Blt->Blue = BmpColorMap[*Image].Blue;\r
+ break;\r
+\r
+ case 24:\r
+ //\r
+ // It is 24-bit BMP.\r
+ //\r
+ Blt->Blue = *Image++;\r
+ Blt->Green = *Image++;\r
+ Blt->Red = *Image;\r
+ break;\r
+\r
+ default:\r
+ //\r
+ // Other bit format BMP is not supported.\r
+ //\r
+ if (IsAllocated) {\r
+ FreePool (*GopBlt);\r
+ *GopBlt = NULL;\r
+ }\r
+ return EFI_UNSUPPORTED;\r
+ break;\r
+ };\r
+\r
+ }\r
+\r
+ ImageIndex = (UINTN) (Image - ImageHeader);\r
+ if ((ImageIndex % 4) != 0) {\r
+ //\r
+ // Bmp Image starts each row on a 32-bit boundary!\r
+ //\r
+ Image = Image + (4 - (ImageIndex % 4));\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Use Console Control Protocol to lock the Console In Spliter virtual handle. \r
+ This is the ConInHandle and ConIn handle in the EFI system table. All key\r
+ presses will be ignored until the Password is typed in. The only way to\r
+ disable the password is to type it in to a ConIn device.\r
+\r
+ @param Password Password used to lock ConIn device.\r
+\r
+ @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.\r
+ @retval EFI_UNSUPPORTED Password not found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LockKeyboards (\r
+ IN CHAR16 *Password\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
+\r
+ Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Status = ConsoleControl->LockStdIn (ConsoleControl, Password);\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Use Console Control to turn off UGA based Simple Text Out consoles from going\r
+ to the UGA device. Put up LogoFile on every UGA device that is a console.\r
+\r
+ @param LogoFile File name of logo to display on the center of the screen.\r
+\r
+ @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed.\r
+ @retval EFI_UNSUPPORTED Logo not found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EnableQuietBoot (\r
+ IN EFI_GUID *LogoFile OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
+ EFI_OEM_BADGING_PROTOCOL *Badging;\r
+ UINT32 SizeOfX;\r
+ UINT32 SizeOfY;\r
+ INTN DestX;\r
+ INTN DestY;\r
+ UINT8 *ImageData;\r
+ UINTN ImageSize;\r
+ UINTN BltSize;\r
+ UINT32 Instance;\r
+ EFI_BADGING_FORMAT Format;\r
+ EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;\r
+ UINTN CoordinateX;\r
+ UINTN CoordinateY;\r
+ UINTN Height;\r
+ UINTN Width;\r
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
+ EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
+ UINT32 ColorDepth;\r
+ UINT32 RefreshRate;\r
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
+\r
+ Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ UgaDraw = NULL;\r
+ //\r
+ // Try to open GOP first\r
+ //\r
+ Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);\r
+ if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
+ GraphicsOutput = NULL;\r
+ //\r
+ // Open GOP failed, try to open UGA\r
+ //\r
+ Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);\r
+ }\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Badging = NULL;\r
+ Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);\r
+\r
+ //\r
+ // Set console control to graphics mode.\r
+ //\r
+ Status = ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ if (GraphicsOutput != NULL) {\r
+ SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
+ SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
+ } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
+ Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ } else {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Instance = 0;\r
+ while (1) {\r
+ ImageData = NULL;\r
+ ImageSize = 0;\r
+\r
+ if (Badging != NULL) {\r
+ //\r
+ // Get image from OEMBadging protocol.\r
+ //\r
+ Status = Badging->GetImage (\r
+ Badging,\r
+ &Instance,\r
+ &Format,\r
+ &ImageData,\r
+ &ImageSize,\r
+ &Attribute,\r
+ &CoordinateX,\r
+ &CoordinateY\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Currently only support BMP format.\r
+ //\r
+ if (Format != EfiBadgingFormatBMP) {\r
+ if (ImageData != NULL) {\r
+ FreePool (ImageData);\r
+ }\r
+ continue;\r
+ }\r
+ } else {\r
+ //\r
+ // Get the specified image from FV.\r
+ //\r
+ Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **) &ImageData, &ImageSize);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ CoordinateX = 0;\r
+ CoordinateY = 0;\r
+ Attribute = EfiBadgingDisplayAttributeCenter;\r
+ }\r
+\r
+ Blt = NULL;\r
+ Status = ConvertBmpToGopBlt (\r
+ ImageData,\r
+ ImageSize,\r
+ (VOID **) &Blt,\r
+ &BltSize,\r
+ &Height,\r
+ &Width\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ if (ImageData != NULL) {\r
+ FreePool (ImageData);\r
+ }\r
+ if (Badging == NULL) {\r
+ return Status;\r
+ } else {\r
+ continue;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Caculate the display position according to Attribute.\r
+ //\r
+ switch (Attribute) {\r
+ case EfiBadgingDisplayAttributeLeftTop:\r
+ DestX = CoordinateX;\r
+ DestY = CoordinateY;\r
+ break;\r
+\r
+ case EfiBadgingDisplayAttributeCenterTop:\r
+ DestX = (SizeOfX - Width) / 2;\r
+ DestY = CoordinateY;\r
+ break;\r
+\r
+ case EfiBadgingDisplayAttributeRightTop:\r
+ DestX = (SizeOfX - Width - CoordinateX);\r
+ DestY = CoordinateY;;\r
+ break;\r
+\r
+ case EfiBadgingDisplayAttributeCenterRight:\r
+ DestX = (SizeOfX - Width - CoordinateX);\r
+ DestY = (SizeOfY - Height) / 2;\r
+ break;\r
+\r
+ case EfiBadgingDisplayAttributeRightBottom:\r
+ DestX = (SizeOfX - Width - CoordinateX);\r
+ DestY = (SizeOfY - Height - CoordinateY);\r
+ break;\r
+\r
+ case EfiBadgingDisplayAttributeCenterBottom:\r
+ DestX = (SizeOfX - Width) / 2;\r
+ DestY = (SizeOfY - Height - CoordinateY);\r
+ break;\r
+\r
+ case EfiBadgingDisplayAttributeLeftBottom:\r
+ DestX = CoordinateX;\r
+ DestY = (SizeOfY - Height - CoordinateY);\r
+ break;\r
+\r
+ case EfiBadgingDisplayAttributeCenterLeft:\r
+ DestX = CoordinateX;\r
+ DestY = (SizeOfY - Height) / 2;\r
+ break;\r
+\r
+ case EfiBadgingDisplayAttributeCenter:\r
+ DestX = (SizeOfX - Width) / 2;\r
+ DestY = (SizeOfY - Height) / 2;\r
+ break;\r
+\r
+ default:\r
+ DestX = CoordinateX;\r
+ DestY = CoordinateY;\r
+ break;\r
+ }\r
+\r
+ if ((DestX >= 0) && (DestY >= 0)) {\r
+ if (GraphicsOutput != NULL) {\r
+ Status = GraphicsOutput->Blt (\r
+ GraphicsOutput,\r
+ Blt,\r
+ EfiBltBufferToVideo,\r
+ 0,\r
+ 0,\r
+ (UINTN) DestX,\r
+ (UINTN) DestY,\r
+ Width,\r
+ Height,\r
+ Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
+ );\r
+ } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
+ Status = UgaDraw->Blt (\r
+ UgaDraw,\r
+ (EFI_UGA_PIXEL *) Blt,\r
+ EfiUgaBltBufferToVideo,\r
+ 0,\r
+ 0,\r
+ (UINTN) DestX,\r
+ (UINTN) DestY,\r
+ Width,\r
+ Height,\r
+ Width * sizeof (EFI_UGA_PIXEL)\r
+ );\r
+ } else {\r
+ Status = EFI_UNSUPPORTED;\r
+ }\r
+ }\r
+\r
+ if (ImageData != NULL) {\r
+ FreePool (ImageData);\r
+ }\r
+ if (Blt != NULL) {\r
+ FreePool (Blt);\r
+ }\r
+\r
+ if (Badging == NULL) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Use Console Control to turn on UGA based Simple Text Out consoles. The UGA \r
+ Simple Text Out screens will now be synced up with all non UGA output devices\r
+\r
+ @retval EFI_SUCCESS UGA devices are back in text mode and synced up.\r
+ @retval EFI_UNSUPPORTED Logo not found\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DisableQuietBoot (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
+\r
+ Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // Set console control to text mode.\r
+ //\r
+ return ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);\r
+}\r
+\r