]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/GenericBdsLib/BdsConsole.c
Parameter checking in BdsLibMatchDevicePaths() is wrong. This bug was found because...
[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 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 Add or remove the same device path.
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_UNSUPPORTED Request console variable does not exist.
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 Fail to locate ConsoleControl protocol.
631 Fail to get UgaDraw or Gop handle.
632 Fail to switch grahic mode.
633
634 **/
635 EFI_STATUS
636 EFIAPI
637 EnableQuietBoot (
638 IN EFI_GUID *LogoFile OPTIONAL
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 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
700 Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);
701 if (EFI_ERROR (Status)) {
702 return EFI_UNSUPPORTED;
703 }
704 } else {
705 return EFI_UNSUPPORTED;
706 }
707
708 Instance = 0;
709 while (1) {
710 ImageData = NULL;
711 ImageSize = 0;
712
713 if (Badging != NULL) {
714 //
715 // Get image from OEMBadging protocol.
716 //
717 Status = Badging->GetImage (
718 Badging,
719 &Instance,
720 &Format,
721 &ImageData,
722 &ImageSize,
723 &Attribute,
724 &CoordinateX,
725 &CoordinateY
726 );
727 if (EFI_ERROR (Status)) {
728 return Status;
729 }
730
731 //
732 // Currently only support BMP format.
733 //
734 if (Format != EfiBadgingFormatBMP) {
735 if (ImageData != NULL) {
736 FreePool (ImageData);
737 }
738 continue;
739 }
740 } else {
741 //
742 // Get the specified image from FV.
743 //
744 Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **) &ImageData, &ImageSize);
745 if (EFI_ERROR (Status)) {
746 return EFI_UNSUPPORTED;
747 }
748
749 CoordinateX = 0;
750 CoordinateY = 0;
751 Attribute = EfiBadgingDisplayAttributeCenter;
752 }
753
754 Blt = NULL;
755 Status = ConvertBmpToGopBlt (
756 ImageData,
757 ImageSize,
758 (VOID **) &Blt,
759 &BltSize,
760 &Height,
761 &Width
762 );
763 if (EFI_ERROR (Status)) {
764 if (ImageData != NULL) {
765 FreePool (ImageData);
766 }
767 if (Badging == NULL) {
768 return Status;
769 } else {
770 continue;
771 }
772 }
773
774 //
775 // Caculate 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 (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 if (ImageData != NULL) {
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 @retval EFI_UNSUPPORTED Fail to locate ConsoleControl Protocol.
882
883 **/
884 EFI_STATUS
885 EFIAPI
886 DisableQuietBoot (
887 VOID
888 )
889 {
890 EFI_STATUS Status;
891 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;
892
893 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);
894 if (EFI_ERROR (Status)) {
895 return EFI_UNSUPPORTED;
896 }
897
898 //
899 // Set console control to text mode.
900 //
901 return ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);
902 }
903