]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c
MdeModulePkg/GraphicsConsoleDxe: Initialize the output mode
[mirror_edk2.git] / MdeModulePkg / Universal / Console / GraphicsConsoleDxe / GraphicsConsole.c
index 553a8146346076d50480e5e9bd351664c64242bd..c042451a9b5234baf309d7626c5a41755355fb8e 100644 (file)
@@ -1,14 +1,8 @@
 /** @file\r
   This is the main routine for initializing the Graphics Console support routines.\r
 \r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
-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) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -35,26 +29,29 @@ GRAPHICS_CONSOLE_DEV    mGraphicsConsoleDevTemplate = {
   },\r
   {\r
     0,\r
-    0,\r
+    -1,\r
     EFI_TEXT_ATTR(EFI_LIGHTGRAY, EFI_BLACK),\r
     0,\r
     0,\r
     TRUE\r
   },\r
-  {\r
-    { 80, 25, 0, 0, 0, 0, 0 },  // Mode 0\r
-    { 80, 50, 0, 0, 0, 0, 0 },  // Mode 1\r
-    { 100,31, 0, 0, 0, 0, 0 },  // Mode 2\r
-    {  0,  0, 0, 0, 0, 0, 0 },  // Mode 3\r
-    {  0,  0, 0, 0, 0, 0, 0 }   // Mode 4\r
-  },\r
+  (GRAPHICS_CONSOLE_MODE_DATA *) NULL,\r
   (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL\r
 };\r
 \r
+GRAPHICS_CONSOLE_MODE_DATA mGraphicsConsoleModeData[] = {\r
+  {100, 31},\r
+  //\r
+  // New modes can be added here.\r
+  // The last entry is specific for full screen mode.\r
+  //\r
+  {0, 0}\r
+};\r
+\r
 EFI_HII_DATABASE_PROTOCOL   *mHiiDatabase;\r
 EFI_HII_FONT_PROTOCOL       *mHiiFont;\r
 EFI_HII_HANDLE              mHiiHandle;\r
-EFI_EVENT                   mHiiRegistration;\r
+VOID                        *mHiiRegistration;\r
 \r
 EFI_GUID             mFontPackageListGuid = {0xf5f219d3, 0x7006, 0x4648, {0xac, 0x8d, 0xd6, 0x1d, 0xfb, 0x7b, 0xc6, 0xad}};\r
 \r
@@ -210,6 +207,148 @@ Error:
   return Status;\r
 }\r
 \r
+/**\r
+  Initialize all the text modes which the graphics console supports.\r
+\r
+  It returns information for available text modes that the graphics can support.\r
+\r
+  @param[in]  HorizontalResolution     The size of video screen in pixels in the X dimension.\r
+  @param[in]  VerticalResolution       The size of video screen in pixels in the Y dimension.\r
+  @param[in]  GopModeNumber            The graphics mode number which graphis console is based on.\r
+  @param[out] TextModeCount            The total number of text modes that graphics console supports.\r
+  @param[out] TextModeData             The buffer to the text modes column and row information.\r
+                                       Caller is responsible to free it when it's non-NULL.\r
+\r
+  @retval EFI_SUCCESS                  The supporting mode information is returned.\r
+  @retval EFI_INVALID_PARAMETER        The parameters are invalid.\r
+\r
+**/\r
+EFI_STATUS\r
+InitializeGraphicsConsoleTextMode (\r
+  IN UINT32                        HorizontalResolution,\r
+  IN UINT32                        VerticalResolution,\r
+  IN UINT32                        GopModeNumber,\r
+  OUT UINTN                        *TextModeCount,\r
+  OUT GRAPHICS_CONSOLE_MODE_DATA   **TextModeData\r
+  )\r
+{\r
+  UINTN                       Index;\r
+  UINTN                       Count;\r
+  GRAPHICS_CONSOLE_MODE_DATA  *ModeBuffer;\r
+  GRAPHICS_CONSOLE_MODE_DATA  *NewModeBuffer;\r
+  UINTN                       ValidCount;\r
+  UINTN                       ValidIndex;\r
+  UINTN                       MaxColumns;\r
+  UINTN                       MaxRows;\r
+\r
+  if ((TextModeCount == NULL) || (TextModeData == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Count = sizeof (mGraphicsConsoleModeData) / sizeof (GRAPHICS_CONSOLE_MODE_DATA);\r
+\r
+  //\r
+  // Compute the maximum number of text Rows and Columns that this current graphics mode can support.\r
+  // To make graphics console work well, MaxColumns and MaxRows should not be zero.\r
+  //\r
+  MaxColumns = HorizontalResolution / EFI_GLYPH_WIDTH;\r
+  MaxRows    = VerticalResolution / EFI_GLYPH_HEIGHT;\r
+\r
+  //\r
+  // According to UEFI spec, all output devices support at least 80x25 text mode.\r
+  //\r
+  ASSERT ((MaxColumns >= 80) && (MaxRows >= 25));\r
+\r
+  //\r
+  // Add full screen mode to the last entry.\r
+  //\r
+  mGraphicsConsoleModeData[Count - 1].Columns = MaxColumns;\r
+  mGraphicsConsoleModeData[Count - 1].Rows    = MaxRows;\r
+\r
+  //\r
+  // Get defined mode buffer pointer.\r
+  //\r
+  ModeBuffer = mGraphicsConsoleModeData;\r
+\r
+  //\r
+  // Here we make sure that the final mode exposed does not include the duplicated modes,\r
+  // and does not include the invalid modes which exceed the max column and row.\r
+  // Reserve 2 modes for 80x25, 80x50 of graphics console.\r
+  //\r
+  NewModeBuffer = AllocateZeroPool (sizeof (GRAPHICS_CONSOLE_MODE_DATA) * (Count + 2));\r
+  ASSERT (NewModeBuffer != NULL);\r
+\r
+  //\r
+  // Mode 0 and mode 1 is for 80x25, 80x50 according to UEFI spec.\r
+  //\r
+  ValidCount = 0;\r
+\r
+  NewModeBuffer[ValidCount].Columns       = 80;\r
+  NewModeBuffer[ValidCount].Rows          = 25;\r
+  NewModeBuffer[ValidCount].GopWidth      = HorizontalResolution;\r
+  NewModeBuffer[ValidCount].GopHeight     = VerticalResolution;\r
+  NewModeBuffer[ValidCount].GopModeNumber = GopModeNumber;\r
+  NewModeBuffer[ValidCount].DeltaX        = (HorizontalResolution - (NewModeBuffer[ValidCount].Columns * EFI_GLYPH_WIDTH)) >> 1;\r
+  NewModeBuffer[ValidCount].DeltaY        = (VerticalResolution - (NewModeBuffer[ValidCount].Rows * EFI_GLYPH_HEIGHT)) >> 1;\r
+  ValidCount++;\r
+\r
+  if ((MaxColumns >= 80) && (MaxRows >= 50)) {\r
+    NewModeBuffer[ValidCount].Columns = 80;\r
+    NewModeBuffer[ValidCount].Rows    = 50;\r
+    NewModeBuffer[ValidCount].DeltaX  = (HorizontalResolution - (80 * EFI_GLYPH_WIDTH)) >> 1;\r
+    NewModeBuffer[ValidCount].DeltaY  = (VerticalResolution - (50 * EFI_GLYPH_HEIGHT)) >> 1;\r
+  }\r
+  NewModeBuffer[ValidCount].GopWidth      = HorizontalResolution;\r
+  NewModeBuffer[ValidCount].GopHeight     = VerticalResolution;\r
+  NewModeBuffer[ValidCount].GopModeNumber = GopModeNumber;\r
+  ValidCount++;\r
+\r
+  //\r
+  // Start from mode 2 to put the valid mode other than 80x25 and 80x50 in the output mode buffer.\r
+  //\r
+  for (Index = 0; Index < Count; Index++) {\r
+    if ((ModeBuffer[Index].Columns == 0) || (ModeBuffer[Index].Rows == 0) ||\r
+        (ModeBuffer[Index].Columns > MaxColumns) || (ModeBuffer[Index].Rows > MaxRows)) {\r
+      //\r
+      // Skip the pre-defined mode which is invalid or exceeds the max column and row.\r
+      //\r
+      continue;\r
+    }\r
+    for (ValidIndex = 0; ValidIndex < ValidCount; ValidIndex++) {\r
+      if ((ModeBuffer[Index].Columns == NewModeBuffer[ValidIndex].Columns) &&\r
+          (ModeBuffer[Index].Rows == NewModeBuffer[ValidIndex].Rows)) {\r
+        //\r
+        // Skip the duplicated mode.\r
+        //\r
+        break;\r
+      }\r
+    }\r
+    if (ValidIndex == ValidCount) {\r
+      NewModeBuffer[ValidCount].Columns       = ModeBuffer[Index].Columns;\r
+      NewModeBuffer[ValidCount].Rows          = ModeBuffer[Index].Rows;\r
+      NewModeBuffer[ValidCount].GopWidth      = HorizontalResolution;\r
+      NewModeBuffer[ValidCount].GopHeight     = VerticalResolution;\r
+      NewModeBuffer[ValidCount].GopModeNumber = GopModeNumber;\r
+      NewModeBuffer[ValidCount].DeltaX        = (HorizontalResolution - (NewModeBuffer[ValidCount].Columns * EFI_GLYPH_WIDTH)) >> 1;\r
+      NewModeBuffer[ValidCount].DeltaY        = (VerticalResolution - (NewModeBuffer[ValidCount].Rows * EFI_GLYPH_HEIGHT)) >> 1;\r
+      ValidCount++;\r
+    }\r
+  }\r
+\r
+  DEBUG_CODE (\r
+    for (Index = 0; Index < ValidCount; Index++) {\r
+      DEBUG ((EFI_D_INFO, "Graphics - Mode %d, Column = %d, Row = %d\n",\r
+                           Index, NewModeBuffer[Index].Columns, NewModeBuffer[Index].Rows));\r
+    }\r
+  );\r
+\r
+  //\r
+  // Return valid mode count and mode information buffer.\r
+  //\r
+  *TextModeCount = ValidCount;\r
+  *TextModeData  = NewModeBuffer;\r
+  return EFI_SUCCESS;\r
+}\r
 \r
 /**\r
   Start this driver on Controller by opening Graphics Output protocol or\r
@@ -241,15 +380,17 @@ GraphicsConsoleControllerDriverStart (
   UINT32                               RefreshRate;\r
   UINT32                               ModeIndex;\r
   UINTN                                MaxMode;\r
-  UINTN                                MaxColumns;\r
-  UINTN                                MaxRows;\r
   UINT32                               ModeNumber;\r
   EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE    *Mode;\r
-  GRAPHICS_CONSOLE_MODE_DATA           *ModeData;\r
-  UINTN                                SizeOfInfo;  \r
+  UINTN                                SizeOfInfo;\r
   EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
-  BOOLEAN                              TextModeFound;\r
-  \r
+  INT32                                PreferMode;\r
+  INT32                                Index;\r
+  UINTN                                Column;\r
+  UINTN                                Row;\r
+  UINTN                                DefaultColumn;\r
+  UINTN                                DefaultRow;\r
+\r
   ModeNumber = 0;\r
 \r
   //\r
@@ -301,9 +442,9 @@ GraphicsConsoleControllerDriverStart (
     if ((HorizontalResolution == 0x0) || (VerticalResolution == 0x0)) {\r
       //\r
       // Find the highest resolution which GOP supports.\r
-      //    \r
+      //\r
       MaxMode = Private->GraphicsOutput->Mode->MaxMode;\r
-      \r
+\r
       for (ModeIndex = 0; ModeIndex < MaxMode; ModeIndex++) {\r
         Status = Private->GraphicsOutput->QueryMode (\r
                            Private->GraphicsOutput,\r
@@ -312,8 +453,8 @@ GraphicsConsoleControllerDriverStart (
                            &Info\r
                            );\r
         if (!EFI_ERROR (Status)) {\r
-          if ((Info->HorizontalResolution >= HorizontalResolution) &&\r
-              (Info->VerticalResolution >= VerticalResolution)) {\r
+          if ((Info->HorizontalResolution > HorizontalResolution) ||\r
+              ((Info->HorizontalResolution == HorizontalResolution) && (Info->VerticalResolution > VerticalResolution))) {\r
             HorizontalResolution = Info->HorizontalResolution;\r
             VerticalResolution   = Info->VerticalResolution;\r
             ModeNumber           = ModeIndex;\r
@@ -339,10 +480,12 @@ GraphicsConsoleControllerDriverStart (
         //\r
         // if not supporting current mode, try 800x600 which is required by UEFI/EFI spec\r
         //\r
+        HorizontalResolution = 800;\r
+        VerticalResolution   = 600;\r
         Status = CheckModeSupported (\r
                      Private->GraphicsOutput,\r
-                     800,\r
-                     600,\r
+                     HorizontalResolution,\r
+                     VerticalResolution,\r
                      &ModeNumber\r
                      );\r
         Mode = Private->GraphicsOutput->Mode;\r
@@ -356,6 +499,19 @@ GraphicsConsoleControllerDriverStart (
         }\r
       }\r
     }\r
+    if (ModeNumber != Private->GraphicsOutput->Mode->Mode) {\r
+      //\r
+      // Current graphics mode is not set or is not set to the mode which we has found,\r
+      // set the new graphic mode.\r
+      //\r
+      Status = Private->GraphicsOutput->SetMode (Private->GraphicsOutput, ModeNumber);\r
+      if (EFI_ERROR (Status)) {\r
+        //\r
+        // The mode set operation failed\r
+        //\r
+        goto Error;\r
+      }\r
+    }\r
   } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
     //\r
     // At first try to set user-defined resolution\r
@@ -392,87 +548,23 @@ GraphicsConsoleControllerDriverStart (
           goto Error;\r
         }\r
       }\r
-    } else {\r
-      Status = EFI_UNSUPPORTED;\r
-      goto Error;\r
     }\r
   }\r
 \r
-  //\r
-  // Include the existing pre-defined 80x25, 80x50 and 100x31 \r
-  // in mGraphicsConsoleDevTemplate.\r
-  //\r
-  MaxMode = 3;\r
-\r
-  //\r
-  // Compute the maximum number of text Rows and Columns that this current graphics mode can support\r
-  //\r
-  MaxColumns = HorizontalResolution / EFI_GLYPH_WIDTH;\r
-  MaxRows    = VerticalResolution / EFI_GLYPH_HEIGHT;\r
-\r
-  //\r
-  // Add Mode #3 that uses the entire display for user-defined mode\r
-  //\r
-  Private->ModeData[MaxMode].Columns = MaxColumns;\r
-  Private->ModeData[MaxMode].Rows    = MaxRows;\r
-  MaxMode++;\r
-\r
-  //\r
-  // Add Mode #4 that uses the PCD values\r
-  //\r
-  Private->ModeData[MaxMode].Columns = (UINTN) PcdGet32 (PcdConOutColumn);\r
-  Private->ModeData[MaxMode].Rows    = (UINTN) PcdGet32 (PcdConOutRow);  \r
-  if ((Private->ModeData[MaxMode].Columns != 0) && (Private->ModeData[MaxMode].Rows != 0)) {\r
-    MaxMode++;\r
-  }\r
+  DEBUG ((EFI_D_INFO, "GraphicsConsole video resolution %d x %d\n", HorizontalResolution, VerticalResolution));\r
 \r
   //\r
-  // Here we make sure that mode 0 is valid\r
+  // Initialize the mode which GraphicsConsole supports.\r
   //\r
-  if (MaxColumns < Private->ModeData[0].Columns ||\r
-      MaxRows < Private->ModeData[0].Rows) {\r
-    //\r
-    // 80x25 cannot be supported.\r
-    //\r
-    if ((Private->ModeData[4].Columns != 0) && (Private->ModeData[4].Rows != 0)) {\r
-    //\r
-    // Fallback to using the Mode 4 for mode 0 if PcdConOutColumn and PcdConOutRow\r
-    // are not 0. If the PCDs are also too large, then mode 0\r
-    // will be shrunk to fit as needed. If the PCDs are all 0,\r
-    // then mode 0 will be the entire display.\r
-    //\r
-      Private->ModeData[0].Columns = MIN (Private->ModeData[4].Columns, MaxColumns);\r
-      Private->ModeData[0].Rows    = MIN (Private->ModeData[4].Rows, MaxRows);\r
-    } else {\r
-      Private->ModeData[0].Columns = MaxColumns;\r
-      Private->ModeData[0].Rows    = MaxRows;\r
-    }\r
-  }\r
-  \r
-  TextModeFound = FALSE;\r
-  for (ModeIndex = 0; ModeIndex < GRAPHICS_MAX_MODE; ModeIndex++) {\r
-    ModeData = &Private->ModeData[ModeIndex];\r
-    ModeData->GopWidth      = HorizontalResolution;\r
-    ModeData->GopHeight     = VerticalResolution;\r
-    ModeData->GopModeNumber = ModeNumber;\r
-    if ((ModeData->Columns != 0) && (ModeData->Rows != 0) &&\r
-        (MaxColumns >= ModeData->Columns) && (MaxRows >= ModeData->Rows)) {\r
-      ModeData->DeltaX        = (HorizontalResolution - (ModeData->Columns * EFI_GLYPH_WIDTH)) >> 1;\r
-      ModeData->DeltaY        = (VerticalResolution - (ModeData->Rows * EFI_GLYPH_HEIGHT)) >> 1;\r
-      TextModeFound = TRUE;\r
-    } else {\r
-      ModeData->Columns       = 0;\r
-      ModeData->Rows          = 0;\r
-      ModeData->DeltaX        = 0;\r
-      ModeData->DeltaY        = 0;\r
-    }\r
-  }\r
+  Status = InitializeGraphicsConsoleTextMode (\r
+             HorizontalResolution,\r
+             VerticalResolution,\r
+             ModeNumber,\r
+             &MaxMode,\r
+             &Private->ModeData\r
+             );\r
 \r
-  //\r
-  // See if the resolution was too small to support any text modes\r
-  //\r
-  if (!TextModeFound) {\r
-    Status = EFI_UNSUPPORTED;\r
+  if (EFI_ERROR (Status)) {\r
     goto Error;\r
   }\r
 \r
@@ -482,16 +574,31 @@ GraphicsConsoleControllerDriverStart (
   Private->SimpleTextOutputMode.MaxMode = (INT32) MaxMode;\r
 \r
   //\r
-  // Determine the number of text modes that this protocol can support\r
+  // Initialize the Mode of graphics console devices\r
   //\r
-  Status = GraphicsConsoleConOutSetMode (&Private->SimpleTextOutput, 0);\r
-  if (EFI_ERROR (Status)) {\r
-    goto Error;\r
+  PreferMode = -1;\r
+  DefaultColumn = PcdGet32 (PcdConOutColumn);\r
+  DefaultRow = PcdGet32 (PcdConOutRow);\r
+  Column = 0;\r
+  Row = 0;\r
+  for (Index = 0; Index < (INT32)MaxMode; Index++) {\r
+    if (DefaultColumn != 0 && DefaultRow != 0) {\r
+      if ((Private->ModeData[Index].Columns == DefaultColumn) &&\r
+          (Private->ModeData[Index].Rows == DefaultRow)) {\r
+        PreferMode = Index;\r
+        break;\r
+      }\r
+    } else {\r
+      if ((Private->ModeData[Index].Columns > Column) &&\r
+          (Private->ModeData[Index].Rows > Row)) {\r
+        Column = Private->ModeData[Index].Columns;\r
+        Row = Private->ModeData[Index].Rows;\r
+        PreferMode = Index;\r
+      }\r
+    }\r
   }\r
-\r
-  DEBUG_CODE_BEGIN ();\r
-    GraphicsConsoleConOutOutputString (&Private->SimpleTextOutput, (CHAR16 *)L"Graphics Console Started\n\r");\r
-  DEBUG_CODE_END ();\r
+  Private->SimpleTextOutput.Mode->Mode = (INT32)PreferMode;\r
+  DEBUG ((DEBUG_INFO, "Graphics Console Started, Mode: %d\n", PreferMode));\r
 \r
   //\r
   // Install protocol interfaces for the Graphics Console device.\r
@@ -528,6 +635,10 @@ Error:
       FreePool (Private->LineBuffer);\r
     }\r
 \r
+    if (Private->ModeData != NULL) {\r
+      FreePool (Private->ModeData);\r
+    }\r
+\r
     //\r
     // Free private data\r
     //\r
@@ -612,6 +723,10 @@ GraphicsConsoleControllerDriverStop (
       FreePool (Private->LineBuffer);\r
     }\r
 \r
+    if (Private->ModeData != NULL) {\r
+      FreePool (Private->ModeData);\r
+    }\r
+\r
     //\r
     // Free our instance data\r
     //\r
@@ -672,6 +787,7 @@ CheckModeSupported (
           //\r
           // If video device has been set to this mode, we do not need to SetMode again\r
           //\r
+          FreePool (Info);\r
           break;\r
         } else {\r
           Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);\r
@@ -708,42 +824,14 @@ EfiLocateHiiProtocol (
   VOID\r
   )\r
 {\r
-  EFI_HANDLE  Handle;\r
-  UINTN       Size;\r
   EFI_STATUS  Status;\r
 \r
-  //\r
-  // There should only be one - so buffer size is this\r
-  //\r
-  Size = sizeof (EFI_HANDLE);\r
-\r
-  Status = gBS->LocateHandle (\r
-                  ByProtocol,\r
-                  &gEfiHiiDatabaseProtocolGuid,\r
-                  NULL,\r
-                  &Size,\r
-                  (VOID **) &Handle\r
-                  );\r
-\r
+  Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &mHiiDatabase);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
-  Status = gBS->HandleProtocol (\r
-                  Handle,\r
-                  &gEfiHiiDatabaseProtocolGuid,\r
-                  (VOID **) &mHiiDatabase\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  Status = gBS->HandleProtocol (\r
-                  Handle,\r
-                  &gEfiHiiFontProtocolGuid,\r
-                  (VOID **) &mHiiFont\r
-                  );\r
+  Status = gBS->LocateProtocol (&gEfiHiiFontProtocolGuid, NULL, (VOID **) &mHiiFont);\r
   return Status;\r
 }\r
 \r
@@ -776,8 +864,13 @@ GraphicsConsoleConOutReset (
   IN  BOOLEAN                          ExtendedVerification\r
   )\r
 {\r
-  This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));\r
-  return This->SetMode (This, 0);\r
+  EFI_STATUS    Status;\r
+  Status = This->SetMode (This, 0);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  Status = This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));\r
+  return Status;\r
 }\r
 \r
 \r
@@ -830,6 +923,13 @@ GraphicsConsoleConOutOutputString (
   INT32                 OriginAttribute;\r
   EFI_TPL               OldTpl;\r
 \r
+  if (This->Mode->Mode == -1) {\r
+    //\r
+    // If current mode is not valid, return error.\r
+    //\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
   Status = EFI_SUCCESS;\r
 \r
   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
@@ -1162,7 +1262,7 @@ GraphicsConsoleConOutQueryMode (
   *Columns  = Private->ModeData[ModeNumber].Columns;\r
   *Rows     = Private->ModeData[ModeNumber].Rows;\r
 \r
-  if (*Columns <= 0 && *Rows <= 0) {\r
+  if (*Columns <= 0 || *Rows <= 0) {\r
     Status = EFI_UNSUPPORTED;\r
     goto Done;\r
 \r
@@ -1213,7 +1313,6 @@ GraphicsConsoleConOutSetMode (
   Private   = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
   GraphicsOutput = Private->GraphicsOutput;\r
   UgaDraw   = Private->UgaDraw;\r
-  ModeData  = &(Private->ModeData[ModeNumber]);\r
 \r
   //\r
   // Make sure the requested mode number is supported\r
@@ -1223,37 +1322,25 @@ GraphicsConsoleConOutSetMode (
     goto Done;\r
   }\r
 \r
+  ModeData  = &(Private->ModeData[ModeNumber]);\r
+\r
   if (ModeData->Columns <= 0 && ModeData->Rows <= 0) {\r
     Status = EFI_UNSUPPORTED;\r
     goto Done;\r
   }\r
-  //\r
-  // Attempt to allocate a line buffer for the requested mode number\r
-  //\r
-  NewLineBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ModeData->Columns * EFI_GLYPH_WIDTH * EFI_GLYPH_HEIGHT);\r
 \r
-  if (NewLineBuffer == NULL) {\r
-    //\r
-    // The new line buffer could not be allocated, so return an error.\r
-    // No changes to the state of the current console have been made, so the current console is still valid\r
-    //\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Done;\r
-  }\r
   //\r
   // If the mode has been set at least one other time, then LineBuffer will not be NULL\r
   //\r
   if (Private->LineBuffer != NULL) {\r
-    //\r
-    // Clear the current text window on the current graphics console\r
-    //\r
-    This->ClearScreen (This);\r
-\r
     //\r
     // If the new mode is the same as the old mode, then just return EFI_SUCCESS\r
     //\r
     if ((INT32) ModeNumber == This->Mode->Mode) {\r
-      FreePool (NewLineBuffer);\r
+      //\r
+      // Clear the current text window on the current graphics console\r
+      //\r
+      This->ClearScreen (This);\r
       Status = EFI_SUCCESS;\r
       goto Done;\r
     }\r
@@ -1265,6 +1352,21 @@ GraphicsConsoleConOutSetMode (
 \r
     FreePool (Private->LineBuffer);\r
   }\r
+\r
+  //\r
+  // Attempt to allocate a line buffer for the requested mode number\r
+  //\r
+  NewLineBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ModeData->Columns * EFI_GLYPH_WIDTH * EFI_GLYPH_HEIGHT);\r
+\r
+  if (NewLineBuffer == NULL) {\r
+    //\r
+    // The new line buffer could not be allocated, so return an error.\r
+    // No changes to the state of the current console have been made, so the current console is still valid\r
+    //\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+\r
   //\r
   // Assign the current line buffer to the newly allocated line buffer\r
   //\r
@@ -1357,7 +1459,7 @@ GraphicsConsoleConOutSetMode (
   This->Mode->CursorColumn  = 0;\r
   This->Mode->CursorRow     = 0;\r
 \r
-  FlushCursor (This);  \r
+  FlushCursor (This);\r
 \r
   Status = EFI_SUCCESS;\r
 \r
@@ -1392,7 +1494,7 @@ GraphicsConsoleConOutSetAttribute (
 {\r
   EFI_TPL               OldTpl;\r
 \r
-  if ((Attribute | 0xFF) != 0xFF) {\r
+  if ((Attribute | 0x7F) != 0x7F) {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -1442,6 +1544,13 @@ GraphicsConsoleConOutClearScreen (
   EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
   EFI_TPL                       OldTpl;\r
 \r
+  if (This->Mode->Mode == -1) {\r
+    //\r
+    // If current mode is not valid, return error.\r
+    //\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
 \r
   Private   = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
@@ -1523,6 +1632,13 @@ GraphicsConsoleConOutSetCursorPosition (
   EFI_STATUS                  Status;\r
   EFI_TPL                     OldTpl;\r
 \r
+  if (This->Mode->Mode == -1) {\r
+    //\r
+    // If current mode is not valid, return error.\r
+    //\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
   Status = EFI_SUCCESS;\r
 \r
   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
@@ -1564,6 +1680,8 @@ Done:
                                 the cursor is set to be invisible.\r
 \r
   @retval EFI_SUCCESS           The operation completed successfully.\r
+  @retval EFI_UNSUPPORTED       The output device's mode is not currently in a\r
+                                defined text mode.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1575,6 +1693,13 @@ GraphicsConsoleConOutEnableCursor (
 {\r
   EFI_TPL               OldTpl;\r
 \r
+  if (This->Mode->Mode == -1) {\r
+    //\r
+    // If current mode is not valid, return error.\r
+    //\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
 \r
   FlushCursor (This);\r
@@ -1767,11 +1892,11 @@ DrawUnicodeWeightAtCursorN (
 \r
 /**\r
   Flush the cursor on the screen.\r
-  \r
+\r
   If CursorVisible is FALSE, nothing to do and return directly.\r
-  If CursorVisible is TRUE, \r
+  If CursorVisible is TRUE,\r
      i) If the cursor shows on screen, it will be erased.\r
-    ii) If the cursor does not show on screen, it will be shown. \r
+    ii) If the cursor does not show on screen, it will be shown.\r
 \r
   @param  This                  Protocol instance pointer.\r
 \r
@@ -1915,7 +2040,9 @@ RegisterFontPackage (
                   NULL,\r
                   (VOID **) &HiiDatabase\r
                   );\r
-  ASSERT_EFI_ERROR (Status);\r
+  if (EFI_ERROR (Status)) {\r
+    return;\r
+  }\r
 \r
   //\r
   // Add 4 bytes to the header for entire length for HiiAddPackages use only.\r