]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/GenericBdsLib/BdsConsole.c
999de49ba3507bb5758df5eb93f7b71114945611
[mirror_edk2.git] / MdeModulePkg / 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 variabel as NV type.
24 @retval FALSE EFI variabel 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 /**
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 Add or remove the same device path.
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) {
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 Next = Instance;
231 while (!IsDevicePathEndType (Next)) {
232 Next = NextDevicePathNode (Next);
233 }
234
235 SetDevicePathEndNode (Next);
236 //
237 // Check USB1.1 console
238 //
239 if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&
240 ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP)
241 || (DevicePathSubType (Instance) == MSG_USB_WWID_DP)
242 )) {
243 //
244 // Check the Usb console in Usb2.0 bus firstly, then Usb1.1 bus
245 //
246 Status = BdsLibConnectUsbDevByShortFormDP (PCI_CLASSC_PI_EHCI, Instance);
247 if (!EFI_ERROR (Status)) {
248 DeviceExist = TRUE;
249 }
250
251 Status = BdsLibConnectUsbDevByShortFormDP (PCI_CLASSC_PI_UHCI, Instance);
252 if (!EFI_ERROR (Status)) {
253 DeviceExist = TRUE;
254 }
255 } else {
256 //
257 // Connect the instance device path
258 //
259 Status = BdsLibConnectDevicePath (Instance);
260 if (EFI_ERROR (Status)) {
261 //
262 // Delete the instance from the console varialbe
263 //
264 BdsLibUpdateConsoleVariable (ConVarName, NULL, Instance);
265 } else {
266 DeviceExist = TRUE;
267 }
268 }
269 FreePool(Instance);
270 } while (CopyOfDevicePath != NULL);
271
272 FreePool (StartDevicePath);
273
274 if (!DeviceExist) {
275 return EFI_NOT_FOUND;
276 }
277
278 return EFI_SUCCESS;
279 }
280
281
282 /**
283 This function will search every simpletxt devive in current system,
284 and make every simpletxt device as pertantial console device.
285
286 **/
287 VOID
288 EFIAPI
289 BdsLibConnectAllConsoles (
290 VOID
291 )
292 {
293 UINTN Index;
294 EFI_DEVICE_PATH_PROTOCOL *ConDevicePath;
295 UINTN HandleCount;
296 EFI_HANDLE *HandleBuffer;
297
298 Index = 0;
299 HandleCount = 0;
300 HandleBuffer = NULL;
301 ConDevicePath = NULL;
302
303 //
304 // Update all the console varables
305 //
306 gBS->LocateHandleBuffer (
307 ByProtocol,
308 &gEfiSimpleTextInProtocolGuid,
309 NULL,
310 &HandleCount,
311 &HandleBuffer
312 );
313
314 for (Index = 0; Index < HandleCount; Index++) {
315 gBS->HandleProtocol (
316 HandleBuffer[Index],
317 &gEfiDevicePathProtocolGuid,
318 (VOID **) &ConDevicePath
319 );
320 BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL);
321 }
322
323 if (HandleBuffer != NULL) {
324 FreePool(HandleBuffer);
325 HandleBuffer = NULL;
326 }
327
328 gBS->LocateHandleBuffer (
329 ByProtocol,
330 &gEfiSimpleTextOutProtocolGuid,
331 NULL,
332 &HandleCount,
333 &HandleBuffer
334 );
335 for (Index = 0; Index < HandleCount; Index++) {
336 gBS->HandleProtocol (
337 HandleBuffer[Index],
338 &gEfiDevicePathProtocolGuid,
339 (VOID **) &ConDevicePath
340 );
341 BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL);
342 BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL);
343 }
344
345 if (HandleBuffer != NULL) {
346 FreePool(HandleBuffer);
347 }
348
349 //
350 // Connect all console variables
351 //
352 BdsLibConnectAllDefaultConsoles ();
353
354 }
355
356 /**
357 This function will connect console device base on the console
358 device variable ConIn, ConOut and ErrOut.
359
360 @retval EFI_SUCCESS At least one of the ConIn and ConOut device have
361 been connected success.
362 @retval EFI_STATUS Return the status of
363 BdsLibConnectConsoleVariable ().
364
365 **/
366 EFI_STATUS
367 EFIAPI
368 BdsLibConnectAllDefaultConsoles (
369 VOID
370 )
371 {
372 EFI_STATUS Status;
373
374 //
375 // Connect all default console variables
376 //
377
378 //
379 // It seems impossible not to have any ConOut device on platform,
380 // so we check the status here.
381 //
382 Status = BdsLibConnectConsoleVariable (L"ConOut");
383 if (EFI_ERROR (Status)) {
384 return Status;
385 }
386
387 //
388 // Insert the performance probe for Console Out
389 //
390 PERF_START (NULL, "ConOut", "BDS", 1);
391 PERF_END (NULL, "ConOut", "BDS", 0);
392
393 //
394 // Because possibly the platform is legacy free, in such case,
395 // ConIn devices (Serial Port and PS2 Keyboard ) does not exist,
396 // so we need not check the status.
397 //
398 BdsLibConnectConsoleVariable (L"ConIn");
399
400 //
401 // The _ModuleEntryPoint err out var is legal.
402 //
403 BdsLibConnectConsoleVariable (L"ErrOut");
404
405 return EFI_SUCCESS;
406
407 }
408
409 /**
410 Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer
411 is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt
412 buffer is passed in it will be used if it is big enough.
413
414 @param BmpImage Pointer to BMP file
415 @param BmpImageSize Number of bytes in BmpImage
416 @param GopBlt Buffer containing GOP version of BmpImage.
417 @param GopBltSize Size of GopBlt in bytes.
418 @param PixelHeight Height of GopBlt/BmpImage in pixels
419 @param PixelWidth Width of GopBlt/BmpImage in pixels
420
421 @retval EFI_SUCCESS GopBlt and GopBltSize are returned.
422 @retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image
423 @retval EFI_BUFFER_TOO_SMALL The passed in GopBlt buffer is not big enough.
424 GopBltSize will contain the required size.
425 @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate.
426
427 **/
428 EFI_STATUS
429 ConvertBmpToGopBlt (
430 IN VOID *BmpImage,
431 IN UINTN BmpImageSize,
432 IN OUT VOID **GopBlt,
433 IN OUT UINTN *GopBltSize,
434 OUT UINTN *PixelHeight,
435 OUT UINTN *PixelWidth
436 )
437 {
438 UINT8 *Image;
439 UINT8 *ImageHeader;
440 BMP_IMAGE_HEADER *BmpHeader;
441 BMP_COLOR_MAP *BmpColorMap;
442 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
443 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
444 UINTN BltBufferSize;
445 UINTN Index;
446 UINTN Height;
447 UINTN Width;
448 UINTN ImageIndex;
449 BOOLEAN IsAllocated;
450
451 BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;
452
453 if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {
454 return EFI_UNSUPPORTED;
455 }
456
457 //
458 // Doesn't support compress.
459 //
460 if (BmpHeader->CompressionType != 0) {
461 return EFI_UNSUPPORTED;
462 }
463
464 //
465 // Calculate Color Map offset in the image.
466 //
467 Image = BmpImage;
468 BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));
469
470 //
471 // Calculate graphics image data address in the image
472 //
473 Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;
474 ImageHeader = Image;
475
476 //
477 // Calculate the BltBuffer needed size.
478 //
479 BltBufferSize = BmpHeader->PixelWidth * BmpHeader->PixelHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
480 IsAllocated = FALSE;
481 if (*GopBlt == NULL) {
482 //
483 // GopBlt is not allocated by caller.
484 //
485 *GopBltSize = BltBufferSize;
486 *GopBlt = AllocatePool (*GopBltSize);
487 IsAllocated = TRUE;
488 if (*GopBlt == NULL) {
489 return EFI_OUT_OF_RESOURCES;
490 }
491 } else {
492 //
493 // GopBlt has been allocated by caller.
494 //
495 if (*GopBltSize < BltBufferSize) {
496 *GopBltSize = BltBufferSize;
497 return EFI_BUFFER_TOO_SMALL;
498 }
499 }
500
501 *PixelWidth = BmpHeader->PixelWidth;
502 *PixelHeight = BmpHeader->PixelHeight;
503
504 //
505 // Convert image from BMP to Blt buffer format
506 //
507 BltBuffer = *GopBlt;
508 for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {
509 Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];
510 for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {
511 switch (BmpHeader->BitPerPixel) {
512 case 1:
513 //
514 // Convert 1-bit (2 colors) BMP to 24-bit color
515 //
516 for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {
517 Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;
518 Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;
519 Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;
520 Blt++;
521 Width++;
522 }
523
524 Blt --;
525 Width --;
526 break;
527
528 case 4:
529 //
530 // Convert 4-bit (16 colors) BMP Palette to 24-bit color
531 //
532 Index = (*Image) >> 4;
533 Blt->Red = BmpColorMap[Index].Red;
534 Blt->Green = BmpColorMap[Index].Green;
535 Blt->Blue = BmpColorMap[Index].Blue;
536 if (Width < (BmpHeader->PixelWidth - 1)) {
537 Blt++;
538 Width++;
539 Index = (*Image) & 0x0f;
540 Blt->Red = BmpColorMap[Index].Red;
541 Blt->Green = BmpColorMap[Index].Green;
542 Blt->Blue = BmpColorMap[Index].Blue;
543 }
544 break;
545
546 case 8:
547 //
548 // Convert 8-bit (256 colors) BMP Palette to 24-bit color
549 //
550 Blt->Red = BmpColorMap[*Image].Red;
551 Blt->Green = BmpColorMap[*Image].Green;
552 Blt->Blue = BmpColorMap[*Image].Blue;
553 break;
554
555 case 24:
556 //
557 // It is 24-bit BMP.
558 //
559 Blt->Blue = *Image++;
560 Blt->Green = *Image++;
561 Blt->Red = *Image;
562 break;
563
564 default:
565 //
566 // Other bit format BMP is not supported.
567 //
568 if (IsAllocated) {
569 FreePool (*GopBlt);
570 *GopBlt = NULL;
571 }
572 return EFI_UNSUPPORTED;
573 break;
574 };
575
576 }
577
578 ImageIndex = (UINTN) (Image - ImageHeader);
579 if ((ImageIndex % 4) != 0) {
580 //
581 // Bmp Image starts each row on a 32-bit boundary!
582 //
583 Image = Image + (4 - (ImageIndex % 4));
584 }
585 }
586
587 return EFI_SUCCESS;
588 }
589
590
591 /**
592 Use Console Control Protocol to lock the Console In Spliter virtual handle.
593 This is the ConInHandle and ConIn handle in the EFI system table. All key
594 presses will be ignored until the Password is typed in. The only way to
595 disable the password is to type it in to a ConIn device.
596
597 @param Password Password used to lock ConIn device.
598
599 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
600 @retval EFI_UNSUPPORTED Password not found.
601
602 **/
603 EFI_STATUS
604 EFIAPI
605 LockKeyboards (
606 IN CHAR16 *Password
607 )
608 {
609 EFI_STATUS Status;
610 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;
611
612 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);
613 if (EFI_ERROR (Status)) {
614 return EFI_UNSUPPORTED;
615 }
616
617 Status = ConsoleControl->LockStdIn (ConsoleControl, Password);
618 return Status;
619 }
620
621
622 /**
623 Use Console Control to turn off UGA based Simple Text Out consoles from going
624 to the UGA device. Put up LogoFile on every UGA device that is a console.
625
626 @param LogoFile File name of logo to display on the center of the screen.
627
628 @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed.
629 @retval EFI_UNSUPPORTED Logo not found.
630
631 **/
632 EFI_STATUS
633 EFIAPI
634 EnableQuietBoot (
635 IN EFI_GUID *LogoFile OPTIONAL
636 )
637 {
638 EFI_STATUS Status;
639 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;
640 EFI_OEM_BADGING_PROTOCOL *Badging;
641 UINT32 SizeOfX;
642 UINT32 SizeOfY;
643 INTN DestX;
644 INTN DestY;
645 UINT8 *ImageData;
646 UINTN ImageSize;
647 UINTN BltSize;
648 UINT32 Instance;
649 EFI_BADGING_FORMAT Format;
650 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;
651 UINTN CoordinateX;
652 UINTN CoordinateY;
653 UINTN Height;
654 UINTN Width;
655 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
656 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
657 UINT32 ColorDepth;
658 UINT32 RefreshRate;
659 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
660
661 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);
662 if (EFI_ERROR (Status)) {
663 return EFI_UNSUPPORTED;
664 }
665
666 UgaDraw = NULL;
667 //
668 // Try to open GOP first
669 //
670 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);
671 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
672 GraphicsOutput = NULL;
673 //
674 // Open GOP failed, try to open UGA
675 //
676 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);
677 }
678 if (EFI_ERROR (Status)) {
679 return EFI_UNSUPPORTED;
680 }
681
682 Badging = NULL;
683 Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);
684
685 //
686 // Set console control to graphics mode.
687 //
688 Status = ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics);
689 if (EFI_ERROR (Status)) {
690 return EFI_UNSUPPORTED;
691 }
692
693 if (GraphicsOutput != NULL) {
694 SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
695 SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
696 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
697 Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);
698 if (EFI_ERROR (Status)) {
699 return EFI_UNSUPPORTED;
700 }
701 } else {
702 return EFI_UNSUPPORTED;
703 }
704
705 Instance = 0;
706 while (1) {
707 ImageData = NULL;
708 ImageSize = 0;
709
710 if (Badging != NULL) {
711 //
712 // Get image from OEMBadging protocol.
713 //
714 Status = Badging->GetImage (
715 Badging,
716 &Instance,
717 &Format,
718 &ImageData,
719 &ImageSize,
720 &Attribute,
721 &CoordinateX,
722 &CoordinateY
723 );
724 if (EFI_ERROR (Status)) {
725 return Status;
726 }
727
728 //
729 // Currently only support BMP format.
730 //
731 if (Format != EfiBadgingFormatBMP) {
732 if (ImageData != NULL) {
733 FreePool (ImageData);
734 }
735 continue;
736 }
737 } else {
738 //
739 // Get the specified image from FV.
740 //
741 Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **) &ImageData, &ImageSize);
742 if (EFI_ERROR (Status)) {
743 return EFI_UNSUPPORTED;
744 }
745
746 CoordinateX = 0;
747 CoordinateY = 0;
748 Attribute = EfiBadgingDisplayAttributeCenter;
749 }
750
751 Blt = NULL;
752 Status = ConvertBmpToGopBlt (
753 ImageData,
754 ImageSize,
755 (VOID **) &Blt,
756 &BltSize,
757 &Height,
758 &Width
759 );
760 if (EFI_ERROR (Status)) {
761 if (ImageData != NULL) {
762 FreePool (ImageData);
763 }
764 if (Badging == NULL) {
765 return Status;
766 } else {
767 continue;
768 }
769 }
770
771 //
772 // Caculate the display position according to Attribute.
773 //
774 switch (Attribute) {
775 case EfiBadgingDisplayAttributeLeftTop:
776 DestX = CoordinateX;
777 DestY = CoordinateY;
778 break;
779
780 case EfiBadgingDisplayAttributeCenterTop:
781 DestX = (SizeOfX - Width) / 2;
782 DestY = CoordinateY;
783 break;
784
785 case EfiBadgingDisplayAttributeRightTop:
786 DestX = (SizeOfX - Width - CoordinateX);
787 DestY = CoordinateY;;
788 break;
789
790 case EfiBadgingDisplayAttributeCenterRight:
791 DestX = (SizeOfX - Width - CoordinateX);
792 DestY = (SizeOfY - Height) / 2;
793 break;
794
795 case EfiBadgingDisplayAttributeRightBottom:
796 DestX = (SizeOfX - Width - CoordinateX);
797 DestY = (SizeOfY - Height - CoordinateY);
798 break;
799
800 case EfiBadgingDisplayAttributeCenterBottom:
801 DestX = (SizeOfX - Width) / 2;
802 DestY = (SizeOfY - Height - CoordinateY);
803 break;
804
805 case EfiBadgingDisplayAttributeLeftBottom:
806 DestX = CoordinateX;
807 DestY = (SizeOfY - Height - CoordinateY);
808 break;
809
810 case EfiBadgingDisplayAttributeCenterLeft:
811 DestX = CoordinateX;
812 DestY = (SizeOfY - Height) / 2;
813 break;
814
815 case EfiBadgingDisplayAttributeCenter:
816 DestX = (SizeOfX - Width) / 2;
817 DestY = (SizeOfY - Height) / 2;
818 break;
819
820 default:
821 DestX = CoordinateX;
822 DestY = CoordinateY;
823 break;
824 }
825
826 if ((DestX >= 0) && (DestY >= 0)) {
827 if (GraphicsOutput != NULL) {
828 Status = GraphicsOutput->Blt (
829 GraphicsOutput,
830 Blt,
831 EfiBltBufferToVideo,
832 0,
833 0,
834 (UINTN) DestX,
835 (UINTN) DestY,
836 Width,
837 Height,
838 Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
839 );
840 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
841 Status = UgaDraw->Blt (
842 UgaDraw,
843 (EFI_UGA_PIXEL *) Blt,
844 EfiUgaBltBufferToVideo,
845 0,
846 0,
847 (UINTN) DestX,
848 (UINTN) DestY,
849 Width,
850 Height,
851 Width * sizeof (EFI_UGA_PIXEL)
852 );
853 } else {
854 Status = EFI_UNSUPPORTED;
855 }
856 }
857
858 if (ImageData != NULL) {
859 FreePool (ImageData);
860 }
861 if (Blt != NULL) {
862 FreePool (Blt);
863 }
864
865 if (Badging == NULL) {
866 break;
867 }
868 }
869
870 return Status;
871 }
872
873 /**
874 Use Console Control to turn on UGA based Simple Text Out consoles. The UGA
875 Simple Text Out screens will now be synced up with all non UGA output devices
876
877 @retval EFI_SUCCESS UGA devices are back in text mode and synced up.
878 @retval EFI_UNSUPPORTED Logo not found
879
880 **/
881 EFI_STATUS
882 EFIAPI
883 DisableQuietBoot (
884 VOID
885 )
886 {
887 EFI_STATUS Status;
888 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;
889
890 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);
891 if (EFI_ERROR (Status)) {
892 return EFI_UNSUPPORTED;
893 }
894
895 //
896 // Set console control to text mode.
897 //
898 return ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);
899 }
900