]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/UefiLib/UefiLibPrint.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdePkg / Library / UefiLib / UefiLibPrint.c
index a95178c8792c721758fbb0f403f1fdd00577c9d6..39edeb7283dd7af85c02c3398849df28070f9395 100644 (file)
 /** @file\r
-  Mde UEFI library API implemention.\r
+  Mde UEFI library API implementation.\r
   Print to StdErr or ConOut defined in EFI_SYSTEM_TABLE\r
 \r
-  Copyright (c) 2007, Intel Corporation<BR>\r
-  All rights reserved. This program and the accompanying materials                          \r
-  are licensed and made available under the terms and conditions of the BSD License         \r
-  which accompanies this distribution.  The full text of the license may be found at        \r
-  http://opensource.org/licenses/bsd-license.php                                            \r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
-/** \r
-  Internal function which prints a formatted Unicode string to the console output device \r
+#include "UefiLibInternal.h"\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_GRAPHICS_OUTPUT_BLT_PIXEL  mEfiColors[16] = {\r
+  { 0x00, 0x00, 0x00, 0x00 },\r
+  { 0x98, 0x00, 0x00, 0x00 },\r
+  { 0x00, 0x98, 0x00, 0x00 },\r
+  { 0x98, 0x98, 0x00, 0x00 },\r
+  { 0x00, 0x00, 0x98, 0x00 },\r
+  { 0x98, 0x00, 0x98, 0x00 },\r
+  { 0x00, 0x98, 0x98, 0x00 },\r
+  { 0x98, 0x98, 0x98, 0x00 },\r
+  { 0x10, 0x10, 0x10, 0x00 },\r
+  { 0xff, 0x10, 0x10, 0x00 },\r
+  { 0x10, 0xff, 0x10, 0x00 },\r
+  { 0xff, 0xff, 0x10, 0x00 },\r
+  { 0x10, 0x10, 0xff, 0x00 },\r
+  { 0xf0, 0x10, 0xff, 0x00 },\r
+  { 0x10, 0xff, 0xff, 0x00 },\r
+  { 0xff, 0xff, 0xff, 0x00 }\r
+};\r
+\r
+/**\r
+  Internal function which prints a formatted Unicode string to the console output device\r
   specified by Console\r
 \r
-  This function prints a formatted Unicode string to the console output device \r
-  specified by Console and returns the number of Unicode characters that printed \r
-  to it.  If the length of the formatted Unicode string is greater than PcdUefiLibMaxPrintBufferSize, \r
+  This function prints a formatted Unicode string to the console output device\r
+  specified by Console and returns the number of Unicode characters that printed\r
+  to it.  If the length of the formatted Unicode string is greater than PcdUefiLibMaxPrintBufferSize,\r
   then only the first PcdUefiLibMaxPrintBufferSize characters are sent to Console.\r
-\r
-  @param Format   Null-terminated Unicode format string.\r
-  @param Console  The output console.\r
-  @param Marker   VA_LIST marker for the variable argument list.\r
-  \r
   If Format is NULL, then ASSERT().\r
   If Format is not aligned on a 16-bit boundary, then ASSERT().\r
 \r
-**/\r
+  @param Format   A Null-terminated Unicode format string.\r
+  @param Console  The output console.\r
+  @param Marker   A VA_LIST marker for the variable argument list.\r
 \r
-STATIC\r
+  @return The number of Unicode characters in the produced\r
+          output buffer, not including the Null-terminator.\r
+**/\r
 UINTN\r
 InternalPrint (\r
-  IN  CONST CHAR16                  *Format,\r
-  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *Console,\r
-  IN  VA_LIST                       Marker\r
+  IN  CONST CHAR16                     *Format,\r
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *Console,\r
+  IN  VA_LIST                          Marker\r
   )\r
 {\r
-  UINTN   Return;\r
-  CHAR16  *Buffer;\r
-  UINTN   BufferSize;\r
+  EFI_STATUS  Status;\r
+  UINTN       Return;\r
+  CHAR16      *Buffer;\r
+  UINTN       BufferSize;\r
 \r
   ASSERT (Format != NULL);\r
-  ASSERT (((UINTN) Format & 0x01) == 0);\r
+  ASSERT (((UINTN)Format & BIT0) == 0);\r
+  ASSERT (Console != NULL);\r
 \r
   BufferSize = (PcdGet32 (PcdUefiLibMaxPrintBufferSize) + 1) * sizeof (CHAR16);\r
-  \r
-  Buffer = (CHAR16 *) AllocatePool(BufferSize);\r
+\r
+  Buffer = (CHAR16 *)AllocatePool (BufferSize);\r
   ASSERT (Buffer != NULL);\r
 \r
   Return = UnicodeVSPrint (Buffer, BufferSize, Format, Marker);\r
 \r
-  if (Console != NULL) {\r
+  if ((Console != NULL) && (Return > 0)) {\r
     //\r
     // To be extra safe make sure Console has been initialized\r
     //\r
-    Console->OutputString (Console, Buffer);\r
+    Status = Console->OutputString (Console, Buffer);\r
+    if (EFI_ERROR (Status)) {\r
+      Return = 0;\r
+    }\r
   }\r
 \r
   FreePool (Buffer);\r
 \r
-  return Return;  \r
+  return Return;\r
 }\r
 \r
-/** \r
-  Prints a formatted Unicode string to the console output device specified by \r
+/**\r
+  Prints a formatted Unicode string to the console output device specified by\r
   ConOut defined in the EFI_SYSTEM_TABLE.\r
 \r
-  This function prints a formatted Unicode string to the console output device \r
-  specified by ConOut in EFI_SYSTEM_TABLE and returns the number of Unicode \r
-  characters that printed to ConOut.  If the length of the formatted Unicode \r
-  string is greater than PcdUefiLibMaxPrintBufferSize, then only the first \r
+  This function prints a formatted Unicode string to the console output device\r
+  specified by ConOut in EFI_SYSTEM_TABLE and returns the number of Unicode\r
+  characters that printed to ConOut.  If the length of the formatted Unicode\r
+  string is greater than PcdUefiLibMaxPrintBufferSize, then only the first\r
   PcdUefiLibMaxPrintBufferSize characters are sent to ConOut.\r
-\r
-  @param Format   Null-terminated Unicode format string.\r
-  @param ...      VARARG list consumed to process Format.\r
   If Format is NULL, then ASSERT().\r
   If Format is not aligned on a 16-bit boundary, then ASSERT().\r
+  If gST->ConOut is NULL, then ASSERT().\r
+\r
+  @param Format   A Null-terminated Unicode format string.\r
+  @param ...      A Variable argument list whose contents are accessed based\r
+                  on the format string specified by Format.\r
+\r
+  @return The number of Unicode characters printed to ConOut.\r
 \r
 **/\r
 UINTN\r
@@ -88,8 +111,8 @@ Print (
   ...\r
   )\r
 {\r
-  VA_LIST Marker;\r
-  UINTN   Return;\r
+  VA_LIST  Marker;\r
+  UINTN    Return;\r
 \r
   VA_START (Marker, Format);\r
 \r
@@ -100,23 +123,26 @@ Print (
   return Return;\r
 }\r
 \r
-/** \r
-  Prints a formatted Unicode string to the console output device specified by \r
+/**\r
+  Prints a formatted Unicode string to the console output device specified by\r
   StdErr defined in the EFI_SYSTEM_TABLE.\r
 \r
-  This function prints a formatted Unicode string to the console output device \r
-  specified by StdErr in EFI_SYSTEM_TABLE and returns the number of Unicode \r
-  characters that printed to StdErr.  If the length of the formatted Unicode \r
-  string is greater than PcdUefiLibMaxPrintBufferSize, then only the first \r
+  This function prints a formatted Unicode string to the console output device\r
+  specified by StdErr in EFI_SYSTEM_TABLE and returns the number of Unicode\r
+  characters that printed to StdErr.  If the length of the formatted Unicode\r
+  string is greater than PcdUefiLibMaxPrintBufferSize, then only the first\r
   PcdUefiLibMaxPrintBufferSize characters are sent to StdErr.\r
-\r
-  @param Format   Null-terminated Unicode format string.\r
-  @param ...      VARARG list consumed to process Format.\r
   If Format is NULL, then ASSERT().\r
   If Format is not aligned on a 16-bit boundary, then ASSERT().\r
+  If gST->StdErr is NULL, then ASSERT().\r
 \r
-**/\r
+  @param Format   A Null-terminated Unicode format string.\r
+  @param ...      Variable argument list whose contents are accessed based\r
+                  on the format string specified by Format.\r
+\r
+  @return The number of Unicode characters printed to StdErr.\r
 \r
+**/\r
 UINTN\r
 EFIAPI\r
 ErrorPrint (\r
@@ -124,53 +150,55 @@ ErrorPrint (
   ...\r
   )\r
 {\r
-  VA_LIST Marker;\r
-  UINTN   Return;\r
+  VA_LIST  Marker;\r
+  UINTN    Return;\r
 \r
   VA_START (Marker, Format);\r
 \r
-  Return = InternalPrintFormat, gST->StdErr, Marker);\r
+  Return = InternalPrint (Format, gST->StdErr, Marker);\r
 \r
   VA_END (Marker);\r
 \r
   return Return;\r
 }\r
 \r
-\r
-/** \r
-  Internal function which prints a formatted ASCII string to the console output device \r
+/**\r
+  Internal function which prints a formatted ASCII string to the console output device\r
   specified by Console\r
 \r
-  This function prints a formatted ASCII string to the console output device \r
-  specified by Console and returns the number of ASCII characters that printed \r
-  to it.  If the length of the formatted ASCII string is greater than PcdUefiLibMaxPrintBufferSize, \r
+  This function prints a formatted ASCII string to the console output device\r
+  specified by Console and returns the number of ASCII characters that printed\r
+  to it.  If the length of the formatted ASCII string is greater than PcdUefiLibMaxPrintBufferSize,\r
   then only the first PcdUefiLibMaxPrintBufferSize characters are sent to Console.\r
 \r
-  @param Format   Null-terminated ASCII format string.\r
+  If Format is NULL, then ASSERT().\r
+\r
+  @param Format   A Null-terminated ASCII format string.\r
   @param Console  The output console.\r
   @param Marker   VA_LIST marker for the variable argument list.\r
-  \r
-  If Format is NULL, then ASSERT().\r
-  \r
-**/\r
 \r
-STATIC\r
+  @return The number of Unicode characters in the produced\r
+          output buffer not including the Null-terminator.\r
+\r
+**/\r
 UINTN\r
 AsciiInternalPrint (\r
-  IN  CONST CHAR8                   *Format,\r
-  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *Console,\r
-  IN  VA_LIST                       Marker\r
+  IN  CONST CHAR8                      *Format,\r
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *Console,\r
+  IN  VA_LIST                          Marker\r
   )\r
 {\r
-  UINTN   Return;\r
-  CHAR16  *Buffer;\r
-  UINTN   BufferSize;\r
+  EFI_STATUS  Status;\r
+  UINTN       Return;\r
+  CHAR16      *Buffer;\r
+  UINTN       BufferSize;\r
 \r
   ASSERT (Format != NULL);\r
+  ASSERT (Console != NULL);\r
 \r
   BufferSize = (PcdGet32 (PcdUefiLibMaxPrintBufferSize) + 1) * sizeof (CHAR16);\r
-  \r
-  Buffer = (CHAR16 *) AllocatePool(BufferSize);\r
+\r
+  Buffer = (CHAR16 *)AllocatePool (BufferSize);\r
   ASSERT (Buffer != NULL);\r
 \r
   Return = UnicodeVSPrintAsciiFormat (Buffer, BufferSize, Format, Marker);\r
@@ -179,28 +207,34 @@ AsciiInternalPrint (
     //\r
     // To be extra safe make sure Console has been initialized\r
     //\r
-    Console->OutputString (Console, Buffer);\r
+    Status = Console->OutputString (Console, Buffer);\r
+    if (EFI_ERROR (Status)) {\r
+      Return = 0;\r
+    }\r
   }\r
 \r
   FreePool (Buffer);\r
 \r
-  return Return;  \r
+  return Return;\r
 }\r
 \r
-/** \r
-  Prints a formatted ASCII string to the console output device specified by \r
+/**\r
+  Prints a formatted ASCII string to the console output device specified by\r
   ConOut defined in the EFI_SYSTEM_TABLE.\r
 \r
-  This function prints a formatted ASCII string to the console output device \r
-  specified by ConOut in EFI_SYSTEM_TABLE and returns the number of ASCII \r
-  characters that printed to ConOut.  If the length of the formatted ASCII \r
-  string is greater than PcdUefiLibMaxPrintBufferSize, then only the first \r
+  This function prints a formatted ASCII string to the console output device\r
+  specified by ConOut in EFI_SYSTEM_TABLE and returns the number of ASCII\r
+  characters that printed to ConOut.  If the length of the formatted ASCII\r
+  string is greater than PcdUefiLibMaxPrintBufferSize, then only the first\r
   PcdUefiLibMaxPrintBufferSize characters are sent to ConOut.\r
-\r
-  @param Format   Null-terminated ASCII format string.\r
-  @param ...      VARARG list consumed to process Format.\r
   If Format is NULL, then ASSERT().\r
-  If Format is not aligned on a 16-bit boundary, then ASSERT().\r
+  If gST->ConOut is NULL, then ASSERT().\r
+\r
+  @param Format   A Null-terminated ASCII format string.\r
+  @param ...      Variable argument list whose contents are accessed based\r
+                  on the format string specified by Format.\r
+\r
+  @return The number of ASCII characters printed to ConOut.\r
 \r
 **/\r
 UINTN\r
@@ -210,32 +244,37 @@ AsciiPrint (
   ...\r
   )\r
 {\r
-  VA_LIST Marker;\r
-  UINTN   Return;\r
+  VA_LIST  Marker;\r
+  UINTN    Return;\r
+\r
+  ASSERT (Format != NULL);\r
 \r
   VA_START (Marker, Format);\r
 \r
-  Return = AsciiInternalPrintFormat, gST->ConOut, Marker);\r
+  Return = AsciiInternalPrint (Format, gST->ConOut, Marker);\r
 \r
   VA_END (Marker);\r
 \r
   return Return;\r
 }\r
 \r
-/** \r
-  Prints a formatted ASCII string to the console output device specified by \r
+/**\r
+  Prints a formatted ASCII string to the console output device specified by\r
   StdErr defined in the EFI_SYSTEM_TABLE.\r
 \r
-  This function prints a formatted ASCII string to the console output device \r
-  specified by StdErr in EFI_SYSTEM_TABLE and returns the number of ASCII \r
-  characters that printed to StdErr.  If the length of the formatted ASCII \r
-  string is greater than PcdUefiLibMaxPrintBufferSize, then only the first \r
+  This function prints a formatted ASCII string to the console output device\r
+  specified by StdErr in EFI_SYSTEM_TABLE and returns the number of ASCII\r
+  characters that printed to StdErr.  If the length of the formatted ASCII\r
+  string is greater than PcdUefiLibMaxPrintBufferSize, then only the first\r
   PcdUefiLibMaxPrintBufferSize characters are sent to StdErr.\r
-\r
-  @param Format   Null-terminated ASCII format string.\r
-  @param ...      VARARG list consumed to process Format.\r
   If Format is NULL, then ASSERT().\r
-  If Format is not aligned on a 16-bit boundary, then ASSERT().\r
+  If gST->StdErr is NULL, then ASSERT().\r
+\r
+  @param Format   A Null-terminated ASCII format string.\r
+  @param ...      Variable argument list whose contents are accessed based\r
+                  on the format string specified by Format.\r
+\r
+  @return The number of ASCII characters printed to ConErr.\r
 \r
 **/\r
 UINTN\r
@@ -245,15 +284,537 @@ AsciiErrorPrint (
   ...\r
   )\r
 {\r
-  VA_LIST Marker;\r
-  UINTN   Return;\r
+  VA_LIST  Marker;\r
+  UINTN    Return;\r
+\r
+  ASSERT (Format != NULL);\r
 \r
   VA_START (Marker, Format);\r
 \r
-  Return = AsciiInternalPrintFormat, gST->StdErr, Marker);\r
+  Return = AsciiInternalPrint (Format, gST->StdErr, Marker);\r
 \r
   VA_END (Marker);\r
 \r
   return Return;\r
 }\r
 \r
+/**\r
+  Internal function to print a formatted Unicode string to a graphics console device specified by\r
+  ConsoleOutputHandle defined in the EFI_SYSTEM_TABLE at the given (X,Y) coordinates.\r
+\r
+  This function prints a formatted Unicode string to the graphics console device\r
+  specified by ConsoleOutputHandle in EFI_SYSTEM_TABLE and returns the number of\r
+  Unicode characters printed. The EFI_HII_FONT_PROTOCOL is used to convert the\r
+  string to a bitmap using the glyphs registered with the\r
+  HII database.  No wrapping is performed, so any portions of the string the fall\r
+  outside the active display region will not be displayed.\r
+\r
+  If a graphics console device is not associated with the ConsoleOutputHandle\r
+  defined in the EFI_SYSTEM_TABLE then no string is printed, and 0 is returned.\r
+  If the EFI_HII_FONT_PROTOCOL is not present in the handle database, then no\r
+  string is printed, and 0 is returned.\r
+\r
+  @param  PointX       An X coordinate to print the string.\r
+  @param  PointY       A Y coordinate to print the string.\r
+  @param  Foreground   The foreground color of the string being printed.  This is\r
+                       an optional parameter that may be NULL.  If it is NULL,\r
+                       then the foreground color of the current ConOut device\r
+                       in the EFI_SYSTEM_TABLE is used.\r
+  @param  Background   The background color of the string being printed.  This is\r
+                       an optional parameter that may be NULL.  If it is NULL,\r
+                       then the background color of the current ConOut device\r
+                       in the EFI_SYSTEM_TABLE is used.\r
+  @param  Buffer       A Null-terminated Unicode formatted string.\r
+  @param  PrintNum     The number of Unicode formatted string to be printed.\r
+\r
+  @return  The number of Unicode Characters printed. Zero means no any character\r
+           displayed successfully.\r
+\r
+**/\r
+UINTN\r
+InternalPrintGraphic (\r
+  IN UINTN                          PointX,\r
+  IN UINTN                          PointY,\r
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *Foreground,\r
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *Background,\r
+  IN CHAR16                         *Buffer,\r
+  IN UINTN                          PrintNum\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  UINT32                           HorizontalResolution;\r
+  UINT32                           VerticalResolution;\r
+  UINT32                           ColorDepth;\r
+  UINT32                           RefreshRate;\r
+  EFI_HII_FONT_PROTOCOL            *HiiFont;\r
+  EFI_IMAGE_OUTPUT                 *Blt;\r
+  EFI_FONT_DISPLAY_INFO            FontInfo;\r
+  EFI_HII_ROW_INFO                 *RowInfoArray;\r
+  UINTN                            RowInfoArraySize;\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL     *GraphicsOutput;\r
+  EFI_UGA_DRAW_PROTOCOL            *UgaDraw;\r
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *Sto;\r
+  EFI_HANDLE                       ConsoleHandle;\r
+  UINTN                            Width;\r
+  UINTN                            Height;\r
+  UINTN                            Delta;\r
+\r
+  HorizontalResolution = 0;\r
+  VerticalResolution   = 0;\r
+  Blt                  = NULL;\r
+  RowInfoArray         = NULL;\r
+\r
+  ConsoleHandle = gST->ConsoleOutHandle;\r
+\r
+  ASSERT (ConsoleHandle != NULL);\r
+\r
+  Status = gBS->HandleProtocol (\r
+                  ConsoleHandle,\r
+                  &gEfiGraphicsOutputProtocolGuid,\r
+                  (VOID **)&GraphicsOutput\r
+                  );\r
+\r
+  UgaDraw = NULL;\r
+  if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
+    //\r
+    // If no GOP available, try to open UGA Draw protocol if supported.\r
+    //\r
+    GraphicsOutput = NULL;\r
+\r
+    Status = gBS->HandleProtocol (\r
+                    ConsoleHandle,\r
+                    &gEfiUgaDrawProtocolGuid,\r
+                    (VOID **)&UgaDraw\r
+                    );\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+\r
+  Status = gBS->HandleProtocol (\r
+                  ConsoleHandle,\r
+                  &gEfiSimpleTextOutProtocolGuid,\r
+                  (VOID **)&Sto\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+\r
+  if (GraphicsOutput != NULL) {\r
+    HorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;\r
+    VerticalResolution   = GraphicsOutput->Mode->Info->VerticalResolution;\r
+  } else if ((UgaDraw != NULL) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
+    UgaDraw->GetMode (UgaDraw, &HorizontalResolution, &VerticalResolution, &ColorDepth, &RefreshRate);\r
+  } else {\r
+    goto Error;\r
+  }\r
+\r
+  ASSERT ((HorizontalResolution != 0) && (VerticalResolution != 0));\r
+\r
+  Status = gBS->LocateProtocol (&gEfiHiiFontProtocolGuid, NULL, (VOID **)&HiiFont);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+\r
+  Blt = (EFI_IMAGE_OUTPUT *)AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
+  ASSERT (Blt != NULL);\r
+\r
+  Blt->Width  = (UINT16)(HorizontalResolution);\r
+  Blt->Height = (UINT16)(VerticalResolution);\r
+\r
+  ZeroMem (&FontInfo, sizeof (EFI_FONT_DISPLAY_INFO));\r
+\r
+  if (Foreground != NULL) {\r
+    CopyMem (&FontInfo.ForegroundColor, Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+  } else {\r
+    CopyMem (\r
+      &FontInfo.ForegroundColor,\r
+      &mEfiColors[Sto->Mode->Attribute & 0x0f],\r
+      sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
+      );\r
+  }\r
+\r
+  if (Background != NULL) {\r
+    CopyMem (&FontInfo.BackgroundColor, Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+  } else {\r
+    CopyMem (\r
+      &FontInfo.BackgroundColor,\r
+      &mEfiColors[Sto->Mode->Attribute >> 4],\r
+      sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
+      );\r
+  }\r
+\r
+  if (GraphicsOutput != NULL) {\r
+    Blt->Image.Screen = GraphicsOutput;\r
+\r
+    Status = HiiFont->StringToImage (\r
+                        HiiFont,\r
+                        EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_OUT_FLAG_CLIP |\r
+                        EFI_HII_OUT_FLAG_CLIP_CLEAN_X | EFI_HII_OUT_FLAG_CLIP_CLEAN_Y |\r
+                        EFI_HII_IGNORE_LINE_BREAK | EFI_HII_DIRECT_TO_SCREEN,\r
+                        Buffer,\r
+                        &FontInfo,\r
+                        &Blt,\r
+                        PointX,\r
+                        PointY,\r
+                        &RowInfoArray,\r
+                        &RowInfoArraySize,\r
+                        NULL\r
+                        );\r
+    if (EFI_ERROR (Status)) {\r
+      goto Error;\r
+    }\r
+  } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
+    ASSERT (UgaDraw != NULL);\r
+\r
+    //\r
+    // Ensure Width * Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow.\r
+    //\r
+    if (Blt->Width > DivU64x32 (MAX_UINTN, Blt->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {\r
+      goto Error;\r
+    }\r
+\r
+    Blt->Image.Bitmap = AllocateZeroPool ((UINT32)Blt->Width * Blt->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+    ASSERT (Blt->Image.Bitmap != NULL);\r
+\r
+    //\r
+    //  StringToImage only support blt'ing image to device using GOP protocol. If GOP is not supported in this platform,\r
+    //  we ask StringToImage to print the string to blt buffer, then blt to device using UgaDraw.\r
+    //\r
+    Status = HiiFont->StringToImage (\r
+                        HiiFont,\r
+                        EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_OUT_FLAG_CLIP |\r
+                        EFI_HII_OUT_FLAG_CLIP_CLEAN_X | EFI_HII_OUT_FLAG_CLIP_CLEAN_Y |\r
+                        EFI_HII_IGNORE_LINE_BREAK,\r
+                        Buffer,\r
+                        &FontInfo,\r
+                        &Blt,\r
+                        PointX,\r
+                        PointY,\r
+                        &RowInfoArray,\r
+                        &RowInfoArraySize,\r
+                        NULL\r
+                        );\r
+\r
+    if (!EFI_ERROR (Status)) {\r
+      ASSERT (RowInfoArray != NULL);\r
+      //\r
+      // Explicit Line break characters are ignored, so the updated parameter RowInfoArraySize by StringToImage will\r
+      // always be 1 or 0 (if there is no valid Unicode Char can be printed). ASSERT here to make sure.\r
+      //\r
+      ASSERT (RowInfoArraySize <= 1);\r
+\r
+      if (RowInfoArraySize != 0) {\r
+        Width  = RowInfoArray[0].LineWidth;\r
+        Height = RowInfoArray[0].LineHeight;\r
+        Delta  = Blt->Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
+      } else {\r
+        Width  = 0;\r
+        Height = 0;\r
+        Delta  = 0;\r
+      }\r
+\r
+      Status = UgaDraw->Blt (\r
+                          UgaDraw,\r
+                          (EFI_UGA_PIXEL *)Blt->Image.Bitmap,\r
+                          EfiUgaBltBufferToVideo,\r
+                          PointX,\r
+                          PointY,\r
+                          PointX,\r
+                          PointY,\r
+                          Width,\r
+                          Height,\r
+                          Delta\r
+                          );\r
+    } else {\r
+      goto Error;\r
+    }\r
+\r
+    FreePool (Blt->Image.Bitmap);\r
+  } else {\r
+    goto Error;\r
+  }\r
+\r
+  //\r
+  // Calculate the number of actual printed characters\r
+  //\r
+  if (RowInfoArraySize != 0) {\r
+    PrintNum = RowInfoArray[0].EndIndex - RowInfoArray[0].StartIndex + 1;\r
+  } else {\r
+    PrintNum = 0;\r
+  }\r
+\r
+  FreePool (RowInfoArray);\r
+  FreePool (Blt);\r
+  return PrintNum;\r
+\r
+Error:\r
+  if (Blt != NULL) {\r
+    FreePool (Blt);\r
+  }\r
+\r
+  return 0;\r
+}\r
+\r
+/**\r
+  Prints a formatted Unicode string to a graphics console device specified by\r
+  ConsoleOutputHandle defined in the EFI_SYSTEM_TABLE at the given (X,Y) coordinates.\r
+\r
+  This function prints a formatted Unicode string to the graphics console device\r
+  specified by ConsoleOutputHandle in EFI_SYSTEM_TABLE and returns the number of\r
+  Unicode characters displayed, not including partial characters that may be clipped\r
+  by the right edge of the display.  If the length of the formatted Unicode string is\r
+  greater than PcdUefiLibMaxPrintBufferSize, then at most the first\r
+  PcdUefiLibMaxPrintBufferSize characters are printed.The EFI_HII_FONT_PROTOCOL\r
+  StringToImage() service is used to convert the string to a bitmap using the glyphs\r
+  registered with the HII database. No wrapping is performed, so any portions of the\r
+  string the fall outside the active display region will not be displayed. Please see\r
+  Section 27.2.6 of the UEFI Specification for a description of the supported string\r
+  format including the set of control codes supported by the StringToImage() service.\r
+\r
+  If a graphics console device is not associated with the ConsoleOutputHandle\r
+  defined in the EFI_SYSTEM_TABLE then no string is printed, and 0 is returned.\r
+  If the EFI_HII_FONT_PROTOCOL is not present in the handle database, then no\r
+  string is printed, and 0 is returned.\r
+  If Format is NULL, then ASSERT().\r
+  If Format is not aligned on a 16-bit boundary, then ASSERT().\r
+  If gST->ConsoleOutputHandle is NULL, then ASSERT().\r
+\r
+  @param  PointX       An X coordinate to print the string.\r
+  @param  PointY       A Y coordinate to print the string.\r
+  @param  ForeGround   The foreground color of the string being printed.  This is\r
+                       an optional parameter that may be NULL.  If it is NULL,\r
+                       then the foreground color of the current ConOut device\r
+                       in the EFI_SYSTEM_TABLE is used.\r
+  @param  BackGround   The background color of the string being printed.  This is\r
+                       an optional parameter that may be NULL.  If it is NULL,\r
+                       then the background color of the current ConOut device\r
+                       in the EFI_SYSTEM_TABLE is used.\r
+  @param  Format       A Null-terminated Unicode format string.  See Print Library\r
+                       for the supported format string syntax.\r
+  @param  ...          A Variable argument list whose contents are accessed based on\r
+                       the format string specified by Format.\r
+\r
+  @return  The number of Unicode characters printed.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+PrintXY (\r
+  IN UINTN                          PointX,\r
+  IN UINTN                          PointY,\r
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *ForeGround  OPTIONAL,\r
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *BackGround  OPTIONAL,\r
+  IN CONST CHAR16                   *Format,\r
+  ...\r
+  )\r
+{\r
+  VA_LIST  Marker;\r
+  CHAR16   *Buffer;\r
+  UINTN    BufferSize;\r
+  UINTN    PrintNum;\r
+  UINTN    ReturnNum;\r
+\r
+  ASSERT (Format != NULL);\r
+  ASSERT (((UINTN)Format & BIT0) == 0);\r
+\r
+  VA_START (Marker, Format);\r
+\r
+  BufferSize = (PcdGet32 (PcdUefiLibMaxPrintBufferSize) + 1) * sizeof (CHAR16);\r
+\r
+  Buffer = (CHAR16 *)AllocatePool (BufferSize);\r
+  ASSERT (Buffer != NULL);\r
+\r
+  PrintNum = UnicodeVSPrint (Buffer, BufferSize, Format, Marker);\r
+\r
+  VA_END (Marker);\r
+\r
+  ReturnNum = InternalPrintGraphic (PointX, PointY, ForeGround, BackGround, Buffer, PrintNum);\r
+\r
+  FreePool (Buffer);\r
+\r
+  return ReturnNum;\r
+}\r
+\r
+/**\r
+  Prints a formatted ASCII string to a graphics console device specified by\r
+  ConsoleOutputHandle defined in the EFI_SYSTEM_TABLE at the given (X,Y) coordinates.\r
+\r
+  This function prints a formatted ASCII string to the graphics console device\r
+  specified by ConsoleOutputHandle in EFI_SYSTEM_TABLE and returns the number of\r
+  ASCII characters displayed, not including partial characters that may be clipped\r
+  by the right edge of the display.  If the length of the formatted ASCII string is\r
+  greater than PcdUefiLibMaxPrintBufferSize, then at most the first\r
+  PcdUefiLibMaxPrintBufferSize characters are printed.The EFI_HII_FONT_PROTOCOL\r
+  StringToImage() service is used to convert the string to a bitmap using the glyphs\r
+  registered with the HII database. No wrapping is performed, so any portions of the\r
+  string the fall outside the active display region will not be displayed. Please see\r
+  Section 27.2.6 of the UEFI Specification for a description of the supported string\r
+  format including the set of control codes supported by the StringToImage() service.\r
+\r
+  If a graphics console device is not associated with the ConsoleOutputHandle\r
+  defined in the EFI_SYSTEM_TABLE then no string is printed, and 0 is returned.\r
+  If the EFI_HII_FONT_PROTOCOL is not present in the handle database, then no\r
+  string is printed, and 0 is returned.\r
+  If Format is NULL, then ASSERT().\r
+  If gST->ConsoleOutputHandle is NULL, then ASSERT().\r
+\r
+  @param  PointX       An X coordinate to print the string.\r
+  @param  PointY       A Y coordinate to print the string.\r
+  @param  ForeGround   The foreground color of the string being printed.  This is\r
+                       an optional parameter that may be NULL.  If it is NULL,\r
+                       then the foreground color of the current ConOut device\r
+                       in the EFI_SYSTEM_TABLE is used.\r
+  @param  BackGround   The background color of the string being printed.  This is\r
+                       an optional parameter that may be NULL.  If it is NULL,\r
+                       then the background color of the current ConOut device\r
+                       in the EFI_SYSTEM_TABLE is used.\r
+  @param  Format       A Null-terminated ASCII format string.  See Print Library\r
+                       for the supported format string syntax.\r
+  @param  ...          Variable argument list whose contents are accessed based on\r
+                       the format string specified by Format.\r
+\r
+  @return  The number of ASCII characters printed.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsciiPrintXY (\r
+  IN UINTN                          PointX,\r
+  IN UINTN                          PointY,\r
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *ForeGround  OPTIONAL,\r
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *BackGround  OPTIONAL,\r
+  IN CONST CHAR8                    *Format,\r
+  ...\r
+  )\r
+{\r
+  VA_LIST  Marker;\r
+  CHAR16   *Buffer;\r
+  UINTN    BufferSize;\r
+  UINTN    PrintNum;\r
+  UINTN    ReturnNum;\r
+\r
+  ASSERT (Format != NULL);\r
+\r
+  VA_START (Marker, Format);\r
+\r
+  BufferSize = (PcdGet32 (PcdUefiLibMaxPrintBufferSize) + 1) * sizeof (CHAR16);\r
+\r
+  Buffer = (CHAR16 *)AllocatePool (BufferSize);\r
+  ASSERT (Buffer != NULL);\r
+\r
+  PrintNum = UnicodeSPrintAsciiFormat (Buffer, BufferSize, Format, Marker);\r
+\r
+  VA_END (Marker);\r
+\r
+  ReturnNum = InternalPrintGraphic (PointX, PointY, ForeGround, BackGround, Buffer, PrintNum);\r
+\r
+  FreePool (Buffer);\r
+\r
+  return ReturnNum;\r
+}\r
+\r
+/**\r
+  Appends a formatted Unicode string to a Null-terminated Unicode string\r
+\r
+  This function appends a formatted Unicode string to the Null-terminated\r
+  Unicode string specified by String.   String is optional and may be NULL.\r
+  Storage for the formatted Unicode string returned is allocated using\r
+  AllocatePool().  The pointer to the appended string is returned.  The caller\r
+  is responsible for freeing the returned string.\r
+\r
+  If String is not NULL and not aligned on a 16-bit boundary, then ASSERT().\r
+  If FormatString is NULL, then ASSERT().\r
+  If FormatString is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  @param[in] String         A Null-terminated Unicode string.\r
+  @param[in] FormatString   A Null-terminated Unicode format string.\r
+  @param[in]  Marker        VA_LIST marker for the variable argument list.\r
+\r
+  @retval NULL    There was not enough available memory.\r
+  @return         Null-terminated Unicode string is that is the formatted\r
+                  string appended to String.\r
+**/\r
+CHAR16 *\r
+EFIAPI\r
+CatVSPrint (\r
+  IN  CHAR16        *String  OPTIONAL,\r
+  IN  CONST CHAR16  *FormatString,\r
+  IN  VA_LIST       Marker\r
+  )\r
+{\r
+  UINTN    CharactersRequired;\r
+  UINTN    SizeRequired;\r
+  CHAR16   *BufferToReturn;\r
+  VA_LIST  ExtraMarker;\r
+\r
+  VA_COPY (ExtraMarker, Marker);\r
+  CharactersRequired = SPrintLength (FormatString, ExtraMarker);\r
+  VA_END (ExtraMarker);\r
+\r
+  if (String != NULL) {\r
+    SizeRequired = StrSize (String) + (CharactersRequired * sizeof (CHAR16));\r
+  } else {\r
+    SizeRequired = sizeof (CHAR16) + (CharactersRequired * sizeof (CHAR16));\r
+  }\r
+\r
+  BufferToReturn = AllocatePool (SizeRequired);\r
+\r
+  if (BufferToReturn == NULL) {\r
+    return NULL;\r
+  } else {\r
+    BufferToReturn[0] = L'\0';\r
+  }\r
+\r
+  if (String != NULL) {\r
+    StrCpyS (BufferToReturn, SizeRequired / sizeof (CHAR16), String);\r
+  }\r
+\r
+  UnicodeVSPrint (BufferToReturn + StrLen (BufferToReturn), (CharactersRequired+1) * sizeof (CHAR16), FormatString, Marker);\r
+\r
+  ASSERT (StrSize (BufferToReturn) == SizeRequired);\r
+\r
+  return (BufferToReturn);\r
+}\r
+\r
+/**\r
+  Appends a formatted Unicode string to a Null-terminated Unicode string\r
+\r
+  This function appends a formatted Unicode string to the Null-terminated\r
+  Unicode string specified by String.   String is optional and may be NULL.\r
+  Storage for the formatted Unicode string returned is allocated using\r
+  AllocatePool().  The pointer to the appended string is returned.  The caller\r
+  is responsible for freeing the returned string.\r
+\r
+  If String is not NULL and not aligned on a 16-bit boundary, then ASSERT().\r
+  If FormatString is NULL, then ASSERT().\r
+  If FormatString is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  @param[in] String         A Null-terminated Unicode string.\r
+  @param[in] FormatString   A Null-terminated Unicode format string.\r
+  @param[in] ...            The variable argument list whose contents are\r
+                            accessed based on the format string specified by\r
+                            FormatString.\r
+\r
+  @retval NULL    There was not enough available memory.\r
+  @return         Null-terminated Unicode string is that is the formatted\r
+                  string appended to String.\r
+**/\r
+CHAR16 *\r
+EFIAPI\r
+CatSPrint (\r
+  IN  CHAR16        *String  OPTIONAL,\r
+  IN  CONST CHAR16  *FormatString,\r
+  ...\r
+  )\r
+{\r
+  VA_LIST  Marker;\r
+  CHAR16   *NewString;\r
+\r
+  VA_START (Marker, FormatString);\r
+  NewString = CatVSPrint (String, FormatString, Marker);\r
+  VA_END (Marker);\r
+  return NewString;\r
+}\r