]> git.proxmox.com Git - mirror_edk2.git/blame - ArmVirtPkg/Library/PlatformBootManagerLib/QuietBoot.c
OvmfPkg: set SMM stack size to 16KB
[mirror_edk2.git] / ArmVirtPkg / Library / PlatformBootManagerLib / QuietBoot.c
CommitLineData
1f73aef5
LE
1/** @file\r
2 Platform BDS function for quiet boot support.\r
3\r
4Copyright (C) 2016, Red Hat, Inc.\r
5Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>\r
6This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include <IndustryStandard/Bmp.h>\r
17#include <Library/DxeServicesLib.h>\r
18#include <Protocol/BootLogo.h>\r
19#include <Protocol/OEMBadging.h>\r
20#include <Protocol/UgaDraw.h>\r
21\r
22#include "PlatformBm.h"\r
23\r
24/**\r
25 Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer\r
26 is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt\r
27 buffer is passed in it will be used if it is big enough.\r
28\r
29 @param BmpImage Pointer to BMP file\r
30 @param BmpImageSize Number of bytes in BmpImage\r
31 @param GopBlt Buffer containing GOP version of BmpImage.\r
32 @param GopBltSize Size of GopBlt in bytes.\r
33 @param PixelHeight Height of GopBlt/BmpImage in pixels\r
34 @param PixelWidth Width of GopBlt/BmpImage in pixels\r
35\r
36 @retval EFI_SUCCESS GopBlt and GopBltSize are returned.\r
37 @retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image\r
38 @retval EFI_BUFFER_TOO_SMALL The passed in GopBlt buffer is not big enough.\r
39 GopBltSize will contain the required size.\r
40 @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate.\r
41\r
42**/\r
43STATIC\r
44EFI_STATUS\r
45ConvertBmpToGopBlt (\r
46 IN VOID *BmpImage,\r
47 IN UINTN BmpImageSize,\r
48 IN OUT VOID **GopBlt,\r
49 IN OUT UINTN *GopBltSize,\r
50 OUT UINTN *PixelHeight,\r
51 OUT UINTN *PixelWidth\r
52 )\r
53{\r
54 UINT8 *Image;\r
55 UINT8 *ImageHeader;\r
56 BMP_IMAGE_HEADER *BmpHeader;\r
57 BMP_COLOR_MAP *BmpColorMap;\r
58 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
59 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
60 UINT64 BltBufferSize;\r
61 UINTN Index;\r
62 UINTN Height;\r
63 UINTN Width;\r
64 UINTN ImageIndex;\r
65 UINT32 DataSizePerLine;\r
66 BOOLEAN IsAllocated;\r
67 UINT32 ColorMapNum;\r
68\r
69 if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) {\r
70 return EFI_INVALID_PARAMETER;\r
71 }\r
72\r
73 BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;\r
74\r
75 if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {\r
76 return EFI_UNSUPPORTED;\r
77 }\r
78\r
79 //\r
80 // Doesn't support compress.\r
81 //\r
82 if (BmpHeader->CompressionType != 0) {\r
83 return EFI_UNSUPPORTED;\r
84 }\r
85\r
86 //\r
87 // Only support BITMAPINFOHEADER format.\r
88 // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER\r
89 //\r
90 if (BmpHeader->HeaderSize != sizeof (BMP_IMAGE_HEADER) - OFFSET_OF(BMP_IMAGE_HEADER, HeaderSize)) {\r
91 return EFI_UNSUPPORTED;\r
92 }\r
93\r
94 //\r
95 // The data size in each line must be 4 byte alignment.\r
96 //\r
97 DataSizePerLine = ((BmpHeader->PixelWidth * BmpHeader->BitPerPixel + 31) >> 3) & (~0x3);\r
98 BltBufferSize = MultU64x32 (DataSizePerLine, BmpHeader->PixelHeight);\r
99 if (BltBufferSize > (UINT32) ~0) {\r
100 return EFI_INVALID_PARAMETER;\r
101 }\r
102\r
103 if ((BmpHeader->Size != BmpImageSize) ||\r
104 (BmpHeader->Size < BmpHeader->ImageOffset) ||\r
105 (BmpHeader->Size - BmpHeader->ImageOffset != BmpHeader->PixelHeight * DataSizePerLine)) {\r
106 return EFI_INVALID_PARAMETER;\r
107 }\r
108\r
109 //\r
110 // Calculate Color Map offset in the image.\r
111 //\r
112 Image = BmpImage;\r
113 BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));\r
114 if (BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)) {\r
115 return EFI_INVALID_PARAMETER;\r
116 }\r
117\r
118 if (BmpHeader->ImageOffset > sizeof (BMP_IMAGE_HEADER)) {\r
119 switch (BmpHeader->BitPerPixel) {\r
120 case 1:\r
121 ColorMapNum = 2;\r
122 break;\r
123 case 4:\r
124 ColorMapNum = 16;\r
125 break;\r
126 case 8:\r
127 ColorMapNum = 256;\r
128 break;\r
129 default:\r
130 ColorMapNum = 0;\r
131 break;\r
132 }\r
133 //\r
134 // BMP file may has padding data between the bmp header section and the bmp data section.\r
135 //\r
136 if (BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) < sizeof (BMP_COLOR_MAP) * ColorMapNum) {\r
137 return EFI_INVALID_PARAMETER;\r
138 }\r
139 }\r
140\r
141 //\r
142 // Calculate graphics image data address in the image\r
143 //\r
144 Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;\r
145 ImageHeader = Image;\r
146\r
147 //\r
148 // Calculate the BltBuffer needed size.\r
149 //\r
150 BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader->PixelHeight);\r
151 //\r
152 // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow\r
153 //\r
154 if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {\r
155 return EFI_UNSUPPORTED;\r
156 }\r
157 BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
158\r
159 IsAllocated = FALSE;\r
160 if (*GopBlt == NULL) {\r
161 //\r
162 // GopBlt is not allocated by caller.\r
163 //\r
164 *GopBltSize = (UINTN) BltBufferSize;\r
165 *GopBlt = AllocatePool (*GopBltSize);\r
166 IsAllocated = TRUE;\r
167 if (*GopBlt == NULL) {\r
168 return EFI_OUT_OF_RESOURCES;\r
169 }\r
170 } else {\r
171 //\r
172 // GopBlt has been allocated by caller.\r
173 //\r
174 if (*GopBltSize < (UINTN) BltBufferSize) {\r
175 *GopBltSize = (UINTN) BltBufferSize;\r
176 return EFI_BUFFER_TOO_SMALL;\r
177 }\r
178 }\r
179\r
180 *PixelWidth = BmpHeader->PixelWidth;\r
181 *PixelHeight = BmpHeader->PixelHeight;\r
182\r
183 //\r
184 // Convert image from BMP to Blt buffer format\r
185 //\r
186 BltBuffer = *GopBlt;\r
187 for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {\r
188 Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];\r
189 for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {\r
190 switch (BmpHeader->BitPerPixel) {\r
191 case 1:\r
192 //\r
193 // Convert 1-bit (2 colors) BMP to 24-bit color\r
194 //\r
195 for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {\r
196 Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;\r
197 Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;\r
198 Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;\r
199 Blt++;\r
200 Width++;\r
201 }\r
202\r
203 Blt--;\r
204 Width--;\r
205 break;\r
206\r
207 case 4:\r
208 //\r
209 // Convert 4-bit (16 colors) BMP Palette to 24-bit color\r
210 //\r
211 Index = (*Image) >> 4;\r
212 Blt->Red = BmpColorMap[Index].Red;\r
213 Blt->Green = BmpColorMap[Index].Green;\r
214 Blt->Blue = BmpColorMap[Index].Blue;\r
215 if (Width < (BmpHeader->PixelWidth - 1)) {\r
216 Blt++;\r
217 Width++;\r
218 Index = (*Image) & 0x0f;\r
219 Blt->Red = BmpColorMap[Index].Red;\r
220 Blt->Green = BmpColorMap[Index].Green;\r
221 Blt->Blue = BmpColorMap[Index].Blue;\r
222 }\r
223 break;\r
224\r
225 case 8:\r
226 //\r
227 // Convert 8-bit (256 colors) BMP Palette to 24-bit color\r
228 //\r
229 Blt->Red = BmpColorMap[*Image].Red;\r
230 Blt->Green = BmpColorMap[*Image].Green;\r
231 Blt->Blue = BmpColorMap[*Image].Blue;\r
232 break;\r
233\r
234 case 24:\r
235 //\r
236 // It is 24-bit BMP.\r
237 //\r
238 Blt->Blue = *Image++;\r
239 Blt->Green = *Image++;\r
240 Blt->Red = *Image;\r
241 break;\r
242\r
243 default:\r
244 //\r
245 // Other bit format BMP is not supported.\r
246 //\r
247 if (IsAllocated) {\r
248 FreePool (*GopBlt);\r
249 *GopBlt = NULL;\r
250 }\r
251 return EFI_UNSUPPORTED;\r
252 };\r
253\r
254 }\r
255\r
256 ImageIndex = (UINTN) (Image - ImageHeader);\r
257 if ((ImageIndex % 4) != 0) {\r
258 //\r
259 // Bmp Image starts each row on a 32-bit boundary!\r
260 //\r
261 Image = Image + (4 - (ImageIndex % 4));\r
262 }\r
263 }\r
264\r
265 return EFI_SUCCESS;\r
266}\r
267\r
268/**\r
269 Use SystemTable Conout to stop video based Simple Text Out consoles from going\r
270 to the video device. Put up LogoFile on every video device that is a console.\r
271\r
272 @param[in] LogoFile File name of logo to display on the center of the screen.\r
273\r
274 @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed.\r
275 @retval EFI_UNSUPPORTED Logo not found\r
276\r
277**/\r
278EFI_STATUS\r
279EnableQuietBoot (\r
280 IN EFI_GUID *LogoFile\r
281 )\r
282{\r
283 EFI_STATUS Status;\r
284 EFI_OEM_BADGING_PROTOCOL *Badging;\r
285 UINT32 SizeOfX;\r
286 UINT32 SizeOfY;\r
287 INTN DestX;\r
288 INTN DestY;\r
289 UINT8 *ImageData;\r
290 UINTN ImageSize;\r
291 UINTN BltSize;\r
292 UINT32 Instance;\r
293 EFI_BADGING_FORMAT Format;\r
294 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;\r
295 UINTN CoordinateX;\r
296 UINTN CoordinateY;\r
297 UINTN Height;\r
298 UINTN Width;\r
299 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
300 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
301 UINT32 ColorDepth;\r
302 UINT32 RefreshRate;\r
303 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
304 EFI_BOOT_LOGO_PROTOCOL *BootLogo;\r
305 UINTN NumberOfLogos;\r
306 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LogoBlt;\r
307 UINTN LogoDestX;\r
308 UINTN LogoDestY;\r
309 UINTN LogoHeight;\r
310 UINTN LogoWidth;\r
311 UINTN NewDestX;\r
312 UINTN NewDestY;\r
313 UINTN NewHeight;\r
314 UINTN NewWidth;\r
315 UINT64 BufferSize;\r
316\r
317 UgaDraw = NULL;\r
318 //\r
319 // Try to open GOP first\r
320 //\r
321 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);\r
322 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
323 GraphicsOutput = NULL;\r
324 //\r
325 // Open GOP failed, try to open UGA\r
326 //\r
327 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);\r
328 }\r
329 if (EFI_ERROR (Status)) {\r
330 return EFI_UNSUPPORTED;\r
331 }\r
332\r
333 //\r
334 // Try to open Boot Logo Protocol.\r
335 //\r
336 BootLogo = NULL;\r
337 gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);\r
338\r
339 //\r
340 // Erase Cursor from screen\r
341 //\r
342 gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
343\r
344 Badging = NULL;\r
345 Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);\r
346\r
347 if (GraphicsOutput != NULL) {\r
348 SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
349 SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
350\r
351 } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
352 Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);\r
353 if (EFI_ERROR (Status)) {\r
354 return EFI_UNSUPPORTED;\r
355 }\r
356 } else {\r
357 return EFI_UNSUPPORTED;\r
358 }\r
359\r
360 Blt = NULL;\r
361 NumberOfLogos = 0;\r
362 LogoDestX = 0;\r
363 LogoDestY = 0;\r
364 LogoHeight = 0;\r
365 LogoWidth = 0;\r
366 NewDestX = 0;\r
367 NewDestY = 0;\r
368 NewHeight = 0;\r
369 NewWidth = 0;\r
370 Instance = 0;\r
371 Height = 0;\r
372 Width = 0;\r
373 while (1) {\r
374 ImageData = NULL;\r
375 ImageSize = 0;\r
376\r
377 if (Badging != NULL) {\r
378 //\r
379 // Get image from OEMBadging protocol.\r
380 //\r
381 Status = Badging->GetImage (\r
382 Badging,\r
383 &Instance,\r
384 &Format,\r
385 &ImageData,\r
386 &ImageSize,\r
387 &Attribute,\r
388 &CoordinateX,\r
389 &CoordinateY\r
390 );\r
391 if (EFI_ERROR (Status)) {\r
392 goto Done;\r
393 }\r
394\r
395 //\r
396 // Currently only support BMP format.\r
397 //\r
398 if (Format != EfiBadgingFormatBMP) {\r
399 if (ImageData != NULL) {\r
400 FreePool (ImageData);\r
401 }\r
402 continue;\r
403 }\r
404 } else {\r
405 //\r
406 // Get the specified image from FV.\r
407 //\r
408 Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **) &ImageData, &ImageSize);\r
409 if (EFI_ERROR (Status)) {\r
410 return EFI_UNSUPPORTED;\r
411 }\r
412\r
413 CoordinateX = 0;\r
414 CoordinateY = 0;\r
415 if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {\r
416 Attribute = EfiBadgingDisplayAttributeCenter;\r
417 } else {\r
418 Attribute = EfiBadgingDisplayAttributeCustomized;\r
419 }\r
420 }\r
421\r
422 if (Blt != NULL) {\r
423 FreePool (Blt);\r
424 }\r
425 Blt = NULL;\r
426 Status = ConvertBmpToGopBlt (\r
427 ImageData,\r
428 ImageSize,\r
429 (VOID **) &Blt,\r
430 &BltSize,\r
431 &Height,\r
432 &Width\r
433 );\r
434 if (EFI_ERROR (Status)) {\r
435 FreePool (ImageData);\r
436\r
437 if (Badging == NULL) {\r
438 return Status;\r
439 } else {\r
440 continue;\r
441 }\r
442 }\r
443\r
444 //\r
445 // Calculate the display position according to Attribute.\r
446 //\r
447 switch (Attribute) {\r
448 case EfiBadgingDisplayAttributeLeftTop:\r
449 DestX = CoordinateX;\r
450 DestY = CoordinateY;\r
451 break;\r
452\r
453 case EfiBadgingDisplayAttributeCenterTop:\r
454 DestX = (SizeOfX - Width) / 2;\r
455 DestY = CoordinateY;\r
456 break;\r
457\r
458 case EfiBadgingDisplayAttributeRightTop:\r
459 DestX = (SizeOfX - Width - CoordinateX);\r
460 DestY = CoordinateY;;\r
461 break;\r
462\r
463 case EfiBadgingDisplayAttributeCenterRight:\r
464 DestX = (SizeOfX - Width - CoordinateX);\r
465 DestY = (SizeOfY - Height) / 2;\r
466 break;\r
467\r
468 case EfiBadgingDisplayAttributeRightBottom:\r
469 DestX = (SizeOfX - Width - CoordinateX);\r
470 DestY = (SizeOfY - Height - CoordinateY);\r
471 break;\r
472\r
473 case EfiBadgingDisplayAttributeCenterBottom:\r
474 DestX = (SizeOfX - Width) / 2;\r
475 DestY = (SizeOfY - Height - CoordinateY);\r
476 break;\r
477\r
478 case EfiBadgingDisplayAttributeLeftBottom:\r
479 DestX = CoordinateX;\r
480 DestY = (SizeOfY - Height - CoordinateY);\r
481 break;\r
482\r
483 case EfiBadgingDisplayAttributeCenterLeft:\r
484 DestX = CoordinateX;\r
485 DestY = (SizeOfY - Height) / 2;\r
486 break;\r
487\r
488 case EfiBadgingDisplayAttributeCenter:\r
489 DestX = (SizeOfX - Width) / 2;\r
490 DestY = (SizeOfY - Height) / 2;\r
491 break;\r
492\r
493 case EfiBadgingDisplayAttributeCustomized:\r
494 DestX = (SizeOfX - Width) / 2;\r
495 DestY = ((SizeOfY * 382) / 1000) - Height / 2;\r
496 break;\r
497\r
498 default:\r
499 DestX = CoordinateX;\r
500 DestY = CoordinateY;\r
501 break;\r
502 }\r
503\r
504 if ((DestX >= 0) && (DestY >= 0)) {\r
505 if (GraphicsOutput != NULL) {\r
506 Status = GraphicsOutput->Blt (\r
507 GraphicsOutput,\r
508 Blt,\r
509 EfiBltBufferToVideo,\r
510 0,\r
511 0,\r
512 (UINTN) DestX,\r
513 (UINTN) DestY,\r
514 Width,\r
515 Height,\r
516 Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
517 );\r
518 } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
519 Status = UgaDraw->Blt (\r
520 UgaDraw,\r
521 (EFI_UGA_PIXEL *) Blt,\r
522 EfiUgaBltBufferToVideo,\r
523 0,\r
524 0,\r
525 (UINTN) DestX,\r
526 (UINTN) DestY,\r
527 Width,\r
528 Height,\r
529 Width * sizeof (EFI_UGA_PIXEL)\r
530 );\r
531 } else {\r
532 Status = EFI_UNSUPPORTED;\r
533 }\r
534\r
535 //\r
536 // Report displayed Logo information.\r
537 //\r
538 if (!EFI_ERROR (Status)) {\r
539 NumberOfLogos++;\r
540\r
541 if (LogoWidth == 0) {\r
542 //\r
543 // The first Logo.\r
544 //\r
545 LogoDestX = (UINTN) DestX;\r
546 LogoDestY = (UINTN) DestY;\r
547 LogoWidth = Width;\r
548 LogoHeight = Height;\r
549 } else {\r
550 //\r
551 // Merge new logo with old one.\r
552 //\r
553 NewDestX = MIN ((UINTN) DestX, LogoDestX);\r
554 NewDestY = MIN ((UINTN) DestY, LogoDestY);\r
555 NewWidth = MAX ((UINTN) DestX + Width, LogoDestX + LogoWidth) - NewDestX;\r
556 NewHeight = MAX ((UINTN) DestY + Height, LogoDestY + LogoHeight) - NewDestY;\r
557\r
558 LogoDestX = NewDestX;\r
559 LogoDestY = NewDestY;\r
560 LogoWidth = NewWidth;\r
561 LogoHeight = NewHeight;\r
562 }\r
563 }\r
564 }\r
565\r
566 FreePool (ImageData);\r
567\r
568 if (Badging == NULL) {\r
569 break;\r
570 }\r
571 }\r
572\r
573Done:\r
574 if (BootLogo == NULL || NumberOfLogos == 0) {\r
575 //\r
576 // No logo displayed.\r
577 //\r
578 if (Blt != NULL) {\r
579 FreePool (Blt);\r
580 }\r
581\r
582 return Status;\r
583 }\r
584\r
585 //\r
586 // Advertise displayed Logo information.\r
587 //\r
588 if (NumberOfLogos == 1) {\r
589 //\r
590 // Only one logo displayed, use its Blt buffer directly for BootLogo protocol.\r
591 //\r
592 LogoBlt = Blt;\r
593 Status = EFI_SUCCESS;\r
594 } else {\r
595 //\r
596 // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation.\r
597 //\r
598 if (Blt != NULL) {\r
599 FreePool (Blt);\r
600 }\r
601\r
602 //\r
603 // Ensure the LogoHeight * LogoWidth doesn't overflow\r
604 //\r
605 if (LogoHeight > DivU64x64Remainder ((UINTN) ~0, LogoWidth, NULL)) {\r
606 return EFI_UNSUPPORTED;\r
607 }\r
608 BufferSize = MultU64x64 (LogoWidth, LogoHeight);\r
609\r
610 //\r
611 // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow\r
612 //\r
613 if (BufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {\r
614 return EFI_UNSUPPORTED;\r
615 }\r
616\r
617 LogoBlt = AllocateZeroPool ((UINTN)BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
618 if (LogoBlt == NULL) {\r
619 return EFI_OUT_OF_RESOURCES;\r
620 }\r
621\r
622 if (GraphicsOutput != NULL) {\r
623 Status = GraphicsOutput->Blt (\r
624 GraphicsOutput,\r
625 LogoBlt,\r
626 EfiBltVideoToBltBuffer,\r
627 LogoDestX,\r
628 LogoDestY,\r
629 0,\r
630 0,\r
631 LogoWidth,\r
632 LogoHeight,\r
633 LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
634 );\r
635 } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
636 Status = UgaDraw->Blt (\r
637 UgaDraw,\r
638 (EFI_UGA_PIXEL *) LogoBlt,\r
639 EfiUgaVideoToBltBuffer,\r
640 LogoDestX,\r
641 LogoDestY,\r
642 0,\r
643 0,\r
644 LogoWidth,\r
645 LogoHeight,\r
646 LogoWidth * sizeof (EFI_UGA_PIXEL)\r
647 );\r
648 } else {\r
649 Status = EFI_UNSUPPORTED;\r
650 }\r
651 }\r
652\r
653 if (!EFI_ERROR (Status)) {\r
654 BootLogo->SetBootLogo (BootLogo, LogoBlt, LogoDestX, LogoDestY, LogoWidth, LogoHeight);\r
655 }\r
656 FreePool (LogoBlt);\r
657\r
658 return Status;\r
659}\r
660\r
661/**\r
662 Use SystemTable Conout to turn on video based Simple Text Out consoles. The\r
663 Simple Text Out screens will now be synced up with all non video output devices\r
664\r
665 @retval EFI_SUCCESS UGA devices are back in text mode and synced up.\r
666\r
667**/\r
668EFI_STATUS\r
669DisableQuietBoot (\r
670 VOID\r
671 )\r
672{\r
673\r
674 //\r
675 // Enable Cursor on Screen\r
676 //\r
677 gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
678 return EFI_SUCCESS;\r
679}\r
680\r