]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c
f9860a24777101c86681c1ac1d5a24a7ef1b0da6
[mirror_edk2.git] / IntelFrameworkModulePkg / Library / GenericBdsLib / BdsConsole.c
1 /** @file
2 BDS Lib functions which contain all the code to connect console device
3
4 Copyright (c) 2004 - 2008, Intel Corporation. <BR>
5 All rights reserved. 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
9
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.
12
13 **/
14
15 #include "InternalBdsLib.h"
16 #include "Bmp.h"
17
18 /**
19 Check if we need to save the EFI variable with "ConVarName" as name
20 as NV type
21
22 @param ConVarName The name of the EFI variable.
23
24 @retval TRUE Set the EFI variable as NV type.
25 @retval FALSE EFI variable as NV type can be set NonNV.
26 **/
27 BOOLEAN
28 IsNvNeed (
29 IN CHAR16 *ConVarName
30 )
31 {
32 CHAR16 *Ptr;
33
34 Ptr = ConVarName;
35
36 //
37 // If the variable includes "Dev" at last, we consider
38 // it does not support NV attribute.
39 //
40 while (*Ptr != L'\0') {
41 Ptr++;
42 }
43
44 if ((*(Ptr - 3) == 'D') && (*(Ptr - 2) == 'e') && (*(Ptr - 1) == 'v')) {
45 return FALSE;
46 } else {
47 return TRUE;
48 }
49 }
50
51 /**
52 This function update console variable based on ConVarName, it can
53 add or remove one specific console device path from the variable
54
55 @param ConVarName Console related variable name, ConIn, ConOut,
56 ErrOut.
57 @param CustomizedConDevicePath The console device path which will be added to
58 the console variable ConVarName, this parameter
59 can not be multi-instance.
60 @param ExclusiveDevicePath The console device path which will be removed
61 from the console variable ConVarName, this
62 parameter can not be multi-instance.
63
64 @retval EFI_UNSUPPORTED The added device path is same to the removed one.
65 @retval EFI_SUCCESS Success add or remove the device path from the
66 console variable.
67
68 **/
69 EFI_STATUS
70 EFIAPI
71 BdsLibUpdateConsoleVariable (
72 IN CHAR16 *ConVarName,
73 IN EFI_DEVICE_PATH_PROTOCOL *CustomizedConDevicePath,
74 IN EFI_DEVICE_PATH_PROTOCOL *ExclusiveDevicePath
75 )
76 {
77 EFI_DEVICE_PATH_PROTOCOL *VarConsole;
78 UINTN DevicePathSize;
79 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
80 EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;
81 UINT32 Attributes;
82
83 VarConsole = NULL;
84 DevicePathSize = 0;
85
86 //
87 // Notes: check the device path point, here should check
88 // with compare memory
89 //
90 if (CustomizedConDevicePath == ExclusiveDevicePath) {
91 return EFI_UNSUPPORTED;
92 }
93 //
94 // Delete the ExclusiveDevicePath from current default console
95 //
96 VarConsole = BdsLibGetVariableAndSize (
97 ConVarName,
98 &gEfiGlobalVariableGuid,
99 &DevicePathSize
100 );
101
102 //
103 // Initialize NewDevicePath
104 //
105 NewDevicePath = VarConsole;
106
107 //
108 // If ExclusiveDevicePath is even the part of the instance in VarConsole, delete it.
109 // In the end, NewDevicePath is the final device path.
110 //
111 if (ExclusiveDevicePath != NULL && VarConsole != NULL) {
112 NewDevicePath = BdsLibDelPartMatchInstance (VarConsole, ExclusiveDevicePath);
113 }
114 //
115 // Try to append customized device path to NewDevicePath.
116 //
117 if (CustomizedConDevicePath != NULL) {
118 if (!BdsLibMatchDevicePaths (NewDevicePath, CustomizedConDevicePath)) {
119 //
120 // Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.
121 //
122 NewDevicePath = BdsLibDelPartMatchInstance (NewDevicePath, CustomizedConDevicePath);
123 //
124 // In the first check, the default console variable will be _ModuleEntryPoint,
125 // just append current customized device path
126 //
127 TempNewDevicePath = NewDevicePath;
128 NewDevicePath = AppendDevicePathInstance (NewDevicePath, CustomizedConDevicePath);
129 if (TempNewDevicePath != NULL) {
130 FreePool(TempNewDevicePath);
131 }
132 }
133 }
134
135 //
136 // The attribute for ConInDev, ConOutDev and ErrOutDev does not include NV.
137 //
138 if (IsNvNeed(ConVarName)) {
139 //
140 // ConVarName has NV attribute.
141 //
142 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
143 } else {
144 //
145 // ConVarName does not have NV attribute.
146 //
147 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
148 }
149
150 //
151 // Finally, Update the variable of the default console by NewDevicePath
152 //
153 gRT->SetVariable (
154 ConVarName,
155 &gEfiGlobalVariableGuid,
156 Attributes,
157 GetDevicePathSize (NewDevicePath),
158 NewDevicePath
159 );
160
161 if (VarConsole == NewDevicePath) {
162 if (VarConsole != NULL) {
163 FreePool(VarConsole);
164 }
165 } else {
166 if (VarConsole != NULL) {
167 FreePool(VarConsole);
168 }
169 if (NewDevicePath != NULL) {
170 FreePool(NewDevicePath);
171 }
172 }
173
174 return EFI_SUCCESS;
175
176 }
177
178
179 /**
180 Connect the console device base on the variable ConVarName, if
181 device path of the ConVarName is multi-instance device path, if
182 anyone of the instances is connected success, then this function
183 will return success.
184
185 @param ConVarName Console related variable name, ConIn, ConOut,
186 ErrOut.
187
188 @retval EFI_NOT_FOUND There is not any console devices connected
189 success
190 @retval EFI_SUCCESS Success connect any one instance of the console
191 device path base on the variable ConVarName.
192
193 **/
194 EFI_STATUS
195 EFIAPI
196 BdsLibConnectConsoleVariable (
197 IN CHAR16 *ConVarName
198 )
199 {
200 EFI_STATUS Status;
201 EFI_DEVICE_PATH_PROTOCOL *StartDevicePath;
202 UINTN VariableSize;
203 EFI_DEVICE_PATH_PROTOCOL *Instance;
204 EFI_DEVICE_PATH_PROTOCOL *Next;
205 EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath;
206 UINTN Size;
207 BOOLEAN DeviceExist;
208
209 Status = EFI_SUCCESS;
210 DeviceExist = FALSE;
211
212 //
213 // Check if the console variable exist
214 //
215 StartDevicePath = BdsLibGetVariableAndSize (
216 ConVarName,
217 &gEfiGlobalVariableGuid,
218 &VariableSize
219 );
220 if (StartDevicePath == NULL) {
221 return EFI_UNSUPPORTED;
222 }
223
224 CopyOfDevicePath = StartDevicePath;
225 do {
226 //
227 // Check every instance of the console variable
228 //
229 Instance = GetNextDevicePathInstance (&CopyOfDevicePath, &Size);
230 if (Instance == NULL) {
231 FreePool (StartDevicePath);
232 return EFI_UNSUPPORTED;
233 }
234
235 Next = Instance;
236 while (!IsDevicePathEndType (Next)) {
237 Next = NextDevicePathNode (Next);
238 }
239
240 SetDevicePathEndNode (Next);
241 //
242 // Check USB1.1 console
243 //
244 if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&
245 ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP)
246 || (DevicePathSubType (Instance) == MSG_USB_WWID_DP)
247 )) {
248 //
249 // Check the Usb console in Usb2.0 bus firstly, then Usb1.1 bus
250 //
251 Status = BdsLibConnectUsbDevByShortFormDP (PCI_CLASSC_PI_EHCI, Instance);
252 if (!EFI_ERROR (Status)) {
253 DeviceExist = TRUE;
254 }
255
256 Status = BdsLibConnectUsbDevByShortFormDP (PCI_CLASSC_PI_UHCI, Instance);
257 if (!EFI_ERROR (Status)) {
258 DeviceExist = TRUE;
259 }
260 } else {
261 //
262 // Connect the instance device path
263 //
264 Status = BdsLibConnectDevicePath (Instance);
265 if (EFI_ERROR (Status)) {
266 //
267 // Delete the instance from the console varialbe
268 //
269 BdsLibUpdateConsoleVariable (ConVarName, NULL, Instance);
270 } else {
271 DeviceExist = TRUE;
272 }
273 }
274 FreePool(Instance);
275 } while (CopyOfDevicePath != NULL);
276
277 FreePool (StartDevicePath);
278
279 if (!DeviceExist) {
280 return EFI_NOT_FOUND;
281 }
282
283 return EFI_SUCCESS;
284 }
285
286
287 /**
288 This function will search every simpletext device in current system,
289 and make every simpletext device as pertantial console device.
290
291 **/
292 VOID
293 EFIAPI
294 BdsLibConnectAllConsoles (
295 VOID
296 )
297 {
298 UINTN Index;
299 EFI_DEVICE_PATH_PROTOCOL *ConDevicePath;
300 UINTN HandleCount;
301 EFI_HANDLE *HandleBuffer;
302
303 Index = 0;
304 HandleCount = 0;
305 HandleBuffer = NULL;
306 ConDevicePath = NULL;
307
308 //
309 // Update all the console variables
310 //
311 gBS->LocateHandleBuffer (
312 ByProtocol,
313 &gEfiSimpleTextInProtocolGuid,
314 NULL,
315 &HandleCount,
316 &HandleBuffer
317 );
318
319 for (Index = 0; Index < HandleCount; Index++) {
320 gBS->HandleProtocol (
321 HandleBuffer[Index],
322 &gEfiDevicePathProtocolGuid,
323 (VOID **) &ConDevicePath
324 );
325 BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL);
326 }
327
328 if (HandleBuffer != NULL) {
329 FreePool(HandleBuffer);
330 HandleBuffer = NULL;
331 }
332
333 gBS->LocateHandleBuffer (
334 ByProtocol,
335 &gEfiSimpleTextOutProtocolGuid,
336 NULL,
337 &HandleCount,
338 &HandleBuffer
339 );
340 for (Index = 0; Index < HandleCount; Index++) {
341 gBS->HandleProtocol (
342 HandleBuffer[Index],
343 &gEfiDevicePathProtocolGuid,
344 (VOID **) &ConDevicePath
345 );
346 BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL);
347 BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL);
348 }
349
350 if (HandleBuffer != NULL) {
351 FreePool(HandleBuffer);
352 }
353
354 //
355 // Connect all console variables
356 //
357 BdsLibConnectAllDefaultConsoles ();
358
359 }
360
361 /**
362 This function will connect console device base on the console
363 device variable ConIn, ConOut and ErrOut.
364
365 @retval EFI_SUCCESS At least one of the ConIn and ConOut device have
366 been connected success.
367 @retval EFI_STATUS Return the status of BdsLibConnectConsoleVariable ().
368
369 **/
370 EFI_STATUS
371 EFIAPI
372 BdsLibConnectAllDefaultConsoles (
373 VOID
374 )
375 {
376 EFI_STATUS Status;
377
378 //
379 // Connect all default console variables
380 //
381
382 //
383 // It seems impossible not to have any ConOut device on platform,
384 // so we check the status here.
385 //
386 Status = BdsLibConnectConsoleVariable (L"ConOut");
387 if (EFI_ERROR (Status)) {
388 return Status;
389 }
390
391 //
392 // Insert the performance probe for Console Out
393 //
394 PERF_START (NULL, "ConOut", "BDS", 1);
395 PERF_END (NULL, "ConOut", "BDS", 0);
396
397 //
398 // Because possibly the platform is legacy free, in such case,
399 // ConIn devices (Serial Port and PS2 Keyboard ) does not exist,
400 // so we need not check the status.
401 //
402 BdsLibConnectConsoleVariable (L"ConIn");
403
404 //
405 // The _ModuleEntryPoint err out var is legal.
406 //
407 BdsLibConnectConsoleVariable (L"ErrOut");
408
409 return EFI_SUCCESS;
410
411 }
412
413 /**
414 Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer
415 is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt
416 buffer is passed in it will be used if it is big enough.
417
418 @param BmpImage Pointer to BMP file
419 @param BmpImageSize Number of bytes in BmpImage
420 @param GopBlt Buffer containing GOP version of BmpImage.
421 @param GopBltSize Size of GopBlt in bytes.
422 @param PixelHeight Height of GopBlt/BmpImage in pixels
423 @param PixelWidth Width of GopBlt/BmpImage in pixels
424
425 @retval EFI_SUCCESS GopBlt and GopBltSize are returned.
426 @retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image
427 @retval EFI_BUFFER_TOO_SMALL The passed in GopBlt buffer is not big enough.
428 GopBltSize will contain the required size.
429 @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate.
430
431 **/
432 EFI_STATUS
433 ConvertBmpToGopBlt (
434 IN VOID *BmpImage,
435 IN UINTN BmpImageSize,
436 IN OUT VOID **GopBlt,
437 IN OUT UINTN *GopBltSize,
438 OUT UINTN *PixelHeight,
439 OUT UINTN *PixelWidth
440 )
441 {
442 UINT8 *Image;
443 UINT8 *ImageHeader;
444 BMP_IMAGE_HEADER *BmpHeader;
445 BMP_COLOR_MAP *BmpColorMap;
446 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
447 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
448 UINTN BltBufferSize;
449 UINTN Index;
450 UINTN Height;
451 UINTN Width;
452 UINTN ImageIndex;
453 BOOLEAN IsAllocated;
454
455 BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;
456
457 if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {
458 return EFI_UNSUPPORTED;
459 }
460
461 //
462 // Doesn't support compress.
463 //
464 if (BmpHeader->CompressionType != 0) {
465 return EFI_UNSUPPORTED;
466 }
467
468 //
469 // Calculate Color Map offset in the image.
470 //
471 Image = BmpImage;
472 BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));
473
474 //
475 // Calculate graphics image data address in the image
476 //
477 Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;
478 ImageHeader = Image;
479
480 //
481 // Calculate the BltBuffer needed size.
482 //
483 BltBufferSize = BmpHeader->PixelWidth * BmpHeader->PixelHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
484 IsAllocated = FALSE;
485 if (*GopBlt == NULL) {
486 //
487 // GopBlt is not allocated by caller.
488 //
489 *GopBltSize = BltBufferSize;
490 *GopBlt = AllocatePool (*GopBltSize);
491 IsAllocated = TRUE;
492 if (*GopBlt == NULL) {
493 return EFI_OUT_OF_RESOURCES;
494 }
495 } else {
496 //
497 // GopBlt has been allocated by caller.
498 //
499 if (*GopBltSize < BltBufferSize) {
500 *GopBltSize = BltBufferSize;
501 return EFI_BUFFER_TOO_SMALL;
502 }
503 }
504
505 *PixelWidth = BmpHeader->PixelWidth;
506 *PixelHeight = BmpHeader->PixelHeight;
507
508 //
509 // Convert image from BMP to Blt buffer format
510 //
511 BltBuffer = *GopBlt;
512 for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {
513 Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];
514 for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {
515 switch (BmpHeader->BitPerPixel) {
516 case 1:
517 //
518 // Convert 1-bit (2 colors) BMP to 24-bit color
519 //
520 for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {
521 Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;
522 Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;
523 Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;
524 Blt++;
525 Width++;
526 }
527
528 Blt--;
529 Width--;
530 break;
531
532 case 4:
533 //
534 // Convert 4-bit (16 colors) BMP Palette to 24-bit color
535 //
536 Index = (*Image) >> 4;
537 Blt->Red = BmpColorMap[Index].Red;
538 Blt->Green = BmpColorMap[Index].Green;
539 Blt->Blue = BmpColorMap[Index].Blue;
540 if (Width < (BmpHeader->PixelWidth - 1)) {
541 Blt++;
542 Width++;
543 Index = (*Image) & 0x0f;
544 Blt->Red = BmpColorMap[Index].Red;
545 Blt->Green = BmpColorMap[Index].Green;
546 Blt->Blue = BmpColorMap[Index].Blue;
547 }
548 break;
549
550 case 8:
551 //
552 // Convert 8-bit (256 colors) BMP Palette to 24-bit color
553 //
554 Blt->Red = BmpColorMap[*Image].Red;
555 Blt->Green = BmpColorMap[*Image].Green;
556 Blt->Blue = BmpColorMap[*Image].Blue;
557 break;
558
559 case 24:
560 //
561 // It is 24-bit BMP.
562 //
563 Blt->Blue = *Image++;
564 Blt->Green = *Image++;
565 Blt->Red = *Image;
566 break;
567
568 default:
569 //
570 // Other bit format BMP is not supported.
571 //
572 if (IsAllocated) {
573 FreePool (*GopBlt);
574 *GopBlt = NULL;
575 }
576 return EFI_UNSUPPORTED;
577 break;
578 };
579
580 }
581
582 ImageIndex = (UINTN) (Image - ImageHeader);
583 if ((ImageIndex % 4) != 0) {
584 //
585 // Bmp Image starts each row on a 32-bit boundary!
586 //
587 Image = Image + (4 - (ImageIndex % 4));
588 }
589 }
590
591 return EFI_SUCCESS;
592 }
593
594
595 /**
596 Use Console Control Protocol to lock the Console In Spliter virtual handle.
597 This is the ConInHandle and ConIn handle in the EFI system table. All key
598 presses will be ignored until the Password is typed in. The only way to
599 disable the password is to type it in to a ConIn device.
600
601 @param Password Password used to lock ConIn device.
602
603 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
604 @retval EFI_UNSUPPORTED Password not found
605
606 **/
607 EFI_STATUS
608 EFIAPI
609 LockKeyboards (
610 IN CHAR16 *Password
611 )
612 {
613 EFI_STATUS Status;
614 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;
615
616 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);
617 if (EFI_ERROR (Status)) {
618 return EFI_UNSUPPORTED;
619 }
620
621 Status = ConsoleControl->LockStdIn (ConsoleControl, Password);
622 return Status;
623 }
624
625
626 /**
627 Use Console Control to turn off UGA based Simple Text Out consoles from going
628 to the UGA device. Put up LogoFile on every UGA device that is a console
629
630 @param[in] LogoFile File name of logo to display on the center of the screen.
631
632 @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed.
633 @retval EFI_UNSUPPORTED Logo not found
634
635 **/
636 EFI_STATUS
637 EFIAPI
638 EnableQuietBoot (
639 IN EFI_GUID *LogoFile
640 )
641 {
642 EFI_STATUS Status;
643 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;
644 EFI_OEM_BADGING_PROTOCOL *Badging;
645 UINT32 SizeOfX;
646 UINT32 SizeOfY;
647 INTN DestX;
648 INTN DestY;
649 UINT8 *ImageData;
650 UINTN ImageSize;
651 UINTN BltSize;
652 UINT32 Instance;
653 EFI_BADGING_FORMAT Format;
654 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;
655 UINTN CoordinateX;
656 UINTN CoordinateY;
657 UINTN Height;
658 UINTN Width;
659 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
660 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
661 UINT32 ColorDepth;
662 UINT32 RefreshRate;
663 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
664
665 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);
666 if (EFI_ERROR (Status)) {
667 return EFI_UNSUPPORTED;
668 }
669
670 UgaDraw = NULL;
671 //
672 // Try to open GOP first
673 //
674 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);
675 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
676 GraphicsOutput = NULL;
677 //
678 // Open GOP failed, try to open UGA
679 //
680 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);
681 }
682 if (EFI_ERROR (Status)) {
683 return EFI_UNSUPPORTED;
684 }
685
686 Badging = NULL;
687 Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);
688
689 //
690 // Set console control to graphics mode.
691 //
692 Status = ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics);
693 if (EFI_ERROR (Status)) {
694 return EFI_UNSUPPORTED;
695 }
696
697 if (GraphicsOutput != NULL) {
698 SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
699 SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
700
701 } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
702 Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);
703 if (EFI_ERROR (Status)) {
704 return EFI_UNSUPPORTED;
705 }
706 } else {
707 return EFI_UNSUPPORTED;
708 }
709
710 Instance = 0;
711 while (1) {
712 ImageData = NULL;
713 ImageSize = 0;
714
715 if (Badging != NULL) {
716 //
717 // Get image from OEMBadging protocol.
718 //
719 Status = Badging->GetImage (
720 Badging,
721 &Instance,
722 &Format,
723 &ImageData,
724 &ImageSize,
725 &Attribute,
726 &CoordinateX,
727 &CoordinateY
728 );
729 if (EFI_ERROR (Status)) {
730 return Status;
731 }
732
733 //
734 // Currently only support BMP format.
735 //
736 if (Format != EfiBadgingFormatBMP) {
737 if (ImageData != NULL) {
738 FreePool (ImageData);
739 }
740 continue;
741 }
742 } else {
743 //
744 // Get the specified image from FV.
745 //
746 Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **) &ImageData, &ImageSize);
747 if (EFI_ERROR (Status)) {
748 return EFI_UNSUPPORTED;
749 }
750
751 CoordinateX = 0;
752 CoordinateY = 0;
753 Attribute = EfiBadgingDisplayAttributeCenter;
754 }
755
756 Blt = NULL;
757 Status = ConvertBmpToGopBlt (
758 ImageData,
759 ImageSize,
760 (VOID **) &Blt,
761 &BltSize,
762 &Height,
763 &Width
764 );
765 if (EFI_ERROR (Status)) {
766 FreePool (ImageData);
767
768 if (Badging == NULL) {
769 return Status;
770 } else {
771 continue;
772 }
773 }
774
775 //
776 // Calculate the display position according to Attribute.
777 //
778 switch (Attribute) {
779 case EfiBadgingDisplayAttributeLeftTop:
780 DestX = CoordinateX;
781 DestY = CoordinateY;
782 break;
783
784 case EfiBadgingDisplayAttributeCenterTop:
785 DestX = (SizeOfX - Width) / 2;
786 DestY = CoordinateY;
787 break;
788
789 case EfiBadgingDisplayAttributeRightTop:
790 DestX = (SizeOfX - Width - CoordinateX);
791 DestY = CoordinateY;;
792 break;
793
794 case EfiBadgingDisplayAttributeCenterRight:
795 DestX = (SizeOfX - Width - CoordinateX);
796 DestY = (SizeOfY - Height) / 2;
797 break;
798
799 case EfiBadgingDisplayAttributeRightBottom:
800 DestX = (SizeOfX - Width - CoordinateX);
801 DestY = (SizeOfY - Height - CoordinateY);
802 break;
803
804 case EfiBadgingDisplayAttributeCenterBottom:
805 DestX = (SizeOfX - Width) / 2;
806 DestY = (SizeOfY - Height - CoordinateY);
807 break;
808
809 case EfiBadgingDisplayAttributeLeftBottom:
810 DestX = CoordinateX;
811 DestY = (SizeOfY - Height - CoordinateY);
812 break;
813
814 case EfiBadgingDisplayAttributeCenterLeft:
815 DestX = CoordinateX;
816 DestY = (SizeOfY - Height) / 2;
817 break;
818
819 case EfiBadgingDisplayAttributeCenter:
820 DestX = (SizeOfX - Width) / 2;
821 DestY = (SizeOfY - Height) / 2;
822 break;
823
824 default:
825 DestX = CoordinateX;
826 DestY = CoordinateY;
827 break;
828 }
829
830 if ((DestX >= 0) && (DestY >= 0)) {
831 if (GraphicsOutput != NULL) {
832 Status = GraphicsOutput->Blt (
833 GraphicsOutput,
834 Blt,
835 EfiBltBufferToVideo,
836 0,
837 0,
838 (UINTN) DestX,
839 (UINTN) DestY,
840 Width,
841 Height,
842 Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
843 );
844 } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
845 Status = UgaDraw->Blt (
846 UgaDraw,
847 (EFI_UGA_PIXEL *) Blt,
848 EfiUgaBltBufferToVideo,
849 0,
850 0,
851 (UINTN) DestX,
852 (UINTN) DestY,
853 Width,
854 Height,
855 Width * sizeof (EFI_UGA_PIXEL)
856 );
857 } else {
858 Status = EFI_UNSUPPORTED;
859 }
860 }
861
862 FreePool (ImageData);
863
864 if (Blt != NULL) {
865 FreePool (Blt);
866 }
867
868 if (Badging == NULL) {
869 break;
870 }
871 }
872
873 return Status;
874 }
875
876 /**
877 Use Console Control to turn on UGA based Simple Text Out consoles. The UGA
878 Simple Text Out screens will now be synced up with all non UGA output devices
879
880 @retval EFI_SUCCESS UGA devices are back in text mode and synced up.
881
882 **/
883 EFI_STATUS
884 EFIAPI
885 DisableQuietBoot (
886 VOID
887 )
888 {
889 EFI_STATUS Status;
890 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;
891
892 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);
893 if (EFI_ERROR (Status)) {
894 return EFI_UNSUPPORTED;
895 }
896
897 //
898 // Set console control to text mode.
899 //
900 return ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);
901 }
902