//\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
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
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
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
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
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
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
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
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
Mode = 0;\r
MapTable = TextOutModeMap + Private->CurrentNumberOfConsoles;\r
while (Mode < TextOut->Mode->MaxMode) {\r
- TextOut->QueryMode (TextOut, Mode, &Columns, &Rows);\r
+ Status = TextOut->QueryMode (TextOut, Mode, &Columns, &Rows);\r
+ if (EFI_ERROR(Status)) {\r
+ if (Mode == 1) {\r
MapTable[StepSize] = Mode;\r
-\r
+ TextOutQueryData[Mode].Columns = 0;\r
+ TextOutQueryData[Mode].Rows = 0;\r
+ }\r
+ Mode++;\r
+ continue;\r
+ }\r
//\r
// Search the intersection map and QueryData database to see if they intersects\r
//\r
}\r
}\r
}\r
- if (UgaDraw != NULL) {\r
+ if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
//\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
if (GraphicsOutput != NULL) {\r
Private->CurrentNumberOfGraphicsOutput++;\r
}\r
- if (UgaDraw != NULL) {\r
+ if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
Private->CurrentNumberOfUgaDraw++;\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
}\r
}\r
if (FeaturePcdGet (PcdConOutUgaSupport)) {\r
- if (UgaDraw != NULL) {\r
+ if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
Status = UgaDraw->GetMode (\r
UgaDraw,\r
&UgaHorizontalResolution,\r
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
if (TextOutList->TextOut == TextOut) {\r
CopyMem (TextOutList, TextOutList + 1, sizeof (TEXT_OUT_AND_GOP_DATA) * Index);\r
CurrentNumOfConsoles--;\r
- if (TextOutList->UgaDraw != NULL) {\r
+ if (TextOutList->UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
Private->CurrentNumberOfUgaDraw--;\r
}\r
if (TextOutList->GraphicsOutput != NULL) {\r