/** @file\r
handles console redirection from boot manager\r
\r
-Copyright (c) 2004 - 2009, Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2004 - 2010, 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
+ (UINT8)(sizeof(UART_FLOW_CONTROL_DEVICE_PATH)),\r
+ (UINT8)((sizeof(UART_FLOW_CONTROL_DEVICE_PATH)) >> 8),\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
+ @param Acpi Device path node to be checked\r
+\r
+ @retval TRUE It's ISA Serial Node.\r
+ @retval FALSE It's NOT ISA Serial Node.\r
+\r
+**/\r
+BOOLEAN\r
+IsIsaSerialNode (\r
+ IN ACPI_HID_DEVICE_PATH *Acpi\r
+ )\r
+{\r
+ return (BOOLEAN) (\r
+ (DevicePathType (Acpi) == ACPI_DEVICE_PATH) &&\r
+ (DevicePathSubType (Acpi) == ACPI_DP) &&\r
+ (ReadUnaligned32 (&Acpi->HID) == EISA_PNP_ID (0x0501))\r
+ );\r
+}\r
+\r
/**\r
Update Com Ports attributes from DevicePath\r
\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
UART_DEVICE_PATH *Uart;\r
UART_DEVICE_PATH *Uart1;\r
UINTN Com;\r
- UINT32 Match;\r
BM_TERMINAL_CONTEXT *NewTerminalContext;\r
BM_MENU_ENTRY *NewMenuEntry;\r
+ UART_FLOW_CONTROL_DEVICE_PATH *FlowControlNode;\r
\r
- Match = EISA_PNP_ID (0x0501);\r
- Node = DevicePath;\r
+ Node = *DevicePath;\r
Node = NextDevicePathNode (Node);\r
Com = 0;\r
while (!IsDevicePathEnd (Node)) {\r
- if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) {\r
- Acpi = (ACPI_HID_DEVICE_PATH *) Node;\r
- if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {\r
- CopyMem (&Com, &Acpi->UID, sizeof (UINT32));\r
- }\r
+ Acpi = (ACPI_HID_DEVICE_PATH *) Node;\r
+ if (IsIsaSerialNode (Acpi)) {\r
+ CopyMem (&Com, &Acpi->UID, sizeof (UINT32));\r
}\r
\r
NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Com);\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
ACPI_HID_DEVICE_PATH *Acpi;\r
UART_DEVICE_PATH *Uart;\r
UINTN Com;\r
- UINT32 Match;\r
BM_TERMINAL_CONTEXT *NewTerminalContext;\r
BM_MENU_ENTRY *NewMenuEntry;\r
\r
- Match = EISA_PNP_ID (0x0501);\r
Node = DevicePath;\r
Node = NextDevicePathNode (Node);\r
Com = 0;\r
while (!IsDevicePathEnd (Node)) {\r
- if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) {\r
- Acpi = (ACPI_HID_DEVICE_PATH *) Node;\r
- if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {\r
- CopyMem (&Com, &Acpi->UID, sizeof (UINT32));\r
- }\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
IN OUT UINT32 *AcpiUid\r
)\r
{\r
- UINT32 Match;\r
- UINT8 *Ptr;\r
+ EFI_STATUS Status;\r
ACPI_HID_DEVICE_PATH *Acpi;\r
EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
\r
- gBS->HandleProtocol (\r
- Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **) &DevicePath\r
- );\r
- Ptr = (UINT8 *) DevicePath;\r
-\r
- while (*Ptr != END_DEVICE_PATH_TYPE) {\r
- Ptr++;\r
+ Status = gBS->HandleProtocol (\r
+ Handle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &DevicePath\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return FALSE;\r
}\r
\r
- Ptr = Ptr - sizeof (UART_DEVICE_PATH) - sizeof (ACPI_HID_DEVICE_PATH);\r
- Acpi = (ACPI_HID_DEVICE_PATH *) Ptr;\r
- Match = EISA_PNP_ID (0x0501);\r
+ Acpi = NULL;\r
+ for (; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {\r
+ if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (DevicePath) == MSG_UART_DP)) {\r
+ break;\r
+ }\r
+ //\r
+ // Acpi points to the node before the Uart node\r
+ //\r
+ Acpi = (ACPI_HID_DEVICE_PATH *) DevicePath;\r
+ }\r
\r
- if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {\r
+ if ((Acpi != NULL) && IsIsaSerialNode (Acpi)) {\r
if (AcpiUid != NULL) {\r
- *AcpiUid = Acpi->UID;\r
+ CopyMem (AcpiUid, &Acpi->UID, sizeof (UINT32));\r
}\r
return TRUE;\r
} else {\r
VOID\r
)\r
{\r
- UINT8 *Ptr;\r
UINTN Index;\r
UINTN Index2;\r
UINTN NoHandles;\r
EFI_STATUS Status;\r
ACPI_HID_DEVICE_PATH *Acpi;\r
EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
- UINT32 Match;\r
EFI_SERIAL_IO_PROTOCOL *SerialIo;\r
+ EFI_DEVICE_PATH_PROTOCOL *Node;\r
EFI_DEVICE_PATH_PROTOCOL *OutDevicePath;\r
EFI_DEVICE_PATH_PROTOCOL *InpDevicePath;\r
EFI_DEVICE_PATH_PROTOCOL *ErrDevicePath;\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
&gEfiDevicePathProtocolGuid,\r
(VOID **) &DevicePath\r
);\r
- Ptr = (UINT8 *) DevicePath;\r
- while (*Ptr != END_DEVICE_PATH_TYPE) {\r
- Ptr++;\r
- }\r
\r
- Ptr = Ptr - sizeof (UART_DEVICE_PATH) - sizeof (ACPI_HID_DEVICE_PATH);\r
- Acpi = (ACPI_HID_DEVICE_PATH *) Ptr;\r
- Match = EISA_PNP_ID (0x0501);\r
+ Acpi = NULL;\r
+ for (Node = DevicePath; !IsDevicePathEnd (Node); Node = NextDevicePathNode (Node)) {\r
+ if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {\r
+ break;\r
+ }\r
+ //\r
+ // Acpi points to the node before Uart node\r
+ //\r
+ Acpi = (ACPI_HID_DEVICE_PATH *) Node;\r
+ }\r
\r
- if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {\r
+ if ((Acpi != NULL) && IsIsaSerialNode (Acpi)) {\r
NewMenuEntry = BOpt_CreateMenuEntry (BM_TERMINAL_CONTEXT_SELECT);\r
if (NewMenuEntry == NULL) {\r
FreePool (Handles);\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
ACPI_HID_DEVICE_PATH *Acpi;\r
UART_DEVICE_PATH *Uart;\r
UART_DEVICE_PATH *Uart1;\r
- UINT32 Match;\r
UINTN TerminalNumber;\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
- Match = EISA_PNP_ID (0x0501);\r
+ HasFlowControlNode = FALSE;\r
Node = DevicePath;\r
Node = NextDevicePathNode (Node);\r
TerminalNumber = 0;\r
for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
while (!IsDevicePathEnd (Node)) {\r
- if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) {\r
- Acpi = (ACPI_HID_DEVICE_PATH *) Node;\r
- if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {\r
- CopyMem (&TerminalNumber, &Acpi->UID, sizeof (UINT32));\r
- }\r
+ Acpi = (ACPI_HID_DEVICE_PATH *) Node;\r
+ if (IsIsaSerialNode (Acpi)) {\r
+ CopyMem (&TerminalNumber, &Acpi->UID, sizeof (UINT32));\r
}\r
\r
if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {\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
OUT UINTN *Com\r
)\r
{\r
- UINT8 *Ptr;\r
- BOOLEAN IsTerminal;\r
- VENDOR_DEVICE_PATH *Vendor;\r
- ACPI_HID_DEVICE_PATH *Acpi;\r
- UINT32 Match;\r
- EFI_GUID TempGuid;\r
+ BOOLEAN IsTerminal;\r
+ EFI_DEVICE_PATH_PROTOCOL *Node;\r
+ VENDOR_DEVICE_PATH *Vendor;\r
+ UART_DEVICE_PATH *Uart;\r
+ ACPI_HID_DEVICE_PATH *Acpi;\r
\r
IsTerminal = FALSE;\r
\r
- //\r
- // Parse the Device Path, should be change later!!!\r
- //\r
- Ptr = (UINT8 *) DevicePath;\r
- while (*Ptr != END_DEVICE_PATH_TYPE) {\r
- Ptr++;\r
+ Uart = NULL;\r
+ Vendor = NULL;\r
+ Acpi = NULL;\r
+ for (Node = DevicePath; !IsDevicePathEnd (Node); Node = NextDevicePathNode (Node)) {\r
+ //\r
+ // Vendor points to the node before the End node\r
+ //\r
+ Vendor = (VENDOR_DEVICE_PATH *) Node;\r
+\r
+ if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {\r
+ Uart = (UART_DEVICE_PATH *) Node;\r
+ }\r
+\r
+ if (Uart == NULL) {\r
+ //\r
+ // Acpi points to the node before the UART node\r
+ //\r
+ Acpi = (ACPI_HID_DEVICE_PATH *) Node;\r
+ }\r
}\r
\r
- Ptr = Ptr - sizeof (VENDOR_DEVICE_PATH);\r
- Vendor = (VENDOR_DEVICE_PATH *) Ptr;\r
+ if (Vendor == NULL ||\r
+ DevicePathType (Vendor) != MESSAGING_DEVICE_PATH ||\r
+ DevicePathSubType (Vendor) != MSG_VENDOR_DP ||\r
+ Uart == NULL) {\r
+ return FALSE;\r
+ }\r
\r
//\r
// There are four kinds of Terminal types\r
// check to see whether this devicepath\r
// is one of that type\r
//\r
- CopyMem (&TempGuid, &Vendor->Guid, sizeof (EFI_GUID));\r
-\r
- if (CompareGuid (&TempGuid, &TerminalTypeGuid[0])) {\r
+ if (CompareGuid (&Vendor->Guid, &TerminalTypeGuid[0])) {\r
*Termi = TerminalTypePcAnsi;\r
IsTerminal = TRUE;\r
} else {\r
- if (CompareGuid (&TempGuid, &TerminalTypeGuid[1])) {\r
+ if (CompareGuid (&Vendor->Guid, &TerminalTypeGuid[1])) {\r
*Termi = TerminalTypeVt100;\r
IsTerminal = TRUE;\r
} else {\r
- if (CompareGuid (&TempGuid, &TerminalTypeGuid[2])) {\r
+ if (CompareGuid (&Vendor->Guid, &TerminalTypeGuid[2])) {\r
*Termi = TerminalTypeVt100Plus;\r
IsTerminal = TRUE;\r
} else {\r
- if (CompareGuid (&TempGuid, &TerminalTypeGuid[3])) {\r
+ if (CompareGuid (&Vendor->Guid, &TerminalTypeGuid[3])) {\r
*Termi = TerminalTypeVtUtf8;\r
IsTerminal = TRUE;\r
} else {\r
return FALSE;\r
}\r
\r
- Ptr = Ptr - sizeof (UART_DEVICE_PATH) - sizeof (ACPI_HID_DEVICE_PATH);\r
- Acpi = (ACPI_HID_DEVICE_PATH *) Ptr;\r
- Match = EISA_PNP_ID (0x0501);\r
- if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {\r
+ if ((Acpi != NULL) && IsIsaSerialNode (Acpi)) {\r
CopyMem (Com, &Acpi->UID, sizeof (UINT32));\r
} else {\r
return FALSE;\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