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