]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkModulePkg/Universal/Console/ConSplitter/Dxe/ConSplitter.c
Merge GOP related code from r8->r9.
[mirror_edk2.git] / EdkModulePkg / Universal / Console / ConSplitter / Dxe / ConSplitter.c
index a9d39e945eb31205798294b3523d3c0ee6e3c2c7..fc2903eaa068b0dcf51d208fd7f4c5384288548b 100644 (file)
@@ -39,7 +39,7 @@ Abstract:
 //\r
 // Global Variables\r
 //\r
-static TEXT_IN_SPLITTER_PRIVATE_DATA  mConIn = {\r
+STATIC TEXT_IN_SPLITTER_PRIVATE_DATA  mConIn = {\r
   TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE,\r
   (EFI_HANDLE) NULL,\r
   {\r
@@ -88,7 +88,7 @@ static TEXT_IN_SPLITTER_PRIVATE_DATA  mConIn = {
   FALSE\r
 };\r
 \r
-static TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut = {\r
+STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut = {\r
   TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE,\r
   (EFI_HANDLE) NULL,\r
   {\r
@@ -111,6 +111,7 @@ static TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut = {
     0,\r
     FALSE,\r
   },\r
+#if (EFI_SPECIFICATION_VERSION < 0x00020000)\r
   {\r
     ConSpliterUgaDrawGetMode,\r
     ConSpliterUgaDrawSetMode,\r
@@ -121,7 +122,18 @@ static TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut = {
   0,\r
   0,\r
   (EFI_UGA_PIXEL *) NULL,\r
-\r
+#else\r
+  {\r
+    ConSpliterGraphicsOutputQueryMode,\r
+    ConSpliterGraphicsOutputSetMode,\r
+    ConSpliterGraphicsOutputBlt,\r
+    NULL\r
+  },\r
+  (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL,\r
+  (TEXT_OUT_GOP_MODE *) NULL,\r
+  0,\r
+  TRUE,\r
+#endif\r
   {\r
     ConSpliterConsoleControlGetMode,\r
     ConSpliterConsoleControlSetMode,\r
@@ -129,7 +141,7 @@ static TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut = {
   },\r
 \r
   0,\r
-  (TEXT_OUT_AND_UGA_DATA *) NULL,\r
+  (TEXT_OUT_AND_GOP_DATA *) NULL,\r
   0,\r
   (TEXT_OUT_SPLITTER_QUERY_DATA *) NULL,\r
   0,\r
@@ -142,7 +154,7 @@ static TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut = {
   (INT32 *) NULL\r
 };\r
 \r
-static TEXT_OUT_SPLITTER_PRIVATE_DATA mStdErr = {\r
+STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mStdErr = {\r
   TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE,\r
   (EFI_HANDLE) NULL,\r
   {\r
@@ -165,6 +177,7 @@ static TEXT_OUT_SPLITTER_PRIVATE_DATA mStdErr = {
     0,\r
     FALSE,\r
   },\r
+#if (EFI_SPECIFICATION_VERSION < 0x00020000)\r
   {\r
     ConSpliterUgaDrawGetMode,\r
     ConSpliterUgaDrawSetMode,\r
@@ -175,7 +188,18 @@ static TEXT_OUT_SPLITTER_PRIVATE_DATA mStdErr = {
   0,\r
   0,\r
   (EFI_UGA_PIXEL *) NULL,\r
-\r
+#else\r
+  {\r
+    ConSpliterGraphicsOutputQueryMode,\r
+    ConSpliterGraphicsOutputSetMode,\r
+    ConSpliterGraphicsOutputBlt,\r
+    NULL\r
+  },\r
+  (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL,\r
+  (TEXT_OUT_GOP_MODE *) NULL,\r
+  0,\r
+  TRUE,\r
+#endif\r
   {\r
     ConSpliterConsoleControlGetMode,\r
     ConSpliterConsoleControlSetMode,\r
@@ -183,7 +207,7 @@ static TEXT_OUT_SPLITTER_PRIVATE_DATA mStdErr = {
   },\r
 \r
   0,\r
-  (TEXT_OUT_AND_UGA_DATA *) NULL,\r
+  (TEXT_OUT_AND_GOP_DATA *) NULL,\r
   0,\r
   (TEXT_OUT_SPLITTER_QUERY_DATA *) NULL,\r
   0,\r
@@ -301,6 +325,10 @@ Returns:
   //\r
   Status = ConSplitterTextOutConstructor (&mConOut);\r
   if (!EFI_ERROR (Status)) {\r
+#if (EFI_SPECIFICATION_VERSION < 0x00020000)\r
+    //\r
+    // In EFI mode, UGA Draw protocol is installed\r
+    //\r
     Status = gBS->InstallMultipleProtocolInterfaces (\r
                     &mConOut.VirtualHandle,\r
                     &gEfiSimpleTextOutProtocolGuid,\r
@@ -313,6 +341,24 @@ Returns:
                     NULL,\r
                     NULL\r
                     );\r
+#else\r
+    //\r
+    // In UEFI mode, Graphics Output Protocol is installed on virtual handle.\r
+    //\r
+    Status = gBS->InstallMultipleProtocolInterfaces (\r
+                    &mConOut.VirtualHandle,\r
+                    &gEfiSimpleTextOutProtocolGuid,\r
+                    &mConOut.TextOut,\r
+                    &gEfiGraphicsOutputProtocolGuid,\r
+                    &mConOut.GraphicsOutput,\r
+                    &gEfiConsoleControlProtocolGuid,\r
+                    &mConOut.ConsoleControl,\r
+                    &gEfiPrimaryConsoleOutDeviceGuid,\r
+                    NULL,\r
+                    NULL\r
+                    );\r
+#endif\r
+\r
     if (!EFI_ERROR (Status)) {\r
       //\r
       // Update the EFI System Table with new virtual console\r
@@ -335,7 +381,7 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
+STATIC\r
 EFI_STATUS\r
 ConSplitterTextInConstructor (\r
   TEXT_IN_SPLITTER_PRIVATE_DATA       *ConInPrivate\r
@@ -411,7 +457,7 @@ Returns:
   return Status;\r
 }\r
 \r
-\r
+STATIC\r
 EFI_STATUS\r
 ConSplitterTextOutConstructor (\r
   TEXT_OUT_SPLITTER_PRIVATE_DATA      *ConOutPrivate\r
@@ -425,7 +471,7 @@ ConSplitterTextOutConstructor (
   ConOutPrivate->TextOut.Mode = &ConOutPrivate->TextOutMode;\r
 \r
   Status = ConSplitterGrowBuffer (\r
-            sizeof (TEXT_OUT_AND_UGA_DATA),\r
+            sizeof (TEXT_OUT_AND_GOP_DATA),\r
             &ConOutPrivate->TextOutListCount,\r
             (VOID **) &ConOutPrivate->TextOutList\r
             );\r
@@ -448,15 +494,53 @@ ConSplitterTextOutConstructor (
   ConOutPrivate->TextOutQueryData[0].Rows     = 25;\r
   DevNullTextOutSetMode (ConOutPrivate, 0);\r
 \r
+#if (EFI_SPECIFICATION_VERSION < 0x00020000)\r
   //\r
   // Setup the DevNullUgaDraw to 800 x 600 x 32 bits per pixel\r
   //\r
   ConSpliterUgaDrawSetMode (&ConOutPrivate->UgaDraw, 800, 600, 32, 60);\r
+#else\r
+  //\r
+  // Setup resource for mode information in Graphics Output Protocol interface\r
+  //\r
+  if ((ConOutPrivate->GraphicsOutput.Mode = AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE))) == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  if ((ConOutPrivate->GraphicsOutput.Mode->Info = AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION))) == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  //\r
+  // Setup the DevNullGraphicsOutput to 800 x 600 x 32 bits per pixel\r
+  //\r
+  if ((ConOutPrivate->GraphicsOutputModeBuffer = AllocateZeroPool (sizeof (TEXT_OUT_GOP_MODE))) == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  ConOutPrivate->GraphicsOutputModeBuffer[0].HorizontalResolution = 800;\r
+  ConOutPrivate->GraphicsOutputModeBuffer[0].VerticalResolution = 600;\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
+  //\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->FrameBufferSize = 0;\r
+\r
+  ConOutPrivate->GraphicsOutput.Mode->MaxMode = 1;\r
+  //\r
+  // Initial current mode to unknow state, and then set to mode 0\r
+  //\r
+  ConOutPrivate->GraphicsOutput.Mode->Mode = 0xffff;\r
+  ConOutPrivate->GraphicsOutput.SetMode (&ConOutPrivate->GraphicsOutput, 0);\r
+#endif\r
 \r
   return Status;\r
 }\r
 \r
-\r
+STATIC\r
 EFI_STATUS\r
 ConSplitterSupported (\r
   IN  EFI_DRIVER_BINDING_PROTOCOL     *This,\r
@@ -523,7 +607,7 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
+STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 ConSplitterConInDriverBindingSupported (\r
@@ -554,7 +638,7 @@ Returns:
           );\r
 }\r
 \r
-\r
+STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 ConSplitterSimplePointerDriverBindingSupported (\r
@@ -585,7 +669,7 @@ Returns:
           );\r
 }\r
 \r
-\r
+STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 ConSplitterConOutDriverBindingSupported (\r
@@ -616,7 +700,7 @@ Returns:
           );\r
 }\r
 \r
-\r
+STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 ConSplitterStdErrDriverBindingSupported (\r
@@ -647,7 +731,7 @@ Returns:
           );\r
 }\r
 \r
-\r
+STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 ConSplitterStart (\r
@@ -712,7 +796,7 @@ Returns:
                 );\r
 }\r
 \r
-\r
+STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 ConSplitterConInDriverBindingStart (\r
@@ -760,7 +844,7 @@ Returns:
   return ConSplitterTextInAddDevice (&mConIn, TextIn);\r
 }\r
 \r
-\r
+STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 ConSplitterSimplePointerDriverBindingStart (\r
@@ -803,7 +887,7 @@ Returns:
   return ConSplitterSimplePointerAddDevice (&mConIn, SimplePointer);\r
 }\r
 \r
-\r
+STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 ConSplitterConOutDriverBindingStart (\r
@@ -829,6 +913,7 @@ Returns:
 {\r
   EFI_STATUS                    Status;\r
   EFI_SIMPLE_TEXT_OUT_PROTOCOL  *TextOut;\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL  *GraphicsOutput;\r
   EFI_UGA_DRAW_PROTOCOL         *UgaDraw;\r
 \r
   Status = ConSplitterStart (\r
@@ -843,6 +928,20 @@ Returns:
     return Status;\r
   }\r
   //\r
+  // Try to Open Graphics Output protocol\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiGraphicsOutputProtocolGuid,\r
+                  &GraphicsOutput,\r
+                  This->DriverBindingHandle,\r
+                  mConOut.VirtualHandle,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    GraphicsOutput = NULL;\r
+  }\r
+  //\r
   // Open UGA_DRAW protocol\r
   //\r
   Status = gBS->OpenProtocol (\r
@@ -860,12 +959,14 @@ Returns:
   // If both ConOut and StdErr incorporate the same Text Out device,\r
   // their MaxMode and QueryData should be the intersection of both.\r
   //\r
-  Status = ConSplitterTextOutAddDevice (&mConOut, TextOut, UgaDraw);\r
+  Status = ConSplitterTextOutAddDevice (&mConOut, TextOut, GraphicsOutput, UgaDraw);\r
   ConSplitterTextOutSetAttribute (&mConOut.TextOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
+\r
+#if (EFI_SPECIFICATION_VERSION < 0x00020000)\r
   //\r
   // Match the UGA mode data of ConOut with the current mode\r
   //\r
-  if (UgaDraw) {\r
+  if (UgaDraw != NULL) {\r
     UgaDraw->GetMode (\r
                UgaDraw,\r
                &mConOut.UgaHorizontalResolution,\r
@@ -873,11 +974,13 @@ Returns:
                &mConOut.UgaColorDepth,\r
                &mConOut.UgaRefreshRate\r
                );\r
-  }  \r
+  }\r
+#endif\r
+\r
   return Status;\r
 }\r
 \r
-\r
+STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 ConSplitterStdErrDriverBindingStart (\r
@@ -919,7 +1022,7 @@ Returns:
   // If both ConOut and StdErr incorporate the same Text Out device,\r
   // their MaxMode and QueryData should be the intersection of both.\r
   //\r
-  Status = ConSplitterTextOutAddDevice (&mStdErr, TextOut, NULL);\r
+  Status = ConSplitterTextOutAddDevice (&mStdErr, TextOut, NULL, NULL);\r
   ConSplitterTextOutSetAttribute (&mStdErr.TextOut, EFI_TEXT_ATTR (EFI_MAGENTA, EFI_BLACK));\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
@@ -942,7 +1045,7 @@ Returns:
   return Status;\r
 }\r
 \r
-\r
+STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 ConSplitterStop (\r
@@ -998,7 +1101,7 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
+STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 ConSplitterConInDriverBindingStop (\r
@@ -1044,7 +1147,7 @@ Returns:
   return ConSplitterTextInDeleteDevice (&mConIn, TextIn);\r
 }\r
 \r
-\r
+STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 ConSplitterSimplePointerDriverBindingStop (\r
@@ -1090,7 +1193,7 @@ Returns:
   return ConSplitterSimplePointerDeleteDevice (&mConIn, SimplePointer);\r
 }\r
 \r
-\r
+STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 ConSplitterConOutDriverBindingStop (\r
@@ -1114,7 +1217,6 @@ Returns:
 {\r
   EFI_STATUS                    Status;\r
   EFI_SIMPLE_TEXT_OUT_PROTOCOL  *TextOut;\r
-  EFI_UGA_DRAW_PROTOCOL         *UgaDraw;\r
 \r
   if (NumberOfChildren == 0) {\r
     return EFI_SUCCESS;\r
@@ -1131,17 +1233,6 @@ Returns:
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
-  //\r
-  // Remove any UGA devices\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
   // Delete this console output device's data structures.\r
@@ -1149,7 +1240,7 @@ Returns:
   return ConSplitterTextOutDeleteDevice (&mConOut, TextOut);\r
 }\r
 \r
-\r
+STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 ConSplitterStdErrDriverBindingStop (\r
@@ -1717,13 +1808,14 @@ Arguments:
 Returns:\r
 \r
   None\r
+  EFI_OUT_OF_RESOURCES\r
 \r
 --*/\r
 {\r
   UINTN                         ConOutNumOfConsoles;\r
   UINTN                         StdErrNumOfConsoles;\r
-  TEXT_OUT_AND_UGA_DATA         *ConOutTextOutList;\r
-  TEXT_OUT_AND_UGA_DATA         *StdErrTextOutList;\r
+  TEXT_OUT_AND_GOP_DATA         *ConOutTextOutList;\r
+  TEXT_OUT_AND_GOP_DATA         *StdErrTextOutList;\r
   UINTN                         Indexi;\r
   UINTN                         Indexj;\r
   UINTN                         Rows;\r
@@ -1864,10 +1956,198 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
+EFI_STATUS\r
+ConSplitterAddGraphicsOutputMode (\r
+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput,\r
+  IN  EFI_UGA_DRAW_PROTOCOL           *UgaDraw\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                           Status;\r
+  UINTN                                Index;\r
+  TEXT_OUT_GOP_MODE                    *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
+  UINTN                                NumberIndex;\r
+  BOOLEAN                              Match;\r
+\r
+  if ((GraphicsOutput == NULL) && (UgaDraw == NULL)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  CurrentGraphicsOutputMode = Private->GraphicsOutput.Mode;\r
+\r
+  if (GraphicsOutput != NULL) {\r
+    if (Private->CurrentNumberOfGraphicsOutput == 0) {\r
+        //\r
+        // This is the first Graphics Output device added\r
+        //\r
+        CurrentGraphicsOutputMode->MaxMode = GraphicsOutput->Mode->MaxMode;\r
+        CurrentGraphicsOutputMode->Mode = GraphicsOutput->Mode->Mode;\r
+        CopyMem (CurrentGraphicsOutputMode->Info, GraphicsOutput->Mode->Info, GraphicsOutput->Mode->SizeOfInfo);\r
+        CurrentGraphicsOutputMode->SizeOfInfo = GraphicsOutput->Mode->SizeOfInfo;\r
+        CurrentGraphicsOutputMode->FrameBufferBase = GraphicsOutput->Mode->FrameBufferBase;\r
+        CurrentGraphicsOutputMode->FrameBufferSize = GraphicsOutput->Mode->FrameBufferSize;\r
+\r
+        //\r
+        // Allocate resource for the private mode buffer\r
+        //\r
+        ModeBuffer = AllocatePool (sizeof (TEXT_OUT_GOP_MODE) * GraphicsOutput->Mode->MaxMode);\r
+        if (ModeBuffer == NULL) {\r
+          return EFI_OUT_OF_RESOURCES;\r
+        }\r
+        gBS->FreePool (Private->GraphicsOutputModeBuffer);\r
+        Private->GraphicsOutputModeBuffer = ModeBuffer;\r
+\r
+        //\r
+        // Store all supported display modes to the private mode buffer\r
+        //\r
+        Mode = ModeBuffer;\r
+        for (Index = 0; Index < GraphicsOutput->Mode->MaxMode; Index++) {\r
+          Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32) Index, &SizeOfInfo, &Info);\r
+          if (EFI_ERROR (Status)) {\r
+            return Status;\r
+          }\r
+          Mode->HorizontalResolution = Info->HorizontalResolution;\r
+          Mode->VerticalResolution = Info->VerticalResolution;\r
+          Mode++;\r
+          gBS->FreePool (Info);\r
+        }\r
+    } else {\r
+      //\r
+      // Check intersection of display mode\r
+      //\r
+      ModeBuffer = AllocatePool (sizeof (TEXT_OUT_GOP_MODE) * CurrentGraphicsOutputMode->MaxMode);\r
+      if (ModeBuffer == NULL) {\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+\r
+      MatchedMode = ModeBuffer;\r
+      Mode = &Private->GraphicsOutputModeBuffer[0];\r
+      for (Index = 0; Index < CurrentGraphicsOutputMode->MaxMode; Index++) {\r
+        Match = FALSE;\r
+\r
+        for (NumberIndex = 0; NumberIndex < GraphicsOutput->Mode->MaxMode; NumberIndex++) {\r
+          Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32) NumberIndex, &SizeOfInfo, &Info);\r
+          if (EFI_ERROR (Status)) {\r
+            return Status;\r
+          }\r
+          if ((Info->HorizontalResolution == Mode->HorizontalResolution) &&\r
+              (Info->VerticalResolution == Mode->VerticalResolution)){\r
+            Match = TRUE;\r
+            gBS->FreePool (Info);\r
+            break;\r
+          }\r
+          gBS->FreePool (Info);\r
+        }\r
+\r
+        if (Match) {\r
+          CopyMem (MatchedMode, Mode, sizeof (TEXT_OUT_GOP_MODE));\r
+          MatchedMode++;\r
+        }\r
+\r
+        Mode++;\r
+      }\r
+\r
+      //\r
+      // Drop the old mode buffer, assign it to a new one\r
+      //\r
+      gBS->FreePool (Private->GraphicsOutputModeBuffer);\r
+      Private->GraphicsOutputModeBuffer = ModeBuffer;\r
+\r
+      //\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->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->FrameBufferSize = 0;\r
+    }\r
+\r
+    //\r
+    // Select a prefered Display 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
+        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
+\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
+    // 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
+    //\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
+    CurrentGraphicsOutputMode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
+    CurrentGraphicsOutputMode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) 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
+\r
+    //\r
+    // Current mode is unknow now, set it to an invalid mode number 0xffff\r
+    //\r
+    CurrentGraphicsOutputMode->Mode = 0xffff;\r
+    Index = 0;\r
+  }\r
+\r
+  //\r
+  // Force GraphicsOutput mode to be set,\r
+  // 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
+  Private->CurrentNumberOfGraphicsOutput++;\r
+\r
+  return Status;\r
+}\r
+#endif\r
+\r
 EFI_STATUS\r
 ConSplitterTextOutAddDevice (\r
   IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,\r
   IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *TextOut,\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput,\r
   IN  EFI_UGA_DRAW_PROTOCOL           *UgaDraw\r
   )\r
 /*++\r
@@ -1886,7 +2166,7 @@ Returns:
   UINTN                 CurrentNumOfConsoles;\r
   INT32                 CurrentMode;\r
   INT32                 MaxMode;\r
-  TEXT_OUT_AND_UGA_DATA *TextAndUga;\r
+  TEXT_OUT_AND_GOP_DATA *TextAndGop;\r
 \r
   Status                = EFI_SUCCESS;\r
   CurrentNumOfConsoles  = Private->CurrentNumberOfConsoles;\r
@@ -1896,7 +2176,7 @@ Returns:
   //\r
   while (CurrentNumOfConsoles >= Private->TextOutListCount) {\r
     Status = ConSplitterGrowBuffer (\r
-              sizeof (TEXT_OUT_AND_UGA_DATA),\r
+              sizeof (TEXT_OUT_AND_GOP_DATA),\r
               &Private->TextOutListCount,\r
               (VOID **) &Private->TextOutList\r
               );\r
@@ -1912,20 +2192,22 @@ Returns:
     }\r
   }\r
 \r
-  TextAndUga          = &Private->TextOutList[CurrentNumOfConsoles];\r
+  TextAndGop          = &Private->TextOutList[CurrentNumOfConsoles];\r
+\r
+  TextAndGop->TextOut = TextOut;\r
+  TextAndGop->GraphicsOutput = GraphicsOutput;\r
+  TextAndGop->UgaDraw = UgaDraw;\r
 \r
-  TextAndUga->TextOut = TextOut;\r
-  TextAndUga->UgaDraw = UgaDraw;\r
-  if (UgaDraw == NULL) {\r
+  if ((GraphicsOutput == NULL) && (UgaDraw == NULL)) {\r
     //\r
     // If No UGA device then use the ConOut device\r
     //\r
-    TextAndUga->TextOutEnabled = TRUE;\r
+    TextAndGop->TextOutEnabled = TRUE;\r
   } else {\r
     //\r
     // If UGA device use ConOut device only used if UGA screen is in Text mode\r
     //\r
-    TextAndUga->TextOutEnabled = (BOOLEAN) (Private->UgaMode == EfiConsoleControlScreenText);\r
+    TextAndGop->TextOutEnabled = (BOOLEAN) (Private->ConsoleOutputMode == EfiConsoleControlScreenText);\r
   }\r
 \r
   if (CurrentNumOfConsoles == 0) {\r
@@ -1950,17 +2232,26 @@ Returns:
   MaxMode     = Private->TextOutMode.MaxMode;\r
   ASSERT (MaxMode >= 1);\r
 \r
-  if (Private->UgaMode == EfiConsoleControlScreenGraphics && UgaDraw != NULL) {\r
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
+  if ((GraphicsOutput != NULL) || (UgaDraw != NULL)) {\r
+    ConSplitterAddGraphicsOutputMode (Private, GraphicsOutput, UgaDraw);\r
+  }\r
+#endif\r
+\r
+  if (Private->ConsoleOutputMode == EfiConsoleControlScreenGraphics && GraphicsOutput != NULL) {\r
     //\r
     // We just added a new UGA device in graphics mode\r
     //\r
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
+    DevNullGopSync (Private, GraphicsOutput, UgaDraw);\r
+#else\r
     DevNullUgaSync (Private, UgaDraw);\r
-\r
-  } else if ((CurrentMode >= 0) && (UgaDraw != NULL) && (CurrentMode < Private->TextOutMode.MaxMode)) {\r
+#endif\r
+  } else if ((CurrentMode >= 0) && ((GraphicsOutput != NULL) || (UgaDraw != NULL)) && (CurrentMode < Private->TextOutMode.MaxMode)) {\r
     //\r
     // The new console supports the same mode of the current console so sync up\r
     //\r
-    DevNullSyncUgaStdOut (Private);\r
+    DevNullSyncGopStdOut (Private);\r
   } else {\r
     //\r
     // If ConOut, then set the mode to Mode #0 which us 80 x 25\r
@@ -1990,7 +2281,7 @@ Returns:
 {\r
   INT32                 Index;\r
   UINTN                 CurrentNumOfConsoles;\r
-  TEXT_OUT_AND_UGA_DATA *TextOutList;\r
+  TEXT_OUT_AND_GOP_DATA *TextOutList;\r
   EFI_STATUS            Status;\r
 \r
   //\r
@@ -2002,7 +2293,7 @@ Returns:
   TextOutList           = Private->TextOutList;\r
   while (Index >= 0) {\r
     if (TextOutList->TextOut == TextOut) {\r
-      CopyMem (TextOutList, TextOutList + 1, sizeof (TEXT_OUT_AND_UGA_DATA) * Index);\r
+      CopyMem (TextOutList, TextOutList + 1, sizeof (TEXT_OUT_AND_GOP_DATA) * Index);\r
       CurrentNumOfConsoles--;\r
       break;\r
     }\r
@@ -2862,7 +3153,8 @@ ConSplitterTextOutQueryMode (
   // Check whether param ModeNumber is valid.\r
   // ModeNumber should be within range 0 ~ MaxMode - 1.\r
   //\r
-  if (ModeNumber > (UINTN)(((UINT32)-1)>>1)) {\r
+  if ( (ModeNumber < 0)                         ||\r
+       (ModeNumber > (UINTN)(((UINT32)-1)>>1)) ) {\r
     return EFI_UNSUPPORTED;\r
   }\r
   \r
@@ -2916,7 +3208,8 @@ ConSplitterTextOutSetMode (
   // Check whether param ModeNumber is valid.\r
   // ModeNumber should be within range 0 ~ MaxMode - 1.\r
   //\r
-  if (ModeNumber > (UINTN)(((UINT32)-1)>>1)) {\r
+  if ( (ModeNumber < 0)                         ||\r
+       (ModeNumber > (UINTN)(((UINT32)-1)>>1)) ) {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -2944,7 +3237,7 @@ ConSplitterTextOutSetMode (
       // 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
       //\r
-      if (Private->TextOutList[Index].UgaDraw != NULL) {\r
+      if ((Private->TextOutList[Index].GraphicsOutput != NULL) || (Private->TextOutList[Index].UgaDraw != NULL)) {\r
         Private->TextOutList[Index].TextOut->ClearScreen (Private->TextOutList[Index].TextOut);\r
       }\r
 \r