/** @file\r
handles console redirection from boot manager\r
\r
-Copyright (c) 2004 - 2010, Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
http://opensource.org/licenses/bsd-license.php\r
\r
#include "BootMaint.h"\r
\r
+UART_FLOW_CONTROL_DEVICE_PATH mFlowControlDevicePath =\r
+{\r
+ {\r
+ MESSAGING_DEVICE_PATH,\r
+ MSG_VENDOR_DP,\r
+ {\r
+ (UINT8)(sizeof(UART_FLOW_CONTROL_DEVICE_PATH)),\r
+ (UINT8)((sizeof(UART_FLOW_CONTROL_DEVICE_PATH)) >> 8)\r
+ }\r
+ },\r
+ DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL,\r
+ UART_FLOW_CONTROL_HARDWARE\r
+};\r
+\r
+/**\r
+ Check the device path node whether it's the Flow Control node or not.\r
+\r
+ @param[in] FlowControl The device path node to be checked.\r
+\r
+ @retval TRUE It's the Flow Control node.\r
+ @retval FALSE It's not.\r
+\r
+**/\r
+BOOLEAN\r
+IsUartFlowControlNode (\r
+ IN UART_FLOW_CONTROL_DEVICE_PATH *FlowControl\r
+ )\r
+{\r
+ return (BOOLEAN) (\r
+ (DevicePathType (FlowControl) == MESSAGING_DEVICE_PATH) &&\r
+ (DevicePathSubType (FlowControl) == MSG_VENDOR_DP) &&\r
+ (CompareGuid (&FlowControl->Guid, &gEfiUartDevicePathGuid))\r
+ );\r
+}\r
+\r
/**\r
Check whether the device path node is ISA Serial Node.\r
\r
\r
/**\r
Update the multi-instance device path of Terminal Device based on\r
- the global TerminalMenu. If ChangeTernimal is TRUE, the terminal \r
+ the global TerminalMenu. If ChangeTernimal is TRUE, the terminal\r
device path in the Terminal Device in TerminalMenu is also updated.\r
\r
@param DevicePath The multi-instance device path.\r
- @param ChangeTerminal TRUE, then device path in the Terminal Device \r
+ @param ChangeTerminal TRUE, then device path in the Terminal Device\r
in TerminalMenu is also updated; FALSE, no update.\r
\r
@return EFI_SUCCESS The function completes successfully.\r
**/\r
EFI_STATUS\r
ChangeTerminalDevicePath (\r
- IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,\r
IN BOOLEAN ChangeTerminal\r
)\r
{\r
UINTN Com;\r
BM_TERMINAL_CONTEXT *NewTerminalContext;\r
BM_MENU_ENTRY *NewMenuEntry;\r
+ UART_FLOW_CONTROL_DEVICE_PATH *FlowControlNode;\r
\r
- Node = DevicePath;\r
+ Node = *DevicePath;\r
Node = NextDevicePathNode (Node);\r
Com = 0;\r
while (!IsDevicePathEnd (Node)) {\r
&NewTerminalContext->StopBits,\r
sizeof (UINT8)\r
);\r
+\r
+ FlowControlNode = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (Node);\r
+ if (IsUartFlowControlNode (FlowControlNode)) {\r
+ FlowControlNode->FlowControlMap = NewTerminalContext->FlowControl;\r
+ } else {\r
+ //\r
+ // Append the Flow control device node when user enable flow control.\r
+ //\r
+ if (NewTerminalContext->FlowControl != 0) {\r
+ mFlowControlDevicePath.FlowControlMap = NewTerminalContext->FlowControl;\r
+ *DevicePath = AppendDevicePathNode (\r
+ *DevicePath,\r
+ (EFI_DEVICE_PATH_PROTOCOL *) (&mFlowControlDevicePath)\r
+ );\r
+ }\r
+ }\r
+\r
//\r
// Change the device path in the ComPort\r
//\r
\r
}\r
\r
-/**\r
- Update the device path that describing a terminal device\r
- based on the new BaudRate, Data Bits, parity and Stop Bits\r
- set.\r
\r
- @param DevicePath terminal device's path\r
-\r
-**/\r
-VOID\r
-ChangeVariableDevicePath (\r
- IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
- )\r
-{\r
- EFI_DEVICE_PATH_PROTOCOL *Node;\r
- ACPI_HID_DEVICE_PATH *Acpi;\r
- UART_DEVICE_PATH *Uart;\r
- UINTN Com;\r
- BM_TERMINAL_CONTEXT *NewTerminalContext;\r
- BM_MENU_ENTRY *NewMenuEntry;\r
-\r
- Node = DevicePath;\r
- Node = NextDevicePathNode (Node);\r
- Com = 0;\r
- while (!IsDevicePathEnd (Node)) {\r
- Acpi = (ACPI_HID_DEVICE_PATH *) Node;\r
- if (IsIsaSerialNode (Acpi)) {\r
- CopyMem (&Com, &Acpi->UID, sizeof (UINT32));\r
- }\r
-\r
- if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {\r
- NewMenuEntry = BOpt_GetMenuEntry (\r
- &TerminalMenu,\r
- Com\r
- );\r
- ASSERT (NewMenuEntry != NULL);\r
- NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
- Uart = (UART_DEVICE_PATH *) Node;\r
- CopyMem (\r
- &Uart->BaudRate,\r
- &NewTerminalContext->BaudRate,\r
- sizeof (UINT64)\r
- );\r
-\r
- CopyMem (\r
- &Uart->DataBits,\r
- &NewTerminalContext->DataBits,\r
- sizeof (UINT8)\r
- );\r
-\r
- CopyMem (\r
- &Uart->Parity,\r
- &NewTerminalContext->Parity,\r
- sizeof (UINT8)\r
- );\r
-\r
- CopyMem (\r
- &Uart->StopBits,\r
- &NewTerminalContext->StopBits,\r
- sizeof (UINT8)\r
- );\r
- }\r
-\r
- Node = NextDevicePathNode (Node);\r
- }\r
-}\r
\r
/**\r
Retrieve ACPI UID of UART from device path\r
BM_TERMINAL_CONTEXT *NewTerminalContext;\r
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
VENDOR_DEVICE_PATH Vendor;\r
+ UINT32 FlowControl;\r
//\r
// Get all handles that have SerialIo protocol installed\r
//\r
&SerialIo->Mode->StopBits,\r
sizeof (UINT8)\r
);\r
+\r
+ NewTerminalContext->FlowControl = 0;\r
+ SerialIo->GetControl(SerialIo, &FlowControl);\r
+ if ((FlowControl & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) != 0) {\r
+ NewTerminalContext->FlowControl = UART_FLOW_CONTROL_HARDWARE;\r
+ }\r
+\r
InsertTailList (&TerminalMenu.Head, &NewMenuEntry->Link);\r
TerminalMenu.MenuNumber++;\r
}\r
BM_MENU_ENTRY *NewMenuEntry;\r
BM_TERMINAL_CONTEXT *NewTerminalContext;\r
UINTN Index;\r
+ UART_FLOW_CONTROL_DEVICE_PATH *FlowControlNode;\r
+ BOOLEAN HasFlowControlNode;\r
\r
+ HasFlowControlNode = FALSE;\r
Node = DevicePath;\r
Node = NextDevicePathNode (Node);\r
TerminalNumber = 0;\r
sizeof (UINT8)\r
);\r
\r
+ FlowControlNode = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (Node);\r
+ if (IsUartFlowControlNode (FlowControlNode)) {\r
+ HasFlowControlNode = TRUE;\r
+ NewTerminalContext->FlowControl = (UINT8) ReadUnaligned32 (&FlowControlNode->FlowControlMap);\r
+ } else if (NewTerminalContext->FlowControl != 0) {\r
+ //\r
+ // No Flow Control device path node, assumption no Flow control\r
+ //\r
+ NewTerminalContext->FlowControl = 0;\r
+ }\r
+\r
SerialNode = NewTerminalContext->DevicePath;\r
SerialNode = NextDevicePathNode (SerialNode);\r
while (!IsDevicePathEnd (SerialNode)) {\r
sizeof (UINT8)\r
);\r
\r
+ FlowControlNode = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (SerialNode);\r
+ if (IsUartFlowControlNode (FlowControlNode)) {\r
+ FlowControlNode->FlowControlMap = NewTerminalContext->FlowControl;\r
+ } else {\r
+ if (HasFlowControlNode) {\r
+ mFlowControlDevicePath.FlowControlMap = NewTerminalContext->FlowControl;\r
+ NewTerminalContext->DevicePath = AppendDevicePathNode (\r
+ NewTerminalContext->DevicePath,\r
+ (EFI_DEVICE_PATH_PROTOCOL *) (&mFlowControlDevicePath)\r
+ );\r
+ }\r
+ }\r
break;\r
}\r
\r
and BM_CONSOLE_ERR_CONTEXT_SELECT.\r
\r
@retval EFI_UNSUPPORTED The type passed in is not in the 3 types defined.\r
- @retval EFI_NOT_FOUND If the EFI Variable defined in UEFI spec with name "ConOutDev", \r
+ @retval EFI_NOT_FOUND If the EFI Variable defined in UEFI spec with name "ConOutDev",\r
"ConInDev" or "ConErrDev" doesn't exists.\r
@retval EFI_OUT_OF_RESOURCES Not enough resource to complete the operations.\r
@retval EFI_SUCCESS Function completes successfully.\r
ConOut = gST->ConOut;\r
MaxMode = (UINTN) (ConOut->Mode->MaxMode);\r
\r
- CurrentCol = PcdGet32 (PcdConOutColumn);\r
- CurrentRow = PcdGet32 (PcdConOutRow);\r
+ CurrentCol = PcdGet32 (PcdSetupConOutColumn);\r
+ CurrentRow = PcdGet32 (PcdSetupConOutRow);\r
for (Mode = 0; Mode < MaxMode; Mode++) {\r
Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row);\r
if (!EFI_ERROR(Status)) {\r
}\r
}\r
}\r
+\r
+/**\r
+\r
+ Initialize console input device check box to ConsoleInCheck[MAX_MENU_NUMBER]\r
+ in BMM_FAKE_NV_DATA structure.\r
+\r
+ @param CallbackData The BMM context data.\r
+\r
+**/\r
+VOID\r
+GetConsoleInCheck (\r
+ IN BMM_CALLBACK_DATA *CallbackData\r
+ )\r
+{\r
+ UINT16 Index;\r
+ BM_MENU_ENTRY *NewMenuEntry;\r
+ UINT8 *ConInCheck;\r
+ BM_CONSOLE_CONTEXT *NewConsoleContext;\r
+\r
+ ASSERT (CallbackData != NULL);\r
+\r
+ ConInCheck = &CallbackData->BmmFakeNvData.ConsoleInCheck[0];\r
+ for (Index = 0; ((Index < ConsoleInpMenu.MenuNumber) && \\r
+ (Index < MAX_MENU_NUMBER)) ; Index++) {\r
+ NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);\r
+ NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
+ ConInCheck[Index] = NewConsoleContext->IsActive;\r
+ }\r
+}\r
+\r
+/**\r
+\r
+ Initialize console output device check box to ConsoleOutCheck[MAX_MENU_NUMBER]\r
+ in BMM_FAKE_NV_DATA structure.\r
+\r
+ @param CallbackData The BMM context data.\r
+\r
+**/\r
+VOID\r
+GetConsoleOutCheck (\r
+ IN BMM_CALLBACK_DATA *CallbackData\r
+ )\r
+{\r
+ UINT16 Index;\r
+ BM_MENU_ENTRY *NewMenuEntry;\r
+ UINT8 *ConOutCheck;\r
+ BM_CONSOLE_CONTEXT *NewConsoleContext;\r
+\r
+ ASSERT (CallbackData != NULL);\r
+ ConOutCheck = &CallbackData->BmmFakeNvData.ConsoleOutCheck[0];\r
+ for (Index = 0; ((Index < ConsoleOutMenu.MenuNumber) && \\r
+ (Index < MAX_MENU_NUMBER)) ; Index++) {\r
+ NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);\r
+ NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
+ ConOutCheck[Index] = NewConsoleContext->IsActive;\r
+ }\r
+}\r
+\r
+/**\r
+\r
+ Initialize standard error output device check box to ConsoleErrCheck[MAX_MENU_NUMBER]\r
+ in BMM_FAKE_NV_DATA structure.\r
+\r
+ @param CallbackData The BMM context data.\r
+\r
+**/\r
+VOID\r
+GetConsoleErrCheck (\r
+ IN BMM_CALLBACK_DATA *CallbackData\r
+ )\r
+{\r
+ UINT16 Index;\r
+ BM_MENU_ENTRY *NewMenuEntry;\r
+ UINT8 *ConErrCheck;\r
+ BM_CONSOLE_CONTEXT *NewConsoleContext;\r
+\r
+ ASSERT (CallbackData != NULL);\r
+ ConErrCheck = &CallbackData->BmmFakeNvData.ConsoleErrCheck[0];\r
+ for (Index = 0; ((Index < ConsoleErrMenu.MenuNumber) && \\r
+ (Index < MAX_MENU_NUMBER)) ; Index++) {\r
+ NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);\r
+ NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
+ ConErrCheck[Index] = NewConsoleContext->IsActive;\r
+ }\r
+}\r
+\r
+/**\r
+\r
+ Initialize terminal attributes (baudrate, data rate, stop bits, parity and terminal type)\r
+ to BMM_FAKE_NV_DATA structure.\r
+\r
+ @param CallbackData The BMM context data.\r
+\r
+**/\r
+VOID\r
+GetTerminalAttribute (\r
+ IN BMM_CALLBACK_DATA *CallbackData\r
+ )\r
+{\r
+ BMM_FAKE_NV_DATA *CurrentFakeNVMap;\r
+ BM_MENU_ENTRY *NewMenuEntry;\r
+ BM_TERMINAL_CONTEXT *NewTerminalContext;\r
+ UINT16 TerminalIndex;\r
+ UINT8 AttributeIndex;\r
+\r
+ ASSERT (CallbackData != NULL);\r
+\r
+ CurrentFakeNVMap = &CallbackData->BmmFakeNvData;\r
+ for (TerminalIndex = 0; ((TerminalIndex < TerminalMenu.MenuNumber) && \\r
+ (TerminalIndex < MAX_MENU_NUMBER)); TerminalIndex++) {\r
+ NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, TerminalIndex);\r
+ NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
+ for (AttributeIndex = 0; AttributeIndex < sizeof (BaudRateList) / sizeof (BaudRateList [0]); AttributeIndex++) {\r
+ if (NewTerminalContext->BaudRate == (UINT64) (BaudRateList[AttributeIndex].Value)) {\r
+ NewTerminalContext->BaudRateIndex = AttributeIndex;\r
+ break;\r
+ }\r
+ }\r
+ for (AttributeIndex = 0; AttributeIndex < ARRAY_SIZE (DataBitsList); AttributeIndex++) {\r
+ if (NewTerminalContext->DataBits == (UINT64) (DataBitsList[AttributeIndex].Value)) {\r
+ NewTerminalContext->DataBitsIndex = AttributeIndex;\r
+ break;\r
+ }\r
+ }\r
+\r
+ for (AttributeIndex = 0; AttributeIndex < ARRAY_SIZE (ParityList); AttributeIndex++) {\r
+ if (NewTerminalContext->Parity == (UINT64) (ParityList[AttributeIndex].Value)) {\r
+ NewTerminalContext->ParityIndex = AttributeIndex;\r
+ break;\r
+ }\r
+ }\r
+\r
+ for (AttributeIndex = 0; AttributeIndex < ARRAY_SIZE (StopBitsList); AttributeIndex++) {\r
+ if (NewTerminalContext->StopBits == (UINT64) (StopBitsList[AttributeIndex].Value)) {\r
+ NewTerminalContext->StopBitsIndex = AttributeIndex;\r
+ break;\r
+ }\r
+ }\r
+ CurrentFakeNVMap->COMBaudRate[TerminalIndex] = NewTerminalContext->BaudRateIndex;\r
+ CurrentFakeNVMap->COMDataRate[TerminalIndex] = NewTerminalContext->DataBitsIndex;\r
+ CurrentFakeNVMap->COMStopBits[TerminalIndex] = NewTerminalContext->StopBitsIndex;\r
+ CurrentFakeNVMap->COMParity[TerminalIndex] = NewTerminalContext->ParityIndex;\r
+ CurrentFakeNVMap->COMTerminalType[TerminalIndex] = NewTerminalContext->TerminalType;\r
+ CurrentFakeNVMap->COMFlowControl[TerminalIndex] = NewTerminalContext->FlowControl;\r
+ }\r
+}\r
+\r