]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c
Fix warnings generated by gcc for ia32 builds:
[mirror_edk2.git] / MdeModulePkg / Universal / Console / ConSplitterDxe / ConSplitter.c
index 39e67c8f42f8bb5899a7783df6fe3f497d86e53e..a6fecb8772b7f97cc8b836381ac9e14672597910 100644 (file)
@@ -90,7 +90,7 @@ STATIC TEXT_IN_SPLITTER_PRIVATE_DATA  mConIn = {
     0x10000, //AbsoluteMaxX\r
     0x10000, //AbsoluteMaxY\r
     0x10000, //AbsoluteMaxZ\r
-    0        //Attributes    \r
+    0        //Attributes\r
   },\r
   0,\r
   (EFI_ABSOLUTE_POINTER_PROTOCOL **) NULL,\r
@@ -117,6 +117,19 @@ STATIC TEXT_IN_SPLITTER_PRIVATE_DATA  mConIn = {
   FALSE\r
 };\r
 \r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UGA_DRAW_PROTOCOL gUgaDrawProtocolTemplate = {\r
+  ConSpliterUgaDrawGetMode,\r
+  ConSpliterUgaDrawSetMode,\r
+  ConSpliterUgaDrawBlt\r
+};\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_GRAPHICS_OUTPUT_PROTOCOL gGraphicsOutputProtocolTemplate = {\r
+  ConSpliterGraphicsOutputQueryMode,\r
+  ConSpliterGraphicsOutputSetMode,\r
+  ConSpliterGraphicsOutputBlt,\r
+  NULL\r
+};\r
+\r
 STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut = {\r
   TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE,\r
   (EFI_HANDLE) NULL,\r
@@ -141,9 +154,9 @@ STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut = {
     FALSE,\r
   },\r
   {\r
-    ConSpliterUgaDrawGetMode,\r
-    ConSpliterUgaDrawSetMode,\r
-    ConSpliterUgaDrawBlt\r
+    NULL,\r
+    NULL,\r
+    NULL\r
   },\r
   0,\r
   0,\r
@@ -151,13 +164,14 @@ STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut = {
   0,\r
   (EFI_UGA_PIXEL *) NULL,\r
   {\r
-    ConSpliterGraphicsOutputQueryMode,\r
-    ConSpliterGraphicsOutputSetMode,\r
-    ConSpliterGraphicsOutputBlt,\r
+    NULL,\r
+    NULL,\r
+    NULL,\r
     NULL\r
   },\r
   (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL,\r
-  (TEXT_OUT_GOP_MODE *) NULL,\r
+  (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *) NULL,\r
+  0,\r
   0,\r
   TRUE,\r
   {\r
@@ -204,9 +218,9 @@ STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mStdErr = {
     FALSE,\r
   },\r
   {\r
-    ConSpliterUgaDrawGetMode,\r
-    ConSpliterUgaDrawSetMode,\r
-    ConSpliterUgaDrawBlt\r
+    NULL,\r
+    NULL,\r
+    NULL\r
   },\r
   0,\r
   0,\r
@@ -214,13 +228,14 @@ STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mStdErr = {
   0,\r
   (EFI_UGA_PIXEL *) NULL,\r
   {\r
-    ConSpliterGraphicsOutputQueryMode,\r
-    ConSpliterGraphicsOutputSetMode,\r
-    ConSpliterGraphicsOutputBlt,\r
+    NULL,\r
+    NULL,\r
+    NULL,\r
     NULL\r
   },\r
   (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL,\r
-  (TEXT_OUT_GOP_MODE *) NULL,\r
+  (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *) NULL,\r
+  0,\r
   0,\r
   TRUE,\r
   {\r
@@ -429,8 +444,8 @@ Returns:
                     &mConIn.TextInEx,\r
                     &gEfiSimplePointerProtocolGuid,\r
                     &mConIn.SimplePointer,\r
-                                       &gEfiAbsolutePointerProtocolGuid,\r
-                                       &mConIn.AbsolutePointer,\r
+                    &gEfiAbsolutePointerProtocolGuid,\r
+                    &mConIn.AbsolutePointer,\r
                     &gEfiPrimaryConsoleInDeviceGuid,\r
                     NULL,\r
                     NULL\r
@@ -578,7 +593,7 @@ Returns:
 \r
   //\r
   // Buffer for Simple Text Input Ex Protocol\r
-  //  \r
+  //\r
   Status = ConSplitterGrowBuffer (\r
              sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *),\r
              &ConInPrivate->TextInExListCount,\r
@@ -597,7 +612,7 @@ Returns:
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  InitializeListHead (&ConInPrivate->NotifyList); \r
+  InitializeListHead (&ConInPrivate->NotifyList);\r
 \r
   //\r
   // Allocate Buffer and Create Event for Absolute Pointer and Simple Pointer Protocols\r
@@ -605,21 +620,21 @@ Returns:
   ConInPrivate->AbsolutePointer.Mode = &ConInPrivate->AbsolutePointerMode;\r
 \r
   Status = ConSplitterGrowBuffer (\r
-                                 sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL *),\r
-                                 &ConInPrivate->AbsolutePointerListCount,\r
-                                 (VOID **) &ConInPrivate->AbsolutePointerList\r
-                                 );\r
+            sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL *),\r
+            &ConInPrivate->AbsolutePointerListCount,\r
+            (VOID **) &ConInPrivate->AbsolutePointerList\r
+            );\r
   if (EFI_ERROR (Status)) {\r
-         return EFI_OUT_OF_RESOURCES;\r
+    return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
   Status = gBS->CreateEvent (\r
-                         EVT_NOTIFY_WAIT,\r
-                         TPL_NOTIFY,\r
-                         ConSplitterAbsolutePointerWaitForInput,\r
-                         ConInPrivate,\r
-                         &ConInPrivate->AbsolutePointer.WaitForInput\r
-                         );\r
+            EVT_NOTIFY_WAIT,\r
+            TPL_NOTIFY,\r
+            ConSplitterAbsolutePointerWaitForInput,\r
+            ConInPrivate,\r
+            &ConInPrivate->AbsolutePointer.WaitForInput\r
+        );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   ConInPrivate->SimplePointer.Mode = &ConInPrivate->SimplePointerMode;\r
@@ -650,12 +665,30 @@ ConSplitterTextOutConstructor (
   )\r
 {\r
   EFI_STATUS  Status;\r
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info;\r
+\r
+  //\r
+  // Copy protocols template\r
+  //\r
+  if (FeaturePcdGet (PcdConOutUgaSupport)) {\r
+    CopyMem (&ConOutPrivate->UgaDraw, &gUgaDrawProtocolTemplate, sizeof (EFI_UGA_DRAW_PROTOCOL));\r
+  }\r
+\r
+  if (FeaturePcdGet (PcdConOutGopSupport)) {\r
+    CopyMem (&ConOutPrivate->GraphicsOutput, &gGraphicsOutputProtocolTemplate, sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL));\r
+  }\r
 \r
   //\r
   // Initilize console output splitter's private data.\r
   //\r
   ConOutPrivate->TextOut.Mode = &ConOutPrivate->TextOutMode;\r
 \r
+  //\r
+  // When new console device is added, the new mode will be set later,\r
+  // so put current mode back to init state.\r
+  //\r
+  ConOutPrivate->TextOutMode.Mode = 0xFF;\r
+\r
   Status = ConSplitterGrowBuffer (\r
             sizeof (TEXT_OUT_AND_GOP_DATA),\r
             &ConOutPrivate->TextOutListCount,\r
@@ -698,22 +731,25 @@ ConSplitterTextOutConstructor (
     }\r
     //\r
     // Setup the DevNullGraphicsOutput to 800 x 600 x 32 bits per pixel\r
+    // DevNull will be updated to user-defined mode after driver has started.\r
     //\r
-    if ((ConOutPrivate->GraphicsOutputModeBuffer = AllocateZeroPool (sizeof (TEXT_OUT_GOP_MODE))) == NULL) {\r
+    if ((ConOutPrivate->GraphicsOutputModeBuffer = AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION))) == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
-    ConOutPrivate->GraphicsOutputModeBuffer[0].HorizontalResolution = 800;\r
-    ConOutPrivate->GraphicsOutputModeBuffer[0].VerticalResolution = 600;\r
+    Info = &ConOutPrivate->GraphicsOutputModeBuffer[0];\r
+    Info->Version = 0;\r
+    Info->HorizontalResolution = 800;\r
+    Info->VerticalResolution = 600;\r
+    Info->PixelFormat = PixelBltOnly;\r
+    Info->PixelsPerScanLine = 800;\r
+    CopyMem (ConOutPrivate->GraphicsOutput.Mode->Info, Info, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
+    ConOutPrivate->GraphicsOutput.Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
 \r
     //\r
     // Initialize the following items, theset items remain unchanged in GraphicsOutput->SetMode()\r
-    //  GraphicsOutputMode->Info->Version, GraphicsOutputMode->Info->PixelFormat\r
-    //  GraphicsOutputMode->SizeOfInfo, GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize\r
+    // GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize\r
     //\r
-    ConOutPrivate->GraphicsOutput.Mode->Info->Version = 0;\r
-    ConOutPrivate->GraphicsOutput.Mode->Info->PixelFormat = PixelBltOnly;\r
-    ConOutPrivate->GraphicsOutput.Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
-    ConOutPrivate->GraphicsOutput.Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) NULL;\r
+    ConOutPrivate->GraphicsOutput.Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;\r
     ConOutPrivate->GraphicsOutput.Mode->FrameBufferSize = 0;\r
 \r
     ConOutPrivate->GraphicsOutput.Mode->MaxMode = 1;\r
@@ -1072,7 +1108,7 @@ Returns:
   }\r
 \r
   Status = ConSplitterTextInExAddDevice (&mConIn, TextInEx);\r
-   \r
+\r
   return Status;\r
 }\r
 \r
@@ -1153,7 +1189,7 @@ Returns:
              &gEfiAbsolutePointerProtocolGuid,\r
              (VOID **) &AbsolutePointer\r
              );\r
-  \r
+\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
@@ -1200,6 +1236,9 @@ Returns:
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
+\r
+  GraphicsOutput = NULL;\r
+  UgaDraw        = NULL;\r
   //\r
   // Try to Open Graphics Output protocol\r
   //\r
@@ -1211,23 +1250,27 @@ Returns:
                   mConOut.VirtualHandle,\r
                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
                   );\r
-  if (EFI_ERROR (Status)) {\r
-    GraphicsOutput = NULL;\r
+\r
+  if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
+    //\r
+    // Open UGA_DRAW protocol\r
+    //\r
+    Status = gBS->OpenProtocol (\r
+                    ControllerHandle,\r
+                    &gEfiUgaDrawProtocolGuid,\r
+                    (VOID **) &UgaDraw,\r
+                    This->DriverBindingHandle,\r
+                    mConOut.VirtualHandle,\r
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                    );\r
   }\r
+\r
   //\r
-  // Open UGA_DRAW protocol\r
+  // When new console device is added, the new mode will be set later,\r
+  // so put current mode back to init state.\r
   //\r
-  Status = gBS->OpenProtocol (\r
-                  ControllerHandle,\r
-                  &gEfiUgaDrawProtocolGuid,\r
-                  (VOID **) &UgaDraw,\r
-                  This->DriverBindingHandle,\r
-                  mConOut.VirtualHandle,\r
-                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    UgaDraw = NULL;\r
-  }\r
+  mConOut.TextOutMode.Mode = 0xFF;\r
+\r
   //\r
   // If both ConOut and StdErr incorporate the same Text Out device,\r
   // their MaxMode and QueryData should be the intersection of both.\r
@@ -1235,7 +1278,7 @@ Returns:
   Status = ConSplitterTextOutAddDevice (&mConOut, TextOut, GraphicsOutput, UgaDraw);\r
   ConSplitterTextOutSetAttribute (&mConOut.TextOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
 \r
-  if (FeaturePcdGet (PcdConOutUgaSupport)) {\r
+  if (FeaturePcdGet (PcdConOutUgaSupport) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
     //\r
     // Match the UGA mode data of ConOut with the current mode\r
     //\r
@@ -1289,6 +1332,13 @@ Returns:
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
+\r
+  //\r
+  // When new console device is added, the new mode will be set later,\r
+  // so put current mode back to init state.\r
+  //\r
+  mStdErr.TextOutMode.Mode = 0xFF;\r
+\r
   //\r
   // If both ConOut and StdErr incorporate the same Text Out device,\r
   // their MaxMode and QueryData should be the intersection of both.\r
@@ -1417,8 +1467,8 @@ Returns:
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
-  \r
-  \r
+\r
+\r
   Status = ConSplitterStop (\r
             This,\r
             ControllerHandle,\r
@@ -2122,12 +2172,20 @@ Returns:
   Mode  = 0;\r
   Index = 0;\r
   while (Mode < MaxMode) {\r
-    TextOut->QueryMode (\r
-              TextOut,\r
-              Mode,\r
-              &Private->TextOutQueryData[Mode].Columns,\r
-              &Private->TextOutQueryData[Mode].Rows\r
-              );\r
+    Status = TextOut->QueryMode (\r
+                  TextOut,\r
+                  Mode,\r
+                  &Private->TextOutQueryData[Mode].Columns,\r
+                  &Private->TextOutQueryData[Mode].Rows\r
+                  );\r
+    //\r
+    // If mode 1 (80x50) is not supported, make sure mode 1 in TextOutQueryData\r
+    // is clear to 0x0.\r
+    //\r
+    if ((EFI_ERROR(Status)) && (Mode == 1)) {\r
+      Private->TextOutQueryData[Mode].Columns = 0;\r
+      Private->TextOutQueryData[Mode].Rows = 0;\r
+    }\r
     Private->TextOutModeMap[Index] = Mode;\r
     Mode++;\r
     Index += Private->TextOutListCount;\r
@@ -2136,6 +2194,24 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Reconstruct TextOutModeMap to get intersection of modes\r
+\r
+  This routine reconstruct TextOutModeMap to get the intersection\r
+  of modes for all console out devices. Because EFI/UEFI spec require\r
+  mode 0 is 80x25, mode 1 is 80x50, this routine will not check the\r
+  intersection for mode 0 and mode 1.\r
+\r
+  @parm TextOutModeMap  Current text out mode map, begin with the mode 80x25\r
+  @parm NewlyAddedMap   New text out mode map, begin with the mode 80x25\r
+  @parm MapStepSize     Mode step size for one console device\r
+  @parm NewMapStepSize  Mode step size for one console device\r
+  @parm MaxMode         Current max text mode\r
+  @parm CurrentMode     Current text mode\r
+\r
+  @retval None\r
+\r
+**/\r
 STATIC\r
 VOID\r
 ConSplitterGetIntersection (\r
@@ -2153,9 +2229,16 @@ ConSplitterGetIntersection (
   INT32 CurrentMaxMode;\r
   INT32 Mode;\r
 \r
-  Index           = 0;\r
-  CurrentMapEntry = TextOutModeMap;\r
-  NextMapEntry    = TextOutModeMap;\r
+  //\r
+  // According to EFI/UEFI spec, mode 0 and mode 1 have been reserved\r
+  // for 80x25 and 80x50 in Simple Text Out protocol, so don't make intersection\r
+  // for mode 0 and mode 1, mode number starts from 2.\r
+  //\r
+  Index           = 2;\r
+  CurrentMapEntry = &TextOutModeMap[MapStepSize * 2];\r
+  NextMapEntry    = &TextOutModeMap[MapStepSize * 2];\r
+  NewlyAddedMap   = &NewlyAddedMap[NewMapStepSize * 2];\r
+\r
   CurrentMaxMode  = *MaxMode;\r
   Mode            = *CurrentMode;\r
 \r
@@ -2213,10 +2296,12 @@ Returns:
   INT32                         Index;\r
   INT32                         *TextOutModeMap;\r
   INT32                         *MapTable;\r
+  INT32                         QueryMode;\r
   TEXT_OUT_SPLITTER_QUERY_DATA  *TextOutQueryData;\r
   UINTN                         Rows;\r
   UINTN                         Columns;\r
   UINTN                         StepSize;\r
+  EFI_STATUS                    Status;\r
 \r
   //\r
   // Must make sure that current mode won't change even if mode number changes\r
@@ -2232,14 +2317,23 @@ Returns:
   Mode      = 0;\r
   MapTable  = TextOutModeMap + Private->CurrentNumberOfConsoles;\r
   while (Mode < TextOut->Mode->MaxMode) {\r
-    TextOut->QueryMode (TextOut, Mode, &Columns, &Rows);\r
-\r
+    Status = TextOut->QueryMode (TextOut, Mode, &Columns, &Rows);\r
+    if (EFI_ERROR(Status)) {\r
+      if (Mode == 1) {\r
+        MapTable[StepSize] = Mode;\r
+        TextOutQueryData[Mode].Columns = 0;\r
+        TextOutQueryData[Mode].Rows = 0;\r
+      }\r
+      Mode++;\r
+      continue;\r
+    }\r
     //\r
-    // Search the QueryData database to see if they intersects\r
+    // Search the intersection map and QueryData database to see if they intersects\r
     //\r
     Index = 0;\r
     while (Index < CurrentMaxMode) {\r
-      if ((TextOutQueryData[Index].Rows == Rows) && (TextOutQueryData[Index].Columns == Columns)) {\r
+      QueryMode = *(TextOutModeMap + Index * StepSize);\r
+      if ((TextOutQueryData[QueryMode].Rows == Rows) && (TextOutQueryData[QueryMode].Columns == Columns)) {\r
         MapTable[Index * StepSize] = Mode;\r
         break;\r
       }\r
@@ -2278,7 +2372,7 @@ Arguments:
 \r
 Returns:\r
 \r
-  None\r
+  EFI_SUCCESS\r
   EFI_OUT_OF_RESOURCES\r
 \r
 --*/\r
@@ -2289,10 +2383,14 @@ Returns:
   TEXT_OUT_AND_GOP_DATA         *StdErrTextOutList;\r
   UINTN                         Indexi;\r
   UINTN                         Indexj;\r
-  UINTN                         Rows;\r
-  UINTN                         Columns;\r
+  UINTN                         ConOutRows;\r
+  UINTN                         ConOutColumns;\r
+  UINTN                         StdErrRows;\r
+  UINTN                         StdErrColumns;\r
   INT32                         ConOutMaxMode;\r
   INT32                         StdErrMaxMode;\r
+  INT32                         ConOutMode;\r
+  INT32                         StdErrMode;\r
   INT32                         Mode;\r
   INT32                         Index;\r
   INT32                         *ConOutModeMap;\r
@@ -2301,6 +2399,8 @@ Returns:
   INT32                         *StdErrMapTable;\r
   TEXT_OUT_SPLITTER_QUERY_DATA  *ConOutQueryData;\r
   TEXT_OUT_SPLITTER_QUERY_DATA  *StdErrQueryData;\r
+  UINTN                         ConOutStepSize;\r
+  UINTN                         StdErrStepSize;\r
   BOOLEAN                       FoundTheSameTextOut;\r
   UINTN                         ConOutMapTableSize;\r
   UINTN                         StdErrMapTableSize;\r
@@ -2336,10 +2436,12 @@ Returns:
   //\r
   ConOutMaxMode     = mConOut.TextOutMode.MaxMode;\r
   ConOutModeMap     = mConOut.TextOutModeMap;\r
+  ConOutStepSize    = mConOut.TextOutListCount;\r
   ConOutQueryData   = mConOut.TextOutQueryData;\r
 \r
   StdErrMaxMode     = mStdErr.TextOutMode.MaxMode;\r
   StdErrModeMap     = mStdErr.TextOutModeMap;\r
+  StdErrStepSize    = mStdErr.TextOutListCount;\r
   StdErrQueryData   = mStdErr.TextOutQueryData;\r
 \r
   //\r
@@ -2368,13 +2470,17 @@ Returns:
   Mode = 0;\r
   while (Mode < ConOutMaxMode) {\r
     //\r
-    // Search the other's QueryData database to see if they intersect\r
+    // Search the intersection map and QueryData database to see if they intersect\r
     //\r
-    Index   = 0;\r
-    Rows    = ConOutQueryData[Mode].Rows;\r
-    Columns = ConOutQueryData[Mode].Columns;\r
+    Index = 0;\r
+    ConOutMode    = *(ConOutModeMap + Mode * ConOutStepSize);\r
+    ConOutRows    = ConOutQueryData[ConOutMode].Rows;\r
+    ConOutColumns = ConOutQueryData[ConOutMode].Columns;\r
     while (Index < StdErrMaxMode) {\r
-      if ((StdErrQueryData[Index].Rows == Rows) && (StdErrQueryData[Index].Columns == Columns)) {\r
+      StdErrMode    = *(StdErrModeMap + Index * StdErrStepSize);\r
+      StdErrRows    = StdErrQueryData[StdErrMode].Rows;\r
+      StdErrColumns = StdErrQueryData[StdErrMode].Columns;\r
+      if ((StdErrRows == ConOutRows) && (StdErrColumns == ConOutColumns)) {\r
         ConOutMapTable[Mode]  = 1;\r
         StdErrMapTable[Index] = 1;\r
         break;\r
@@ -2440,14 +2546,20 @@ Returns:
 {\r
   EFI_STATUS                           Status;\r
   UINTN                                Index;\r
-  TEXT_OUT_GOP_MODE                    *Mode;\r
+  UINTN                                CurrentIndex;\r
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Mode;\r
   UINTN                                SizeOfInfo;\r
   EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
   EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE    *CurrentGraphicsOutputMode;\r
-  TEXT_OUT_GOP_MODE                    *ModeBuffer;\r
-  TEXT_OUT_GOP_MODE                    *MatchedMode;\r
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *ModeBuffer;\r
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *MatchedMode;\r
   UINTN                                NumberIndex;\r
   BOOLEAN                              Match;\r
+  BOOLEAN                              AlreadyExist;\r
+  UINT32                               UgaHorizontalResolution;\r
+  UINT32                               UgaVerticalResolution;\r
+  UINT32                               UgaColorDepth;\r
+  UINT32                               UgaRefreshRate;\r
 \r
   if ((GraphicsOutput == NULL) && (UgaDraw == NULL)) {\r
     return EFI_UNSUPPORTED;\r
@@ -2455,6 +2567,18 @@ Returns:
 \r
   CurrentGraphicsOutputMode = Private->GraphicsOutput.Mode;\r
 \r
+  Index        = 0;\r
+  CurrentIndex = 0;\r
+\r
+  if (Private->CurrentNumberOfUgaDraw != 0) {\r
+    //\r
+    // If any UGA device has already been added, then there is no need to\r
+    // calculate intersection of display mode of different GOP/UGA device,\r
+    // since only one display mode will be exported (i.e. user-defined mode)\r
+    //\r
+    goto Done;\r
+  }\r
+\r
   if (GraphicsOutput != NULL) {\r
     if (Private->CurrentNumberOfGraphicsOutput == 0) {\r
         //\r
@@ -2470,7 +2594,7 @@ Returns:
         //\r
         // Allocate resource for the private mode buffer\r
         //\r
-        ModeBuffer = AllocatePool (sizeof (TEXT_OUT_GOP_MODE) * GraphicsOutput->Mode->MaxMode);\r
+        ModeBuffer = AllocatePool (GraphicsOutput->Mode->SizeOfInfo * GraphicsOutput->Mode->MaxMode);\r
         if (ModeBuffer == NULL) {\r
           return EFI_OUT_OF_RESOURCES;\r
         }\r
@@ -2486,8 +2610,7 @@ Returns:
           if (EFI_ERROR (Status)) {\r
             return Status;\r
           }\r
-          Mode->HorizontalResolution = Info->HorizontalResolution;\r
-          Mode->VerticalResolution = Info->VerticalResolution;\r
+          CopyMem (Mode, Info, SizeOfInfo);\r
           Mode++;\r
           FreePool (Info);\r
         }\r
@@ -2495,7 +2618,7 @@ Returns:
       //\r
       // Check intersection of display mode\r
       //\r
-      ModeBuffer = AllocatePool (sizeof (TEXT_OUT_GOP_MODE) * CurrentGraphicsOutputMode->MaxMode);\r
+      ModeBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION) * CurrentGraphicsOutputMode->MaxMode);\r
       if (ModeBuffer == NULL) {\r
         return EFI_OUT_OF_RESOURCES;\r
       }\r
@@ -2511,7 +2634,7 @@ Returns:
             return Status;\r
           }\r
           if ((Info->HorizontalResolution == Mode->HorizontalResolution) &&\r
-              (Info->VerticalResolution == Mode->VerticalResolution)){\r
+              (Info->VerticalResolution == Mode->VerticalResolution)) {\r
             Match = TRUE;\r
             FreePool (Info);\r
             break;\r
@@ -2520,8 +2643,28 @@ Returns:
         }\r
 \r
         if (Match) {\r
-          CopyMem (MatchedMode, Mode, sizeof (TEXT_OUT_GOP_MODE));\r
-          MatchedMode++;\r
+          AlreadyExist = FALSE;\r
+\r
+          for (Info = ModeBuffer; Info < MatchedMode; Info++) {\r
+            if ((Info->HorizontalResolution == Mode->HorizontalResolution) &&\r
+                (Info->VerticalResolution == Mode->VerticalResolution)) {\r
+              AlreadyExist = TRUE;\r
+              break;\r
+            }\r
+          }\r
+\r
+          if (!AlreadyExist) {\r
+            CopyMem (MatchedMode, Mode, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
+\r
+            //\r
+            // Physical frame buffer is no longer available, change PixelFormat to PixelBltOnly\r
+            //\r
+            MatchedMode->Version = 0;\r
+            MatchedMode->PixelFormat = PixelBltOnly;\r
+            ZeroMem (&MatchedMode->PixelInformation, sizeof (EFI_PIXEL_BITMASK));\r
+\r
+            MatchedMode++;\r
+          }\r
         }\r
 \r
         Mode++;\r
@@ -2536,61 +2679,80 @@ Returns:
       //\r
       // Physical frame buffer is no longer available when there are more than one physical GOP devices\r
       //\r
-      CurrentGraphicsOutputMode->MaxMode = (UINT32) (((UINTN) MatchedMode - (UINTN) ModeBuffer) / sizeof (TEXT_OUT_GOP_MODE));\r
+      CurrentGraphicsOutputMode->MaxMode = (UINT32) (((UINTN) MatchedMode - (UINTN) ModeBuffer) / sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
       CurrentGraphicsOutputMode->Info->PixelFormat = PixelBltOnly;\r
       ZeroMem (&CurrentGraphicsOutputMode->Info->PixelInformation, sizeof (EFI_PIXEL_BITMASK));\r
       CurrentGraphicsOutputMode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
-      CurrentGraphicsOutputMode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) NULL;\r
+      CurrentGraphicsOutputMode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;\r
       CurrentGraphicsOutputMode->FrameBufferSize = 0;\r
     }\r
 \r
     //\r
-    // Select a prefered Display mode 800x600\r
+    // Graphics console driver can ensure the same mode for all GOP devices\r
     //\r
     for (Index = 0; Index < CurrentGraphicsOutputMode->MaxMode; Index++) {\r
       Mode = &Private->GraphicsOutputModeBuffer[Index];\r
-      if ((Mode->HorizontalResolution == 800) && (Mode->VerticalResolution == 600)) {\r
+      if ((Mode->HorizontalResolution == GraphicsOutput->Mode->Info->HorizontalResolution) &&\r
+         (Mode->VerticalResolution == GraphicsOutput->Mode->Info->VerticalResolution)) {\r
+        CurrentIndex = Index;\r
         break;\r
       }\r
     }\r
-    //\r
-    // Prefered mode is not found, set to mode 0\r
-    //\r
     if (Index >= CurrentGraphicsOutputMode->MaxMode) {\r
-      Index = 0;\r
+      //\r
+      // if user defined mode is not found, set to default mode 800x600\r
+      //\r
+      for (Index = 0; Index < CurrentGraphicsOutputMode->MaxMode; Index++) {\r
+        Mode = &Private->GraphicsOutputModeBuffer[Index];\r
+        if ((Mode->HorizontalResolution == 800) && (Mode->VerticalResolution == 600)) {\r
+          CurrentIndex = Index;\r
+          break;\r
+        }\r
+      }\r
     }\r
-\r
-    //\r
-    // Current mode number may need update now, so set it to an invalide mode number\r
-    //\r
-    CurrentGraphicsOutputMode->Mode = 0xffff;\r
-  } else {\r
+  }\r
+  if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
     //\r
-    // For UGA device, it's inconvenient to retrieve all the supported display modes.\r
-    // To simplify the implementation, only add one resolution(800x600, 32bit color depth) as defined in UEFI spec\r
+    // Graphics console driver can ensure the same mode for all GOP devices\r
+    // so we can get the current mode from this video device\r
     //\r
+    UgaDraw->GetMode (\r
+               UgaDraw,\r
+               &UgaHorizontalResolution,\r
+               &UgaVerticalResolution,\r
+               &UgaColorDepth,\r
+               &UgaRefreshRate\r
+               );\r
+\r
     CurrentGraphicsOutputMode->MaxMode = 1;\r
-    CurrentGraphicsOutputMode->Info->Version = 0;\r
-    CurrentGraphicsOutputMode->Info->HorizontalResolution = 800;\r
-    CurrentGraphicsOutputMode->Info->VerticalResolution = 600;\r
-    CurrentGraphicsOutputMode->Info->PixelFormat = PixelBltOnly;\r
-    CurrentGraphicsOutputMode->Info->PixelsPerScanLine = 800;\r
+    Info = CurrentGraphicsOutputMode->Info;\r
+    Info->Version = 0;\r
+    Info->HorizontalResolution = UgaHorizontalResolution;\r
+    Info->VerticalResolution = UgaVerticalResolution;\r
+    Info->PixelFormat = PixelBltOnly;\r
+    Info->PixelsPerScanLine = UgaHorizontalResolution;\r
     CurrentGraphicsOutputMode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
-    CurrentGraphicsOutputMode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) NULL;\r
+    CurrentGraphicsOutputMode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;\r
     CurrentGraphicsOutputMode->FrameBufferSize = 0;\r
 \r
     //\r
     // Update the private mode buffer\r
     //\r
-    ModeBuffer = &Private->GraphicsOutputModeBuffer[0];\r
-    ModeBuffer->HorizontalResolution = 800;\r
-    ModeBuffer->VerticalResolution   = 600;\r
+    CopyMem (&Private->GraphicsOutputModeBuffer[0], Info, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
 \r
     //\r
-    // Current mode is unknow now, set it to an invalid mode number 0xffff\r
+    // Only mode 0 is available to be set\r
     //\r
-    CurrentGraphicsOutputMode->Mode = 0xffff;\r
-    Index = 0;\r
+    CurrentIndex = 0;\r
+  }\r
+\r
+Done:\r
+\r
+  if (GraphicsOutput != NULL) {\r
+    Private->CurrentNumberOfGraphicsOutput++;\r
+  }\r
+  if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
+    Private->CurrentNumberOfUgaDraw++;\r
   }\r
 \r
   //\r
@@ -2598,13 +2760,133 @@ Returns:
   // regardless whether the console is in EfiConsoleControlScreenGraphics or EfiConsoleControlScreenText mode\r
   //\r
   Private->HardwareNeedsStarting = TRUE;\r
-  Status = Private->GraphicsOutput.SetMode (&Private->GraphicsOutput, (UINT32) Index);\r
+  //\r
+  // Current mode number may need update now, so set it to an invalid mode number\r
+  //\r
+  CurrentGraphicsOutputMode->Mode = 0xffff;\r
+  //\r
+  // Graphics console can ensure all GOP devices have the same mode which can be taken as current mode.\r
+  //\r
+  Status = Private->GraphicsOutput.SetMode (&Private->GraphicsOutput, (UINT32) CurrentIndex);\r
 \r
-  Private->CurrentNumberOfGraphicsOutput++;\r
+  //\r
+  // If user defined mode is not valid for UGA, set to the default mode 800x600.\r
+  //\r
+  if (EFI_ERROR(Status)) {\r
+    (Private->GraphicsOutputModeBuffer[0]).HorizontalResolution = 800;\r
+    (Private->GraphicsOutputModeBuffer[0]).VerticalResolution   = 600;\r
+    Status = Private->GraphicsOutput.SetMode (&Private->GraphicsOutput, 0);\r
+  }\r
 \r
   return Status;\r
 }\r
 \r
+VOID\r
+ConsplitterSetConsoleOutMode (\r
+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This routine will get the current console mode information (column, row)\r
+  from ConsoleOutMode variable and set it; if the variable does not exist,\r
+  set to user defined console mode.\r
+\r
+Arguments:\r
+\r
+  None\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  UINTN                         Col;\r
+  UINTN                         Row;\r
+  UINTN                         Mode;\r
+  UINTN                         PreferMode;\r
+  UINTN                         BaseMode;\r
+  UINTN                         ModeInfoSize;\r
+  UINTN                         MaxMode;\r
+  EFI_STATUS                    Status;\r
+  CONSOLE_OUT_MODE              *ModeInfo;\r
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *TextOut;\r
+\r
+  PreferMode   = 0xFF;\r
+  BaseMode     = 0xFF;\r
+  TextOut      = &Private->TextOut;\r
+  MaxMode      = (UINTN) (TextOut->Mode->MaxMode);\r
+  ModeInfoSize = sizeof (CONSOLE_OUT_MODE);\r
+\r
+  ModeInfo = AllocateZeroPool (sizeof(CONSOLE_OUT_MODE));\r
+  ASSERT(ModeInfo != NULL);\r
+\r
+  Status = gRT->GetVariable (\r
+                   VarConOutMode,\r
+                   &gEfiGenericPlatformVariableGuid,\r
+                   NULL,\r
+                   &ModeInfoSize,\r
+                   ModeInfo\r
+                   );\r
+\r
+  //\r
+  // Set to the default mode 80 x 25 required by EFI/UEFI spec;\r
+  // user can also define other valid default console mode here.\r
+  //\r
+  if (EFI_ERROR(Status)) {\r
+    ModeInfo->Column = 80;\r
+    ModeInfo->Row    = 25;\r
+    Status = gRT->SetVariable (\r
+                    VarConOutMode,\r
+                    &gEfiGenericPlatformVariableGuid,\r
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+                    sizeof (CONSOLE_OUT_MODE),\r
+                    ModeInfo\r
+                    );\r
+  }\r
+\r
+  for (Mode = 0; Mode < MaxMode; Mode++) {\r
+    Status = TextOut->QueryMode (TextOut, Mode, &Col, &Row);\r
+    if (!EFI_ERROR(Status)) {\r
+      if (Col == ModeInfo->Column && Row == ModeInfo->Row) {\r
+        PreferMode = Mode;\r
+      }\r
+      if (Col == 80 && Row == 25) {\r
+        BaseMode = Mode;\r
+      }\r
+    }\r
+  }\r
+\r
+  Status = TextOut->SetMode (TextOut, PreferMode);\r
+\r
+  //\r
+  // if current mode setting is failed, default 80x25 mode will be set.\r
+  //\r
+  if (EFI_ERROR(Status)) {\r
+    Status = TextOut->SetMode (TextOut, BaseMode);\r
+    ASSERT(!EFI_ERROR(Status));\r
+\r
+    ModeInfo->Column = 80;\r
+    ModeInfo->Row    = 25;\r
+\r
+    //\r
+    // Update ConOutMode variable\r
+    //\r
+    Status = gRT->SetVariable (\r
+                    VarConOutMode,\r
+                    &gEfiGenericPlatformVariableGuid,\r
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+                    sizeof (CONSOLE_OUT_MODE),\r
+                    ModeInfo\r
+                    );\r
+  }\r
+\r
+  gBS->FreePool (ModeInfo);\r
+}\r
+\r
+\r
 EFI_STATUS\r
 ConSplitterTextOutAddDevice (\r
   IN  TEXT_OUT_SPLITTER_PRIVATE_DATA     *Private,\r
@@ -2628,6 +2910,10 @@ Returns:
   UINTN                 CurrentNumOfConsoles;\r
   INT32                 CurrentMode;\r
   INT32                 MaxMode;\r
+  UINT32                UgaHorizontalResolution;\r
+  UINT32                UgaVerticalResolution;\r
+  UINT32                UgaColorDepth;\r
+  UINT32                UgaRefreshRate;\r
   TEXT_OUT_AND_GOP_DATA *TextAndGop;\r
 \r
   Status                = EFI_SUCCESS;\r
@@ -2662,12 +2948,12 @@ Returns:
 \r
   if ((GraphicsOutput == NULL) && (UgaDraw == NULL)) {\r
     //\r
-    // If No UGA device then use the ConOut device\r
+    // If No GOP/UGA device then use the ConOut device\r
     //\r
     TextAndGop->TextOutEnabled = TRUE;\r
   } else {\r
     //\r
-    // If UGA device use ConOut device only used if UGA screen is in Text mode\r
+    // If GOP/UGA device use ConOut device only used if screen is in Text mode\r
     //\r
     TextAndGop->TextOutEnabled = (BOOLEAN) (Private->ConsoleOutputMode == EfiConsoleControlScreenText);\r
   }\r
@@ -2694,15 +2980,50 @@ Returns:
   MaxMode     = Private->TextOutMode.MaxMode;\r
   ASSERT (MaxMode >= 1);\r
 \r
+  //\r
+  // Update DevNull mode according to current video device\r
+  //\r
   if (FeaturePcdGet (PcdConOutGopSupport)) {\r
     if ((GraphicsOutput != NULL) || (UgaDraw != NULL)) {\r
       ConSplitterAddGraphicsOutputMode (Private, GraphicsOutput, UgaDraw);\r
     }\r
   }\r
+  if (FeaturePcdGet (PcdConOutUgaSupport)) {\r
+    if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
+      Status = UgaDraw->GetMode (\r
+                    UgaDraw,\r
+                    &UgaHorizontalResolution,\r
+                    &UgaVerticalResolution,\r
+                    &UgaColorDepth,\r
+                    &UgaRefreshRate\r
+                    );\r
+      if (!EFI_ERROR (Status)) {\r
+        Status = ConSpliterUgaDrawSetMode (\r
+                    &Private->UgaDraw,\r
+                    UgaHorizontalResolution,\r
+                    UgaVerticalResolution,\r
+                    UgaColorDepth,\r
+                    UgaRefreshRate\r
+                    );\r
+      }\r
+      //\r
+      // If GetMode/SetMode is failed, set to 800x600 mode\r
+      //\r
+      if(EFI_ERROR (Status)) {\r
+        Status = ConSpliterUgaDrawSetMode (\r
+                    &Private->UgaDraw,\r
+                    800,\r
+                    600,\r
+                    32,\r
+                    60\r
+                    );\r
+      }\r
+    }\r
+  }\r
 \r
   if (Private->ConsoleOutputMode == EfiConsoleControlScreenGraphics && GraphicsOutput != NULL) {\r
     //\r
-    // We just added a new UGA device in graphics mode\r
+    // We just added a new GOP or UGA device in graphics mode\r
     //\r
     if (FeaturePcdGet (PcdConOutGopSupport)) {\r
       DevNullGopSync (Private, TextAndGop->GraphicsOutput, TextAndGop->UgaDraw);\r
@@ -2713,7 +3034,7 @@ Returns:
     //\r
     // The new console supports the same mode of the current console so sync up\r
     //\r
-    DevNullSyncGopStdOut (Private);\r
+    DevNullSyncStdOut (Private);\r
   } else {\r
     //\r
     // If ConOut, then set the mode to Mode #0 which us 80 x 25\r
@@ -2721,6 +3042,12 @@ Returns:
     Private->TextOut.SetMode (&Private->TextOut, 0);\r
   }\r
 \r
+  //\r
+  // After adding new console device, all existing console devices should be\r
+  // synced to the current shared mode.\r
+  //\r
+  ConsplitterSetConsoleOutMode (Private);\r
+\r
   return Status;\r
 }\r
 \r
@@ -2757,6 +3084,12 @@ Returns:
     if (TextOutList->TextOut == TextOut) {\r
       CopyMem (TextOutList, TextOutList + 1, sizeof (TEXT_OUT_AND_GOP_DATA) * Index);\r
       CurrentNumOfConsoles--;\r
+      if (TextOutList->UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
+        Private->CurrentNumberOfUgaDraw--;\r
+      }\r
+      if (TextOutList->GraphicsOutput != NULL) {\r
+        Private->CurrentNumberOfGraphicsOutput--;\r
+      }\r
       break;\r
     }\r
 \r
@@ -3175,36 +3508,36 @@ Routine Description:
 \r
 Arguments:\r
 \r
-  RegsiteredData    - A pointer to a buffer that is filled in with the keystroke \r
+  RegsiteredData    - A pointer to a buffer that is filled in with the keystroke\r
                       state data for the key that was registered.\r
-  InputData         - A pointer to a buffer that is filled in with the keystroke \r
+  InputData         - A pointer to a buffer that is filled in with the keystroke\r
                       state data for the key that was pressed.\r
 \r
 Returns:\r
   TRUE              - Key be pressed matches a registered key.\r
-  FLASE             - Match failed. \r
-  \r
+  FLASE             - Match failed.\r
+\r
 --*/\r
 {\r
   ASSERT (RegsiteredData != NULL && InputData != NULL);\r
-  \r
+\r
   if ((RegsiteredData->Key.ScanCode    != InputData->Key.ScanCode) ||\r
       (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {\r
-    return FALSE;  \r
-  }      \r
-  \r
+    return FALSE;\r
+  }\r
+\r
   //\r
   // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.\r
   //\r
   if (RegsiteredData->KeyState.KeyShiftState != 0 &&\r
       RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) {\r
-    return FALSE;    \r
-  }   \r
+    return FALSE;\r
+  }\r
   if (RegsiteredData->KeyState.KeyToggleState != 0 &&\r
       RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {\r
-    return FALSE;    \r
-  }     \r
-  \r
+    return FALSE;\r
+  }\r
+\r
   return TRUE;\r
 \r
 }\r
@@ -3230,7 +3563,7 @@ ConSplitterTextInResetEx (
 \r
   Returns:\r
     EFI_SUCCESS           - The device was reset.\r
-    EFI_DEVICE_ERROR      - The device is not functioning properly and could \r
+    EFI_DEVICE_ERROR      - The device is not functioning properly and could\r
                             not be reset.\r
 \r
 --*/\r
@@ -3270,20 +3603,20 @@ ConSplitterTextInReadKeyStrokeEx (
 /*++\r
 \r
   Routine Description:\r
-    Reads the next keystroke from the input device. The WaitForKey Event can \r
+    Reads the next keystroke from the input device. The WaitForKey Event can\r
     be used to test for existance of a keystroke via WaitForEvent () call.\r
 \r
   Arguments:\r
     This       - Protocol instance pointer.\r
-    KeyData    - A pointer to a buffer that is filled in with the keystroke \r
+    KeyData    - A pointer to a buffer that is filled in with the keystroke\r
                  state data for the key that was pressed.\r
 \r
   Returns:\r
     EFI_SUCCESS           - The keystroke information was returned.\r
     EFI_NOT_READY         - There was no keystroke data availiable.\r
-    EFI_DEVICE_ERROR      - The keystroke information was not returned due to \r
+    EFI_DEVICE_ERROR      - The keystroke information was not returned due to\r
                             hardware errors.\r
-    EFI_INVALID_PARAMETER - KeyData is NULL.                        \r
+    EFI_INVALID_PARAMETER - KeyData is NULL.\r
 \r
 --*/\r
 {\r
@@ -3292,7 +3625,7 @@ ConSplitterTextInReadKeyStrokeEx (
   UINTN                         Index;\r
   EFI_KEY_DATA                  CurrentKeyData;\r
 \r
-  \r
+\r
   if (KeyData == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
@@ -3326,7 +3659,7 @@ ConSplitterTextInReadKeyStrokeEx (
     }\r
   }\r
 \r
-  return EFI_NOT_READY;  \r
+  return EFI_NOT_READY;\r
 }\r
 \r
 EFI_STATUS\r
@@ -3342,17 +3675,17 @@ ConSplitterTextInSetState (
 \r
   Arguments:\r
     This                  - Protocol instance pointer.\r
-    KeyToggleState        - A pointer to the EFI_KEY_TOGGLE_STATE to set the \r
+    KeyToggleState        - A pointer to the EFI_KEY_TOGGLE_STATE to set the\r
                             state for the input device.\r
-                          \r
-  Returns:                \r
+\r
+  Returns:\r
     EFI_SUCCESS           - The device state was set successfully.\r
-    EFI_DEVICE_ERROR      - The device is not functioning correctly and could \r
+    EFI_DEVICE_ERROR      - The device is not functioning correctly and could\r
                             not have the setting adjusted.\r
     EFI_UNSUPPORTED       - The device does not have the ability to set its state.\r
-    EFI_INVALID_PARAMETER - KeyToggleState is NULL.                       \r
+    EFI_INVALID_PARAMETER - KeyToggleState is NULL.\r
 \r
---*/   \r
+--*/\r
 {\r
   TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
   EFI_STATUS                    Status;\r
@@ -3378,7 +3711,7 @@ ConSplitterTextInSetState (
     }\r
   }\r
 \r
-  return EFI_SUCCESS;  \r
+  return EFI_SUCCESS;\r
 \r
 }\r
 \r
@@ -3397,26 +3730,26 @@ ConSplitterTextInRegisterKeyNotify (
 \r
   Arguments:\r
     This                    - Protocol instance pointer.\r
-    KeyData                 - A pointer to a buffer that is filled in with the keystroke \r
+    KeyData                 - A pointer to a buffer that is filled in with the keystroke\r
                               information data for the key that was pressed.\r
-    KeyNotificationFunction - Points to the function to be called when the key \r
-                              sequence is typed specified by KeyData.                        \r
-    NotifyHandle            - Points to the unique handle assigned to the registered notification.                          \r
+    KeyNotificationFunction - Points to the function to be called when the key\r
+                              sequence is typed specified by KeyData.\r
+    NotifyHandle            - Points to the unique handle assigned to the registered notification.\r
 \r
   Returns:\r
     EFI_SUCCESS             - The notification function was registered successfully.\r
     EFI_OUT_OF_RESOURCES    - Unable to allocate resources for necesssary data structures.\r
-    EFI_INVALID_PARAMETER   - KeyData or NotifyHandle is NULL.                       \r
-                              \r
---*/   \r
+    EFI_INVALID_PARAMETER   - KeyData or NotifyHandle is NULL.\r
+\r
+--*/\r
 {\r
   TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
   EFI_STATUS                    Status;\r
   UINTN                         Index;\r
   TEXT_IN_EX_SPLITTER_NOTIFY    *NewNotify;\r
   LIST_ENTRY                    *Link;\r
-  TEXT_IN_EX_SPLITTER_NOTIFY    *CurrentNotify;  \r
-  \r
+  TEXT_IN_EX_SPLITTER_NOTIFY    *CurrentNotify;\r
+\r
 \r
   if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -3425,7 +3758,7 @@ ConSplitterTextInRegisterKeyNotify (
   Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
 \r
   //\r
-  // if no physical console input device exists, \r
+  // if no physical console input device exists,\r
   // return EFI_SUCCESS directly.\r
   //\r
   if (Private->CurrentNumberOfExConsoles <= 0) {\r
@@ -3437,22 +3770,22 @@ ConSplitterTextInRegisterKeyNotify (
   //\r
   for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {\r
     CurrentNotify = CR (\r
-                      Link, \r
-                      TEXT_IN_EX_SPLITTER_NOTIFY, \r
-                      NotifyEntry, \r
+                      Link,\r
+                      TEXT_IN_EX_SPLITTER_NOTIFY,\r
+                      NotifyEntry,\r
                       TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE\r
                       );\r
-    if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { \r
+    if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {\r
       if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
-        *NotifyHandle = CurrentNotify->NotifyHandle;        \r
+        *NotifyHandle = CurrentNotify->NotifyHandle;\r
         return EFI_SUCCESS;\r
       }\r
     }\r
   }\r
-  \r
+\r
   //\r
   // Allocate resource to save the notification function\r
-  //  \r
+  //\r
   NewNotify = (TEXT_IN_EX_SPLITTER_NOTIFY *) AllocateZeroPool (sizeof (TEXT_IN_EX_SPLITTER_NOTIFY));\r
   if (NewNotify == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
@@ -3462,12 +3795,12 @@ ConSplitterTextInRegisterKeyNotify (
     gBS->FreePool (NewNotify);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  NewNotify->Signature         = TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE;     \r
+  NewNotify->Signature         = TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE;\r
   NewNotify->KeyNotificationFn = KeyNotificationFunction;\r
   CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData));\r
-  \r
+\r
   //\r
-  // Return the wrong status of registering key notify of \r
+  // Return the wrong status of registering key notify of\r
   // physical console input device if meet problems\r
   //\r
   for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
@@ -3486,7 +3819,7 @@ ConSplitterTextInRegisterKeyNotify (
 \r
   //\r
   // Use gSimpleTextInExNotifyGuid to get a valid EFI_HANDLE\r
-  //  \r
+  //\r
   Status = gBS->InstallMultipleProtocolInterfaces (\r
                   &NewNotify->NotifyHandle,\r
                   &gSimpleTextInExNotifyGuid,\r
@@ -3496,11 +3829,11 @@ ConSplitterTextInRegisterKeyNotify (
   ASSERT_EFI_ERROR (Status);\r
 \r
   InsertTailList (&mConIn.NotifyList, &NewNotify->NotifyEntry);\r
-  \r
-  *NotifyHandle                = NewNotify->NotifyHandle;  \r
-  \r
-  return EFI_SUCCESS;  \r
-  \r
+\r
+  *NotifyHandle                = NewNotify->NotifyHandle;\r
+\r
+  return EFI_SUCCESS;\r
+\r
 }\r
 \r
 EFI_STATUS\r
@@ -3515,21 +3848,21 @@ ConSplitterTextInUnregisterKeyNotify (
     Remove a registered notification function from a particular keystroke.\r
 \r
   Arguments:\r
-    This                    - Protocol instance pointer.    \r
+    This                    - Protocol instance pointer.\r
     NotificationHandle      - The handle of the notification function being unregistered.\r
 \r
   Returns:\r
     EFI_SUCCESS             - The notification function was unregistered successfully.\r
     EFI_INVALID_PARAMETER   - The NotificationHandle is invalid.\r
-    EFI_NOT_FOUND           - Can not find the matching entry in database.  \r
-                              \r
---*/   \r
+    EFI_NOT_FOUND           - Can not find the matching entry in database.\r
+\r
+--*/\r
 {\r
   TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
   EFI_STATUS                    Status;\r
   UINTN                         Index;\r
   TEXT_IN_EX_SPLITTER_NOTIFY    *CurrentNotify;\r
-  LIST_ENTRY                    *Link;            \r
+  LIST_ENTRY                    *Link;\r
 \r
   if (NotificationHandle == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -3550,7 +3883,7 @@ ConSplitterTextInUnregisterKeyNotify (
   Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
 \r
   //\r
-  // if no physical console input device exists, \r
+  // if no physical console input device exists,\r
   // return EFI_SUCCESS directly.\r
   //\r
   if (Private->CurrentNumberOfExConsoles <= 0) {\r
@@ -3562,14 +3895,14 @@ ConSplitterTextInUnregisterKeyNotify (
     if (CurrentNotify->NotifyHandle == NotificationHandle) {\r
       for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
         Status = Private->TextInExList[Index]->UnregisterKeyNotify (\r
-                                                 Private->TextInExList[Index], \r
+                                                 Private->TextInExList[Index],\r
                                                  CurrentNotify->NotifyHandleList[Index]\r
                                                  );\r
         if (EFI_ERROR (Status)) {\r
           return Status;\r
-        }        \r
+        }\r
       }\r
-      RemoveEntryList (&CurrentNotify->NotifyEntry);      \r
+      RemoveEntryList (&CurrentNotify->NotifyEntry);\r
       Status = gBS->UninstallMultipleProtocolInterfaces (\r
                       CurrentNotify->NotifyHandle,\r
                       &gSimpleTextInExNotifyGuid,\r
@@ -3579,12 +3912,12 @@ ConSplitterTextInUnregisterKeyNotify (
       ASSERT_EFI_ERROR (Status);\r
       gBS->FreePool (CurrentNotify->NotifyHandleList);\r
       gBS->FreePool (CurrentNotify);\r
-      return EFI_SUCCESS;      \r
-    }    \r
+      return EFI_SUCCESS;\r
+    }\r
   }\r
 \r
-  return EFI_NOT_FOUND;    \r
-  \r
+  return EFI_NOT_FOUND;\r
+\r
 }\r
 \r
 EFI_STATUS\r
@@ -3833,9 +4166,9 @@ ConSplitterAbsolutePointerReset (
 \r
   Returns:\r
     EFI_SUCCESS           - The device was reset.\r
-    EFI_DEVICE_ERROR      - The device is not functioning correctly and could \r
+    EFI_DEVICE_ERROR      - The device is not functioning correctly and could\r
                             not be reset.\r
-                            \r
+\r
 --*/\r
 {\r
   EFI_STATUS                    Status;\r
@@ -3846,7 +4179,7 @@ ConSplitterAbsolutePointerReset (
   Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This);\r
 \r
   Private->AbsoluteInputEventSignalState = FALSE;\r
-    \r
+\r
   if (Private->CurrentNumberOfAbsolutePointers == 0) {\r
     return EFI_SUCCESS;\r
   }\r
@@ -3867,7 +4200,7 @@ ConSplitterAbsolutePointerReset (
 }\r
 \r
 EFI_STATUS\r
-EFIAPI \r
+EFIAPI\r
 ConSplitterAbsolutePointerGetState (\r
   IN EFI_ABSOLUTE_POINTER_PROTOCOL   *This,\r
   IN OUT EFI_ABSOLUTE_POINTER_STATE  *State\r
@@ -3884,9 +4217,9 @@ ConSplitterAbsolutePointerGetState (
   Returns:\r
     EFI_SUCCESS           - The state of the pointer device was returned in State..\r
     EFI_NOT_READY         - The state of the pointer device has not changed since the last call to\r
-                            GetState().                                                           \r
+                            GetState().\r
     EFI_DEVICE_ERROR      - A device error occurred while attempting to retrieve the pointer\r
-                            device's current state.                                         \r
+                            device's current state.\r
 --*/\r
 {\r
   TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
@@ -3910,7 +4243,7 @@ ConSplitterAbsolutePointerGetState (
   State->CurrentY                        = 0;\r
   State->CurrentZ                        = 0;\r
   State->ActiveButtons                   = 0;\r
-    \r
+\r
   //\r
   // if no physical pointer device exists, return EFI_NOT_READY;\r
   // if any physical pointer device has changed state,\r
@@ -3939,7 +4272,7 @@ ConSplitterAbsolutePointerGetState (
       if (!(Private->AbsolutePointerMode.AbsoluteMinZ == 0 && Private->AbsolutePointerMode.AbsoluteMaxZ == 0)) {\r
         State->CurrentZ = CurrentState.CurrentZ;\r
       }\r
-      \r
+\r
     } else if (Status == EFI_DEVICE_ERROR) {\r
       ReturnStatus = EFI_DEVICE_ERROR;\r
     }\r
@@ -3985,7 +4318,7 @@ Returns:
   }\r
 \r
   //\r
-  // if AbsoluteInputEventSignalState is flagged before, \r
+  // if AbsoluteInputEventSignalState is flagged before,\r
   // and not cleared by Reset() or GetState(), signal it\r
   //\r
   if (Private->AbsoluteInputEventSignalState) {\r
@@ -4226,6 +4559,8 @@ ConSplitterTextOutQueryMode (
 --*/\r
 {\r
   TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;\r
+  UINTN                           CurrentMode;\r
+  INT32                           *TextOutModeMap;\r
 \r
   Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
 \r
@@ -4241,8 +4576,18 @@ ConSplitterTextOutQueryMode (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  *Columns  = Private->TextOutQueryData[ModeNumber].Columns;\r
-  *Rows     = Private->TextOutQueryData[ModeNumber].Rows;\r
+  //\r
+  // We get the available mode from mode intersection map if it's available\r
+  //\r
+  if (Private->TextOutModeMap != NULL) {\r
+    TextOutModeMap = Private->TextOutModeMap + Private->TextOutListCount * ModeNumber;\r
+    CurrentMode    = (UINTN)(*TextOutModeMap);\r
+    *Columns       = Private->TextOutQueryData[CurrentMode].Columns;\r
+    *Rows          = Private->TextOutQueryData[CurrentMode].Rows;\r
+  } else {\r
+    *Columns  = Private->TextOutQueryData[ModeNumber].Columns;\r
+    *Rows     = Private->TextOutQueryData[ModeNumber].Rows;\r
+  }\r
 \r
   if (*Columns <= 0 && *Rows <= 0) {\r
     return EFI_UNSUPPORTED;\r
@@ -4312,8 +4657,8 @@ ConSplitterTextOutSetMode (
                                                       TextOutModeMap[Index]\r
                                                       );\r
       //\r
-      // If this console device is based on a UGA device, then sync up the bitmap from\r
-      // the UGA splitter and reclear the text portion of the display in the new mode.\r
+      // If this console device is based on a GOP or UGA device, then sync up the bitmap from\r
+      // the GOP/UGA splitter and reclear the text portion of the display in the new mode.\r
       //\r
       if ((Private->TextOutList[Index].GraphicsOutput != NULL) || (Private->TextOutList[Index].UgaDraw != NULL)) {\r
         Private->TextOutList[Index].TextOut->ClearScreen (Private->TextOutList[Index].TextOut);\r
@@ -4486,7 +4831,7 @@ ConSplitterTextOutSetCursorPosition (
   Private   = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
   TextOutModeMap  = NULL;\r
   ModeNumber      = Private->TextOutMode.Mode;\r
-  \r
+\r
   //\r
   // Get current MaxColumn and MaxRow from intersection map\r
   //\r
@@ -4496,7 +4841,7 @@ ConSplitterTextOutSetCursorPosition (
   } else {\r
     CurrentMode = ModeNumber;\r
   }\r
-  \r
+\r
   MaxColumn = Private->TextOutQueryData[CurrentMode].Columns;\r
   MaxRow    = Private->TextOutQueryData[CurrentMode].Rows;\r
 \r
@@ -4577,3 +4922,4 @@ ConSplitterTextOutEnableCursor (
 \r
   return ReturnStatus;\r
 }\r
+\r