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