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