};\r
\r
\r
-EFI_GUID *gTerminalType[] = {\r
+EFI_GUID *mTerminalType[] = {\r
&gEfiPcAnsiGuid,\r
&gEfiVT100Guid,\r
&gEfiVT100PlusGuid,\r
};\r
\r
\r
+CHAR16 *mSerialConsoleNames[] = {\r
+ L"PC-ANSI Serial Console",\r
+ L"VT-100 Serial Console",\r
+ L"VT-100+ Serial Console",\r
+ L"VT-UTF8 Serial Console",\r
+ L"Tty Terminal Serial Console"\r
+};\r
+\r
TERMINAL_DEV mTerminalDevTemplate = {\r
TERMINAL_DEV_SIGNATURE,\r
NULL,\r
};\r
\r
TERMINAL_CONSOLE_MODE_DATA mTerminalConsoleModeData[] = {\r
+ {80, 25},\r
+ {80, 50},\r
{100, 31},\r
//\r
// New modes can be added here.\r
//\r
};\r
\r
+/**\r
+ Convert the GUID representation of terminal type to enum type.\r
+\r
+ @param Guid The GUID representation of terminal type.\r
+\r
+ @return The terminal type in enum type.\r
+**/\r
+TERMINAL_TYPE\r
+TerminalTypeFromGuid (\r
+ IN EFI_GUID *Guid\r
+)\r
+{\r
+ TERMINAL_TYPE Type;\r
+\r
+ for (Type = 0; Type < ARRAY_SIZE (mTerminalType); Type++) {\r
+ if (CompareGuid (Guid, mTerminalType[Type])) {\r
+ break;\r
+ }\r
+ }\r
+ return Type;\r
+}\r
+\r
/**\r
Test to see if this driver supports Controller.\r
\r
//\r
// only supports PC ANSI, VT100, VT100+, VT-UTF8, and TtyTerm terminal types\r
//\r
- if (!CompareGuid (&Node->Guid, &gEfiPcAnsiGuid) &&\r
- !CompareGuid (&Node->Guid, &gEfiVT100Guid) &&\r
- !CompareGuid (&Node->Guid, &gEfiVT100PlusGuid) &&\r
- !CompareGuid (&Node->Guid, &gEfiVTUTF8Guid) &&\r
- !CompareGuid (&Node->Guid, &gEfiTtyTermGuid)) {\r
-\r
+ if (TerminalTypeFromGuid (&Node->Guid) == ARRAY_SIZE (mTerminalType)) {\r
return EFI_UNSUPPORTED;\r
}\r
}\r
It returns information for available text modes that the terminal can support.\r
\r
@param[out] TextModeCount The total number of text modes that terminal console supports.\r
- @param[out] TextModeData The buffer to the text modes column and row information.\r
- Caller is responsible to free it when it's non-NULL.\r
\r
- @retval EFI_SUCCESS The supporting mode information is returned.\r
- @retval EFI_INVALID_PARAMETER The parameters are invalid.\r
+ @return The buffer to the text modes column and row information.\r
+ Caller is responsible to free it when it's non-NULL.\r
\r
**/\r
-EFI_STATUS\r
+TERMINAL_CONSOLE_MODE_DATA *\r
InitializeTerminalConsoleTextMode (\r
- OUT UINTN *TextModeCount,\r
- OUT TERMINAL_CONSOLE_MODE_DATA **TextModeData\r
- )\r
+ OUT INT32 *TextModeCount\r
+)\r
{\r
- UINTN Index;\r
- UINTN Count;\r
- TERMINAL_CONSOLE_MODE_DATA *ModeBuffer;\r
- TERMINAL_CONSOLE_MODE_DATA *NewModeBuffer;\r
- UINTN ValidCount;\r
- UINTN ValidIndex;\r
- \r
- if ((TextModeCount == NULL) || (TextModeData == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- \r
- Count = sizeof (mTerminalConsoleModeData) / sizeof (TERMINAL_CONSOLE_MODE_DATA);\r
- \r
- //\r
- // Get defined mode buffer pointer.\r
- //\r
- ModeBuffer = mTerminalConsoleModeData;\r
- \r
+ TERMINAL_CONSOLE_MODE_DATA *TextModeData;\r
+\r
+ ASSERT (TextModeCount != NULL);\r
+\r
//\r
// Here we make sure that the final mode exposed does not include the duplicated modes,\r
// and does not include the invalid modes which exceed the max column and row.\r
// Reserve 2 modes for 80x25, 80x50 of terminal console.\r
//\r
- NewModeBuffer = AllocateZeroPool (sizeof (TERMINAL_CONSOLE_MODE_DATA) * (Count + 2));\r
- ASSERT (NewModeBuffer != NULL);\r
+ TextModeData = AllocateCopyPool (sizeof (mTerminalConsoleModeData), mTerminalConsoleModeData);\r
+ if (TextModeData == NULL) {\r
+ return NULL;\r
+ }\r
+ *TextModeCount = ARRAY_SIZE (mTerminalConsoleModeData);\r
\r
- //\r
- // Mode 0 and mode 1 is for 80x25, 80x50 according to UEFI spec.\r
- //\r
- ValidCount = 0; \r
+ DEBUG_CODE (\r
+ INT32 Index;\r
+ for (Index = 0; Index < *TextModeCount; Index++) {\r
+ DEBUG ((DEBUG_INFO, "Terminal - Mode %d, Column = %d, Row = %d\n",\r
+ Index, TextModeData[Index].Columns, TextModeData[Index].Rows));\r
+ }\r
+ );\r
+ return TextModeData;\r
+}\r
\r
- NewModeBuffer[ValidCount].Columns = 80;\r
- NewModeBuffer[ValidCount].Rows = 25;\r
- ValidCount++;\r
+/**\r
+ Stop the terminal state machine.\r
\r
- NewModeBuffer[ValidCount].Columns = 80;\r
- NewModeBuffer[ValidCount].Rows = 50;\r
- ValidCount++;\r
- \r
- //\r
- // Start from mode 2 to put the valid mode other than 80x25 and 80x50 in the output mode buffer.\r
- //\r
- for (Index = 0; Index < Count; Index++) {\r
- if ((ModeBuffer[Index].Columns == 0) || (ModeBuffer[Index].Rows == 0)) {\r
- //\r
- // Skip the pre-defined mode which is invalid.\r
- //\r
- continue;\r
- }\r
- for (ValidIndex = 0; ValidIndex < ValidCount; ValidIndex++) {\r
- if ((ModeBuffer[Index].Columns == NewModeBuffer[ValidIndex].Columns) &&\r
- (ModeBuffer[Index].Rows == NewModeBuffer[ValidIndex].Rows)) {\r
- //\r
- // Skip the duplicated mode.\r
- //\r
- break;\r
- }\r
- }\r
- if (ValidIndex == ValidCount) {\r
- NewModeBuffer[ValidCount].Columns = ModeBuffer[Index].Columns;\r
- NewModeBuffer[ValidCount].Rows = ModeBuffer[Index].Rows;\r
- ValidCount++;\r
+ @param TerminalDevice The terminal device.\r
+**/\r
+VOID\r
+StopTerminalStateMachine (\r
+ TERMINAL_DEV *TerminalDevice\r
+ )\r
+{\r
+ EFI_TPL OriginalTpl;\r
+\r
+ OriginalTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+ gBS->CloseEvent (TerminalDevice->TimerEvent);\r
+ gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);\r
+\r
+ gBS->RestoreTPL (OriginalTpl);\r
+}\r
+\r
+/**\r
+ Start the terminal state machine.\r
+\r
+ @param TerminalDevice The terminal device.\r
+**/\r
+VOID\r
+StartTerminalStateMachine (\r
+ TERMINAL_DEV *TerminalDevice\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ Status = gBS->CreateEvent (\r
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ TerminalConInTimerHandler,\r
+ TerminalDevice,\r
+ &TerminalDevice->TimerEvent\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ Status = gBS->SetTimer (\r
+ TerminalDevice->TimerEvent,\r
+ TimerPeriodic,\r
+ KEYBOARD_TIMER_INTERVAL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ Status = gBS->CreateEvent (\r
+ EVT_TIMER,\r
+ TPL_CALLBACK,\r
+ NULL,\r
+ NULL,\r
+ &TerminalDevice->TwoSecondTimeOut\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
+/**\r
+ Initialize the controller name table.\r
+\r
+ @param TerminalType The terminal type.\r
+ @param ControllerNameTable The controller name table.\r
+\r
+ @retval EFI_SUCCESS The controller name table is initialized successfully.\r
+ @retval others Return status of AddUnicodeString2 ().\r
+**/\r
+EFI_STATUS\r
+InitializeControllerNameTable (\r
+ TERMINAL_TYPE TerminalType,\r
+ EFI_UNICODE_STRING_TABLE **ControllerNameTable\r
+)\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_UNICODE_STRING_TABLE *Table;\r
+\r
+ ASSERT (TerminalType < ARRAY_SIZE (mTerminalType));\r
+ Table = NULL;\r
+ Status = AddUnicodeString2 (\r
+ "eng",\r
+ gTerminalComponentName.SupportedLanguages,\r
+ &Table,\r
+ mSerialConsoleNames[TerminalType],\r
+ TRUE\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = AddUnicodeString2 (\r
+ "en",\r
+ gTerminalComponentName2.SupportedLanguages,\r
+ &Table,\r
+ mSerialConsoleNames[TerminalType],\r
+ FALSE\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ FreeUnicodeStringTable (Table);\r
}\r
}\r
- \r
- DEBUG_CODE (\r
- for (Index = 0; Index < ValidCount; Index++) {\r
- DEBUG ((EFI_D_INFO, "Terminal - Mode %d, Column = %d, Row = %d\n", \r
- Index, NewModeBuffer[Index].Columns, NewModeBuffer[Index].Rows)); \r
- }\r
- );\r
- \r
- //\r
- // Return valid mode count and mode information buffer.\r
- //\r
- *TextModeCount = ValidCount;\r
- *TextModeData = NewModeBuffer;\r
- return EFI_SUCCESS;\r
+ if (!EFI_ERROR (Status)) {\r
+ *ControllerNameTable = Table;\r
+ }\r
+ return Status;\r
}\r
\r
/**\r
BOOLEAN SimTxtInInstalled;\r
BOOLEAN SimTxtOutInstalled;\r
BOOLEAN FirstEnter;\r
- UINTN ModeCount;\r
\r
TerminalDevice = NULL;\r
ConInSelected = FALSE;\r
//\r
if (RemainingDevicePath == NULL) {\r
TerminalType = PcdGet8 (PcdDefaultTerminalType);\r
- //\r
- // Must be between TerminalTypePcAnsi (0) and TerminalTypeTtyTerm (4)\r
- //\r
- ASSERT (TerminalType <= TerminalTypeTtyTerm);\r
} else if (!IsDevicePathEnd (RemainingDevicePath)) {\r
//\r
// If RemainingDevicePath isn't the End of Device Path Node,\r
// Use the RemainingDevicePath to determine the terminal type\r
//\r
Node = (VENDOR_DEVICE_PATH *)RemainingDevicePath;\r
- if (CompareGuid (&Node->Guid, &gEfiPcAnsiGuid)) {\r
- TerminalType = TerminalTypePcAnsi;\r
- } else if (CompareGuid (&Node->Guid, &gEfiVT100Guid)) {\r
- TerminalType = TerminalTypeVt100;\r
- } else if (CompareGuid (&Node->Guid, &gEfiVT100PlusGuid)) {\r
- TerminalType = TerminalTypeVt100Plus;\r
- } else if (CompareGuid (&Node->Guid, &gEfiVTUTF8Guid)) {\r
- TerminalType = TerminalTypeVtUtf8;\r
- } else if (CompareGuid (&Node->Guid, &gEfiTtyTermGuid)) {\r
- TerminalType = TerminalTypeTtyTerm;\r
- } else {\r
- goto Error;\r
- }\r
+ TerminalType = TerminalTypeFromGuid (&Node->Guid);\r
} else {\r
//\r
// If RemainingDevicePath is the End of Device Path Node,\r
return EFI_SUCCESS;\r
}\r
\r
+ ASSERT (TerminalType < ARRAY_SIZE (mTerminalType));\r
+\r
//\r
// Initialize the Terminal Dev\r
//\r
);\r
SimpleTextOutput->Mode = &TerminalDevice->SimpleTextOutputMode;\r
\r
- Status = InitializeTerminalConsoleTextMode (&ModeCount, &TerminalDevice->TerminalConsoleModeData);\r
- if (EFI_ERROR (Status)) {\r
+ TerminalDevice->TerminalConsoleModeData = InitializeTerminalConsoleTextMode (\r
+ &SimpleTextOutput->Mode->MaxMode\r
+ );\r
+ if (TerminalDevice->TerminalConsoleModeData == NULL) {\r
goto ReportError;\r
}\r
- TerminalDevice->SimpleTextOutputMode.MaxMode = (INT32) ModeCount;\r
- \r
+\r
//\r
// For terminal devices, cursor is always visible\r
//\r
//\r
// Build the component name for the child device\r
//\r
- TerminalDevice->ControllerNameTable = NULL;\r
- switch (TerminalDevice->TerminalType) {\r
- case TerminalTypePcAnsi:\r
- AddUnicodeString2 (\r
- "eng",\r
- gTerminalComponentName.SupportedLanguages,\r
- &TerminalDevice->ControllerNameTable,\r
- (CHAR16 *)L"PC-ANSI Serial Console",\r
- TRUE\r
- );\r
- AddUnicodeString2 (\r
- "en",\r
- gTerminalComponentName2.SupportedLanguages,\r
- &TerminalDevice->ControllerNameTable,\r
- (CHAR16 *)L"PC-ANSI Serial Console",\r
- FALSE\r
- );\r
-\r
- break;\r
-\r
- case TerminalTypeVt100:\r
- AddUnicodeString2 (\r
- "eng",\r
- gTerminalComponentName.SupportedLanguages,\r
- &TerminalDevice->ControllerNameTable,\r
- (CHAR16 *)L"VT-100 Serial Console",\r
- TRUE\r
- );\r
- AddUnicodeString2 (\r
- "en",\r
- gTerminalComponentName2.SupportedLanguages,\r
- &TerminalDevice->ControllerNameTable,\r
- (CHAR16 *)L"VT-100 Serial Console",\r
- FALSE\r
- );\r
-\r
- break;\r
-\r
- case TerminalTypeVt100Plus:\r
- AddUnicodeString2 (\r
- "eng",\r
- gTerminalComponentName.SupportedLanguages,\r
- &TerminalDevice->ControllerNameTable,\r
- (CHAR16 *)L"VT-100+ Serial Console",\r
- TRUE\r
- );\r
- AddUnicodeString2 (\r
- "en",\r
- gTerminalComponentName2.SupportedLanguages,\r
- &TerminalDevice->ControllerNameTable,\r
- (CHAR16 *)L"VT-100+ Serial Console",\r
- FALSE\r
- );\r
-\r
- break;\r
-\r
- case TerminalTypeVtUtf8:\r
- AddUnicodeString2 (\r
- "eng",\r
- gTerminalComponentName.SupportedLanguages,\r
- &TerminalDevice->ControllerNameTable,\r
- (CHAR16 *)L"VT-UTF8 Serial Console",\r
- TRUE\r
- );\r
- AddUnicodeString2 (\r
- "en",\r
- gTerminalComponentName2.SupportedLanguages,\r
- &TerminalDevice->ControllerNameTable,\r
- (CHAR16 *)L"VT-UTF8 Serial Console",\r
- FALSE\r
- );\r
-\r
- break;\r
-\r
- case TerminalTypeTtyTerm:\r
- AddUnicodeString2 (\r
- "eng",\r
- gTerminalComponentName.SupportedLanguages,\r
- &TerminalDevice->ControllerNameTable,\r
- (CHAR16 *)L"Tty Terminal Serial Console",\r
- TRUE\r
- );\r
- AddUnicodeString2 (\r
- "en",\r
- gTerminalComponentName2.SupportedLanguages,\r
- &TerminalDevice->ControllerNameTable,\r
- (CHAR16 *)L"Tty Terminal Serial Console",\r
- FALSE\r
- );\r
-\r
- break;\r
+ Status = InitializeControllerNameTable (TerminalDevice->TerminalType, &TerminalDevice->ControllerNameTable);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Error;\r
}\r
\r
//\r
goto ReportError;\r
}\r
\r
- Status = gBS->CreateEvent (\r
- EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
- TPL_NOTIFY,\r
- TerminalConInTimerHandler,\r
- TerminalDevice,\r
- &TerminalDevice->TimerEvent\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Status = gBS->SetTimer (\r
- TerminalDevice->TimerEvent,\r
- TimerPeriodic,\r
- KEYBOARD_TIMER_INTERVAL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Status = gBS->CreateEvent (\r
- EVT_TIMER,\r
- TPL_CALLBACK,\r
- NULL,\r
- NULL,\r
- &TerminalDevice->TwoSecondTimeOut\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
+ StartTerminalStateMachine (TerminalDevice);\r
\r
Status = gBS->CreateEvent (\r
EVT_NOTIFY_SIGNAL,\r
FreeUnicodeStringTable (TerminalDevice->ControllerNameTable);\r
}\r
\r
- gBS->CloseEvent (TerminalDevice->TimerEvent);\r
- gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);\r
+ StopTerminalStateMachine (TerminalDevice);\r
gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);\r
gBS->CloseEvent (TerminalDevice->SimpleInputEx.WaitForKeyEx);\r
gBS->CloseEvent (TerminalDevice->KeyNotifyProcessEvent);\r
//\r
// Append terminal device path onto the variable.\r
//\r
- for (TerminalType = TerminalTypePcAnsi; TerminalType <= TerminalTypeTtyTerm; TerminalType++) {\r
+ for (TerminalType = 0; TerminalType < ARRAY_SIZE (mTerminalType); TerminalType++) {\r
SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);\r
NewVariable = AppendDevicePathInstance (Variable, TempDevicePath);\r
ASSERT (NewVariable != NULL);\r
// Loop through all the terminal types that this driver supports\r
//\r
Match = FALSE;\r
- for (TerminalType = TerminalTypePcAnsi; TerminalType <= TerminalTypeTtyTerm; TerminalType++) {\r
+ for (TerminalType = 0; TerminalType < ARRAY_SIZE (mTerminalType); TerminalType++) {\r
\r
SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);\r
\r
{\r
VENDOR_DEVICE_PATH Node;\r
\r
- *TerminalDevicePath = NULL;\r
+ ASSERT (TerminalType < ARRAY_SIZE (mTerminalType));\r
Node.Header.Type = MESSAGING_DEVICE_PATH;\r
Node.Header.SubType = MSG_VENDOR_DP;\r
-\r
- //\r
- // Generate terminal device path node according to terminal type.\r
- //\r
- switch (TerminalType) {\r
-\r
- case TerminalTypePcAnsi:\r
- CopyGuid (&Node.Guid, &gEfiPcAnsiGuid);\r
- break;\r
-\r
- case TerminalTypeVt100:\r
- CopyGuid (&Node.Guid, &gEfiVT100Guid);\r
- break;\r
-\r
- case TerminalTypeVt100Plus:\r
- CopyGuid (&Node.Guid, &gEfiVT100PlusGuid);\r
- break;\r
-\r
- case TerminalTypeVtUtf8:\r
- CopyGuid (&Node.Guid, &gEfiVTUTF8Guid);\r
- break;\r
-\r
- case TerminalTypeTtyTerm:\r
- CopyGuid (&Node.Guid, &gEfiTtyTermGuid);\r
- break;\r
-\r
- default:\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Get VENDOR_DEVCIE_PATH size and put into Node.Header\r
- //\r
- SetDevicePathNodeLength (\r
- &Node.Header,\r
- sizeof (VENDOR_DEVICE_PATH)\r
- );\r
+ SetDevicePathNodeLength (&Node, sizeof (VENDOR_DEVICE_PATH));\r
+ CopyGuid (&Node.Guid, mTerminalType[TerminalType]);\r
\r
//\r
// Append the terminal node onto parent device path\r