]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c
Fix build fail.
[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
2df686c6 4Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
180a5a35 5This program and the accompanying materials\r
5c08e117 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
a637802c 16#include <IndustryStandard/Bmp.h>\r
17\r
5c08e117 18\r
19/**\r
20 Check if we need to save the EFI variable with "ConVarName" as name\r
21 as NV type\r
775a9b19 22 If ConVarName is NULL, then ASSERT().\r
23 \r
5c08e117 24 @param ConVarName The name of the EFI variable.\r
25\r
26 @retval TRUE Set the EFI variable as NV type.\r
27 @retval FALSE EFI variable as NV type can be set NonNV.\r
28**/\r
29BOOLEAN\r
30IsNvNeed (\r
31 IN CHAR16 *ConVarName\r
32 )\r
33{\r
34 CHAR16 *Ptr;\r
35\r
775a9b19 36 ASSERT (ConVarName != NULL);\r
37 \r
5c08e117 38 Ptr = ConVarName;\r
39\r
40 //\r
41 // If the variable includes "Dev" at last, we consider\r
42 // it does not support NV attribute.\r
43 //\r
44 while (*Ptr != L'\0') {\r
45 Ptr++;\r
46 }\r
47\r
9260b915 48 if (((INTN)((UINTN)Ptr - (UINTN)ConVarName) / sizeof (CHAR16)) <= 3) {\r
f0a3b1a2 49 return TRUE;\r
50 }\r
51 \r
5c08e117 52 if ((*(Ptr - 3) == 'D') && (*(Ptr - 2) == 'e') && (*(Ptr - 1) == 'v')) {\r
53 return FALSE;\r
54 } else {\r
55 return TRUE;\r
56 }\r
57}\r
58\r
dad60833 59/**\r
60 Fill console handle in System Table if there are no valid console handle in.\r
61\r
62 Firstly, check the validation of console handle in System Table. If it is invalid,\r
63 update it by the first console device handle from EFI console variable. \r
64\r
65 @param VarName The name of the EFI console variable.\r
66 @param ConsoleGuid Specified Console protocol GUID.\r
67 @param ConsoleHandle On IN, console handle in System Table to be checked. \r
68 On OUT, new console hanlde in system table.\r
69 @param ProtocolInterface On IN, console protocol on console handle in System Table to be checked. \r
70 On OUT, new console protocol on new console hanlde in system table.\r
406ddad3 71\r
72 @retval TRUE System Table has been updated.\r
73 @retval FALSE System Table hasn't been updated.\r
74\r
dad60833 75**/\r
406ddad3 76BOOLEAN \r
dad60833 77UpdateSystemTableConsole (\r
78 IN CHAR16 *VarName,\r
79 IN EFI_GUID *ConsoleGuid,\r
80 IN OUT EFI_HANDLE *ConsoleHandle,\r
81 IN OUT VOID **ProtocolInterface\r
82 )\r
83{\r
84 EFI_STATUS Status;\r
85 UINTN DevicePathSize;\r
86 EFI_DEVICE_PATH_PROTOCOL *FullDevicePath;\r
87 EFI_DEVICE_PATH_PROTOCOL *VarConsole;\r
88 EFI_DEVICE_PATH_PROTOCOL *Instance;\r
89 VOID *Interface;\r
90 EFI_HANDLE NewHandle;\r
91\r
92 ASSERT (VarName != NULL);\r
93 ASSERT (ConsoleHandle != NULL);\r
94 ASSERT (ConsoleGuid != NULL);\r
95 ASSERT (ProtocolInterface != NULL);\r
96\r
97 if (*ConsoleHandle != NULL) {\r
98 Status = gBS->HandleProtocol (\r
99 *ConsoleHandle,\r
100 ConsoleGuid,\r
101 &Interface\r
102 );\r
103 if (Status == EFI_SUCCESS && Interface == *ProtocolInterface) {\r
104 //\r
105 // If ConsoleHandle is valid and console protocol on this handle also\r
106 // also matched, just return.\r
107 //\r
406ddad3 108 return FALSE;\r
dad60833 109 }\r
110 }\r
111 \r
112 //\r
113 // Get all possible consoles device path from EFI variable\r
114 //\r
115 VarConsole = BdsLibGetVariableAndSize (\r
116 VarName,\r
117 &gEfiGlobalVariableGuid,\r
118 &DevicePathSize\r
119 );\r
120 if (VarConsole == NULL) {\r
121 //\r
122 // If there is no any console device, just return.\r
123 //\r
406ddad3 124 return FALSE;\r
dad60833 125 }\r
126\r
127 FullDevicePath = VarConsole;\r
128\r
129 do {\r
130 //\r
131 // Check every instance of the console variable\r
132 //\r
133 Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);\r
134 if (Instance == NULL) {\r
135 FreePool (FullDevicePath);\r
136 ASSERT (FALSE);\r
137 }\r
138 \r
139 //\r
140 // Find console device handle by device path instance\r
141 //\r
142 Status = gBS->LocateDevicePath (\r
143 ConsoleGuid,\r
144 &Instance,\r
145 &NewHandle\r
146 );\r
147 if (!EFI_ERROR (Status)) {\r
148 //\r
149 // Get the console protocol on this console device handle\r
150 //\r
151 Status = gBS->HandleProtocol (\r
152 NewHandle,\r
153 ConsoleGuid,\r
154 &Interface\r
155 );\r
156 if (!EFI_ERROR (Status)) {\r
157 //\r
158 // Update new console handle in System Table.\r
159 //\r
160 *ConsoleHandle = NewHandle;\r
161 *ProtocolInterface = Interface;\r
406ddad3 162 return TRUE;\r
dad60833 163 }\r
164 }\r
165\r
166 } while (Instance != NULL);\r
167\r
168 //\r
169 // No any available console devcie found.\r
170 //\r
406ddad3 171 return FALSE;\r
dad60833 172}\r
173\r
bc79c731 174/**\r
175 Connect the console device base on the variable ConVarName, if\r
176 device path of the ConVarName is multi-instance device path and\r
177 anyone of the instances is connected success, this function will\r
178 return success. \r
179 Dispatch service is called basing on input when the handle associate\r
180 with one device path node can not be created successfully. Since in\r
181 some cases we assume driver dependency does not exist and do not \r
182 need to call this service.\r
183\r
184 @param ConVarName Console related variable name, ConIn, ConOut,\r
185 ErrOut.\r
186 @param NeedDispatch Whether requires dispatch service during connection \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
195ConnectConsoleVariableInternal (\r
196 IN CHAR16 *ConVarName,\r
197 IN BOOLEAN NeedDispatch\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 // Connect the USB console\r
243 // USB console device path is a short-form device path that \r
244 // starts with the first element being a USB WWID\r
245 // or a USB Class device path\r
246 //\r
247 if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&\r
248 ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP)\r
249 || (DevicePathSubType (Instance) == MSG_USB_WWID_DP)\r
250 )) {\r
251 Status = BdsLibConnectUsbDevByShortFormDP (0xFF, 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 = ConnectDevicePathInternal (Instance, NeedDispatch);\r
260\r
261 if (EFI_ERROR (Status)) {\r
262 //\r
263 // Delete the instance from the console varialbe\r
264 //\r
265 BdsLibUpdateConsoleVariable (ConVarName, NULL, Instance);\r
266 } else {\r
267 DeviceExist = TRUE;\r
268 }\r
269 }\r
270 FreePool(Instance);\r
271 } while (CopyOfDevicePath != NULL);\r
272\r
273 FreePool (StartDevicePath);\r
274\r
275 if (!DeviceExist) {\r
276 return EFI_NOT_FOUND;\r
277 }\r
278\r
279 return EFI_SUCCESS;\r
280}\r
281\r
5c08e117 282/**\r
283 This function update console variable based on ConVarName, it can\r
284 add or remove one specific console device path from the variable\r
285\r
286 @param ConVarName Console related variable name, ConIn, ConOut,\r
287 ErrOut.\r
288 @param CustomizedConDevicePath The console device path which will be added to\r
289 the console variable ConVarName, this parameter\r
290 can not be multi-instance.\r
291 @param ExclusiveDevicePath The console device path which will be removed\r
292 from the console variable ConVarName, this\r
293 parameter can not be multi-instance.\r
294\r
295 @retval EFI_UNSUPPORTED The added device path is same to the removed one.\r
296 @retval EFI_SUCCESS Success add or remove the device path from the\r
297 console variable.\r
298\r
299**/\r
300EFI_STATUS\r
301EFIAPI\r
302BdsLibUpdateConsoleVariable (\r
303 IN CHAR16 *ConVarName,\r
304 IN EFI_DEVICE_PATH_PROTOCOL *CustomizedConDevicePath,\r
305 IN EFI_DEVICE_PATH_PROTOCOL *ExclusiveDevicePath\r
306 )\r
307{\r
63b30616 308 EFI_STATUS Status;\r
5c08e117 309 EFI_DEVICE_PATH_PROTOCOL *VarConsole;\r
310 UINTN DevicePathSize;\r
311 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
312 EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;\r
313 UINT32 Attributes;\r
314\r
315 VarConsole = NULL;\r
316 DevicePathSize = 0;\r
317\r
318 //\r
319 // Notes: check the device path point, here should check\r
320 // with compare memory\r
321 //\r
322 if (CustomizedConDevicePath == ExclusiveDevicePath) {\r
323 return EFI_UNSUPPORTED;\r
324 }\r
325 //\r
326 // Delete the ExclusiveDevicePath from current default console\r
327 //\r
328 VarConsole = BdsLibGetVariableAndSize (\r
329 ConVarName,\r
330 &gEfiGlobalVariableGuid,\r
331 &DevicePathSize\r
332 );\r
333\r
334 //\r
335 // Initialize NewDevicePath\r
336 //\r
337 NewDevicePath = VarConsole;\r
338\r
339 //\r
340 // If ExclusiveDevicePath is even the part of the instance in VarConsole, delete it.\r
341 // In the end, NewDevicePath is the final device path.\r
342 //\r
343 if (ExclusiveDevicePath != NULL && VarConsole != NULL) {\r
344 NewDevicePath = BdsLibDelPartMatchInstance (VarConsole, ExclusiveDevicePath);\r
345 }\r
346 //\r
347 // Try to append customized device path to NewDevicePath.\r
348 //\r
349 if (CustomizedConDevicePath != NULL) {\r
350 if (!BdsLibMatchDevicePaths (NewDevicePath, CustomizedConDevicePath)) {\r
351 //\r
352 // Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.\r
353 //\r
354 NewDevicePath = BdsLibDelPartMatchInstance (NewDevicePath, CustomizedConDevicePath);\r
355 //\r
356 // In the first check, the default console variable will be _ModuleEntryPoint,\r
357 // just append current customized device path\r
358 //\r
359 TempNewDevicePath = NewDevicePath;\r
360 NewDevicePath = AppendDevicePathInstance (NewDevicePath, CustomizedConDevicePath);\r
361 if (TempNewDevicePath != NULL) {\r
362 FreePool(TempNewDevicePath);\r
363 }\r
364 }\r
365 }\r
366\r
367 //\r
368 // The attribute for ConInDev, ConOutDev and ErrOutDev does not include NV.\r
369 //\r
370 if (IsNvNeed(ConVarName)) {\r
371 //\r
372 // ConVarName has NV attribute.\r
373 //\r
374 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;\r
375 } else {\r
376 //\r
377 // ConVarName does not have NV attribute.\r
378 //\r
379 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;\r
380 }\r
381\r
382 //\r
383 // Finally, Update the variable of the default console by NewDevicePath\r
384 //\r
f6079c70 385 DevicePathSize = GetDevicePathSize (NewDevicePath);\r
63b30616
RN
386 Status = gRT->SetVariable (\r
387 ConVarName,\r
388 &gEfiGlobalVariableGuid,\r
389 Attributes,\r
f6079c70 390 DevicePathSize,\r
63b30616
RN
391 NewDevicePath\r
392 );\r
f6079c70 393 if ((DevicePathSize == 0) && (Status == EFI_NOT_FOUND)) {\r
394 Status = EFI_SUCCESS;\r
395 }\r
63b30616 396 ASSERT_EFI_ERROR (Status);\r
5c08e117 397\r
398 if (VarConsole == NewDevicePath) {\r
399 if (VarConsole != NULL) {\r
400 FreePool(VarConsole);\r
401 }\r
402 } else {\r
403 if (VarConsole != NULL) {\r
404 FreePool(VarConsole);\r
405 }\r
406 if (NewDevicePath != NULL) {\r
407 FreePool(NewDevicePath);\r
408 }\r
409 }\r
410\r
f6079c70 411 return Status;\r
5c08e117 412\r
413}\r
414\r
415\r
416/**\r
417 Connect the console device base on the variable ConVarName, if\r
bc79c731 418 device path of the ConVarName is multi-instance device path and\r
5c08e117 419 anyone of the instances is connected success, then this function\r
420 will return success.\r
bc79c731 421 If the handle associate with one device path node can not\r
422 be created successfully, then still give chance to do the dispatch,\r
423 which load the missing drivers if possible..\r
5c08e117 424\r
425 @param ConVarName Console related variable name, ConIn, ConOut,\r
426 ErrOut.\r
427\r
428 @retval EFI_NOT_FOUND There is not any console devices connected\r
429 success\r
430 @retval EFI_SUCCESS Success connect any one instance of the console\r
431 device path base on the variable ConVarName.\r
432\r
433**/\r
434EFI_STATUS\r
435EFIAPI\r
436BdsLibConnectConsoleVariable (\r
437 IN CHAR16 *ConVarName\r
438 )\r
439{\r
bc79c731 440 return ConnectConsoleVariableInternal(ConVarName, TRUE);\r
441}\r
5c08e117 442\r
bc79c731 443/**\r
444 Connect the console device base on the variable ConVarName, if\r
445 device path of the ConVarName is multi-instance device path and\r
446 anyone of the instances is connected success, then this function\r
447 will return success.\r
448 Dispatch service is not called when the handle associate with one \r
449 device path node can not be created successfully. Here no driver \r
450 dependency is assumed exist, so need not to call this service.\r
5c08e117 451\r
5c08e117 452\r
bc79c731 453 @param ConVarName Console related variable name, ConIn, ConOut,\r
454 ErrOut.\r
5c08e117 455\r
bc79c731 456 @retval EFI_NOT_FOUND There is not any console devices connected\r
457 success\r
458 @retval EFI_SUCCESS Success connect any one instance of the console\r
459 device path base on the variable ConVarName.\r
5c08e117 460\r
bc79c731 461**/\r
462EFI_STATUS\r
463EFIAPI\r
464BdsLibConnectConsoleVariableWithOutDispatch (\r
465 IN CHAR16 *ConVarName\r
466 )\r
467{\r
468 return ConnectConsoleVariableInternal(ConVarName, FALSE);\r
5c08e117 469}\r
470\r
5c08e117 471/**\r
472 This function will search every simpletext device in current system,\r
473 and make every simpletext device as pertantial console device.\r
474\r
475**/\r
476VOID\r
477EFIAPI\r
478BdsLibConnectAllConsoles (\r
479 VOID\r
480 )\r
481{\r
482 UINTN Index;\r
483 EFI_DEVICE_PATH_PROTOCOL *ConDevicePath;\r
484 UINTN HandleCount;\r
485 EFI_HANDLE *HandleBuffer;\r
486\r
487 Index = 0;\r
488 HandleCount = 0;\r
489 HandleBuffer = NULL;\r
490 ConDevicePath = NULL;\r
491\r
492 //\r
493 // Update all the console variables\r
494 //\r
495 gBS->LocateHandleBuffer (\r
496 ByProtocol,\r
497 &gEfiSimpleTextInProtocolGuid,\r
498 NULL,\r
499 &HandleCount,\r
500 &HandleBuffer\r
501 );\r
502\r
503 for (Index = 0; Index < HandleCount; Index++) {\r
504 gBS->HandleProtocol (\r
505 HandleBuffer[Index],\r
506 &gEfiDevicePathProtocolGuid,\r
507 (VOID **) &ConDevicePath\r
508 );\r
509 BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL);\r
510 }\r
511\r
512 if (HandleBuffer != NULL) {\r
513 FreePool(HandleBuffer);\r
514 HandleBuffer = NULL;\r
515 }\r
516\r
517 gBS->LocateHandleBuffer (\r
518 ByProtocol,\r
519 &gEfiSimpleTextOutProtocolGuid,\r
520 NULL,\r
521 &HandleCount,\r
522 &HandleBuffer\r
523 );\r
524 for (Index = 0; Index < HandleCount; Index++) {\r
525 gBS->HandleProtocol (\r
526 HandleBuffer[Index],\r
527 &gEfiDevicePathProtocolGuid,\r
528 (VOID **) &ConDevicePath\r
529 );\r
530 BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL);\r
531 BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL);\r
532 }\r
533\r
534 if (HandleBuffer != NULL) {\r
535 FreePool(HandleBuffer);\r
536 }\r
537\r
538 //\r
539 // Connect all console variables\r
540 //\r
541 BdsLibConnectAllDefaultConsoles ();\r
542\r
543}\r
544\r
545/**\r
546 This function will connect console device base on the console\r
547 device variable ConIn, ConOut and ErrOut.\r
548\r
549 @retval EFI_SUCCESS At least one of the ConIn and ConOut device have\r
550 been connected success.\r
551 @retval EFI_STATUS Return the status of BdsLibConnectConsoleVariable ().\r
552\r
553**/\r
554EFI_STATUS\r
555EFIAPI\r
556BdsLibConnectAllDefaultConsoles (\r
557 VOID\r
558 )\r
559{\r
560 EFI_STATUS Status;\r
406ddad3 561 BOOLEAN SystemTableUpdated;\r
5c08e117 562\r
563 //\r
564 // Connect all default console variables\r
565 //\r
566\r
567 //\r
568 // It seems impossible not to have any ConOut device on platform,\r
569 // so we check the status here.\r
570 //\r
571 Status = BdsLibConnectConsoleVariable (L"ConOut");\r
572 if (EFI_ERROR (Status)) {\r
573 return Status;\r
574 }\r
575\r
576 //\r
577 // Insert the performance probe for Console Out\r
578 //\r
579 PERF_START (NULL, "ConOut", "BDS", 1);\r
580 PERF_END (NULL, "ConOut", "BDS", 0);\r
581\r
582 //\r
583 // Because possibly the platform is legacy free, in such case,\r
584 // ConIn devices (Serial Port and PS2 Keyboard ) does not exist,\r
585 // so we need not check the status.\r
586 //\r
587 BdsLibConnectConsoleVariable (L"ConIn");\r
588\r
589 //\r
590 // The _ModuleEntryPoint err out var is legal.\r
591 //\r
592 BdsLibConnectConsoleVariable (L"ErrOut");\r
593\r
406ddad3 594 SystemTableUpdated = FALSE;\r
dad60833 595 //\r
596 // Fill console handles in System Table if no console device assignd.\r
597 //\r
406ddad3 598 if (UpdateSystemTableConsole (L"ConIn", &gEfiSimpleTextInProtocolGuid, &gST->ConsoleInHandle, (VOID **) &gST->ConIn)) {\r
599 SystemTableUpdated = TRUE;\r
600 }\r
601 if (UpdateSystemTableConsole (L"ConOut", &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **) &gST->ConOut)) {\r
602 SystemTableUpdated = TRUE;\r
603 }\r
604 if (UpdateSystemTableConsole (L"ErrOut", &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **) &gST->StdErr)) {\r
605 SystemTableUpdated = TRUE;\r
606 }\r
607\r
18cf3950 608 if (SystemTableUpdated) {\r
609 //\r
610 // Update the CRC32 in the EFI System Table header\r
611 //\r
612 gST->Hdr.CRC32 = 0;\r
613 gBS->CalculateCrc32 (\r
614 (UINT8 *) &gST->Hdr,\r
615 gST->Hdr.HeaderSize,\r
616 &gST->Hdr.CRC32\r
617 );\r
618 }\r
619\r
620 return EFI_SUCCESS;\r
621\r
622}\r
623\r
624/**\r
625 This function will connect console device except ConIn base on the console\r
626 device variable ConOut and ErrOut.\r
627\r
628 @retval EFI_SUCCESS At least one of the ConOut device have\r
629 been connected success.\r
630 @retval EFI_STATUS Return the status of BdsLibConnectConsoleVariable ().\r
631\r
632**/\r
633EFI_STATUS\r
634EFIAPI\r
635BdsLibConnectAllDefaultConsolesWithOutConIn (\r
636 VOID\r
637 )\r
638{\r
639 EFI_STATUS Status;\r
640 BOOLEAN SystemTableUpdated;\r
641\r
642 //\r
643 // Connect all default console variables except ConIn\r
644 //\r
645\r
646 //\r
647 // It seems impossible not to have any ConOut device on platform,\r
648 // so we check the status here.\r
649 //\r
650 Status = BdsLibConnectConsoleVariable (L"ConOut");\r
651 if (EFI_ERROR (Status)) {\r
652 return Status;\r
653 }\r
654\r
655 //\r
656 // Insert the performance probe for Console Out\r
657 //\r
658 PERF_START (NULL, "ConOut", "BDS", 1);\r
659 PERF_END (NULL, "ConOut", "BDS", 0);\r
660\r
661 //\r
662 // The _ModuleEntryPoint err out var is legal.\r
663 //\r
664 BdsLibConnectConsoleVariable (L"ErrOut");\r
665\r
666 SystemTableUpdated = FALSE;\r
667 //\r
668 // Fill console handles in System Table if no console device assignd.\r
669 //\r
670 if (UpdateSystemTableConsole (L"ConOut", &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **) &gST->ConOut)) {\r
671 SystemTableUpdated = TRUE;\r
672 }\r
673 if (UpdateSystemTableConsole (L"ErrOut", &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **) &gST->StdErr)) {\r
674 SystemTableUpdated = TRUE;\r
675 }\r
676\r
406ddad3 677 if (SystemTableUpdated) {\r
678 //\r
679 // Update the CRC32 in the EFI System Table header\r
680 //\r
681 gST->Hdr.CRC32 = 0;\r
682 gBS->CalculateCrc32 (\r
683 (UINT8 *) &gST->Hdr,\r
684 gST->Hdr.HeaderSize,\r
685 &gST->Hdr.CRC32\r
686 );\r
687 }\r
dad60833 688\r
5c08e117 689 return EFI_SUCCESS;\r
690\r
691}\r
692\r
693/**\r
694 Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer\r
695 is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt\r
696 buffer is passed in it will be used if it is big enough.\r
697\r
698 @param BmpImage Pointer to BMP file\r
699 @param BmpImageSize Number of bytes in BmpImage\r
700 @param GopBlt Buffer containing GOP version of BmpImage.\r
701 @param GopBltSize Size of GopBlt in bytes.\r
702 @param PixelHeight Height of GopBlt/BmpImage in pixels\r
703 @param PixelWidth Width of GopBlt/BmpImage in pixels\r
704\r
705 @retval EFI_SUCCESS GopBlt and GopBltSize are returned.\r
706 @retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image\r
707 @retval EFI_BUFFER_TOO_SMALL The passed in GopBlt buffer is not big enough.\r
708 GopBltSize will contain the required size.\r
709 @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate.\r
710\r
711**/\r
712EFI_STATUS\r
713ConvertBmpToGopBlt (\r
714 IN VOID *BmpImage,\r
715 IN UINTN BmpImageSize,\r
716 IN OUT VOID **GopBlt,\r
717 IN OUT UINTN *GopBltSize,\r
718 OUT UINTN *PixelHeight,\r
719 OUT UINTN *PixelWidth\r
720 )\r
721{\r
722 UINT8 *Image;\r
723 UINT8 *ImageHeader;\r
724 BMP_IMAGE_HEADER *BmpHeader;\r
725 BMP_COLOR_MAP *BmpColorMap;\r
726 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
727 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
88f2bdb5 728 UINT64 BltBufferSize;\r
5c08e117 729 UINTN Index;\r
730 UINTN Height;\r
731 UINTN Width;\r
732 UINTN ImageIndex;\r
a46c3657 733 UINT32 DataSizePerLine;\r
5c08e117 734 BOOLEAN IsAllocated;\r
a46c3657
ED
735 UINT32 ColorMapNum;\r
736\r
737 if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) {\r
738 return EFI_INVALID_PARAMETER;\r
739 }\r
5c08e117 740\r
741 BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;\r
742\r
743 if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {\r
744 return EFI_UNSUPPORTED;\r
745 }\r
746\r
747 //\r
748 // Doesn't support compress.\r
749 //\r
750 if (BmpHeader->CompressionType != 0) {\r
751 return EFI_UNSUPPORTED;\r
752 }\r
753\r
a46c3657
ED
754 //\r
755 // Only support BITMAPINFOHEADER format.\r
756 // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER\r
757 //\r
758 if (BmpHeader->HeaderSize != sizeof (BMP_IMAGE_HEADER) - OFFSET_OF(BMP_IMAGE_HEADER, HeaderSize)) {\r
759 return EFI_UNSUPPORTED;\r
760 }\r
761\r
762 //\r
763 // The data size in each line must be 4 byte alignment.\r
764 //\r
765 DataSizePerLine = ((BmpHeader->PixelWidth * BmpHeader->BitPerPixel + 31) >> 3) & (~0x3);\r
766 BltBufferSize = MultU64x32 (DataSizePerLine, BmpHeader->PixelHeight);\r
767 if (BltBufferSize > (UINT32) ~0) {\r
768 return EFI_INVALID_PARAMETER;\r
769 }\r
770\r
771 if ((BmpHeader->Size != BmpImageSize) || \r
772 (BmpHeader->Size < BmpHeader->ImageOffset) ||\r
773 (BmpHeader->Size - BmpHeader->ImageOffset != BmpHeader->PixelHeight * DataSizePerLine)) {\r
774 return EFI_INVALID_PARAMETER;\r
775 }\r
776\r
5c08e117 777 //\r
778 // Calculate Color Map offset in the image.\r
779 //\r
780 Image = BmpImage;\r
781 BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));\r
a46c3657
ED
782 if (BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)) {\r
783 return EFI_INVALID_PARAMETER;\r
784 }\r
785\r
786 if (BmpHeader->ImageOffset > sizeof (BMP_IMAGE_HEADER)) {\r
787 switch (BmpHeader->BitPerPixel) {\r
788 case 1:\r
789 ColorMapNum = 2;\r
790 break;\r
791 case 4:\r
792 ColorMapNum = 16;\r
793 break;\r
794 case 8:\r
795 ColorMapNum = 256;\r
796 break;\r
797 default:\r
798 ColorMapNum = 0;\r
799 break;\r
800 }\r
801 if (BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) != sizeof (BMP_COLOR_MAP) * ColorMapNum) {\r
802 return EFI_INVALID_PARAMETER;\r
803 }\r
804 }\r
5c08e117 805\r
806 //\r
807 // Calculate graphics image data address in the image\r
808 //\r
809 Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;\r
810 ImageHeader = Image;\r
811\r
812 //\r
813 // Calculate the BltBuffer needed size.\r
814 //\r
d2eec319 815 BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader->PixelHeight);\r
816 //\r
817 // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow\r
818 //\r
819 if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {\r
a46c3657
ED
820 return EFI_UNSUPPORTED;\r
821 }\r
d2eec319 822 BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
823\r
5c08e117 824 IsAllocated = FALSE;\r
825 if (*GopBlt == NULL) {\r
826 //\r
827 // GopBlt is not allocated by caller.\r
828 //\r
88f2bdb5 829 *GopBltSize = (UINTN) BltBufferSize;\r
5c08e117 830 *GopBlt = AllocatePool (*GopBltSize);\r
831 IsAllocated = TRUE;\r
832 if (*GopBlt == NULL) {\r
833 return EFI_OUT_OF_RESOURCES;\r
834 }\r
835 } else {\r
836 //\r
837 // GopBlt has been allocated by caller.\r
838 //\r
2bf3421a 839 if (*GopBltSize < (UINTN) BltBufferSize) {\r
88f2bdb5 840 *GopBltSize = (UINTN) BltBufferSize;\r
5c08e117 841 return EFI_BUFFER_TOO_SMALL;\r
842 }\r
843 }\r
844\r
845 *PixelWidth = BmpHeader->PixelWidth;\r
846 *PixelHeight = BmpHeader->PixelHeight;\r
847\r
848 //\r
849 // Convert image from BMP to Blt buffer format\r
850 //\r
851 BltBuffer = *GopBlt;\r
852 for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {\r
853 Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];\r
854 for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {\r
855 switch (BmpHeader->BitPerPixel) {\r
856 case 1:\r
857 //\r
858 // Convert 1-bit (2 colors) BMP to 24-bit color\r
859 //\r
860 for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {\r
861 Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;\r
862 Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;\r
863 Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;\r
864 Blt++;\r
865 Width++;\r
866 }\r
867\r
868 Blt--;\r
869 Width--;\r
870 break;\r
871\r
872 case 4:\r
873 //\r
874 // Convert 4-bit (16 colors) BMP Palette to 24-bit color\r
875 //\r
876 Index = (*Image) >> 4;\r
877 Blt->Red = BmpColorMap[Index].Red;\r
878 Blt->Green = BmpColorMap[Index].Green;\r
879 Blt->Blue = BmpColorMap[Index].Blue;\r
880 if (Width < (BmpHeader->PixelWidth - 1)) {\r
881 Blt++;\r
882 Width++;\r
883 Index = (*Image) & 0x0f;\r
884 Blt->Red = BmpColorMap[Index].Red;\r
885 Blt->Green = BmpColorMap[Index].Green;\r
886 Blt->Blue = BmpColorMap[Index].Blue;\r
887 }\r
888 break;\r
889\r
890 case 8:\r
891 //\r
892 // Convert 8-bit (256 colors) BMP Palette to 24-bit color\r
893 //\r
894 Blt->Red = BmpColorMap[*Image].Red;\r
895 Blt->Green = BmpColorMap[*Image].Green;\r
896 Blt->Blue = BmpColorMap[*Image].Blue;\r
897 break;\r
898\r
899 case 24:\r
900 //\r
901 // It is 24-bit BMP.\r
902 //\r
903 Blt->Blue = *Image++;\r
904 Blt->Green = *Image++;\r
905 Blt->Red = *Image;\r
906 break;\r
907\r
908 default:\r
909 //\r
910 // Other bit format BMP is not supported.\r
911 //\r
912 if (IsAllocated) {\r
913 FreePool (*GopBlt);\r
914 *GopBlt = NULL;\r
915 }\r
916 return EFI_UNSUPPORTED;\r
917 break;\r
918 };\r
919\r
920 }\r
921\r
922 ImageIndex = (UINTN) (Image - ImageHeader);\r
923 if ((ImageIndex % 4) != 0) {\r
924 //\r
925 // Bmp Image starts each row on a 32-bit boundary!\r
926 //\r
927 Image = Image + (4 - (ImageIndex % 4));\r
928 }\r
929 }\r
930\r
931 return EFI_SUCCESS;\r
932}\r
933\r
5c08e117 934/**\r
24cdd14e
LG
935 Use SystemTable Conout to stop video based Simple Text Out consoles from going\r
936 to the video device. Put up LogoFile on every video device that is a console.\r
5c08e117 937\r
938 @param[in] LogoFile File name of logo to display on the center of the screen.\r
939\r
940 @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed.\r
941 @retval EFI_UNSUPPORTED Logo not found\r
942\r
943**/\r
944EFI_STATUS\r
945EFIAPI\r
946EnableQuietBoot (\r
947 IN EFI_GUID *LogoFile\r
948 )\r
949{\r
950 EFI_STATUS Status;\r
5c08e117 951 EFI_OEM_BADGING_PROTOCOL *Badging;\r
952 UINT32 SizeOfX;\r
953 UINT32 SizeOfY;\r
954 INTN DestX;\r
955 INTN DestY;\r
956 UINT8 *ImageData;\r
957 UINTN ImageSize;\r
958 UINTN BltSize;\r
959 UINT32 Instance;\r
960 EFI_BADGING_FORMAT Format;\r
961 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;\r
962 UINTN CoordinateX;\r
963 UINTN CoordinateY;\r
964 UINTN Height;\r
965 UINTN Width;\r
966 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
967 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
968 UINT32 ColorDepth;\r
969 UINT32 RefreshRate;\r
970 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
a637802c 971 EFI_BOOT_LOGO_PROTOCOL *BootLogo;\r
972 UINTN NumberOfLogos;\r
973 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LogoBlt;\r
974 UINTN LogoDestX;\r
975 UINTN LogoDestY;\r
976 UINTN LogoHeight;\r
977 UINTN LogoWidth;\r
978 UINTN NewDestX;\r
979 UINTN NewDestY;\r
980 UINTN NewHeight;\r
981 UINTN NewWidth;\r
a46c3657 982 UINT64 BufferSize;\r
5c08e117 983\r
5c08e117 984 UgaDraw = NULL;\r
985 //\r
986 // Try to open GOP first\r
987 //\r
988 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);\r
989 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
990 GraphicsOutput = NULL;\r
991 //\r
992 // Open GOP failed, try to open UGA\r
993 //\r
994 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);\r
995 }\r
996 if (EFI_ERROR (Status)) {\r
997 return EFI_UNSUPPORTED;\r
998 }\r
999\r
a637802c 1000 //\r
1001 // Try to open Boot Logo Protocol.\r
1002 //\r
1003 BootLogo = NULL;\r
1004 gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);\r
1005\r
5c08e117 1006 //\r
5d7c1609 1007 // Erase Cursor from screen\r
5c08e117 1008 //\r
5d7c1609 1009 gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
1010\r
1011 Badging = NULL;\r
1012 Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);\r
5c08e117 1013\r
1014 if (GraphicsOutput != NULL) {\r
1015 SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
1016 SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
1017\r
1018 } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
1019 Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);\r
1020 if (EFI_ERROR (Status)) {\r
1021 return EFI_UNSUPPORTED;\r
1022 }\r
1023 } else {\r
1024 return EFI_UNSUPPORTED;\r
1025 }\r
1026\r
a637802c 1027 Blt = NULL;\r
1028 NumberOfLogos = 0;\r
1029 LogoDestX = 0;\r
1030 LogoDestY = 0;\r
1031 LogoHeight = 0;\r
1032 LogoWidth = 0;\r
1033 NewDestX = 0;\r
1034 NewDestY = 0;\r
1035 NewHeight = 0;\r
1036 NewWidth = 0;\r
5c08e117 1037 Instance = 0;\r
1038 while (1) {\r
1039 ImageData = NULL;\r
1040 ImageSize = 0;\r
1041\r
1042 if (Badging != NULL) {\r
1043 //\r
1044 // Get image from OEMBadging protocol.\r
1045 //\r
1046 Status = Badging->GetImage (\r
1047 Badging,\r
1048 &Instance,\r
1049 &Format,\r
1050 &ImageData,\r
1051 &ImageSize,\r
1052 &Attribute,\r
1053 &CoordinateX,\r
1054 &CoordinateY\r
1055 );\r
1056 if (EFI_ERROR (Status)) {\r
a637802c 1057 goto Done;\r
5c08e117 1058 }\r
1059\r
1060 //\r
1061 // Currently only support BMP format.\r
1062 //\r
1063 if (Format != EfiBadgingFormatBMP) {\r
1064 if (ImageData != NULL) {\r
1065 FreePool (ImageData);\r
1066 }\r
1067 continue;\r
1068 }\r
1069 } else {\r
1070 //\r
1071 // Get the specified image from FV.\r
1072 //\r
1073 Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **) &ImageData, &ImageSize);\r
1074 if (EFI_ERROR (Status)) {\r
1075 return EFI_UNSUPPORTED;\r
1076 }\r
1077\r
1078 CoordinateX = 0;\r
1079 CoordinateY = 0;\r
2df686c6 1080 if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {\r
1081 Attribute = EfiBadgingDisplayAttributeCenter;\r
1082 } else {\r
1083 Attribute = EfiBadgingDisplayAttributeCustomized;\r
1084 } \r
5c08e117 1085 }\r
1086\r
a637802c 1087 if (Blt != NULL) {\r
1088 FreePool (Blt);\r
1089 }\r
5c08e117 1090 Blt = NULL;\r
1091 Status = ConvertBmpToGopBlt (\r
1092 ImageData,\r
1093 ImageSize,\r
1094 (VOID **) &Blt,\r
1095 &BltSize,\r
1096 &Height,\r
1097 &Width\r
1098 );\r
1099 if (EFI_ERROR (Status)) {\r
1100 FreePool (ImageData);\r
1101\r
1102 if (Badging == NULL) {\r
1103 return Status;\r
1104 } else {\r
1105 continue;\r
1106 }\r
1107 }\r
1108\r
1109 //\r
1110 // Calculate the display position according to Attribute.\r
1111 //\r
1112 switch (Attribute) {\r
1113 case EfiBadgingDisplayAttributeLeftTop:\r
1114 DestX = CoordinateX;\r
1115 DestY = CoordinateY;\r
1116 break;\r
1117\r
1118 case EfiBadgingDisplayAttributeCenterTop:\r
1119 DestX = (SizeOfX - Width) / 2;\r
1120 DestY = CoordinateY;\r
1121 break;\r
1122\r
1123 case EfiBadgingDisplayAttributeRightTop:\r
1124 DestX = (SizeOfX - Width - CoordinateX);\r
1125 DestY = CoordinateY;;\r
1126 break;\r
1127\r
1128 case EfiBadgingDisplayAttributeCenterRight:\r
1129 DestX = (SizeOfX - Width - CoordinateX);\r
1130 DestY = (SizeOfY - Height) / 2;\r
1131 break;\r
1132\r
1133 case EfiBadgingDisplayAttributeRightBottom:\r
1134 DestX = (SizeOfX - Width - CoordinateX);\r
1135 DestY = (SizeOfY - Height - CoordinateY);\r
1136 break;\r
1137\r
1138 case EfiBadgingDisplayAttributeCenterBottom:\r
1139 DestX = (SizeOfX - Width) / 2;\r
1140 DestY = (SizeOfY - Height - CoordinateY);\r
1141 break;\r
1142\r
1143 case EfiBadgingDisplayAttributeLeftBottom:\r
1144 DestX = CoordinateX;\r
1145 DestY = (SizeOfY - Height - CoordinateY);\r
1146 break;\r
1147\r
1148 case EfiBadgingDisplayAttributeCenterLeft:\r
1149 DestX = CoordinateX;\r
1150 DestY = (SizeOfY - Height) / 2;\r
1151 break;\r
1152\r
1153 case EfiBadgingDisplayAttributeCenter:\r
1154 DestX = (SizeOfX - Width) / 2;\r
1155 DestY = (SizeOfY - Height) / 2;\r
1156 break;\r
1157\r
2df686c6 1158 case EfiBadgingDisplayAttributeCustomized:\r
1159 DestX = (SizeOfX - Width) / 2;\r
1160 DestY = ((SizeOfY * 382) / 1000) - Height / 2;\r
1161 break;\r
1162\r
5c08e117 1163 default:\r
1164 DestX = CoordinateX;\r
1165 DestY = CoordinateY;\r
1166 break;\r
1167 }\r
1168\r
1169 if ((DestX >= 0) && (DestY >= 0)) {\r
1170 if (GraphicsOutput != NULL) {\r
1171 Status = GraphicsOutput->Blt (\r
1172 GraphicsOutput,\r
1173 Blt,\r
1174 EfiBltBufferToVideo,\r
1175 0,\r
1176 0,\r
1177 (UINTN) DestX,\r
1178 (UINTN) DestY,\r
1179 Width,\r
1180 Height,\r
1181 Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
1182 );\r
1183 } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
1184 Status = UgaDraw->Blt (\r
1185 UgaDraw,\r
1186 (EFI_UGA_PIXEL *) Blt,\r
1187 EfiUgaBltBufferToVideo,\r
1188 0,\r
1189 0,\r
1190 (UINTN) DestX,\r
1191 (UINTN) DestY,\r
1192 Width,\r
1193 Height,\r
1194 Width * sizeof (EFI_UGA_PIXEL)\r
1195 );\r
1196 } else {\r
a637802c 1197 Status = EFI_UNSUPPORTED;\r
1198 }\r
1199\r
1200 //\r
1201 // Report displayed Logo information.\r
1202 //\r
1203 if (!EFI_ERROR (Status)) {\r
1204 NumberOfLogos++;\r
1205\r
1206 if (LogoWidth == 0) {\r
1207 //\r
1208 // The first Logo.\r
1209 //\r
6ba8465f 1210 LogoDestX = (UINTN) DestX;\r
1211 LogoDestY = (UINTN) DestY;\r
a637802c 1212 LogoWidth = Width;\r
1213 LogoHeight = Height;\r
1214 } else {\r
1215 //\r
1216 // Merge new logo with old one.\r
1217 //\r
1218 NewDestX = MIN ((UINTN) DestX, LogoDestX);\r
1219 NewDestY = MIN ((UINTN) DestY, LogoDestY);\r
1220 NewWidth = MAX ((UINTN) DestX + Width, LogoDestX + LogoWidth) - NewDestX;\r
1221 NewHeight = MAX ((UINTN) DestY + Height, LogoDestY + LogoHeight) - NewDestY;\r
1222\r
1223 LogoDestX = NewDestX;\r
1224 LogoDestY = NewDestY;\r
1225 LogoWidth = NewWidth;\r
1226 LogoHeight = NewHeight;\r
1227 }\r
5c08e117 1228 }\r
1229 }\r
1230\r
1231 FreePool (ImageData);\r
1232\r
a637802c 1233 if (Badging == NULL) {\r
1234 break;\r
1235 }\r
1236 }\r
1237\r
1238Done:\r
1239 if (BootLogo == NULL || NumberOfLogos == 0) {\r
1240 //\r
1241 // No logo displayed.\r
1242 //\r
5c08e117 1243 if (Blt != NULL) {\r
1244 FreePool (Blt);\r
1245 }\r
1246\r
a637802c 1247 return Status;\r
1248 }\r
1249\r
1250 //\r
1251 // Advertise displayed Logo information.\r
1252 //\r
1253 if (NumberOfLogos == 1) {\r
1254 //\r
1255 // Only one logo displayed, use its Blt buffer directly for BootLogo protocol.\r
1256 //\r
1257 LogoBlt = Blt;\r
1258 Status = EFI_SUCCESS;\r
1259 } else {\r
1260 //\r
1261 // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation. \r
1262 //\r
1263 if (Blt != NULL) {\r
1264 FreePool (Blt);\r
1265 }\r
1266\r
a46c3657
ED
1267 //\r
1268 // Ensure the LogoHeight * LogoWidth doesn't overflow\r
1269 //\r
1270 if (LogoHeight > DivU64x64Remainder ((UINTN) ~0, LogoWidth, NULL)) {\r
1271 return EFI_UNSUPPORTED;\r
1272 }\r
1273 BufferSize = MultU64x64 (LogoWidth, LogoHeight);\r
1274\r
1275 //\r
1276 // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow\r
1277 //\r
1278 if (BufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {\r
1279 return EFI_UNSUPPORTED;\r
1280 }\r
1281\r
1282 LogoBlt = AllocateZeroPool ((UINTN)BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
a637802c 1283 if (LogoBlt == NULL) {\r
1284 return EFI_OUT_OF_RESOURCES;\r
1285 }\r
1286\r
1287 if (GraphicsOutput != NULL) {\r
1288 Status = GraphicsOutput->Blt (\r
1289 GraphicsOutput,\r
1290 LogoBlt,\r
1291 EfiBltVideoToBltBuffer,\r
1292 LogoDestX,\r
1293 LogoDestY,\r
1294 0,\r
1295 0,\r
1296 LogoWidth,\r
1297 LogoHeight,\r
1298 LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
1299 );\r
1300 } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
1301 Status = UgaDraw->Blt (\r
1302 UgaDraw,\r
1303 (EFI_UGA_PIXEL *) LogoBlt,\r
1304 EfiUgaVideoToBltBuffer,\r
1305 LogoDestX,\r
1306 LogoDestY,\r
1307 0,\r
1308 0,\r
1309 LogoWidth,\r
1310 LogoHeight,\r
1311 LogoWidth * sizeof (EFI_UGA_PIXEL)\r
1312 );\r
1313 } else {\r
1314 Status = EFI_UNSUPPORTED;\r
5c08e117 1315 }\r
1316 }\r
1317\r
a637802c 1318 if (!EFI_ERROR (Status)) {\r
1319 BootLogo->SetBootLogo (BootLogo, LogoBlt, LogoDestX, LogoDestY, LogoWidth, LogoHeight);\r
1320 }\r
1321 FreePool (LogoBlt);\r
1322\r
5c08e117 1323 return Status;\r
1324}\r
1325\r
1326/**\r
24cdd14e
LG
1327 Use SystemTable Conout to turn on video based Simple Text Out consoles. The \r
1328 Simple Text Out screens will now be synced up with all non video output devices\r
5c08e117 1329\r
1330 @retval EFI_SUCCESS UGA devices are back in text mode and synced up.\r
1331\r
1332**/\r
1333EFI_STATUS\r
1334EFIAPI\r
1335DisableQuietBoot (\r
1336 VOID\r
1337 )\r
1338{\r
5c08e117 1339\r
1340 //\r
5d7c1609 1341 // Enable Cursor on Screen\r
5c08e117 1342 //\r
5d7c1609 1343 gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
1344 return EFI_SUCCESS;\r
5c08e117 1345}\r
1346\r