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