+++ /dev/null
-/** @file\r
- handles console redirection from boot manager\r
-\r
-Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\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
- @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
- @param DevicePath DevicePath that contains Com ports\r
-\r
- @retval EFI_SUCCESS The update is successful.\r
-\r
-**/\r
-EFI_STATUS\r
-UpdateComAttributeFromVariable (\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath\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
- 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
- in TerminalMenu is also updated; FALSE, no update.\r
-\r
- @return EFI_SUCCESS The function completes successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-ChangeTerminalDevicePath (\r
- IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,\r
- IN BOOLEAN ChangeTerminal\r
- )\r
-{\r
- EFI_DEVICE_PATH_PROTOCOL *Node;\r
- EFI_DEVICE_PATH_PROTOCOL *Node1;\r
- ACPI_HID_DEVICE_PATH *Acpi;\r
- UART_DEVICE_PATH *Uart;\r
- UART_DEVICE_PATH *Uart1;\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 = 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
- NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Com);\r
-\r
- NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
- if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {\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
- 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
- if (ChangeTerminal) {\r
- Node1 = NewTerminalContext->DevicePath;\r
- Node1 = NextDevicePathNode (Node1);\r
- while (!IsDevicePathEnd (Node1)) {\r
- if ((DevicePathType (Node1) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node1) == MSG_UART_DP)) {\r
- Uart1 = (UART_DEVICE_PATH *) Node1;\r
- CopyMem (\r
- &Uart1->BaudRate,\r
- &NewTerminalContext->BaudRate,\r
- sizeof (UINT64)\r
- );\r
-\r
- CopyMem (\r
- &Uart1->DataBits,\r
- &NewTerminalContext->DataBits,\r
- sizeof (UINT8)\r
- );\r
-\r
- CopyMem (\r
- &Uart1->Parity,\r
- &NewTerminalContext->Parity,\r
- sizeof (UINT8)\r
- );\r
-\r
- CopyMem (\r
- &Uart1->StopBits,\r
- &NewTerminalContext->StopBits,\r
- sizeof (UINT8)\r
- );\r
- break;\r
- }\r
- //\r
- // end if\r
- //\r
- Node1 = NextDevicePathNode (Node1);\r
- }\r
- //\r
- // end while\r
- //\r
- break;\r
- }\r
- }\r
-\r
- Node = NextDevicePathNode (Node);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-\r
-\r
-/**\r
- Retrieve ACPI UID of UART from device path\r
-\r
- @param Handle The handle for the UART device.\r
- @param AcpiUid The ACPI UID on output.\r
-\r
- @retval TRUE Find valid UID from device path\r
- @retval FALSE Can't find\r
-\r
-**/\r
-BOOLEAN\r
-RetrieveUartUid (\r
- IN EFI_HANDLE Handle,\r
- IN OUT UINT32 *AcpiUid\r
- )\r
-{\r
- EFI_STATUS Status;\r
- ACPI_HID_DEVICE_PATH *Acpi;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
-\r
- Status = gBS->HandleProtocol (\r
- Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **) &DevicePath\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return FALSE;\r
- }\r
-\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 ((Acpi != NULL) && IsIsaSerialNode (Acpi)) {\r
- if (AcpiUid != NULL) {\r
- CopyMem (AcpiUid, &Acpi->UID, sizeof (UINT32));\r
- }\r
- return TRUE;\r
- } else {\r
- return FALSE;\r
- }\r
-}\r
-\r
-/**\r
- Sort Uart handles array with Acpi->UID from low to high.\r
-\r
- @param Handles EFI_SERIAL_IO_PROTOCOL handle buffer\r
- @param NoHandles EFI_SERIAL_IO_PROTOCOL handle count\r
-**/\r
-VOID\r
-SortedUartHandle (\r
- IN EFI_HANDLE *Handles,\r
- IN UINTN NoHandles\r
- )\r
-{\r
- UINTN Index1;\r
- UINTN Index2;\r
- UINTN Position;\r
- UINT32 AcpiUid1;\r
- UINT32 AcpiUid2;\r
- UINT32 TempAcpiUid;\r
- EFI_HANDLE TempHandle;\r
-\r
- for (Index1 = 0; Index1 < NoHandles-1; Index1++) {\r
- if (!RetrieveUartUid (Handles[Index1], &AcpiUid1)) {\r
- continue;\r
- }\r
- TempHandle = Handles[Index1];\r
- Position = Index1;\r
- TempAcpiUid = AcpiUid1;\r
-\r
- for (Index2 = Index1+1; Index2 < NoHandles; Index2++) {\r
- if (!RetrieveUartUid (Handles[Index2], &AcpiUid2)) {\r
- continue;\r
- }\r
- if (AcpiUid2 < TempAcpiUid) {\r
- TempAcpiUid = AcpiUid2;\r
- TempHandle = Handles[Index2];\r
- Position = Index2;\r
- }\r
- }\r
- Handles[Position] = Handles[Index1];\r
- Handles[Index1] = TempHandle;\r
- }\r
-}\r
-\r
-/**\r
- Test whether DevicePath is a valid Terminal\r
-\r
-\r
- @param DevicePath DevicePath to be checked\r
- @param Termi If DevicePath is valid Terminal, terminal type is returned.\r
- @param Com If DevicePath is valid Terminal, Com Port type is returned.\r
-\r
- @retval TRUE If DevicePath point to a Terminal.\r
- @retval FALSE If DevicePath does not point to a Terminal.\r
-\r
-**/\r
-BOOLEAN\r
-IsTerminalDevicePath (\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
- OUT TYPE_OF_TERMINAL *Termi,\r
- OUT UINTN *Com\r
- );\r
-\r
-/**\r
- Build a list containing all serial devices.\r
-\r
-\r
- @retval EFI_SUCCESS The function complete successfully.\r
- @retval EFI_UNSUPPORTED No serial ports present.\r
-\r
-**/\r
-EFI_STATUS\r
-LocateSerialIo (\r
- VOID\r
- )\r
-{\r
- UINTN Index;\r
- UINTN Index2;\r
- UINTN NoHandles;\r
- EFI_HANDLE *Handles;\r
- EFI_STATUS Status;\r
- ACPI_HID_DEVICE_PATH *Acpi;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\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_MENU_ENTRY *NewMenuEntry;\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
- InitializeListHead (&TerminalMenu.Head);\r
- TerminalMenu.MenuNumber = 0;\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiSerialIoProtocolGuid,\r
- NULL,\r
- &NoHandles,\r
- &Handles\r
- );\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // No serial ports present\r
- //\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Sort Uart handles array with Acpi->UID from low to high\r
- // then Terminal menu can be built from low Acpi->UID to high Acpi->UID\r
- //\r
- SortedUartHandle (Handles, NoHandles);\r
-\r
- for (Index = 0; Index < NoHandles; Index++) {\r
- //\r
- // Check to see whether the handle has DevicePath Protocol installed\r
- //\r
- gBS->HandleProtocol (\r
- Handles[Index],\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **) &DevicePath\r
- );\r
-\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 ((Acpi != NULL) && IsIsaSerialNode (Acpi)) {\r
- NewMenuEntry = BOpt_CreateMenuEntry (BM_TERMINAL_CONTEXT_SELECT);\r
- if (NewMenuEntry == NULL) {\r
- FreePool (Handles);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
- CopyMem (&NewMenuEntry->OptionNumber, &Acpi->UID, sizeof (UINT32));\r
- NewTerminalContext->DevicePath = DuplicateDevicePath (DevicePath);\r
- //\r
- // BugBug: I have no choice, calling EfiLibStrFromDatahub will hang the system!\r
- // coz' the misc data for each platform is not correct, actually it's the device path stored in\r
- // datahub which is not completed, so a searching for end of device path will enter a\r
- // dead-loop.\r
- //\r
- NewMenuEntry->DisplayString = EfiLibStrFromDatahub (DevicePath);\r
- if (NULL == NewMenuEntry->DisplayString) {\r
- NewMenuEntry->DisplayString = DevicePathToStr (DevicePath);\r
- }\r
-\r
- NewMenuEntry->HelpString = NULL;\r
-\r
- gBS->HandleProtocol (\r
- Handles[Index],\r
- &gEfiSerialIoProtocolGuid,\r
- (VOID **) &SerialIo\r
- );\r
-\r
- CopyMem (\r
- &NewTerminalContext->BaudRate,\r
- &SerialIo->Mode->BaudRate,\r
- sizeof (UINT64)\r
- );\r
-\r
- CopyMem (\r
- &NewTerminalContext->DataBits,\r
- &SerialIo->Mode->DataBits,\r
- sizeof (UINT8)\r
- );\r
-\r
- CopyMem (\r
- &NewTerminalContext->Parity,\r
- &SerialIo->Mode->Parity,\r
- sizeof (UINT8)\r
- );\r
-\r
- CopyMem (\r
- &NewTerminalContext->StopBits,\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
- }\r
- if (Handles != NULL) {\r
- FreePool (Handles);\r
- }\r
-\r
- //\r
- // Get L"ConOut", L"ConIn" and L"ErrOut" from the Var\r
- //\r
- OutDevicePath = EfiLibGetVariable (L"ConOut", &gEfiGlobalVariableGuid);\r
- InpDevicePath = EfiLibGetVariable (L"ConIn", &gEfiGlobalVariableGuid);\r
- ErrDevicePath = EfiLibGetVariable (L"ErrOut", &gEfiGlobalVariableGuid);\r
- if (OutDevicePath != NULL) {\r
- UpdateComAttributeFromVariable (OutDevicePath);\r
- }\r
-\r
- if (InpDevicePath != NULL) {\r
- UpdateComAttributeFromVariable (InpDevicePath);\r
- }\r
-\r
- if (ErrDevicePath != NULL) {\r
- UpdateComAttributeFromVariable (ErrDevicePath);\r
- }\r
-\r
- for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
- NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
- if (NULL == NewMenuEntry) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
-\r
- NewTerminalContext->TerminalType = 0;\r
- NewTerminalContext->IsConIn = FALSE;\r
- NewTerminalContext->IsConOut = FALSE;\r
- NewTerminalContext->IsStdErr = FALSE;\r
-\r
- Vendor.Header.Type = MESSAGING_DEVICE_PATH;\r
- Vendor.Header.SubType = MSG_VENDOR_DP;\r
-\r
- for (Index2 = 0; Index2 < 4; Index2++) {\r
- CopyMem (&Vendor.Guid, &TerminalTypeGuid[Index2], sizeof (EFI_GUID));\r
- SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));\r
- NewDevicePath = AppendDevicePathNode (\r
- NewTerminalContext->DevicePath,\r
- (EFI_DEVICE_PATH_PROTOCOL *) &Vendor\r
- );\r
- if (NewMenuEntry->HelpString != NULL) {\r
- FreePool (NewMenuEntry->HelpString);\r
- }\r
- //\r
- // NewMenuEntry->HelpString = DevicePathToStr (NewDevicePath);\r
- // NewMenuEntry->DisplayString = NewMenuEntry->HelpString;\r
- //\r
- NewMenuEntry->HelpString = NULL;\r
-\r
- if (BdsLibMatchDevicePaths (OutDevicePath, NewDevicePath)) {\r
- NewTerminalContext->IsConOut = TRUE;\r
- NewTerminalContext->TerminalType = (UINT8) Index2;\r
- }\r
-\r
- if (BdsLibMatchDevicePaths (InpDevicePath, NewDevicePath)) {\r
- NewTerminalContext->IsConIn = TRUE;\r
- NewTerminalContext->TerminalType = (UINT8) Index2;\r
- }\r
-\r
- if (BdsLibMatchDevicePaths (ErrDevicePath, NewDevicePath)) {\r
- NewTerminalContext->IsStdErr = TRUE;\r
- NewTerminalContext->TerminalType = (UINT8) Index2;\r
- }\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Update Com Ports attributes from DevicePath\r
-\r
- @param DevicePath DevicePath that contains Com ports\r
-\r
- @retval EFI_SUCCESS The update is successful.\r
- @retval EFI_NOT_FOUND Can not find specific menu entry\r
-**/\r
-EFI_STATUS\r
-UpdateComAttributeFromVariable (\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
- )\r
-{\r
- EFI_DEVICE_PATH_PROTOCOL *Node;\r
- EFI_DEVICE_PATH_PROTOCOL *SerialNode;\r
- ACPI_HID_DEVICE_PATH *Acpi;\r
- UART_DEVICE_PATH *Uart;\r
- UART_DEVICE_PATH *Uart1;\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
- 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
- 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
- Uart = (UART_DEVICE_PATH *) Node;\r
- NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, TerminalNumber);\r
- if (NULL == NewMenuEntry) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
- CopyMem (\r
- &NewTerminalContext->BaudRate,\r
- &Uart->BaudRate,\r
- sizeof (UINT64)\r
- );\r
-\r
- CopyMem (\r
- &NewTerminalContext->DataBits,\r
- &Uart->DataBits,\r
- sizeof (UINT8)\r
- );\r
-\r
- CopyMem (\r
- &NewTerminalContext->Parity,\r
- &Uart->Parity,\r
- sizeof (UINT8)\r
- );\r
-\r
- CopyMem (\r
- &NewTerminalContext->StopBits,\r
- &Uart->StopBits,\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
- if ((DevicePathType (SerialNode) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (SerialNode) == MSG_UART_DP)) {\r
- //\r
- // Update following device paths according to\r
- // previous acquired uart attributes\r
- //\r
- Uart1 = (UART_DEVICE_PATH *) SerialNode;\r
- CopyMem (\r
- &Uart1->BaudRate,\r
- &NewTerminalContext->BaudRate,\r
- sizeof (UINT64)\r
- );\r
-\r
- CopyMem (\r
- &Uart1->DataBits,\r
- &NewTerminalContext->DataBits,\r
- sizeof (UINT8)\r
- );\r
- CopyMem (\r
- &Uart1->Parity,\r
- &NewTerminalContext->Parity,\r
- sizeof (UINT8)\r
- );\r
- CopyMem (\r
- &Uart1->StopBits,\r
- &NewTerminalContext->StopBits,\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
- SerialNode = NextDevicePathNode (SerialNode);\r
- }\r
- //\r
- // end while\r
- //\r
- }\r
-\r
- Node = NextDevicePathNode (Node);\r
- }\r
- //\r
- // end while\r
- //\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Build up Console Menu based on types passed in. The type can\r
- be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT\r
- and BM_CONSOLE_ERR_CONTEXT_SELECT.\r
-\r
- @param ConsoleMenuType Can be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT\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
- "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
-\r
-**/\r
-EFI_STATUS\r
-GetConsoleMenu (\r
- IN UINTN ConsoleMenuType\r
- )\r
-{\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
- EFI_DEVICE_PATH_PROTOCOL *AllDevicePath;\r
- EFI_DEVICE_PATH_PROTOCOL *MultiDevicePath;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;\r
- UINTN Size;\r
- UINTN AllCount;\r
- UINTN Index;\r
- UINTN Index2;\r
- BM_MENU_ENTRY *NewMenuEntry;\r
- BM_CONSOLE_CONTEXT *NewConsoleContext;\r
- TYPE_OF_TERMINAL Terminal;\r
- UINTN Com;\r
- BM_MENU_OPTION *ConsoleMenu;\r
-\r
- DevicePath = NULL;\r
- AllDevicePath = NULL;\r
- AllCount = 0;\r
- switch (ConsoleMenuType) {\r
- case BM_CONSOLE_IN_CONTEXT_SELECT:\r
- ConsoleMenu = &ConsoleInpMenu;\r
- DevicePath = EfiLibGetVariable (\r
- L"ConIn",\r
- &gEfiGlobalVariableGuid\r
- );\r
-\r
- AllDevicePath = EfiLibGetVariable (\r
- L"ConInDev",\r
- &gEfiGlobalVariableGuid\r
- );\r
- break;\r
-\r
- case BM_CONSOLE_OUT_CONTEXT_SELECT:\r
- ConsoleMenu = &ConsoleOutMenu;\r
- DevicePath = EfiLibGetVariable (\r
- L"ConOut",\r
- &gEfiGlobalVariableGuid\r
- );\r
-\r
- AllDevicePath = EfiLibGetVariable (\r
- L"ConOutDev",\r
- &gEfiGlobalVariableGuid\r
- );\r
- break;\r
-\r
- case BM_CONSOLE_ERR_CONTEXT_SELECT:\r
- ConsoleMenu = &ConsoleErrMenu;\r
- DevicePath = EfiLibGetVariable (\r
- L"ErrOut",\r
- &gEfiGlobalVariableGuid\r
- );\r
-\r
- AllDevicePath = EfiLibGetVariable (\r
- L"ErrOutDev",\r
- &gEfiGlobalVariableGuid\r
- );\r
- break;\r
-\r
- default:\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if (NULL == AllDevicePath) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- InitializeListHead (&ConsoleMenu->Head);\r
-\r
- AllCount = EfiDevicePathInstanceCount (AllDevicePath);\r
- ConsoleMenu->MenuNumber = 0;\r
- //\r
- // Following is menu building up for Console Devices selected.\r
- //\r
- MultiDevicePath = AllDevicePath;\r
- Index2 = 0;\r
- for (Index = 0; Index < AllCount; Index++) {\r
- DevicePathInst = GetNextDevicePathInstance (&MultiDevicePath, &Size);\r
-\r
- NewMenuEntry = BOpt_CreateMenuEntry (BM_CONSOLE_CONTEXT_SELECT);\r
- if (NULL == NewMenuEntry) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
- NewMenuEntry->OptionNumber = Index2;\r
-\r
- NewConsoleContext->DevicePath = DuplicateDevicePath (DevicePathInst);\r
- ASSERT (NewConsoleContext->DevicePath != NULL);\r
- NewMenuEntry->DisplayString = EfiLibStrFromDatahub (NewConsoleContext->DevicePath);\r
- if (NULL == NewMenuEntry->DisplayString) {\r
- NewMenuEntry->DisplayString = DevicePathToStr (NewConsoleContext->DevicePath);\r
- }\r
-\r
- NewConsoleContext->IsTerminal = IsTerminalDevicePath (\r
- NewConsoleContext->DevicePath,\r
- &Terminal,\r
- &Com\r
- );\r
-\r
- NewConsoleContext->IsActive = BdsLibMatchDevicePaths (\r
- DevicePath,\r
- NewConsoleContext->DevicePath\r
- );\r
-\r
- if (NewConsoleContext->IsTerminal) {\r
- BOpt_DestroyMenuEntry (NewMenuEntry);\r
- } else {\r
- Index2++;\r
- ConsoleMenu->MenuNumber++;\r
- InsertTailList (&ConsoleMenu->Head, &NewMenuEntry->Link);\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Build up ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu\r
-\r
- @retval EFI_SUCCESS The function always complete successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-GetAllConsoles (\r
- VOID\r
- )\r
-{\r
- GetConsoleMenu (BM_CONSOLE_IN_CONTEXT_SELECT);\r
- GetConsoleMenu (BM_CONSOLE_OUT_CONTEXT_SELECT);\r
- GetConsoleMenu (BM_CONSOLE_ERR_CONTEXT_SELECT);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Free ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu\r
-\r
- @retval EFI_SUCCESS The function always complete successfully.\r
-**/\r
-EFI_STATUS\r
-FreeAllConsoles (\r
- VOID\r
- )\r
-{\r
- BOpt_FreeMenu (&ConsoleOutMenu);\r
- BOpt_FreeMenu (&ConsoleInpMenu);\r
- BOpt_FreeMenu (&ConsoleErrMenu);\r
- BOpt_FreeMenu (&TerminalMenu);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Test whether DevicePath is a valid Terminal\r
-\r
-\r
- @param DevicePath DevicePath to be checked\r
- @param Termi If DevicePath is valid Terminal, terminal type is returned.\r
- @param Com If DevicePath is valid Terminal, Com Port type is returned.\r
-\r
- @retval TRUE If DevicePath point to a Terminal.\r
- @retval FALSE If DevicePath does not point to a Terminal.\r
-\r
-**/\r
-BOOLEAN\r
-IsTerminalDevicePath (\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
- OUT TYPE_OF_TERMINAL *Termi,\r
- OUT UINTN *Com\r
- )\r
-{\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
- 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
- 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
- if (CompareGuid (&Vendor->Guid, &TerminalTypeGuid[0])) {\r
- *Termi = TerminalTypePcAnsi;\r
- IsTerminal = TRUE;\r
- } else {\r
- if (CompareGuid (&Vendor->Guid, &TerminalTypeGuid[1])) {\r
- *Termi = TerminalTypeVt100;\r
- IsTerminal = TRUE;\r
- } else {\r
- if (CompareGuid (&Vendor->Guid, &TerminalTypeGuid[2])) {\r
- *Termi = TerminalTypeVt100Plus;\r
- IsTerminal = TRUE;\r
- } else {\r
- if (CompareGuid (&Vendor->Guid, &TerminalTypeGuid[3])) {\r
- *Termi = TerminalTypeVtUtf8;\r
- IsTerminal = TRUE;\r
- } else {\r
- IsTerminal = FALSE;\r
- }\r
- }\r
- }\r
- }\r
-\r
- if (!IsTerminal) {\r
- return FALSE;\r
- }\r
-\r
- if ((Acpi != NULL) && IsIsaSerialNode (Acpi)) {\r
- CopyMem (Com, &Acpi->UID, sizeof (UINT32));\r
- } else {\r
- return FALSE;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-/**\r
- Get mode number according to column and row\r
-\r
- @param CallbackData The BMM context data.\r
-**/\r
-VOID\r
-GetConsoleOutMode (\r
- IN BMM_CALLBACK_DATA *CallbackData\r
- )\r
-{\r
- UINTN Col;\r
- UINTN Row;\r
- UINTN CurrentCol;\r
- UINTN CurrentRow;\r
- UINTN Mode;\r
- UINTN MaxMode;\r
- EFI_STATUS Status;\r
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;\r
-\r
- ConOut = gST->ConOut;\r
- MaxMode = (UINTN) (ConOut->Mode->MaxMode);\r
-\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
- if (CurrentCol == Col && CurrentRow == Row) {\r
- CallbackData->BmmFakeNvData.ConsoleOutMode = (UINT16) Mode;\r
- break;\r
- }\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