2 BDS Lib functions which contain all the code to connect console device
4 Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "InternalBdsLib.h"
16 #include <IndustryStandard/Bmp.h>
20 Check if we need to save the EFI variable with "ConVarName" as name
22 If ConVarName is NULL, then ASSERT().
24 @param ConVarName The name of the EFI variable.
26 @retval TRUE Set the EFI variable as NV type.
27 @retval FALSE EFI variable as NV type can be set NonNV.
36 ASSERT (ConVarName
!= NULL
);
41 // If the variable includes "Dev" at last, we consider
42 // it does not support NV attribute.
44 while (*Ptr
!= L
'\0') {
48 if (((INTN
)((UINTN
)Ptr
- (UINTN
)ConVarName
) / sizeof (CHAR16
)) <= 3) {
52 if ((*(Ptr
- 3) == 'D') && (*(Ptr
- 2) == 'e') && (*(Ptr
- 1) == 'v')) {
60 Fill console handle in System Table if there are no valid console handle in.
62 Firstly, check the validation of console handle in System Table. If it is invalid,
63 update it by the first console device handle from EFI console variable.
65 @param VarName The name of the EFI console variable.
66 @param ConsoleGuid Specified Console protocol GUID.
67 @param ConsoleHandle On IN, console handle in System Table to be checked.
68 On OUT, new console hanlde in system table.
69 @param ProtocolInterface On IN, console protocol on console handle in System Table to be checked.
70 On OUT, new console protocol on new console hanlde in system table.
72 @retval TRUE System Table has been updated.
73 @retval FALSE System Table hasn't been updated.
77 UpdateSystemTableConsole (
79 IN EFI_GUID
*ConsoleGuid
,
80 IN OUT EFI_HANDLE
*ConsoleHandle
,
81 IN OUT VOID
**ProtocolInterface
86 EFI_DEVICE_PATH_PROTOCOL
*FullDevicePath
;
87 EFI_DEVICE_PATH_PROTOCOL
*VarConsole
;
88 EFI_DEVICE_PATH_PROTOCOL
*Instance
;
92 ASSERT (VarName
!= NULL
);
93 ASSERT (ConsoleHandle
!= NULL
);
94 ASSERT (ConsoleGuid
!= NULL
);
95 ASSERT (ProtocolInterface
!= NULL
);
97 if (*ConsoleHandle
!= NULL
) {
98 Status
= gBS
->HandleProtocol (
103 if (Status
== EFI_SUCCESS
&& Interface
== *ProtocolInterface
) {
105 // If ConsoleHandle is valid and console protocol on this handle also
106 // also matched, just return.
113 // Get all possible consoles device path from EFI variable
115 VarConsole
= BdsLibGetVariableAndSize (
117 &gEfiGlobalVariableGuid
,
120 if (VarConsole
== NULL
) {
122 // If there is no any console device, just return.
127 FullDevicePath
= VarConsole
;
131 // Check every instance of the console variable
133 Instance
= GetNextDevicePathInstance (&VarConsole
, &DevicePathSize
);
134 if (Instance
== NULL
) {
135 FreePool (FullDevicePath
);
140 // Find console device handle by device path instance
142 Status
= gBS
->LocateDevicePath (
147 if (!EFI_ERROR (Status
)) {
149 // Get the console protocol on this console device handle
151 Status
= gBS
->HandleProtocol (
156 if (!EFI_ERROR (Status
)) {
158 // Update new console handle in System Table.
160 *ConsoleHandle
= NewHandle
;
161 *ProtocolInterface
= Interface
;
166 } while (Instance
!= NULL
);
169 // No any available console devcie found.
175 This function update console variable based on ConVarName, it can
176 add or remove one specific console device path from the variable
178 @param ConVarName Console related variable name, ConIn, ConOut,
180 @param CustomizedConDevicePath The console device path which will be added to
181 the console variable ConVarName, this parameter
182 can not be multi-instance.
183 @param ExclusiveDevicePath The console device path which will be removed
184 from the console variable ConVarName, this
185 parameter can not be multi-instance.
187 @retval EFI_UNSUPPORTED The added device path is same to the removed one.
188 @retval EFI_SUCCESS Success add or remove the device path from the
194 BdsLibUpdateConsoleVariable (
195 IN CHAR16
*ConVarName
,
196 IN EFI_DEVICE_PATH_PROTOCOL
*CustomizedConDevicePath
,
197 IN EFI_DEVICE_PATH_PROTOCOL
*ExclusiveDevicePath
201 EFI_DEVICE_PATH_PROTOCOL
*VarConsole
;
202 UINTN DevicePathSize
;
203 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
204 EFI_DEVICE_PATH_PROTOCOL
*TempNewDevicePath
;
211 // Notes: check the device path point, here should check
212 // with compare memory
214 if (CustomizedConDevicePath
== ExclusiveDevicePath
) {
215 return EFI_UNSUPPORTED
;
218 // Delete the ExclusiveDevicePath from current default console
220 VarConsole
= BdsLibGetVariableAndSize (
222 &gEfiGlobalVariableGuid
,
227 // Initialize NewDevicePath
229 NewDevicePath
= VarConsole
;
232 // If ExclusiveDevicePath is even the part of the instance in VarConsole, delete it.
233 // In the end, NewDevicePath is the final device path.
235 if (ExclusiveDevicePath
!= NULL
&& VarConsole
!= NULL
) {
236 NewDevicePath
= BdsLibDelPartMatchInstance (VarConsole
, ExclusiveDevicePath
);
239 // Try to append customized device path to NewDevicePath.
241 if (CustomizedConDevicePath
!= NULL
) {
242 if (!BdsLibMatchDevicePaths (NewDevicePath
, CustomizedConDevicePath
)) {
244 // Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.
246 NewDevicePath
= BdsLibDelPartMatchInstance (NewDevicePath
, CustomizedConDevicePath
);
248 // In the first check, the default console variable will be _ModuleEntryPoint,
249 // just append current customized device path
251 TempNewDevicePath
= NewDevicePath
;
252 NewDevicePath
= AppendDevicePathInstance (NewDevicePath
, CustomizedConDevicePath
);
253 if (TempNewDevicePath
!= NULL
) {
254 FreePool(TempNewDevicePath
);
260 // The attribute for ConInDev, ConOutDev and ErrOutDev does not include NV.
262 if (IsNvNeed(ConVarName
)) {
264 // ConVarName has NV attribute.
266 Attributes
= EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
;
269 // ConVarName does not have NV attribute.
271 Attributes
= EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
;
275 // Finally, Update the variable of the default console by NewDevicePath
277 DevicePathSize
= GetDevicePathSize (NewDevicePath
);
278 Status
= gRT
->SetVariable (
280 &gEfiGlobalVariableGuid
,
285 if ((DevicePathSize
== 0) && (Status
== EFI_NOT_FOUND
)) {
286 Status
= EFI_SUCCESS
;
288 ASSERT_EFI_ERROR (Status
);
290 if (VarConsole
== NewDevicePath
) {
291 if (VarConsole
!= NULL
) {
292 FreePool(VarConsole
);
295 if (VarConsole
!= NULL
) {
296 FreePool(VarConsole
);
298 if (NewDevicePath
!= NULL
) {
299 FreePool(NewDevicePath
);
309 Connect the console device base on the variable ConVarName, if
310 device path of the ConVarName is multi-instance device path, if
311 anyone of the instances is connected success, then this function
314 @param ConVarName Console related variable name, ConIn, ConOut,
317 @retval EFI_NOT_FOUND There is not any console devices connected
319 @retval EFI_SUCCESS Success connect any one instance of the console
320 device path base on the variable ConVarName.
325 BdsLibConnectConsoleVariable (
326 IN CHAR16
*ConVarName
330 EFI_DEVICE_PATH_PROTOCOL
*StartDevicePath
;
332 EFI_DEVICE_PATH_PROTOCOL
*Instance
;
333 EFI_DEVICE_PATH_PROTOCOL
*Next
;
334 EFI_DEVICE_PATH_PROTOCOL
*CopyOfDevicePath
;
338 Status
= EFI_SUCCESS
;
342 // Check if the console variable exist
344 StartDevicePath
= BdsLibGetVariableAndSize (
346 &gEfiGlobalVariableGuid
,
349 if (StartDevicePath
== NULL
) {
350 return EFI_UNSUPPORTED
;
353 CopyOfDevicePath
= StartDevicePath
;
356 // Check every instance of the console variable
358 Instance
= GetNextDevicePathInstance (&CopyOfDevicePath
, &Size
);
359 if (Instance
== NULL
) {
360 FreePool (StartDevicePath
);
361 return EFI_UNSUPPORTED
;
365 while (!IsDevicePathEndType (Next
)) {
366 Next
= NextDevicePathNode (Next
);
369 SetDevicePathEndNode (Next
);
371 // Connect the USB console
372 // USB console device path is a short-form device path that
373 // starts with the first element being a USB WWID
374 // or a USB Class device path
376 if ((DevicePathType (Instance
) == MESSAGING_DEVICE_PATH
) &&
377 ((DevicePathSubType (Instance
) == MSG_USB_CLASS_DP
)
378 || (DevicePathSubType (Instance
) == MSG_USB_WWID_DP
)
380 Status
= BdsLibConnectUsbDevByShortFormDP (0xFF, Instance
);
381 if (!EFI_ERROR (Status
)) {
386 // Connect the instance device path
388 Status
= BdsLibConnectDevicePath (Instance
);
389 if (EFI_ERROR (Status
)) {
391 // Delete the instance from the console varialbe
393 BdsLibUpdateConsoleVariable (ConVarName
, NULL
, Instance
);
399 } while (CopyOfDevicePath
!= NULL
);
401 FreePool (StartDevicePath
);
404 return EFI_NOT_FOUND
;
412 This function will search every simpletext device in current system,
413 and make every simpletext device as pertantial console device.
418 BdsLibConnectAllConsoles (
423 EFI_DEVICE_PATH_PROTOCOL
*ConDevicePath
;
425 EFI_HANDLE
*HandleBuffer
;
430 ConDevicePath
= NULL
;
433 // Update all the console variables
435 gBS
->LocateHandleBuffer (
437 &gEfiSimpleTextInProtocolGuid
,
443 for (Index
= 0; Index
< HandleCount
; Index
++) {
444 gBS
->HandleProtocol (
446 &gEfiDevicePathProtocolGuid
,
447 (VOID
**) &ConDevicePath
449 BdsLibUpdateConsoleVariable (L
"ConIn", ConDevicePath
, NULL
);
452 if (HandleBuffer
!= NULL
) {
453 FreePool(HandleBuffer
);
457 gBS
->LocateHandleBuffer (
459 &gEfiSimpleTextOutProtocolGuid
,
464 for (Index
= 0; Index
< HandleCount
; Index
++) {
465 gBS
->HandleProtocol (
467 &gEfiDevicePathProtocolGuid
,
468 (VOID
**) &ConDevicePath
470 BdsLibUpdateConsoleVariable (L
"ConOut", ConDevicePath
, NULL
);
471 BdsLibUpdateConsoleVariable (L
"ErrOut", ConDevicePath
, NULL
);
474 if (HandleBuffer
!= NULL
) {
475 FreePool(HandleBuffer
);
479 // Connect all console variables
481 BdsLibConnectAllDefaultConsoles ();
486 This function will connect console device base on the console
487 device variable ConIn, ConOut and ErrOut.
489 @retval EFI_SUCCESS At least one of the ConIn and ConOut device have
490 been connected success.
491 @retval EFI_STATUS Return the status of BdsLibConnectConsoleVariable ().
496 BdsLibConnectAllDefaultConsoles (
501 BOOLEAN SystemTableUpdated
;
504 // Connect all default console variables
508 // It seems impossible not to have any ConOut device on platform,
509 // so we check the status here.
511 Status
= BdsLibConnectConsoleVariable (L
"ConOut");
512 if (EFI_ERROR (Status
)) {
517 // Insert the performance probe for Console Out
519 PERF_START (NULL
, "ConOut", "BDS", 1);
520 PERF_END (NULL
, "ConOut", "BDS", 0);
523 // Because possibly the platform is legacy free, in such case,
524 // ConIn devices (Serial Port and PS2 Keyboard ) does not exist,
525 // so we need not check the status.
527 BdsLibConnectConsoleVariable (L
"ConIn");
530 // The _ModuleEntryPoint err out var is legal.
532 BdsLibConnectConsoleVariable (L
"ErrOut");
534 SystemTableUpdated
= FALSE
;
536 // Fill console handles in System Table if no console device assignd.
538 if (UpdateSystemTableConsole (L
"ConIn", &gEfiSimpleTextInProtocolGuid
, &gST
->ConsoleInHandle
, (VOID
**) &gST
->ConIn
)) {
539 SystemTableUpdated
= TRUE
;
541 if (UpdateSystemTableConsole (L
"ConOut", &gEfiSimpleTextOutProtocolGuid
, &gST
->ConsoleOutHandle
, (VOID
**) &gST
->ConOut
)) {
542 SystemTableUpdated
= TRUE
;
544 if (UpdateSystemTableConsole (L
"ErrOut", &gEfiSimpleTextOutProtocolGuid
, &gST
->StandardErrorHandle
, (VOID
**) &gST
->StdErr
)) {
545 SystemTableUpdated
= TRUE
;
548 if (SystemTableUpdated
) {
550 // Update the CRC32 in the EFI System Table header
553 gBS
->CalculateCrc32 (
565 This function will connect console device except ConIn base on the console
566 device variable ConOut and ErrOut.
568 @retval EFI_SUCCESS At least one of the ConOut device have
569 been connected success.
570 @retval EFI_STATUS Return the status of BdsLibConnectConsoleVariable ().
575 BdsLibConnectAllDefaultConsolesWithOutConIn (
580 BOOLEAN SystemTableUpdated
;
583 // Connect all default console variables except ConIn
587 // It seems impossible not to have any ConOut device on platform,
588 // so we check the status here.
590 Status
= BdsLibConnectConsoleVariable (L
"ConOut");
591 if (EFI_ERROR (Status
)) {
596 // Insert the performance probe for Console Out
598 PERF_START (NULL
, "ConOut", "BDS", 1);
599 PERF_END (NULL
, "ConOut", "BDS", 0);
602 // The _ModuleEntryPoint err out var is legal.
604 BdsLibConnectConsoleVariable (L
"ErrOut");
606 SystemTableUpdated
= FALSE
;
608 // Fill console handles in System Table if no console device assignd.
610 if (UpdateSystemTableConsole (L
"ConOut", &gEfiSimpleTextOutProtocolGuid
, &gST
->ConsoleOutHandle
, (VOID
**) &gST
->ConOut
)) {
611 SystemTableUpdated
= TRUE
;
613 if (UpdateSystemTableConsole (L
"ErrOut", &gEfiSimpleTextOutProtocolGuid
, &gST
->StandardErrorHandle
, (VOID
**) &gST
->StdErr
)) {
614 SystemTableUpdated
= TRUE
;
617 if (SystemTableUpdated
) {
619 // Update the CRC32 in the EFI System Table header
622 gBS
->CalculateCrc32 (
634 Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer
635 is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt
636 buffer is passed in it will be used if it is big enough.
638 @param BmpImage Pointer to BMP file
639 @param BmpImageSize Number of bytes in BmpImage
640 @param GopBlt Buffer containing GOP version of BmpImage.
641 @param GopBltSize Size of GopBlt in bytes.
642 @param PixelHeight Height of GopBlt/BmpImage in pixels
643 @param PixelWidth Width of GopBlt/BmpImage in pixels
645 @retval EFI_SUCCESS GopBlt and GopBltSize are returned.
646 @retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image
647 @retval EFI_BUFFER_TOO_SMALL The passed in GopBlt buffer is not big enough.
648 GopBltSize will contain the required size.
649 @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate.
655 IN UINTN BmpImageSize
,
656 IN OUT VOID
**GopBlt
,
657 IN OUT UINTN
*GopBltSize
,
658 OUT UINTN
*PixelHeight
,
659 OUT UINTN
*PixelWidth
664 BMP_IMAGE_HEADER
*BmpHeader
;
665 BMP_COLOR_MAP
*BmpColorMap
;
666 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
;
667 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
668 UINT64 BltBufferSize
;
673 UINT32 DataSizePerLine
;
677 if (sizeof (BMP_IMAGE_HEADER
) > BmpImageSize
) {
678 return EFI_INVALID_PARAMETER
;
681 BmpHeader
= (BMP_IMAGE_HEADER
*) BmpImage
;
683 if (BmpHeader
->CharB
!= 'B' || BmpHeader
->CharM
!= 'M') {
684 return EFI_UNSUPPORTED
;
688 // Doesn't support compress.
690 if (BmpHeader
->CompressionType
!= 0) {
691 return EFI_UNSUPPORTED
;
695 // Only support BITMAPINFOHEADER format.
696 // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER
698 if (BmpHeader
->HeaderSize
!= sizeof (BMP_IMAGE_HEADER
) - OFFSET_OF(BMP_IMAGE_HEADER
, HeaderSize
)) {
699 return EFI_UNSUPPORTED
;
703 // The data size in each line must be 4 byte alignment.
705 DataSizePerLine
= ((BmpHeader
->PixelWidth
* BmpHeader
->BitPerPixel
+ 31) >> 3) & (~0x3);
706 BltBufferSize
= MultU64x32 (DataSizePerLine
, BmpHeader
->PixelHeight
);
707 if (BltBufferSize
> (UINT32
) ~0) {
708 return EFI_INVALID_PARAMETER
;
711 if ((BmpHeader
->Size
!= BmpImageSize
) ||
712 (BmpHeader
->Size
< BmpHeader
->ImageOffset
) ||
713 (BmpHeader
->Size
- BmpHeader
->ImageOffset
!= BmpHeader
->PixelHeight
* DataSizePerLine
)) {
714 return EFI_INVALID_PARAMETER
;
718 // Calculate Color Map offset in the image.
721 BmpColorMap
= (BMP_COLOR_MAP
*) (Image
+ sizeof (BMP_IMAGE_HEADER
));
722 if (BmpHeader
->ImageOffset
< sizeof (BMP_IMAGE_HEADER
)) {
723 return EFI_INVALID_PARAMETER
;
726 if (BmpHeader
->ImageOffset
> sizeof (BMP_IMAGE_HEADER
)) {
727 switch (BmpHeader
->BitPerPixel
) {
741 if (BmpHeader
->ImageOffset
- sizeof (BMP_IMAGE_HEADER
) != sizeof (BMP_COLOR_MAP
) * ColorMapNum
) {
742 return EFI_INVALID_PARAMETER
;
747 // Calculate graphics image data address in the image
749 Image
= ((UINT8
*) BmpImage
) + BmpHeader
->ImageOffset
;
753 // Calculate the BltBuffer needed size.
755 BltBufferSize
= MultU64x32 ((UINT64
) BmpHeader
->PixelWidth
, BmpHeader
->PixelHeight
);
757 // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
759 if (BltBufferSize
> DivU64x32 ((UINTN
) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))) {
760 return EFI_UNSUPPORTED
;
762 BltBufferSize
= MultU64x32 (BltBufferSize
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
765 if (*GopBlt
== NULL
) {
767 // GopBlt is not allocated by caller.
769 *GopBltSize
= (UINTN
) BltBufferSize
;
770 *GopBlt
= AllocatePool (*GopBltSize
);
772 if (*GopBlt
== NULL
) {
773 return EFI_OUT_OF_RESOURCES
;
777 // GopBlt has been allocated by caller.
779 if (*GopBltSize
< (UINTN
) BltBufferSize
) {
780 *GopBltSize
= (UINTN
) BltBufferSize
;
781 return EFI_BUFFER_TOO_SMALL
;
785 *PixelWidth
= BmpHeader
->PixelWidth
;
786 *PixelHeight
= BmpHeader
->PixelHeight
;
789 // Convert image from BMP to Blt buffer format
792 for (Height
= 0; Height
< BmpHeader
->PixelHeight
; Height
++) {
793 Blt
= &BltBuffer
[(BmpHeader
->PixelHeight
- Height
- 1) * BmpHeader
->PixelWidth
];
794 for (Width
= 0; Width
< BmpHeader
->PixelWidth
; Width
++, Image
++, Blt
++) {
795 switch (BmpHeader
->BitPerPixel
) {
798 // Convert 1-bit (2 colors) BMP to 24-bit color
800 for (Index
= 0; Index
< 8 && Width
< BmpHeader
->PixelWidth
; Index
++) {
801 Blt
->Red
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Red
;
802 Blt
->Green
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Green
;
803 Blt
->Blue
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Blue
;
814 // Convert 4-bit (16 colors) BMP Palette to 24-bit color
816 Index
= (*Image
) >> 4;
817 Blt
->Red
= BmpColorMap
[Index
].Red
;
818 Blt
->Green
= BmpColorMap
[Index
].Green
;
819 Blt
->Blue
= BmpColorMap
[Index
].Blue
;
820 if (Width
< (BmpHeader
->PixelWidth
- 1)) {
823 Index
= (*Image
) & 0x0f;
824 Blt
->Red
= BmpColorMap
[Index
].Red
;
825 Blt
->Green
= BmpColorMap
[Index
].Green
;
826 Blt
->Blue
= BmpColorMap
[Index
].Blue
;
832 // Convert 8-bit (256 colors) BMP Palette to 24-bit color
834 Blt
->Red
= BmpColorMap
[*Image
].Red
;
835 Blt
->Green
= BmpColorMap
[*Image
].Green
;
836 Blt
->Blue
= BmpColorMap
[*Image
].Blue
;
843 Blt
->Blue
= *Image
++;
844 Blt
->Green
= *Image
++;
850 // Other bit format BMP is not supported.
856 return EFI_UNSUPPORTED
;
862 ImageIndex
= (UINTN
) (Image
- ImageHeader
);
863 if ((ImageIndex
% 4) != 0) {
865 // Bmp Image starts each row on a 32-bit boundary!
867 Image
= Image
+ (4 - (ImageIndex
% 4));
875 Use SystemTable Conout to stop video based Simple Text Out consoles from going
876 to the video device. Put up LogoFile on every video device that is a console.
878 @param[in] LogoFile File name of logo to display on the center of the screen.
880 @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed.
881 @retval EFI_UNSUPPORTED Logo not found
887 IN EFI_GUID
*LogoFile
891 EFI_OEM_BADGING_PROTOCOL
*Badging
;
900 EFI_BADGING_FORMAT Format
;
901 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute
;
906 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
907 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
910 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
911 EFI_BOOT_LOGO_PROTOCOL
*BootLogo
;
913 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*LogoBlt
;
926 // Try to open GOP first
928 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiGraphicsOutputProtocolGuid
, (VOID
**) &GraphicsOutput
);
929 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
930 GraphicsOutput
= NULL
;
932 // Open GOP failed, try to open UGA
934 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiUgaDrawProtocolGuid
, (VOID
**) &UgaDraw
);
936 if (EFI_ERROR (Status
)) {
937 return EFI_UNSUPPORTED
;
941 // Try to open Boot Logo Protocol.
944 gBS
->LocateProtocol (&gEfiBootLogoProtocolGuid
, NULL
, (VOID
**) &BootLogo
);
947 // Erase Cursor from screen
949 gST
->ConOut
->EnableCursor (gST
->ConOut
, FALSE
);
952 Status
= gBS
->LocateProtocol (&gEfiOEMBadgingProtocolGuid
, NULL
, (VOID
**) &Badging
);
954 if (GraphicsOutput
!= NULL
) {
955 SizeOfX
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
956 SizeOfY
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
958 } else if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
959 Status
= UgaDraw
->GetMode (UgaDraw
, &SizeOfX
, &SizeOfY
, &ColorDepth
, &RefreshRate
);
960 if (EFI_ERROR (Status
)) {
961 return EFI_UNSUPPORTED
;
964 return EFI_UNSUPPORTED
;
982 if (Badging
!= NULL
) {
984 // Get image from OEMBadging protocol.
986 Status
= Badging
->GetImage (
996 if (EFI_ERROR (Status
)) {
1001 // Currently only support BMP format.
1003 if (Format
!= EfiBadgingFormatBMP
) {
1004 if (ImageData
!= NULL
) {
1005 FreePool (ImageData
);
1011 // Get the specified image from FV.
1013 Status
= GetSectionFromAnyFv (LogoFile
, EFI_SECTION_RAW
, 0, (VOID
**) &ImageData
, &ImageSize
);
1014 if (EFI_ERROR (Status
)) {
1015 return EFI_UNSUPPORTED
;
1020 if (!FeaturePcdGet(PcdBootlogoOnlyEnable
)) {
1021 Attribute
= EfiBadgingDisplayAttributeCenter
;
1023 Attribute
= EfiBadgingDisplayAttributeCustomized
;
1031 Status
= ConvertBmpToGopBlt (
1039 if (EFI_ERROR (Status
)) {
1040 FreePool (ImageData
);
1042 if (Badging
== NULL
) {
1050 // Calculate the display position according to Attribute.
1052 switch (Attribute
) {
1053 case EfiBadgingDisplayAttributeLeftTop
:
1054 DestX
= CoordinateX
;
1055 DestY
= CoordinateY
;
1058 case EfiBadgingDisplayAttributeCenterTop
:
1059 DestX
= (SizeOfX
- Width
) / 2;
1060 DestY
= CoordinateY
;
1063 case EfiBadgingDisplayAttributeRightTop
:
1064 DestX
= (SizeOfX
- Width
- CoordinateX
);
1065 DestY
= CoordinateY
;;
1068 case EfiBadgingDisplayAttributeCenterRight
:
1069 DestX
= (SizeOfX
- Width
- CoordinateX
);
1070 DestY
= (SizeOfY
- Height
) / 2;
1073 case EfiBadgingDisplayAttributeRightBottom
:
1074 DestX
= (SizeOfX
- Width
- CoordinateX
);
1075 DestY
= (SizeOfY
- Height
- CoordinateY
);
1078 case EfiBadgingDisplayAttributeCenterBottom
:
1079 DestX
= (SizeOfX
- Width
) / 2;
1080 DestY
= (SizeOfY
- Height
- CoordinateY
);
1083 case EfiBadgingDisplayAttributeLeftBottom
:
1084 DestX
= CoordinateX
;
1085 DestY
= (SizeOfY
- Height
- CoordinateY
);
1088 case EfiBadgingDisplayAttributeCenterLeft
:
1089 DestX
= CoordinateX
;
1090 DestY
= (SizeOfY
- Height
) / 2;
1093 case EfiBadgingDisplayAttributeCenter
:
1094 DestX
= (SizeOfX
- Width
) / 2;
1095 DestY
= (SizeOfY
- Height
) / 2;
1098 case EfiBadgingDisplayAttributeCustomized
:
1099 DestX
= (SizeOfX
- Width
) / 2;
1100 DestY
= ((SizeOfY
* 382) / 1000) - Height
/ 2;
1104 DestX
= CoordinateX
;
1105 DestY
= CoordinateY
;
1109 if ((DestX
>= 0) && (DestY
>= 0)) {
1110 if (GraphicsOutput
!= NULL
) {
1111 Status
= GraphicsOutput
->Blt (
1114 EfiBltBufferToVideo
,
1121 Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1123 } else if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
1124 Status
= UgaDraw
->Blt (
1126 (EFI_UGA_PIXEL
*) Blt
,
1127 EfiUgaBltBufferToVideo
,
1134 Width
* sizeof (EFI_UGA_PIXEL
)
1137 Status
= EFI_UNSUPPORTED
;
1141 // Report displayed Logo information.
1143 if (!EFI_ERROR (Status
)) {
1146 if (LogoWidth
== 0) {
1150 LogoDestX
= (UINTN
) DestX
;
1151 LogoDestY
= (UINTN
) DestY
;
1153 LogoHeight
= Height
;
1156 // Merge new logo with old one.
1158 NewDestX
= MIN ((UINTN
) DestX
, LogoDestX
);
1159 NewDestY
= MIN ((UINTN
) DestY
, LogoDestY
);
1160 NewWidth
= MAX ((UINTN
) DestX
+ Width
, LogoDestX
+ LogoWidth
) - NewDestX
;
1161 NewHeight
= MAX ((UINTN
) DestY
+ Height
, LogoDestY
+ LogoHeight
) - NewDestY
;
1163 LogoDestX
= NewDestX
;
1164 LogoDestY
= NewDestY
;
1165 LogoWidth
= NewWidth
;
1166 LogoHeight
= NewHeight
;
1171 FreePool (ImageData
);
1173 if (Badging
== NULL
) {
1179 if (BootLogo
== NULL
|| NumberOfLogos
== 0) {
1181 // No logo displayed.
1191 // Advertise displayed Logo information.
1193 if (NumberOfLogos
== 1) {
1195 // Only one logo displayed, use its Blt buffer directly for BootLogo protocol.
1198 Status
= EFI_SUCCESS
;
1201 // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation.
1208 // Ensure the LogoHeight * LogoWidth doesn't overflow
1210 if (LogoHeight
> DivU64x64Remainder ((UINTN
) ~0, LogoWidth
, NULL
)) {
1211 return EFI_UNSUPPORTED
;
1213 BufferSize
= MultU64x64 (LogoWidth
, LogoHeight
);
1216 // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
1218 if (BufferSize
> DivU64x32 ((UINTN
) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))) {
1219 return EFI_UNSUPPORTED
;
1222 LogoBlt
= AllocateZeroPool ((UINTN
)BufferSize
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
1223 if (LogoBlt
== NULL
) {
1224 return EFI_OUT_OF_RESOURCES
;
1227 if (GraphicsOutput
!= NULL
) {
1228 Status
= GraphicsOutput
->Blt (
1231 EfiBltVideoToBltBuffer
,
1238 LogoWidth
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1240 } else if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
1241 Status
= UgaDraw
->Blt (
1243 (EFI_UGA_PIXEL
*) LogoBlt
,
1244 EfiUgaVideoToBltBuffer
,
1251 LogoWidth
* sizeof (EFI_UGA_PIXEL
)
1254 Status
= EFI_UNSUPPORTED
;
1258 if (!EFI_ERROR (Status
)) {
1259 BootLogo
->SetBootLogo (BootLogo
, LogoBlt
, LogoDestX
, LogoDestY
, LogoWidth
, LogoHeight
);
1267 Use SystemTable Conout to turn on video based Simple Text Out consoles. The
1268 Simple Text Out screens will now be synced up with all non video output devices
1270 @retval EFI_SUCCESS UGA devices are back in text mode and synced up.
1281 // Enable Cursor on Screen
1283 gST
->ConOut
->EnableCursor (gST
->ConOut
, TRUE
);