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