+++ /dev/null
-/** @file\r
- BDS Lib functions which contain all the code to connect console device\r
-\r
-Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "InternalBdsLib.h"\r
-\r
-\r
-/**\r
- Check if we need to save the EFI variable with "ConVarName" as name\r
- as NV type\r
- If ConVarName is NULL, then ASSERT().\r
-\r
- @param ConVarName The name of the EFI variable.\r
-\r
- @retval TRUE Set the EFI variable as NV type.\r
- @retval FALSE EFI variable as NV type can be set NonNV.\r
-**/\r
-BOOLEAN\r
-IsNvNeed (\r
- IN CHAR16 *ConVarName\r
- )\r
-{\r
- CHAR16 *Ptr;\r
-\r
- ASSERT (ConVarName != NULL);\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 (((INTN)((UINTN)Ptr - (UINTN)ConVarName) / sizeof (CHAR16)) <= 3) {\r
- return TRUE;\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
- Fill console handle in System Table if there are no valid console handle in.\r
-\r
- Firstly, check the validation of console handle in System Table. If it is invalid,\r
- update it by the first console device handle from EFI console variable.\r
-\r
- @param VarName The name of the EFI console variable.\r
- @param ConsoleGuid Specified Console protocol GUID.\r
- @param ConsoleHandle On IN, console handle in System Table to be checked.\r
- On OUT, new console handle in system table.\r
- @param ProtocolInterface On IN, console protocol on console handle in System Table to be checked.\r
- On OUT, new console protocol on new console handle in system table.\r
-\r
- @retval TRUE System Table has been updated.\r
- @retval FALSE System Table hasn't been updated.\r
-\r
-**/\r
-BOOLEAN\r
-UpdateSystemTableConsole (\r
- IN CHAR16 *VarName,\r
- IN EFI_GUID *ConsoleGuid,\r
- IN OUT EFI_HANDLE *ConsoleHandle,\r
- IN OUT VOID **ProtocolInterface\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN DevicePathSize;\r
- EFI_DEVICE_PATH_PROTOCOL *FullDevicePath;\r
- EFI_DEVICE_PATH_PROTOCOL *VarConsole;\r
- EFI_DEVICE_PATH_PROTOCOL *Instance;\r
- VOID *Interface;\r
- EFI_HANDLE NewHandle;\r
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;\r
-\r
- ASSERT (VarName != NULL);\r
- ASSERT (ConsoleHandle != NULL);\r
- ASSERT (ConsoleGuid != NULL);\r
- ASSERT (ProtocolInterface != NULL);\r
-\r
- if (*ConsoleHandle != NULL) {\r
- Status = gBS->HandleProtocol (\r
- *ConsoleHandle,\r
- ConsoleGuid,\r
- &Interface\r
- );\r
- if (Status == EFI_SUCCESS && Interface == *ProtocolInterface) {\r
- //\r
- // If ConsoleHandle is valid and console protocol on this handle also\r
- // also matched, just return.\r
- //\r
- return FALSE;\r
- }\r
- }\r
-\r
- //\r
- // Get all possible consoles device path from EFI variable\r
- //\r
- VarConsole = BdsLibGetVariableAndSize (\r
- VarName,\r
- &gEfiGlobalVariableGuid,\r
- &DevicePathSize\r
- );\r
- if (VarConsole == NULL) {\r
- //\r
- // If there is no any console device, just return.\r
- //\r
- return FALSE;\r
- }\r
-\r
- FullDevicePath = VarConsole;\r
-\r
- do {\r
- //\r
- // Check every instance of the console variable\r
- //\r
- Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);\r
- if (Instance == NULL) {\r
- FreePool (FullDevicePath);\r
- ASSERT (FALSE);\r
- }\r
-\r
- //\r
- // Find console device handle by device path instance\r
- //\r
- Status = gBS->LocateDevicePath (\r
- ConsoleGuid,\r
- &Instance,\r
- &NewHandle\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Get the console protocol on this console device handle\r
- //\r
- Status = gBS->HandleProtocol (\r
- NewHandle,\r
- ConsoleGuid,\r
- &Interface\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Update new console handle in System Table.\r
- //\r
- *ConsoleHandle = NewHandle;\r
- *ProtocolInterface = Interface;\r
- if (CompareGuid (ConsoleGuid, &gEfiSimpleTextOutProtocolGuid)) {\r
- //\r
- // If it is console out device, set console mode 80x25 if current mode is invalid.\r
- //\r
- TextOut = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *) Interface;\r
- if (TextOut->Mode->Mode == -1) {\r
- TextOut->SetMode (TextOut, 0);\r
- }\r
- }\r
- return TRUE;\r
- }\r
- }\r
-\r
- } while (Instance != NULL);\r
-\r
- //\r
- // No any available console devcie found.\r
- //\r
- return FALSE;\r
-}\r
-\r
-/**\r
- This function 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 The added device path is same to the removed one.\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_STATUS Status;\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
- DevicePathSize = GetDevicePathSize (NewDevicePath);\r
- Status = SetVariableAndReportStatusCodeOnError (\r
- ConVarName,\r
- &gEfiGlobalVariableGuid,\r
- Attributes,\r
- DevicePathSize,\r
- NewDevicePath\r
- );\r
- if ((DevicePathSize == 0) && (Status == EFI_NOT_FOUND)) {\r
- Status = EFI_SUCCESS;\r
- }\r
-\r
- if (VarConsole == NewDevicePath) {\r
- if (VarConsole != NULL) {\r
- FreePool(VarConsole);\r
- }\r
- } else {\r
- if (VarConsole != NULL) {\r
- FreePool(VarConsole);\r
- }\r
- if (NewDevicePath != NULL) {\r
- FreePool(NewDevicePath);\r
- }\r
- }\r
-\r
- return Status;\r
-\r
-}\r
-\r
-\r
-/**\r
- Connect the console device base on the variable ConVarName, if\r
- device path of the ConVarName is multi-instance device path and\r
- anyone of the instances is connected success, then this function\r
- will return success.\r
- If the handle associate with one device path node can not\r
- be created successfully, then still give chance to do the dispatch,\r
- which load the missing drivers if possible..\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
- if (Instance == NULL) {\r
- FreePool (StartDevicePath);\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Next = Instance;\r
- while (!IsDevicePathEndType (Next)) {\r
- Next = NextDevicePathNode (Next);\r
- }\r
-\r
- SetDevicePathEndNode (Next);\r
- //\r
- // Connect the USB console\r
- // USB console device path is a short-form device path that\r
- // starts with the first element being a USB WWID\r
- // or a USB Class device path\r
- //\r
- if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&\r
- ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP)\r
- || (DevicePathSubType (Instance) == MSG_USB_WWID_DP)\r
- )) {\r
- Status = BdsLibConnectUsbDevByShortFormDP (0xFF, 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
-\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
- This function will search every simpletext device in current system,\r
- and make every simpletext 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 variables\r
- //\r
- gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiSimpleTextInProtocolGuid,\r
- NULL,\r
- &HandleCount,\r
- &HandleBuffer\r
- );\r
-\r
- for (Index = 0; Index < HandleCount; Index++) {\r
- gBS->HandleProtocol (\r
- HandleBuffer[Index],\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **) &ConDevicePath\r
- );\r
- 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 BdsLibConnectConsoleVariable ().\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BdsLibConnectAllDefaultConsoles (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- BOOLEAN SystemTableUpdated;\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
- SystemTableUpdated = FALSE;\r
- //\r
- // Fill console handles in System Table if no console device assignd.\r
- //\r
- if (UpdateSystemTableConsole (L"ConIn", &gEfiSimpleTextInProtocolGuid, &gST->ConsoleInHandle, (VOID **) &gST->ConIn)) {\r
- SystemTableUpdated = TRUE;\r
- }\r
- if (UpdateSystemTableConsole (L"ConOut", &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **) &gST->ConOut)) {\r
- SystemTableUpdated = TRUE;\r
- }\r
- if (UpdateSystemTableConsole (L"ErrOut", &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **) &gST->StdErr)) {\r
- SystemTableUpdated = TRUE;\r
- }\r
-\r
- if (SystemTableUpdated) {\r
- //\r
- // Update the CRC32 in the EFI System Table header\r
- //\r
- gST->Hdr.CRC32 = 0;\r
- gBS->CalculateCrc32 (\r
- (UINT8 *) &gST->Hdr,\r
- gST->Hdr.HeaderSize,\r
- &gST->Hdr.CRC32\r
- );\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-/**\r
- This function will connect console device except ConIn base on the console\r
- device variable ConOut and ErrOut.\r
-\r
- @retval EFI_SUCCESS At least one of the ConOut device have\r
- been connected success.\r
- @retval EFI_STATUS Return the status of BdsLibConnectConsoleVariable ().\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BdsLibConnectAllDefaultConsolesWithOutConIn (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- BOOLEAN SystemTableUpdated;\r
-\r
- //\r
- // Connect all default console variables except ConIn\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
- // The _ModuleEntryPoint err out var is legal.\r
- //\r
- BdsLibConnectConsoleVariable (L"ErrOut");\r
-\r
- SystemTableUpdated = FALSE;\r
- //\r
- // Fill console handles in System Table if no console device assignd.\r
- //\r
- if (UpdateSystemTableConsole (L"ConOut", &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **) &gST->ConOut)) {\r
- SystemTableUpdated = TRUE;\r
- }\r
- if (UpdateSystemTableConsole (L"ErrOut", &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **) &gST->StdErr)) {\r
- SystemTableUpdated = TRUE;\r
- }\r
-\r
- if (SystemTableUpdated) {\r
- //\r
- // Update the CRC32 in the EFI System Table header\r
- //\r
- gST->Hdr.CRC32 = 0;\r
- gBS->CalculateCrc32 (\r
- (UINT8 *) &gST->Hdr,\r
- gST->Hdr.HeaderSize,\r
- &gST->Hdr.CRC32\r
- );\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-/**\r
- Use SystemTable Conout to stop video based Simple Text Out consoles from going\r
- to the video device. Put up LogoFile on every video device that is a console.\r
-\r
- @param[in] 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\r
- )\r
-{\r
- EFI_STATUS Status;\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
- EFI_BOOT_LOGO_PROTOCOL *BootLogo;\r
- UINTN NumberOfLogos;\r
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LogoBlt;\r
- UINTN LogoDestX;\r
- UINTN LogoDestY;\r
- UINTN LogoHeight;\r
- UINTN LogoWidth;\r
- UINTN NewDestX;\r
- UINTN NewDestY;\r
- UINTN NewHeight;\r
- UINTN NewWidth;\r
- UINT64 BufferSize;\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
- //\r
- // Try to open Boot Logo Protocol.\r
- //\r
- BootLogo = NULL;\r
- gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);\r
-\r
- //\r
- // Erase Cursor from screen\r
- //\r
- gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
-\r
- Badging = NULL;\r
- Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);\r
-\r
- if (GraphicsOutput != NULL) {\r
- SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
- SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
-\r
- } else if (UgaDraw != NULL && 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
- Blt = NULL;\r
- NumberOfLogos = 0;\r
- LogoDestX = 0;\r
- LogoDestY = 0;\r
- LogoHeight = 0;\r
- LogoWidth = 0;\r
- NewDestX = 0;\r
- NewDestY = 0;\r
- NewHeight = 0;\r
- NewWidth = 0;\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
- goto Done;\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
- if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {\r
- Attribute = EfiBadgingDisplayAttributeCenter;\r
- } else {\r
- Attribute = EfiBadgingDisplayAttributeCustomized;\r
- }\r
- }\r
-\r
- if (Blt != NULL) {\r
- FreePool (Blt);\r
- }\r
- Blt = NULL;\r
- Status = TranslateBmpToGopBlt (\r
- ImageData,\r
- ImageSize,\r
- &Blt,\r
- &BltSize,\r
- &Height,\r
- &Width\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (ImageData);\r
-\r
- if (Badging == NULL) {\r
- return Status;\r
- } else {\r
- continue;\r
- }\r
- }\r
-\r
- //\r
- // Calculate 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
- case EfiBadgingDisplayAttributeCustomized:\r
- DestX = (SizeOfX - Width) / 2;\r
- DestY = ((SizeOfY * 382) / 1000) - 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 (UgaDraw != NULL && 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
- // Report displayed Logo information.\r
- //\r
- if (!EFI_ERROR (Status)) {\r
- NumberOfLogos++;\r
-\r
- if (LogoWidth == 0) {\r
- //\r
- // The first Logo.\r
- //\r
- LogoDestX = (UINTN) DestX;\r
- LogoDestY = (UINTN) DestY;\r
- LogoWidth = Width;\r
- LogoHeight = Height;\r
- } else {\r
- //\r
- // Merge new logo with old one.\r
- //\r
- NewDestX = MIN ((UINTN) DestX, LogoDestX);\r
- NewDestY = MIN ((UINTN) DestY, LogoDestY);\r
- NewWidth = MAX ((UINTN) DestX + Width, LogoDestX + LogoWidth) - NewDestX;\r
- NewHeight = MAX ((UINTN) DestY + Height, LogoDestY + LogoHeight) - NewDestY;\r
-\r
- LogoDestX = NewDestX;\r
- LogoDestY = NewDestY;\r
- LogoWidth = NewWidth;\r
- LogoHeight = NewHeight;\r
- }\r
- }\r
- }\r
-\r
- FreePool (ImageData);\r
-\r
- if (Badging == NULL) {\r
- break;\r
- }\r
- }\r
-\r
-Done:\r
- if (BootLogo == NULL || NumberOfLogos == 0) {\r
- //\r
- // No logo displayed.\r
- //\r
- if (Blt != NULL) {\r
- FreePool (Blt);\r
- }\r
-\r
- return Status;\r
- }\r
-\r
- //\r
- // Advertise displayed Logo information.\r
- //\r
- if (NumberOfLogos == 1) {\r
- //\r
- // Only one logo displayed, use its Blt buffer directly for BootLogo protocol.\r
- //\r
- LogoBlt = Blt;\r
- Status = EFI_SUCCESS;\r
- } else {\r
- //\r
- // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation.\r
- //\r
- if (Blt != NULL) {\r
- FreePool (Blt);\r
- }\r
-\r
- //\r
- // Ensure the LogoHeight * LogoWidth doesn't overflow\r
- //\r
- if (LogoHeight > DivU64x64Remainder ((UINTN) ~0, LogoWidth, NULL)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- BufferSize = MultU64x64 (LogoWidth, LogoHeight);\r
-\r
- //\r
- // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow\r
- //\r
- if (BufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- LogoBlt = AllocateZeroPool ((UINTN)BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
- if (LogoBlt == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- if (GraphicsOutput != NULL) {\r
- Status = GraphicsOutput->Blt (\r
- GraphicsOutput,\r
- LogoBlt,\r
- EfiBltVideoToBltBuffer,\r
- LogoDestX,\r
- LogoDestY,\r
- 0,\r
- 0,\r
- LogoWidth,\r
- LogoHeight,\r
- LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
- );\r
- } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
- Status = UgaDraw->Blt (\r
- UgaDraw,\r
- (EFI_UGA_PIXEL *) LogoBlt,\r
- EfiUgaVideoToBltBuffer,\r
- LogoDestX,\r
- LogoDestY,\r
- 0,\r
- 0,\r
- LogoWidth,\r
- LogoHeight,\r
- LogoWidth * sizeof (EFI_UGA_PIXEL)\r
- );\r
- } else {\r
- Status = EFI_UNSUPPORTED;\r
- }\r
- }\r
-\r
- if (!EFI_ERROR (Status)) {\r
- BootLogo->SetBootLogo (BootLogo, LogoBlt, LogoDestX, LogoDestY, LogoWidth, LogoHeight);\r
- }\r
- FreePool (LogoBlt);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Use SystemTable Conout to turn on video based Simple Text Out consoles. The\r
- Simple Text Out screens will now be synced up with all non video output devices\r
-\r
- @retval EFI_SUCCESS UGA devices are back in text mode and synced up.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DisableQuietBoot (\r
- VOID\r
- )\r
-{\r
-\r
- //\r
- // Enable Cursor on Screen\r
- //\r
- gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
- return EFI_SUCCESS;\r
-}\r
-\r