]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c
1. Fixed bugs in DxeNetLib to meet consistence with network module DriverBinding...
[mirror_edk2.git] / MdeModulePkg / Universal / Console / ConSplitterDxe / ConSplitter.c
index 8e49c480972686426c5fd3ea1e4f7a729d48056d..63be0b1d8b467a139545e0a3db3a7f531611f387 100644 (file)
@@ -2243,6 +2243,7 @@ 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
@@ -2263,13 +2264,15 @@ Returns:
   MapTable  = TextOutModeMap + Private->CurrentNumberOfConsoles;\r
   while (Mode < TextOut->Mode->MaxMode) {\r
     TextOut->QueryMode (TextOut, Mode, &Columns, &Rows);\r
+        MapTable[StepSize] = Mode;\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
@@ -2308,7 +2311,7 @@ Arguments:
 \r
 Returns:\r
 \r
-  None\r
+  EFI_SUCCESS\r
   EFI_OUT_OF_RESOURCES\r
 \r
 --*/\r
@@ -2319,10 +2322,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
@@ -2331,6 +2338,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
@@ -2366,10 +2375,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
@@ -2398,13 +2409,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
@@ -2470,6 +2485,7 @@ Returns:
 {\r
   EFI_STATUS                           Status;\r
   UINTN                                Index;\r
+  UINTN                                CurrentIndex;\r
   EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Mode;\r
   UINTN                                SizeOfInfo;\r
   EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
@@ -2479,6 +2495,10 @@ Returns:
   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
@@ -2487,6 +2507,7 @@ Returns:
   CurrentGraphicsOutputMode = Private->GraphicsOutput.Mode;\r
 \r
   Index        = 0;\r
+  CurrentIndex = 0;\r
 \r
   if (Private->CurrentNumberOfUgaDraw != 0) {\r
     //\r
@@ -2606,34 +2627,49 @@ Returns:
     }\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
   if (UgaDraw != NULL) {\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
     Info = CurrentGraphicsOutputMode->Info;\r
     Info->Version = 0;\r
-    Info->HorizontalResolution = 800;\r
-    Info->VerticalResolution = 600;\r
+    Info->HorizontalResolution = UgaHorizontalResolution;\r
+    Info->VerticalResolution = UgaVerticalResolution;\r
     Info->PixelFormat = PixelBltOnly;\r
-    Info->PixelsPerScanLine = 800;\r
+    Info->PixelsPerScanLine = UgaHorizontalResolution;\r
     CurrentGraphicsOutputMode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
     CurrentGraphicsOutputMode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) NULL;\r
     CurrentGraphicsOutputMode->FrameBufferSize = 0;\r
@@ -2646,7 +2682,7 @@ Returns:
     //\r
     // Only mode 0 is available to be set\r
     //\r
-    Index = 0;\r
+    CurrentIndex = 0;\r
   }\r
 \r
 Done:\r
@@ -2666,7 +2702,20 @@ Done:
   //\r
   // Current mode number may need update now, so set it to an invalid mode number\r
   //\r
-  Status = Private->GraphicsOutput.SetMode (&Private->GraphicsOutput, (UINT32) Index);\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
+  //\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
@@ -2694,6 +2743,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
@@ -2728,12 +2781,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
@@ -2760,15 +2813,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) {\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
@@ -2823,14 +2911,12 @@ Returns:
     if (TextOutList->TextOut == TextOut) {\r
       CopyMem (TextOutList, TextOutList + 1, sizeof (TEXT_OUT_AND_GOP_DATA) * Index);\r
       CurrentNumOfConsoles--;\r
-    if (FeaturePcdGet (PcdConOutGopSupport)) {\r
       if (TextOutList->UgaDraw != NULL) {\r
         Private->CurrentNumberOfUgaDraw--;\r
       }\r
       if (TextOutList->GraphicsOutput != NULL) {\r
         Private->CurrentNumberOfGraphicsOutput--;\r
       }\r
-    }\r
       break;\r
     }\r
 \r
@@ -4300,6 +4386,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
@@ -4315,8 +4403,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
@@ -4386,8 +4484,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
@@ -4651,3 +4749,4 @@ ConSplitterTextOutEnableCursor (
 \r
   return ReturnStatus;\r
 }\r
+\r