add PCD PcdUgaConsumeSupport to switch on/off EFI UGA Draw Protocol's consuming,...
[people/mcb30/edk2.git] / edk2 / MdeModulePkg / Library / GraphicsLib / Graphics.c
1 /**@file\r
2   Support for Basic Graphics operations.\r
3 \r
4   BugBug: Currently *.BMP files are supported. This will be replaced\r
5           when Tiano graphics format is supported.\r
6 \r
7 \r
8 Copyright (c) 2006, Intel Corporation\r
9 All rights reserved. This program and the accompanying materials\r
10 are licensed and made available under the terms and conditions of the BSD License\r
11 which accompanies this distribution.  The full text of the license may be found at\r
12 http://opensource.org/licenses/bsd-license.php\r
13 \r
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
16 \r
17 **/\r
18 \r
19 \r
20 #include <PiDxe.h>\r
21 \r
22 #include <Protocol/SimpleTextOut.h>\r
23 #include <Protocol/OEMBadging.h>\r
24 #include <Protocol/ConsoleControl.h>\r
25 #include <Protocol/GraphicsOutput.h>\r
26 #include <Protocol/FirmwareVolume2.h>\r
27 #include <Protocol/UgaDraw.h>\r
28 #include <Protocol/HiiFont.h>\r
29 #include <Protocol/HiiImage.h>\r
30 \r
31 #include <Guid/Bmp.h>\r
32 \r
33 #include <Library/GraphicsLib.h>\r
34 #include <Library/PrintLib.h>\r
35 #include <Library/BaseLib.h>\r
36 #include <Library/MemoryAllocationLib.h>\r
37 #include <Library/UefiBootServicesTableLib.h>\r
38 #include <Library/DebugLib.h>\r
39 #include <Library/BaseMemoryLib.h>\r
40 #include <Library/DxePiLib.h>\r
41 #include <Library/PcdLib.h>\r
42 \r
43 STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors[16] = {\r
44   { 0x00, 0x00, 0x00, 0x00 },\r
45   { 0x98, 0x00, 0x00, 0x00 },\r
46   { 0x00, 0x98, 0x00, 0x00 },\r
47   { 0x98, 0x98, 0x00, 0x00 },\r
48   { 0x00, 0x00, 0x98, 0x00 },\r
49   { 0x98, 0x00, 0x98, 0x00 },\r
50   { 0x00, 0x98, 0x98, 0x00 },\r
51   { 0x98, 0x98, 0x98, 0x00 },\r
52   { 0x10, 0x10, 0x10, 0x00 },\r
53   { 0xff, 0x10, 0x10, 0x00 },\r
54   { 0x10, 0xff, 0x10, 0x00 },\r
55   { 0xff, 0xff, 0x10, 0x00 },\r
56   { 0x10, 0x10, 0xff, 0x00 },\r
57   { 0xf0, 0x10, 0xff, 0x00 },\r
58   { 0x10, 0xff, 0xff, 0x00 },\r
59   { 0xff, 0xff, 0xff, 0x00 }\r
60 };\r
61 \r
62 \r
63 EFI_STATUS\r
64 GetGraphicsBitMapFromFV (\r
65   IN  EFI_GUID      *FileNameGuid,\r
66   OUT VOID          **Image,\r
67   OUT UINTN         *ImageSize\r
68   )\r
69 /*++\r
70 \r
71 Routine Description:\r
72 \r
73   Return the graphics image file named FileNameGuid into Image and return it's\r
74   size in ImageSize. All Firmware Volumes (FV) in the system are searched for the\r
75   file name.\r
76 \r
77 Arguments:\r
78 \r
79   FileNameGuid  - File Name of graphics file in the FV(s).\r
80 \r
81   Image         - Pointer to pointer to return graphics image.  If NULL, a\r
82                   buffer will be allocated.\r
83 \r
84   ImageSize     - Size of the graphics Image in bytes. Zero if no image found.\r
85 \r
86 \r
87 Returns:\r
88 \r
89   EFI_SUCCESS          - Image and ImageSize are valid.\r
90   EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size\r
91   EFI_NOT_FOUND        - FileNameGuid not found\r
92 \r
93 --*/\r
94 {\r
95   return GetGraphicsBitMapFromFVEx (NULL, FileNameGuid, Image, ImageSize);\r
96 }\r
97 \r
98 EFI_STATUS\r
99 GetGraphicsBitMapFromFVEx (\r
100   IN  EFI_HANDLE    ImageHandle,\r
101   IN  EFI_GUID      *FileNameGuid,\r
102   OUT VOID          **Image,\r
103   OUT UINTN         *ImageSize\r
104   )\r
105 /*++\r
106 \r
107 Routine Description:\r
108 \r
109   Return the graphics image file named FileNameGuid into Image and return it's\r
110   size in ImageSize. All Firmware Volumes (FV) in the system are searched for the\r
111   file name.\r
112 \r
113 Arguments:\r
114 \r
115   ImageHandle   - The driver image handle of the caller. The parameter is used to\r
116                   optimize the loading of the image file so that the FV from which\r
117                   the driver image is loaded will be tried first.\r
118 \r
119   FileNameGuid  - File Name of graphics file in the FV(s).\r
120 \r
121   Image         - Pointer to pointer to return graphics image.  If NULL, a\r
122                   buffer will be allocated.\r
123 \r
124   ImageSize     - Size of the graphics Image in bytes. Zero if no image found.\r
125 \r
126 \r
127 Returns:\r
128 \r
129   EFI_SUCCESS          - Image and ImageSize are valid.\r
130   EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size\r
131   EFI_NOT_FOUND        - FileNameGuid not found\r
132 \r
133 --*/\r
134 {\r
135   return PiLibGetSectionFromAnyFv (\r
136            FileNameGuid,\r
137            EFI_SECTION_RAW,\r
138            0,\r
139            Image,\r
140            ImageSize\r
141            );\r
142 }\r
143 \r
144 \r
145 EFI_STATUS\r
146 ConvertBmpToGopBlt (\r
147   IN  VOID      *BmpImage,\r
148   IN  UINTN     BmpImageSize,\r
149   IN OUT VOID   **GopBlt,\r
150   IN OUT UINTN  *GopBltSize,\r
151   OUT UINTN     *PixelHeight,\r
152   OUT UINTN     *PixelWidth\r
153   )\r
154 /*++\r
155 \r
156 Routine Description:\r
157 \r
158   Convert a *.BMP graphics image to a GOP/UGA blt buffer. If a NULL Blt buffer\r
159   is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt\r
160   buffer is passed in it will be used if it is big enough.\r
161 \r
162 Arguments:\r
163 \r
164   BmpImage      - Pointer to BMP file\r
165 \r
166   BmpImageSize  - Number of bytes in BmpImage\r
167 \r
168   GopBlt        - Buffer containing GOP version of BmpImage.\r
169 \r
170   GopBltSize    - Size of GopBlt in bytes.\r
171 \r
172   PixelHeight   - Height of GopBlt/BmpImage in pixels\r
173 \r
174   PixelWidth    - Width of GopBlt/BmpImage in pixels\r
175 \r
176 \r
177 Returns:\r
178 \r
179   EFI_SUCCESS           - GopBlt and GopBltSize are returned.\r
180   EFI_UNSUPPORTED       - BmpImage is not a valid *.BMP image\r
181   EFI_BUFFER_TOO_SMALL  - The passed in GopBlt buffer is not big enough.\r
182                           GopBltSize will contain the required size.\r
183   EFI_OUT_OF_RESOURCES  - No enough buffer to allocate\r
184 \r
185 --*/\r
186 {\r
187   UINT8             *Image;\r
188   UINT8             *ImageHeader;\r
189   BMP_IMAGE_HEADER  *BmpHeader;\r
190   BMP_COLOR_MAP     *BmpColorMap;\r
191   EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
192   EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
193   UINTN             BltBufferSize;\r
194   UINTN             Index;\r
195   UINTN             Height;\r
196   UINTN             Width;\r
197   UINTN             ImageIndex;\r
198   BOOLEAN           IsAllocated;\r
199 \r
200   BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;\r
201   if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {\r
202     return EFI_UNSUPPORTED;\r
203   }\r
204 \r
205   if (BmpHeader->CompressionType != 0) {\r
206     return EFI_UNSUPPORTED;\r
207   }\r
208 \r
209   //\r
210   // Calculate Color Map offset in the image.\r
211   //\r
212   Image       = BmpImage;\r
213   BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));\r
214 \r
215   //\r
216   // Calculate graphics image data address in the image\r
217   //\r
218   Image         = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;\r
219   ImageHeader   = Image;\r
220 \r
221   BltBufferSize = BmpHeader->PixelWidth * BmpHeader->PixelHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
222   IsAllocated   = FALSE;\r
223   if (*GopBlt == NULL) {\r
224     *GopBltSize = BltBufferSize;\r
225     *GopBlt     = AllocatePool (*GopBltSize);\r
226     IsAllocated = TRUE;\r
227     if (*GopBlt == NULL) {\r
228       return EFI_OUT_OF_RESOURCES;\r
229     }\r
230   } else {\r
231     if (*GopBltSize < BltBufferSize) {\r
232       *GopBltSize = BltBufferSize;\r
233       return EFI_BUFFER_TOO_SMALL;\r
234     }\r
235   }\r
236 \r
237   *PixelWidth   = BmpHeader->PixelWidth;\r
238   *PixelHeight  = BmpHeader->PixelHeight;\r
239 \r
240   //\r
241   // Convert image from BMP to Blt buffer format\r
242   //\r
243   BltBuffer = *GopBlt;\r
244   for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {\r
245     Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];\r
246     for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {\r
247       switch (BmpHeader->BitPerPixel) {\r
248       case 1:\r
249         //\r
250         // Convert 1bit BMP to 24-bit color\r
251         //\r
252         for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {\r
253           Blt->Red    = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;\r
254           Blt->Green  = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;\r
255           Blt->Blue   = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;\r
256           Blt++;\r
257           Width++;\r
258         }\r
259 \r
260         Blt --;\r
261         Width --;\r
262         break;\r
263 \r
264       case 4:\r
265         //\r
266         // Convert BMP Palette to 24-bit color\r
267         //\r
268         Index       = (*Image) >> 4;\r
269         Blt->Red    = BmpColorMap[Index].Red;\r
270         Blt->Green  = BmpColorMap[Index].Green;\r
271         Blt->Blue   = BmpColorMap[Index].Blue;\r
272         if (Width < (BmpHeader->PixelWidth - 1)) {\r
273           Blt++;\r
274           Width++;\r
275           Index       = (*Image) & 0x0f;\r
276           Blt->Red    = BmpColorMap[Index].Red;\r
277           Blt->Green  = BmpColorMap[Index].Green;\r
278           Blt->Blue   = BmpColorMap[Index].Blue;\r
279         }\r
280         break;\r
281 \r
282       case 8:\r
283         //\r
284         // Convert BMP Palette to 24-bit color\r
285         //\r
286         Blt->Red    = BmpColorMap[*Image].Red;\r
287         Blt->Green  = BmpColorMap[*Image].Green;\r
288         Blt->Blue   = BmpColorMap[*Image].Blue;\r
289         break;\r
290 \r
291       case 24:\r
292         Blt->Blue   = *Image++;\r
293         Blt->Green  = *Image++;\r
294         Blt->Red    = *Image;\r
295         break;\r
296 \r
297       default:\r
298         if (IsAllocated) {\r
299           gBS->FreePool (*GopBlt);\r
300           *GopBlt = NULL;\r
301         }\r
302         return EFI_UNSUPPORTED;\r
303         break;\r
304       };\r
305 \r
306     }\r
307 \r
308     ImageIndex = (UINTN) (Image - ImageHeader);\r
309     if ((ImageIndex % 4) != 0) {\r
310       //\r
311       // Bmp Image starts each row on a 32-bit boundary!\r
312       //\r
313       Image = Image + (4 - (ImageIndex % 4));\r
314     }\r
315   }\r
316 \r
317   return EFI_SUCCESS;\r
318 }\r
319 \r
320 \r
321 EFI_STATUS\r
322 LockKeyboards (\r
323   IN  CHAR16    *Password\r
324   )\r
325 /*++\r
326 \r
327 Routine Description:\r
328   Use Console Control Protocol to lock the Console In Spliter virtual handle.\r
329   This is the ConInHandle and ConIn handle in the EFI system table. All key\r
330   presses will be ignored until the Password is typed in. The only way to\r
331   disable the password is to type it in to a ConIn device.\r
332 \r
333 Arguments:\r
334   Password - Password used to lock ConIn device\r
335 \r
336 \r
337 Returns:\r
338 \r
339   EFI_SUCCESS     - ConsoleControl has been flipped to graphics and logo\r
340                           displayed.\r
341   EFI_UNSUPPORTED - Logo not found\r
342 \r
343 --*/\r
344 {\r
345   EFI_STATUS                    Status;\r
346   EFI_CONSOLE_CONTROL_PROTOCOL  *ConsoleControl;\r
347 \r
348   Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
349   if (EFI_ERROR (Status)) {\r
350     return EFI_UNSUPPORTED;\r
351   }\r
352 \r
353   Status = ConsoleControl->LockStdIn (ConsoleControl, Password);\r
354   return Status;\r
355 }\r
356 \r
357 \r
358 EFI_STATUS\r
359 EnableQuietBoot (\r
360   IN  EFI_GUID  *LogoFile\r
361   )\r
362 /*++\r
363 \r
364 Routine Description:\r
365 \r
366   Use Console Control to turn off UGA based Simple Text Out consoles from going\r
367   to the UGA device. Put up LogoFile on every UGA device that is a console\r
368 \r
369 Arguments:\r
370 \r
371   LogoFile - File name of logo to display on the center of the screen.\r
372 \r
373 \r
374 Returns:\r
375 \r
376   EFI_SUCCESS           - ConsoleControl has been flipped to graphics and logo\r
377                           displayed.\r
378   EFI_UNSUPPORTED       - Logo not found\r
379 \r
380 --*/\r
381 {\r
382   return EnableQuietBootEx (LogoFile, NULL);\r
383 }\r
384 \r
385 EFI_STATUS\r
386 EnableQuietBootEx (\r
387   IN  EFI_GUID    *LogoFile,\r
388   IN  EFI_HANDLE  ImageHandle\r
389   )\r
390 /*++\r
391 \r
392 Routine Description:\r
393 \r
394   Use Console Control to turn off GOP/UGA based Simple Text Out consoles from going\r
395   to the GOP/UGA device. Put up LogoFile on every GOP/UGA device that is a console\r
396 \r
397 Arguments:\r
398 \r
399   LogoFile    - File name of logo to display on the center of the screen.\r
400   ImageHandle - The driver image handle of the caller. The parameter is used to\r
401                 optimize the loading of the logo file so that the FV from which\r
402                 the driver image is loaded will be tried first.\r
403 \r
404 \r
405 Returns:\r
406 \r
407   EFI_SUCCESS           - ConsoleControl has been flipped to graphics and logo\r
408                           displayed.\r
409   EFI_UNSUPPORTED       - Logo not found\r
410 \r
411 --*/\r
412 {\r
413   EFI_STATUS                    Status;\r
414   EFI_CONSOLE_CONTROL_PROTOCOL  *ConsoleControl;\r
415   EFI_OEM_BADGING_PROTOCOL      *Badging;\r
416   UINT32                        SizeOfX;\r
417   UINT32                        SizeOfY;\r
418   INTN                          DestX;\r
419   INTN                          DestY;\r
420   UINT8                         *ImageData;\r
421   UINTN                         ImageSize;\r
422   UINTN                         BltSize;\r
423   UINT32                        Instance;\r
424   EFI_BADGING_FORMAT            Format;\r
425   EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;\r
426   UINTN                         CoordinateX;\r
427   UINTN                         CoordinateY;\r
428   UINTN                         Height;\r
429   UINTN                         Width;\r
430   EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
431   EFI_UGA_DRAW_PROTOCOL         *UgaDraw;\r
432   UINT32                        ColorDepth;\r
433   UINT32                        RefreshRate;\r
434   EFI_GRAPHICS_OUTPUT_PROTOCOL  *GraphicsOutput;\r
435 \r
436   Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID**)&ConsoleControl);\r
437   if (EFI_ERROR (Status)) {\r
438     return EFI_UNSUPPORTED;\r
439   }\r
440 \r
441   UgaDraw = NULL;\r
442   //\r
443   // Try to open GOP first\r
444   //\r
445   Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID**)&GraphicsOutput);\r
446   if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
447     GraphicsOutput = NULL;\r
448     //\r
449     // Open GOP failed, try to open UGwhA\r
450     //\r
451     Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID**)&UgaDraw);\r
452   }\r
453   if (EFI_ERROR (Status)) {\r
454     return EFI_UNSUPPORTED;\r
455   }\r
456 \r
457   Badging = NULL;\r
458   Status  = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID**)&Badging);\r
459 \r
460   Status = ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics);\r
461   if (EFI_ERROR (Status)) {\r
462     return EFI_UNSUPPORTED;\r
463   }\r
464 \r
465   if (GraphicsOutput != NULL) {\r
466     SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
467     SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
468   } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
469     Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);\r
470     if (EFI_ERROR (Status)) {\r
471       return EFI_UNSUPPORTED;\r
472     }\r
473   }\r
474 \r
475   Instance = 0;\r
476   while (1) {\r
477     ImageData = NULL;\r
478     ImageSize = 0;\r
479 \r
480     if (Badging != NULL) {\r
481       Status = Badging->GetImage (\r
482                           Badging,\r
483                           &Instance,\r
484                           &Format,\r
485                           &ImageData,\r
486                           &ImageSize,\r
487                           &Attribute,\r
488                           &CoordinateX,\r
489                           &CoordinateY\r
490                           );\r
491       if (EFI_ERROR (Status)) {\r
492         return Status;\r
493       }\r
494 \r
495       //\r
496       // Currently only support BMP format\r
497       //\r
498       if (Format != EfiBadgingFormatBMP) {\r
499         gBS->FreePool (ImageData);\r
500         continue;\r
501       }\r
502     } else {\r
503       Status = GetGraphicsBitMapFromFVEx (ImageHandle, LogoFile, (VOID **) &ImageData, &ImageSize);\r
504       if (EFI_ERROR (Status)) {\r
505         return EFI_UNSUPPORTED;\r
506       }\r
507 \r
508       CoordinateX = 0;\r
509       CoordinateY = 0;\r
510       Attribute   = EfiBadgingDisplayAttributeCenter;\r
511     }\r
512 \r
513     Blt = NULL;\r
514     Status = ConvertBmpToGopBlt (\r
515               ImageData,\r
516               ImageSize,\r
517               (VOID**)&Blt,\r
518               &BltSize,\r
519               &Height,\r
520               &Width\r
521               );\r
522     if (EFI_ERROR (Status)) {\r
523       gBS->FreePool (ImageData);\r
524       if (Badging == NULL) {\r
525         return Status;\r
526       } else {\r
527         continue;\r
528       }\r
529     }\r
530 \r
531     switch (Attribute) {\r
532     case EfiBadgingDisplayAttributeLeftTop:\r
533       DestX = CoordinateX;\r
534       DestY = CoordinateY;\r
535       break;\r
536 \r
537     case EfiBadgingDisplayAttributeCenterTop:\r
538       DestX = (SizeOfX - Width) / 2;\r
539       DestY = CoordinateY;\r
540       break;\r
541 \r
542     case EfiBadgingDisplayAttributeRightTop:\r
543       DestX = (SizeOfX - Width - CoordinateX);\r
544       DestY = CoordinateY;;\r
545       break;\r
546 \r
547     case EfiBadgingDisplayAttributeCenterRight:\r
548       DestX = (SizeOfX - Width - CoordinateX);\r
549       DestY = (SizeOfY - Height) / 2;\r
550       break;\r
551 \r
552     case EfiBadgingDisplayAttributeRightBottom:\r
553       DestX = (SizeOfX - Width - CoordinateX);\r
554       DestY = (SizeOfY - Height - CoordinateY);\r
555       break;\r
556 \r
557     case EfiBadgingDisplayAttributeCenterBottom:\r
558       DestX = (SizeOfX - Width) / 2;\r
559       DestY = (SizeOfY - Height - CoordinateY);\r
560       break;\r
561 \r
562     case EfiBadgingDisplayAttributeLeftBottom:\r
563       DestX = CoordinateX;\r
564       DestY = (SizeOfY - Height - CoordinateY);\r
565       break;\r
566 \r
567     case EfiBadgingDisplayAttributeCenterLeft:\r
568       DestX = CoordinateX;\r
569       DestY = (SizeOfY - Height) / 2;\r
570       break;\r
571 \r
572     case EfiBadgingDisplayAttributeCenter:\r
573       DestX = (SizeOfX - Width) / 2;\r
574       DestY = (SizeOfY - Height) / 2;\r
575       break;\r
576 \r
577     default:\r
578       DestX = CoordinateX;\r
579       DestY = CoordinateY;\r
580       break;\r
581     }\r
582 \r
583     if ((DestX >= 0) && (DestY >= 0)) {\r
584       if (GraphicsOutput != NULL) {\r
585         Status = GraphicsOutput->Blt (\r
586                             GraphicsOutput,\r
587                             Blt,\r
588                             EfiBltBufferToVideo,\r
589                             0,\r
590                             0,\r
591                             (UINTN) DestX,\r
592                             (UINTN) DestY,\r
593                             Width,\r
594                             Height,\r
595                             Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
596                             );\r
597       } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
598         Status = UgaDraw->Blt (\r
599                             UgaDraw,\r
600                             (EFI_UGA_PIXEL *) Blt,\r
601                             EfiUgaBltBufferToVideo,\r
602                             0,\r
603                             0,\r
604                             (UINTN) DestX,\r
605                             (UINTN) DestY,\r
606                             Width,\r
607                             Height,\r
608                             Width * sizeof (EFI_UGA_PIXEL)\r
609                             );\r
610       }\r
611     }\r
612 \r
613     gBS->FreePool (ImageData);\r
614     gBS->FreePool (Blt);\r
615 \r
616     if (Badging == NULL) {\r
617       break;\r
618     }\r
619   }\r
620 \r
621   return Status;\r
622 }\r
623 \r
624 \r
625 EFI_STATUS\r
626 DisableQuietBoot (\r
627   VOID\r
628   )\r
629 /*++\r
630 \r
631 Routine Description:\r
632 \r
633   Use Console Control to turn on GOP/UGA based Simple Text Out consoles. The GOP/UGA\r
634   Simple Text Out screens will now be synced up with all non GOP/UGA output devices\r
635 \r
636 Arguments:\r
637 \r
638   NONE\r
639 \r
640 Returns:\r
641 \r
642   EFI_SUCCESS           - GOP/UGA devices are back in text mode and synced up.\r
643   EFI_UNSUPPORTED       - Logo not found\r
644 \r
645 --*/\r
646 {\r
647   EFI_STATUS                    Status;\r
648   EFI_CONSOLE_CONTROL_PROTOCOL  *ConsoleControl;\r
649 \r
650   Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
651   if (EFI_ERROR (Status)) {\r
652     return EFI_UNSUPPORTED;\r
653   }\r
654 \r
655   return ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);\r
656 }\r
657 \r
658 UINTN\r
659 _IPrint (\r
660   IN EFI_GRAPHICS_OUTPUT_PROTOCOL     *GraphicsOutput,\r
661   IN EFI_UGA_DRAW_PROTOCOL            *UgaDraw,\r
662   IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *Sto,\r
663   IN UINTN                            X,\r
664   IN UINTN                            Y,\r
665   IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *Foreground,\r
666   IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *Background,\r
667   IN CHAR16                           *fmt,\r
668   IN VA_LIST                          args\r
669   )\r
670 /*++\r
671 \r
672 Routine Description:\r
673 \r
674   Display string worker for: Print, PrintAt, IPrint, IPrintAt\r
675 \r
676 Arguments:\r
677 \r
678   GraphicsOutput  - Graphics output protocol interface\r
679 \r
680   UgaDraw         - UGA draw protocol interface\r
681 \r
682   Sto             - Simple text out protocol interface\r
683 \r
684   X               - X coordinate to start printing\r
685 \r
686   Y               - Y coordinate to start printing\r
687 \r
688   Foreground      - Foreground color\r
689 \r
690   Background      - Background color\r
691 \r
692   fmt             - Format string\r
693 \r
694   args            - Print arguments\r
695 \r
696 Returns:\r
697 \r
698   EFI_SUCCESS             -  success\r
699   EFI_OUT_OF_RESOURCES    -  out of resources\r
700 \r
701 --*/\r
702 {\r
703   VOID                           *Buffer;\r
704   EFI_STATUS                     Status;\r
705   UINTN                          Index;\r
706   CHAR16                         *UnicodeWeight;\r
707   UINT32                         HorizontalResolution;\r
708   UINT32                         VerticalResolution;\r
709   UINT32                         ColorDepth;\r
710   UINT32                         RefreshRate;\r
711   UINTN                          BufferLen;\r
712   UINTN                          LineBufferLen;\r
713   EFI_HII_FONT_PROTOCOL          *HiiFont;\r
714   EFI_IMAGE_OUTPUT               *Blt;\r
715   EFI_FONT_DISPLAY_INFO          *FontInfo;\r
716 \r
717   //\r
718   // For now, allocate an arbitrarily long buffer\r
719   //\r
720   Buffer = AllocateZeroPool (0x10000);\r
721   if (Buffer == NULL) {\r
722     return EFI_OUT_OF_RESOURCES;\r
723   }\r
724 \r
725   HorizontalResolution  = 0;\r
726   VerticalResolution    = 0;\r
727   Blt                   = NULL;\r
728   FontInfo              = NULL;\r
729 \r
730   if (GraphicsOutput != NULL) {\r
731     HorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;\r
732     VerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;\r
733   } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
734     UgaDraw->GetMode (UgaDraw, &HorizontalResolution, &VerticalResolution, &ColorDepth, &RefreshRate);\r
735   } else {\r
736     Status = EFI_UNSUPPORTED;\r
737     goto Error;\r
738   }\r
739 \r
740   ASSERT ((HorizontalResolution != 0) && (VerticalResolution !=0));\r
741 \r
742   ASSERT (GraphicsOutput != NULL);\r
743   Status = gBS->LocateProtocol (&gEfiHiiFontProtocolGuid, NULL, (VOID **) &HiiFont);\r
744   if (EFI_ERROR (Status)) {\r
745     goto Error;\r
746   }\r
747 \r
748   UnicodeVSPrint (Buffer, 0x10000, fmt, args);\r
749 \r
750   UnicodeWeight = (CHAR16 *) Buffer;\r
751 \r
752   for (Index = 0; UnicodeWeight[Index] != 0; Index++) {\r
753     if (UnicodeWeight[Index] == CHAR_BACKSPACE ||\r
754         UnicodeWeight[Index] == CHAR_LINEFEED  ||\r
755         UnicodeWeight[Index] == CHAR_CARRIAGE_RETURN) {\r
756       UnicodeWeight[Index] = 0;\r
757     }\r
758   }\r
759 \r
760   BufferLen = StrLen (Buffer);\r
761 \r
762 \r
763   LineBufferLen = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * HorizontalResolution * EFI_GLYPH_HEIGHT;\r
764   if (EFI_GLYPH_WIDTH * EFI_GLYPH_HEIGHT * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * BufferLen > LineBufferLen) {\r
765      Status = EFI_INVALID_PARAMETER;\r
766      goto Error;\r
767   }\r
768 \r
769   Blt = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
770   if (Blt == NULL) {\r
771     Status = EFI_OUT_OF_RESOURCES;\r
772     goto Error;\r
773   }\r
774 \r
775   Blt->Width        = (UINT16) (HorizontalResolution);\r
776   Blt->Height       = (UINT16) (VerticalResolution);\r
777   Blt->Image.Screen = GraphicsOutput;\r
778 \r
779   FontInfo = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO));\r
780   if (FontInfo == NULL) {\r
781     Status = EFI_OUT_OF_RESOURCES;\r
782     goto Error;\r
783   }\r
784   if (Foreground != NULL) {\r
785     CopyMem (&FontInfo->ForegroundColor, Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
786   } else {\r
787     CopyMem (\r
788       &FontInfo->ForegroundColor,\r
789       &mEfiColors[Sto->Mode->Attribute & 0x0f],\r
790       sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
791       );\r
792   }\r
793   if (Background != NULL) {\r
794     CopyMem (&FontInfo->BackgroundColor, Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
795   } else {\r
796     CopyMem (\r
797       &FontInfo->BackgroundColor,\r
798       &mEfiColors[Sto->Mode->Attribute >> 4],\r
799       sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
800       );\r
801   }\r
802 \r
803   Status = HiiFont->StringToImage (\r
804                        HiiFont,\r
805                        EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_DIRECT_TO_SCREEN,\r
806                        Buffer,\r
807                        FontInfo,\r
808                        &Blt,\r
809                        X,\r
810                        Y,\r
811                        NULL,\r
812                        NULL,\r
813                        NULL\r
814                        );\r
815 \r
816 \r
817 Error:\r
818   SafeFreePool (Blt);\r
819   SafeFreePool (FontInfo);\r
820   gBS->FreePool (Buffer);\r
821   return Status;\r
822 }\r
823 \r
824 UINTN\r
825 PrintXY (\r
826   IN UINTN                            X,\r
827   IN UINTN                            Y,\r
828   IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *ForeGround, OPTIONAL\r
829   IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *BackGround, OPTIONAL\r
830   IN CHAR16                           *Fmt,\r
831   ...\r
832   )\r
833 /*++\r
834 \r
835 Routine Description:\r
836 \r
837     Prints a formatted unicode string to the default console\r
838 \r
839 Arguments:\r
840 \r
841     X           - X coordinate to start printing\r
842 \r
843     Y           - Y coordinate to start printing\r
844 \r
845     ForeGround  - Foreground color\r
846 \r
847     BackGround  - Background color\r
848 \r
849     Fmt         - Format string\r
850 \r
851     ...         - Print arguments\r
852 \r
853 Returns:\r
854 \r
855     Length of string printed to the console\r
856 \r
857 --*/\r
858 {\r
859   EFI_HANDLE                    Handle;\r
860   EFI_GRAPHICS_OUTPUT_PROTOCOL  *GraphicsOutput;\r
861   EFI_UGA_DRAW_PROTOCOL         *UgaDraw;\r
862   EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *Sto;\r
863   EFI_STATUS                    Status;\r
864   VA_LIST                       Args;\r
865 \r
866   VA_START (Args, Fmt);\r
867 \r
868   Handle = gST->ConsoleOutHandle;\r
869 \r
870   Status = gBS->HandleProtocol (\r
871                   Handle,\r
872                   &gEfiGraphicsOutputProtocolGuid,\r
873                   (VOID**)&GraphicsOutput\r
874                   );\r
875 \r
876   UgaDraw = NULL;\r
877   if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
878     GraphicsOutput = NULL;\r
879 \r
880     Status = gBS->HandleProtocol (\r
881                     Handle,\r
882                     &gEfiUgaDrawProtocolGuid,\r
883                     (VOID**)&UgaDraw\r
884                     );\r
885   }\r
886   if (EFI_ERROR (Status)) {\r
887     return Status;\r
888   }\r
889 \r
890   Status = gBS->HandleProtocol (\r
891                   Handle,\r
892                   &gEfiSimpleTextOutProtocolGuid,\r
893                   (VOID**)&Sto\r
894                   );\r
895 \r
896   if (EFI_ERROR (Status)) {\r
897     return Status;\r
898   }\r
899 \r
900   return _IPrint (GraphicsOutput, UgaDraw, Sto, X, Y, ForeGround, BackGround, Fmt, Args);\r
901 }\r
902 \r