]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/ConsoleOption.c
Enhance BMM to support changing FlowControl setting in Front Page.
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMaint / ConsoleOption.c
index 9d32c380fbc5023806918e18e78208cbe1050f98..ed42304c2ba82d84bb4c7d738ab66cda6ef141f8 100644 (file)
@@ -14,6 +14,37 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \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
@@ -62,7 +93,7 @@ UpdateComAttributeFromVariable (
 **/\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
@@ -74,8 +105,9 @@ ChangeTerminalDevicePath (
   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
@@ -112,6 +144,23 @@ ChangeTerminalDevicePath (
         &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
@@ -372,6 +421,7 @@ LocateSerialIo (
   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
@@ -470,6 +520,13 @@ LocateSerialIo (
         &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
@@ -570,7 +627,10 @@ UpdateComAttributeFromVariable (
   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
@@ -613,6 +673,17 @@ UpdateComAttributeFromVariable (
           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
@@ -644,6 +715,18 @@ UpdateComAttributeFromVariable (
               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