2 BDS Lib functions which contain all the code to connect console device
4 Copyright (c) 2004 - 2013, 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
;
91 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
93 ASSERT (VarName
!= NULL
);
94 ASSERT (ConsoleHandle
!= NULL
);
95 ASSERT (ConsoleGuid
!= NULL
);
96 ASSERT (ProtocolInterface
!= NULL
);
98 if (*ConsoleHandle
!= NULL
) {
99 Status
= gBS
->HandleProtocol (
104 if (Status
== EFI_SUCCESS
&& Interface
== *ProtocolInterface
) {
106 // If ConsoleHandle is valid and console protocol on this handle also
107 // also matched, just return.
114 // Get all possible consoles device path from EFI variable
116 VarConsole
= BdsLibGetVariableAndSize (
118 &gEfiGlobalVariableGuid
,
121 if (VarConsole
== NULL
) {
123 // If there is no any console device, just return.
128 FullDevicePath
= VarConsole
;
132 // Check every instance of the console variable
134 Instance
= GetNextDevicePathInstance (&VarConsole
, &DevicePathSize
);
135 if (Instance
== NULL
) {
136 FreePool (FullDevicePath
);
141 // Find console device handle by device path instance
143 Status
= gBS
->LocateDevicePath (
148 if (!EFI_ERROR (Status
)) {
150 // Get the console protocol on this console device handle
152 Status
= gBS
->HandleProtocol (
157 if (!EFI_ERROR (Status
)) {
159 // Update new console handle in System Table.
161 *ConsoleHandle
= NewHandle
;
162 *ProtocolInterface
= Interface
;
163 if (CompareGuid (ConsoleGuid
, &gEfiSimpleTextOutProtocolGuid
)) {
165 // If it is console out device, set console mode 80x25 if current mode is invalid.
167 TextOut
= (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*) Interface
;
168 if (TextOut
->Mode
->Mode
== -1) {
169 TextOut
->SetMode (TextOut
, 0);
176 } while (Instance
!= NULL
);
179 // No any available console devcie found.
185 This function update console variable based on ConVarName, it can
186 add or remove one specific console device path from the variable
188 @param ConVarName Console related variable name, ConIn, ConOut,
190 @param CustomizedConDevicePath The console device path which will be added to
191 the console variable ConVarName, this parameter
192 can not be multi-instance.
193 @param ExclusiveDevicePath The console device path which will be removed
194 from the console variable ConVarName, this
195 parameter can not be multi-instance.
197 @retval EFI_UNSUPPORTED The added device path is same to the removed one.
198 @retval EFI_SUCCESS Success add or remove the device path from the
204 BdsLibUpdateConsoleVariable (
205 IN CHAR16
*ConVarName
,
206 IN EFI_DEVICE_PATH_PROTOCOL
*CustomizedConDevicePath
,
207 IN EFI_DEVICE_PATH_PROTOCOL
*ExclusiveDevicePath
211 EFI_DEVICE_PATH_PROTOCOL
*VarConsole
;
212 UINTN DevicePathSize
;
213 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
214 EFI_DEVICE_PATH_PROTOCOL
*TempNewDevicePath
;
221 // Notes: check the device path point, here should check
222 // with compare memory
224 if (CustomizedConDevicePath
== ExclusiveDevicePath
) {
225 return EFI_UNSUPPORTED
;
228 // Delete the ExclusiveDevicePath from current default console
230 VarConsole
= BdsLibGetVariableAndSize (
232 &gEfiGlobalVariableGuid
,
237 // Initialize NewDevicePath
239 NewDevicePath
= VarConsole
;
242 // If ExclusiveDevicePath is even the part of the instance in VarConsole, delete it.
243 // In the end, NewDevicePath is the final device path.
245 if (ExclusiveDevicePath
!= NULL
&& VarConsole
!= NULL
) {
246 NewDevicePath
= BdsLibDelPartMatchInstance (VarConsole
, ExclusiveDevicePath
);
249 // Try to append customized device path to NewDevicePath.
251 if (CustomizedConDevicePath
!= NULL
) {
252 if (!BdsLibMatchDevicePaths (NewDevicePath
, CustomizedConDevicePath
)) {
254 // Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.
256 NewDevicePath
= BdsLibDelPartMatchInstance (NewDevicePath
, CustomizedConDevicePath
);
258 // In the first check, the default console variable will be _ModuleEntryPoint,
259 // just append current customized device path
261 TempNewDevicePath
= NewDevicePath
;
262 NewDevicePath
= AppendDevicePathInstance (NewDevicePath
, CustomizedConDevicePath
);
263 if (TempNewDevicePath
!= NULL
) {
264 FreePool(TempNewDevicePath
);
270 // The attribute for ConInDev, ConOutDev and ErrOutDev does not include NV.
272 if (IsNvNeed(ConVarName
)) {
274 // ConVarName has NV attribute.
276 Attributes
= EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
;
279 // ConVarName does not have NV attribute.
281 Attributes
= EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
;
285 // Finally, Update the variable of the default console by NewDevicePath
287 DevicePathSize
= GetDevicePathSize (NewDevicePath
);
288 Status
= gRT
->SetVariable (
290 &gEfiGlobalVariableGuid
,
295 if ((DevicePathSize
== 0) && (Status
== EFI_NOT_FOUND
)) {
296 Status
= EFI_SUCCESS
;
298 ASSERT_EFI_ERROR (Status
);
300 if (VarConsole
== NewDevicePath
) {
301 if (VarConsole
!= NULL
) {
302 FreePool(VarConsole
);
305 if (VarConsole
!= NULL
) {
306 FreePool(VarConsole
);
308 if (NewDevicePath
!= NULL
) {
309 FreePool(NewDevicePath
);
319 Connect the console device base on the variable ConVarName, if
320 device path of the ConVarName is multi-instance device path and
321 anyone of the instances is connected success, then this function
323 If the handle associate with one device path node can not
324 be created successfully, then still give chance to do the dispatch,
325 which load the missing drivers if possible..
327 @param ConVarName Console related variable name, ConIn, ConOut,
330 @retval EFI_NOT_FOUND There is not any console devices connected
332 @retval EFI_SUCCESS Success connect any one instance of the console
333 device path base on the variable ConVarName.
338 BdsLibConnectConsoleVariable (
339 IN CHAR16
*ConVarName
343 EFI_DEVICE_PATH_PROTOCOL
*StartDevicePath
;
345 EFI_DEVICE_PATH_PROTOCOL
*Instance
;
346 EFI_DEVICE_PATH_PROTOCOL
*Next
;
347 EFI_DEVICE_PATH_PROTOCOL
*CopyOfDevicePath
;
351 Status
= EFI_SUCCESS
;
355 // Check if the console variable exist
357 StartDevicePath
= BdsLibGetVariableAndSize (
359 &gEfiGlobalVariableGuid
,
362 if (StartDevicePath
== NULL
) {
363 return EFI_UNSUPPORTED
;
366 CopyOfDevicePath
= StartDevicePath
;
369 // Check every instance of the console variable
371 Instance
= GetNextDevicePathInstance (&CopyOfDevicePath
, &Size
);
372 if (Instance
== NULL
) {
373 FreePool (StartDevicePath
);
374 return EFI_UNSUPPORTED
;
378 while (!IsDevicePathEndType (Next
)) {
379 Next
= NextDevicePathNode (Next
);
382 SetDevicePathEndNode (Next
);
384 // Connect the USB console
385 // USB console device path is a short-form device path that
386 // starts with the first element being a USB WWID
387 // or a USB Class device path
389 if ((DevicePathType (Instance
) == MESSAGING_DEVICE_PATH
) &&
390 ((DevicePathSubType (Instance
) == MSG_USB_CLASS_DP
)
391 || (DevicePathSubType (Instance
) == MSG_USB_WWID_DP
)
393 Status
= BdsLibConnectUsbDevByShortFormDP (0xFF, Instance
);
394 if (!EFI_ERROR (Status
)) {
399 // Connect the instance device path
401 Status
= BdsLibConnectDevicePath (Instance
);
403 if (EFI_ERROR (Status
)) {
405 // Delete the instance from the console varialbe
407 BdsLibUpdateConsoleVariable (ConVarName
, NULL
, Instance
);
413 } while (CopyOfDevicePath
!= NULL
);
415 FreePool (StartDevicePath
);
418 return EFI_NOT_FOUND
;
425 This function will search every simpletext device in current system,
426 and make every simpletext device as pertantial console device.
431 BdsLibConnectAllConsoles (
436 EFI_DEVICE_PATH_PROTOCOL
*ConDevicePath
;
438 EFI_HANDLE
*HandleBuffer
;
443 ConDevicePath
= NULL
;
446 // Update all the console variables
448 gBS
->LocateHandleBuffer (
450 &gEfiSimpleTextInProtocolGuid
,
456 for (Index
= 0; Index
< HandleCount
; Index
++) {
457 gBS
->HandleProtocol (
459 &gEfiDevicePathProtocolGuid
,
460 (VOID
**) &ConDevicePath
462 BdsLibUpdateConsoleVariable (L
"ConIn", ConDevicePath
, NULL
);
465 if (HandleBuffer
!= NULL
) {
466 FreePool(HandleBuffer
);
470 gBS
->LocateHandleBuffer (
472 &gEfiSimpleTextOutProtocolGuid
,
477 for (Index
= 0; Index
< HandleCount
; Index
++) {
478 gBS
->HandleProtocol (
480 &gEfiDevicePathProtocolGuid
,
481 (VOID
**) &ConDevicePath
483 BdsLibUpdateConsoleVariable (L
"ConOut", ConDevicePath
, NULL
);
484 BdsLibUpdateConsoleVariable (L
"ErrOut", ConDevicePath
, NULL
);
487 if (HandleBuffer
!= NULL
) {
488 FreePool(HandleBuffer
);
492 // Connect all console variables
494 BdsLibConnectAllDefaultConsoles ();
499 This function will connect console device base on the console
500 device variable ConIn, ConOut and ErrOut.
502 @retval EFI_SUCCESS At least one of the ConIn and ConOut device have
503 been connected success.
504 @retval EFI_STATUS Return the status of BdsLibConnectConsoleVariable ().
509 BdsLibConnectAllDefaultConsoles (
514 BOOLEAN SystemTableUpdated
;
517 // Connect all default console variables
521 // It seems impossible not to have any ConOut device on platform,
522 // so we check the status here.
524 Status
= BdsLibConnectConsoleVariable (L
"ConOut");
525 if (EFI_ERROR (Status
)) {
530 // Insert the performance probe for Console Out
532 PERF_START (NULL
, "ConOut", "BDS", 1);
533 PERF_END (NULL
, "ConOut", "BDS", 0);
536 // Because possibly the platform is legacy free, in such case,
537 // ConIn devices (Serial Port and PS2 Keyboard ) does not exist,
538 // so we need not check the status.
540 BdsLibConnectConsoleVariable (L
"ConIn");
543 // The _ModuleEntryPoint err out var is legal.
545 BdsLibConnectConsoleVariable (L
"ErrOut");
547 SystemTableUpdated
= FALSE
;
549 // Fill console handles in System Table if no console device assignd.
551 if (UpdateSystemTableConsole (L
"ConIn", &gEfiSimpleTextInProtocolGuid
, &gST
->ConsoleInHandle
, (VOID
**) &gST
->ConIn
)) {
552 SystemTableUpdated
= TRUE
;
554 if (UpdateSystemTableConsole (L
"ConOut", &gEfiSimpleTextOutProtocolGuid
, &gST
->ConsoleOutHandle
, (VOID
**) &gST
->ConOut
)) {
555 SystemTableUpdated
= TRUE
;
557 if (UpdateSystemTableConsole (L
"ErrOut", &gEfiSimpleTextOutProtocolGuid
, &gST
->StandardErrorHandle
, (VOID
**) &gST
->StdErr
)) {
558 SystemTableUpdated
= TRUE
;
561 if (SystemTableUpdated
) {
563 // Update the CRC32 in the EFI System Table header
566 gBS
->CalculateCrc32 (
578 This function will connect console device except ConIn base on the console
579 device variable ConOut and ErrOut.
581 @retval EFI_SUCCESS At least one of the ConOut device have
582 been connected success.
583 @retval EFI_STATUS Return the status of BdsLibConnectConsoleVariable ().
588 BdsLibConnectAllDefaultConsolesWithOutConIn (
593 BOOLEAN SystemTableUpdated
;
596 // Connect all default console variables except ConIn
600 // It seems impossible not to have any ConOut device on platform,
601 // so we check the status here.
603 Status
= BdsLibConnectConsoleVariable (L
"ConOut");
604 if (EFI_ERROR (Status
)) {
609 // Insert the performance probe for Console Out
611 PERF_START (NULL
, "ConOut", "BDS", 1);
612 PERF_END (NULL
, "ConOut", "BDS", 0);
615 // The _ModuleEntryPoint err out var is legal.
617 BdsLibConnectConsoleVariable (L
"ErrOut");
619 SystemTableUpdated
= FALSE
;
621 // Fill console handles in System Table if no console device assignd.
623 if (UpdateSystemTableConsole (L
"ConOut", &gEfiSimpleTextOutProtocolGuid
, &gST
->ConsoleOutHandle
, (VOID
**) &gST
->ConOut
)) {
624 SystemTableUpdated
= TRUE
;
626 if (UpdateSystemTableConsole (L
"ErrOut", &gEfiSimpleTextOutProtocolGuid
, &gST
->StandardErrorHandle
, (VOID
**) &gST
->StdErr
)) {
627 SystemTableUpdated
= TRUE
;
630 if (SystemTableUpdated
) {
632 // Update the CRC32 in the EFI System Table header
635 gBS
->CalculateCrc32 (
647 Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer
648 is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt
649 buffer is passed in it will be used if it is big enough.
651 @param BmpImage Pointer to BMP file
652 @param BmpImageSize Number of bytes in BmpImage
653 @param GopBlt Buffer containing GOP version of BmpImage.
654 @param GopBltSize Size of GopBlt in bytes.
655 @param PixelHeight Height of GopBlt/BmpImage in pixels
656 @param PixelWidth Width of GopBlt/BmpImage in pixels
658 @retval EFI_SUCCESS GopBlt and GopBltSize are returned.
659 @retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image
660 @retval EFI_BUFFER_TOO_SMALL The passed in GopBlt buffer is not big enough.
661 GopBltSize will contain the required size.
662 @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate.
668 IN UINTN BmpImageSize
,
669 IN OUT VOID
**GopBlt
,
670 IN OUT UINTN
*GopBltSize
,
671 OUT UINTN
*PixelHeight
,
672 OUT UINTN
*PixelWidth
677 BMP_IMAGE_HEADER
*BmpHeader
;
678 BMP_COLOR_MAP
*BmpColorMap
;
679 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
;
680 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
681 UINT64 BltBufferSize
;
686 UINT32 DataSizePerLine
;
690 if (sizeof (BMP_IMAGE_HEADER
) > BmpImageSize
) {
691 return EFI_INVALID_PARAMETER
;
694 BmpHeader
= (BMP_IMAGE_HEADER
*) BmpImage
;
696 if (BmpHeader
->CharB
!= 'B' || BmpHeader
->CharM
!= 'M') {
697 return EFI_UNSUPPORTED
;
701 // Doesn't support compress.
703 if (BmpHeader
->CompressionType
!= 0) {
704 return EFI_UNSUPPORTED
;
708 // Only support BITMAPINFOHEADER format.
709 // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER
711 if (BmpHeader
->HeaderSize
!= sizeof (BMP_IMAGE_HEADER
) - OFFSET_OF(BMP_IMAGE_HEADER
, HeaderSize
)) {
712 return EFI_UNSUPPORTED
;
716 // The data size in each line must be 4 byte alignment.
718 DataSizePerLine
= ((BmpHeader
->PixelWidth
* BmpHeader
->BitPerPixel
+ 31) >> 3) & (~0x3);
719 BltBufferSize
= MultU64x32 (DataSizePerLine
, BmpHeader
->PixelHeight
);
720 if (BltBufferSize
> (UINT32
) ~0) {
721 return EFI_INVALID_PARAMETER
;
724 if ((BmpHeader
->Size
!= BmpImageSize
) ||
725 (BmpHeader
->Size
< BmpHeader
->ImageOffset
) ||
726 (BmpHeader
->Size
- BmpHeader
->ImageOffset
!= BmpHeader
->PixelHeight
* DataSizePerLine
)) {
727 return EFI_INVALID_PARAMETER
;
731 // Calculate Color Map offset in the image.
734 BmpColorMap
= (BMP_COLOR_MAP
*) (Image
+ sizeof (BMP_IMAGE_HEADER
));
735 if (BmpHeader
->ImageOffset
< sizeof (BMP_IMAGE_HEADER
)) {
736 return EFI_INVALID_PARAMETER
;
739 if (BmpHeader
->ImageOffset
> sizeof (BMP_IMAGE_HEADER
)) {
740 switch (BmpHeader
->BitPerPixel
) {
755 // BMP file may has padding data between the bmp header section and the bmp data section.
757 if (BmpHeader
->ImageOffset
- sizeof (BMP_IMAGE_HEADER
) < sizeof (BMP_COLOR_MAP
) * ColorMapNum
) {
758 return EFI_INVALID_PARAMETER
;
763 // Calculate graphics image data address in the image
765 Image
= ((UINT8
*) BmpImage
) + BmpHeader
->ImageOffset
;
769 // Calculate the BltBuffer needed size.
771 BltBufferSize
= MultU64x32 ((UINT64
) BmpHeader
->PixelWidth
, BmpHeader
->PixelHeight
);
773 // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
775 if (BltBufferSize
> DivU64x32 ((UINTN
) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))) {
776 return EFI_UNSUPPORTED
;
778 BltBufferSize
= MultU64x32 (BltBufferSize
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
781 if (*GopBlt
== NULL
) {
783 // GopBlt is not allocated by caller.
785 *GopBltSize
= (UINTN
) BltBufferSize
;
786 *GopBlt
= AllocatePool (*GopBltSize
);
788 if (*GopBlt
== NULL
) {
789 return EFI_OUT_OF_RESOURCES
;
793 // GopBlt has been allocated by caller.
795 if (*GopBltSize
< (UINTN
) BltBufferSize
) {
796 *GopBltSize
= (UINTN
) BltBufferSize
;
797 return EFI_BUFFER_TOO_SMALL
;
801 *PixelWidth
= BmpHeader
->PixelWidth
;
802 *PixelHeight
= BmpHeader
->PixelHeight
;
805 // Convert image from BMP to Blt buffer format
808 for (Height
= 0; Height
< BmpHeader
->PixelHeight
; Height
++) {
809 Blt
= &BltBuffer
[(BmpHeader
->PixelHeight
- Height
- 1) * BmpHeader
->PixelWidth
];
810 for (Width
= 0; Width
< BmpHeader
->PixelWidth
; Width
++, Image
++, Blt
++) {
811 switch (BmpHeader
->BitPerPixel
) {
814 // Convert 1-bit (2 colors) BMP to 24-bit color
816 for (Index
= 0; Index
< 8 && Width
< BmpHeader
->PixelWidth
; Index
++) {
817 Blt
->Red
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Red
;
818 Blt
->Green
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Green
;
819 Blt
->Blue
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Blue
;
830 // Convert 4-bit (16 colors) BMP Palette to 24-bit color
832 Index
= (*Image
) >> 4;
833 Blt
->Red
= BmpColorMap
[Index
].Red
;
834 Blt
->Green
= BmpColorMap
[Index
].Green
;
835 Blt
->Blue
= BmpColorMap
[Index
].Blue
;
836 if (Width
< (BmpHeader
->PixelWidth
- 1)) {
839 Index
= (*Image
) & 0x0f;
840 Blt
->Red
= BmpColorMap
[Index
].Red
;
841 Blt
->Green
= BmpColorMap
[Index
].Green
;
842 Blt
->Blue
= BmpColorMap
[Index
].Blue
;
848 // Convert 8-bit (256 colors) BMP Palette to 24-bit color
850 Blt
->Red
= BmpColorMap
[*Image
].Red
;
851 Blt
->Green
= BmpColorMap
[*Image
].Green
;
852 Blt
->Blue
= BmpColorMap
[*Image
].Blue
;
859 Blt
->Blue
= *Image
++;
860 Blt
->Green
= *Image
++;
866 // Other bit format BMP is not supported.
872 return EFI_UNSUPPORTED
;
878 ImageIndex
= (UINTN
) (Image
- ImageHeader
);
879 if ((ImageIndex
% 4) != 0) {
881 // Bmp Image starts each row on a 32-bit boundary!
883 Image
= Image
+ (4 - (ImageIndex
% 4));
891 Use SystemTable Conout to stop video based Simple Text Out consoles from going
892 to the video device. Put up LogoFile on every video device that is a console.
894 @param[in] LogoFile File name of logo to display on the center of the screen.
896 @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed.
897 @retval EFI_UNSUPPORTED Logo not found
903 IN EFI_GUID
*LogoFile
907 EFI_OEM_BADGING_PROTOCOL
*Badging
;
916 EFI_BADGING_FORMAT Format
;
917 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute
;
922 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
923 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
926 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
927 EFI_BOOT_LOGO_PROTOCOL
*BootLogo
;
929 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*LogoBlt
;
942 // Try to open GOP first
944 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiGraphicsOutputProtocolGuid
, (VOID
**) &GraphicsOutput
);
945 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
946 GraphicsOutput
= NULL
;
948 // Open GOP failed, try to open UGA
950 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiUgaDrawProtocolGuid
, (VOID
**) &UgaDraw
);
952 if (EFI_ERROR (Status
)) {
953 return EFI_UNSUPPORTED
;
957 // Try to open Boot Logo Protocol.
960 gBS
->LocateProtocol (&gEfiBootLogoProtocolGuid
, NULL
, (VOID
**) &BootLogo
);
963 // Erase Cursor from screen
965 gST
->ConOut
->EnableCursor (gST
->ConOut
, FALSE
);
968 Status
= gBS
->LocateProtocol (&gEfiOEMBadgingProtocolGuid
, NULL
, (VOID
**) &Badging
);
970 if (GraphicsOutput
!= NULL
) {
971 SizeOfX
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
972 SizeOfY
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
974 } else if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
975 Status
= UgaDraw
->GetMode (UgaDraw
, &SizeOfX
, &SizeOfY
, &ColorDepth
, &RefreshRate
);
976 if (EFI_ERROR (Status
)) {
977 return EFI_UNSUPPORTED
;
980 return EFI_UNSUPPORTED
;
998 if (Badging
!= NULL
) {
1000 // Get image from OEMBadging protocol.
1002 Status
= Badging
->GetImage (
1012 if (EFI_ERROR (Status
)) {
1017 // Currently only support BMP format.
1019 if (Format
!= EfiBadgingFormatBMP
) {
1020 if (ImageData
!= NULL
) {
1021 FreePool (ImageData
);
1027 // Get the specified image from FV.
1029 Status
= GetSectionFromAnyFv (LogoFile
, EFI_SECTION_RAW
, 0, (VOID
**) &ImageData
, &ImageSize
);
1030 if (EFI_ERROR (Status
)) {
1031 return EFI_UNSUPPORTED
;
1036 if (!FeaturePcdGet(PcdBootlogoOnlyEnable
)) {
1037 Attribute
= EfiBadgingDisplayAttributeCenter
;
1039 Attribute
= EfiBadgingDisplayAttributeCustomized
;
1047 Status
= ConvertBmpToGopBlt (
1055 if (EFI_ERROR (Status
)) {
1056 FreePool (ImageData
);
1058 if (Badging
== NULL
) {
1066 // Calculate the display position according to Attribute.
1068 switch (Attribute
) {
1069 case EfiBadgingDisplayAttributeLeftTop
:
1070 DestX
= CoordinateX
;
1071 DestY
= CoordinateY
;
1074 case EfiBadgingDisplayAttributeCenterTop
:
1075 DestX
= (SizeOfX
- Width
) / 2;
1076 DestY
= CoordinateY
;
1079 case EfiBadgingDisplayAttributeRightTop
:
1080 DestX
= (SizeOfX
- Width
- CoordinateX
);
1081 DestY
= CoordinateY
;;
1084 case EfiBadgingDisplayAttributeCenterRight
:
1085 DestX
= (SizeOfX
- Width
- CoordinateX
);
1086 DestY
= (SizeOfY
- Height
) / 2;
1089 case EfiBadgingDisplayAttributeRightBottom
:
1090 DestX
= (SizeOfX
- Width
- CoordinateX
);
1091 DestY
= (SizeOfY
- Height
- CoordinateY
);
1094 case EfiBadgingDisplayAttributeCenterBottom
:
1095 DestX
= (SizeOfX
- Width
) / 2;
1096 DestY
= (SizeOfY
- Height
- CoordinateY
);
1099 case EfiBadgingDisplayAttributeLeftBottom
:
1100 DestX
= CoordinateX
;
1101 DestY
= (SizeOfY
- Height
- CoordinateY
);
1104 case EfiBadgingDisplayAttributeCenterLeft
:
1105 DestX
= CoordinateX
;
1106 DestY
= (SizeOfY
- Height
) / 2;
1109 case EfiBadgingDisplayAttributeCenter
:
1110 DestX
= (SizeOfX
- Width
) / 2;
1111 DestY
= (SizeOfY
- Height
) / 2;
1114 case EfiBadgingDisplayAttributeCustomized
:
1115 DestX
= (SizeOfX
- Width
) / 2;
1116 DestY
= ((SizeOfY
* 382) / 1000) - Height
/ 2;
1120 DestX
= CoordinateX
;
1121 DestY
= CoordinateY
;
1125 if ((DestX
>= 0) && (DestY
>= 0)) {
1126 if (GraphicsOutput
!= NULL
) {
1127 Status
= GraphicsOutput
->Blt (
1130 EfiBltBufferToVideo
,
1137 Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1139 } else if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
1140 Status
= UgaDraw
->Blt (
1142 (EFI_UGA_PIXEL
*) Blt
,
1143 EfiUgaBltBufferToVideo
,
1150 Width
* sizeof (EFI_UGA_PIXEL
)
1153 Status
= EFI_UNSUPPORTED
;
1157 // Report displayed Logo information.
1159 if (!EFI_ERROR (Status
)) {
1162 if (LogoWidth
== 0) {
1166 LogoDestX
= (UINTN
) DestX
;
1167 LogoDestY
= (UINTN
) DestY
;
1169 LogoHeight
= Height
;
1172 // Merge new logo with old one.
1174 NewDestX
= MIN ((UINTN
) DestX
, LogoDestX
);
1175 NewDestY
= MIN ((UINTN
) DestY
, LogoDestY
);
1176 NewWidth
= MAX ((UINTN
) DestX
+ Width
, LogoDestX
+ LogoWidth
) - NewDestX
;
1177 NewHeight
= MAX ((UINTN
) DestY
+ Height
, LogoDestY
+ LogoHeight
) - NewDestY
;
1179 LogoDestX
= NewDestX
;
1180 LogoDestY
= NewDestY
;
1181 LogoWidth
= NewWidth
;
1182 LogoHeight
= NewHeight
;
1187 FreePool (ImageData
);
1189 if (Badging
== NULL
) {
1195 if (BootLogo
== NULL
|| NumberOfLogos
== 0) {
1197 // No logo displayed.
1207 // Advertise displayed Logo information.
1209 if (NumberOfLogos
== 1) {
1211 // Only one logo displayed, use its Blt buffer directly for BootLogo protocol.
1214 Status
= EFI_SUCCESS
;
1217 // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation.
1224 // Ensure the LogoHeight * LogoWidth doesn't overflow
1226 if (LogoHeight
> DivU64x64Remainder ((UINTN
) ~0, LogoWidth
, NULL
)) {
1227 return EFI_UNSUPPORTED
;
1229 BufferSize
= MultU64x64 (LogoWidth
, LogoHeight
);
1232 // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
1234 if (BufferSize
> DivU64x32 ((UINTN
) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))) {
1235 return EFI_UNSUPPORTED
;
1238 LogoBlt
= AllocateZeroPool ((UINTN
)BufferSize
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
1239 if (LogoBlt
== NULL
) {
1240 return EFI_OUT_OF_RESOURCES
;
1243 if (GraphicsOutput
!= NULL
) {
1244 Status
= GraphicsOutput
->Blt (
1247 EfiBltVideoToBltBuffer
,
1254 LogoWidth
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
1256 } else if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
1257 Status
= UgaDraw
->Blt (
1259 (EFI_UGA_PIXEL
*) LogoBlt
,
1260 EfiUgaVideoToBltBuffer
,
1267 LogoWidth
* sizeof (EFI_UGA_PIXEL
)
1270 Status
= EFI_UNSUPPORTED
;
1274 if (!EFI_ERROR (Status
)) {
1275 BootLogo
->SetBootLogo (BootLogo
, LogoBlt
, LogoDestX
, LogoDestY
, LogoWidth
, LogoHeight
);
1283 Use SystemTable Conout to turn on video based Simple Text Out consoles. The
1284 Simple Text Out screens will now be synced up with all non video output devices
1286 @retval EFI_SUCCESS UGA devices are back in text mode and synced up.
1297 // Enable Cursor on Screen
1299 gST
->ConOut
->EnableCursor (gST
->ConOut
, TRUE
);