]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
Remove unnecessary use of FixedPcdxxx() functions and [FixedPcd] INF sections. These...
[mirror_edk2.git] / MdeModulePkg / Universal / Console / TerminalDxe / Terminal.c
index b6a191f7ce5dea549d895ff02abc62553737506f..0ae261f019bc4d38c15147e998c118ebba039e5c 100644 (file)
@@ -125,7 +125,7 @@ TerminalDriverBindingSupported (
   //\r
   if (RemainingDevicePath != NULL) {\r
     //\r
-    // Check if RemainingDevicePath is the End of Device Path Node, \r
+    // Check if RemainingDevicePath is the End of Device Path Node,\r
     // if yes, go on checking other conditions\r
     //\r
     if (!IsDevicePathEnd (RemainingDevicePath)) {\r
@@ -134,13 +134,13 @@ TerminalDriverBindingSupported (
       // check its validation\r
       //\r
       Node = (VENDOR_DEVICE_PATH *) RemainingDevicePath;\r
-  \r
+\r
       if (Node->Header.Type != MESSAGING_DEVICE_PATH ||\r
           Node->Header.SubType != MSG_VENDOR_DP ||\r
           DevicePathNodeLength(&Node->Header) != sizeof(VENDOR_DEVICE_PATH)) {\r
-  \r
+\r
         return EFI_UNSUPPORTED;\r
-  \r
+\r
       }\r
       //\r
       // only supports PC ANSI, VT100, VT100+ and VT-UTF8 terminal types\r
@@ -149,7 +149,7 @@ TerminalDriverBindingSupported (
           !CompareGuid (&Node->Guid, &gEfiVT100Guid) &&\r
           !CompareGuid (&Node->Guid, &gEfiVT100PlusGuid) &&\r
           !CompareGuid (&Node->Guid, &gEfiVTUTF8Guid)) {\r
-  \r
+\r
         return EFI_UNSUPPORTED;\r
       }\r
     }\r
@@ -218,6 +218,186 @@ TerminalDriverBindingSupported (
   return Status;\r
 }\r
 \r
+/**\r
+  Build the terminal device path for the child device according to the\r
+  terminal type.\r
+\r
+  @param  ParentDevicePath         Parent device path.\r
+  @param  RemainingDevicePath      A specific child device.\r
+\r
+  @return The child device path built.\r
+\r
+**/\r
+EFI_DEVICE_PATH_PROTOCOL*\r
+EFIAPI\r
+BuildTerminalDevpath  (\r
+  IN EFI_DEVICE_PATH_PROTOCOL       *ParentDevicePath,\r
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
+  )\r
+{\r
+  EFI_DEVICE_PATH_PROTOCOL          *TerminalDevicePath;\r
+  UINT8                             TerminalType;\r
+  VENDOR_DEVICE_PATH                *Node;\r
+  EFI_STATUS                        Status;\r
+\r
+  TerminalDevicePath = NULL;\r
+  TerminalType = PCANSITYPE;\r
+\r
+  //\r
+  // Use the RemainingDevicePath to determine the terminal type\r
+  //\r
+  Node = (VENDOR_DEVICE_PATH *) RemainingDevicePath;\r
+  if (Node == NULL) {\r
+    TerminalType = PCANSITYPE;\r
+\r
+  } else if (CompareGuid (&Node->Guid, &gEfiPcAnsiGuid)) {\r
+\r
+    TerminalType = PCANSITYPE;\r
+\r
+  } else if (CompareGuid (&Node->Guid, &gEfiVT100Guid)) {\r
+\r
+    TerminalType = VT100TYPE;\r
+\r
+  } else if (CompareGuid (&Node->Guid, &gEfiVT100PlusGuid)) {\r
+\r
+    TerminalType = VT100PLUSTYPE;\r
+\r
+  } else if (CompareGuid (&Node->Guid, &gEfiVTUTF8Guid)) {\r
+\r
+    TerminalType = VTUTF8TYPE;\r
+\r
+  } else {\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Build the device path for the child device\r
+  //\r
+  Status = SetTerminalDevicePath (\r
+            TerminalType,\r
+            ParentDevicePath,\r
+            &TerminalDevicePath\r
+            );\r
+  if (EFI_ERROR (Status)) {\r
+    return NULL;\r
+  }\r
+  return TerminalDevicePath;\r
+}\r
+\r
+/**\r
+  Compare a device path data structure to that of all the nodes of a\r
+  second device path instance.\r
+\r
+  @param  Multi          A pointer to a multi-instance device path data structure.\r
+  @param  Single         A pointer to a single-instance device path data structure.\r
+\r
+  @retval TRUE           If the Single is contained within Multi.\r
+  @retval FALSE          The Single is not match within Multi.\r
+\r
+**/\r
+BOOLEAN\r
+MatchDevicePaths (\r
+  IN  EFI_DEVICE_PATH_PROTOCOL  *Multi,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL  *Single\r
+  )\r
+{\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInst;\r
+  UINTN                     Size;\r
+\r
+  DevicePath      = Multi;\r
+  DevicePathInst  = GetNextDevicePathInstance (&DevicePath, &Size);\r
+  //\r
+  // Search for the match of 'Single' in 'Multi'\r
+  //\r
+  while (DevicePathInst != NULL) {\r
+    //\r
+    // If the single device path is found in multiple device paths,\r
+    // return success\r
+    //\r
+    if (CompareMem (Single, DevicePathInst, Size) == 0) {\r
+      FreePool (DevicePathInst);\r
+      return TRUE;\r
+    }\r
+\r
+    FreePool (DevicePathInst);\r
+    DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Check whether the terminal device path is in the global variable.\r
+\r
+  @param  VariableName          Pointer to one global variable.\r
+  @param  TerminalDevicePath    Pointer to the terminal device's device path.\r
+\r
+  @retval TRUE                  The devcie is in the global variable.\r
+  @retval FALSE                 The devcie is not in the global variable.\r
+\r
+**/\r
+BOOLEAN\r
+IsTerminalInConsoleVariable (\r
+  IN CHAR16                    *VariableName,\r
+  IN EFI_DEVICE_PATH_PROTOCOL  *TerminalDevicePath\r
+  )\r
+{\r
+  EFI_DEVICE_PATH_PROTOCOL  *Variable;\r
+  BOOLEAN                   ReturnFlag;\r
+\r
+  //\r
+  // Get global variable and its size according to the name given.\r
+  //\r
+  Variable = GetEfiGlobalVariable (VariableName);\r
+  if (Variable == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Check whether the terminal device path is one of the variable instances.\r
+  //\r
+  ReturnFlag = MatchDevicePaths (Variable, TerminalDevicePath);\r
+\r
+  FreePool (Variable);\r
+\r
+  return ReturnFlag;\r
+}\r
+\r
+/**\r
+  Free notify functions list.\r
+\r
+  @param  ListHead               The list head\r
+\r
+  @retval EFI_SUCCESS            Free the notify list successfully.\r
+  @retval EFI_INVALID_PARAMETER  ListHead is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+TerminalFreeNotifyList (\r
+  IN OUT LIST_ENTRY           *ListHead\r
+  )\r
+{\r
+  TERMINAL_CONSOLE_IN_EX_NOTIFY *NotifyNode;\r
+\r
+  if (ListHead == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  while (!IsListEmpty (ListHead)) {\r
+    NotifyNode = CR (\r
+                   ListHead->ForwardLink,\r
+                   TERMINAL_CONSOLE_IN_EX_NOTIFY,\r
+                   NotifyEntry,\r
+                   TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
+                   );\r
+    RemoveEntryList (ListHead->ForwardLink);\r
+    FreePool (NotifyNode);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
 /**\r
   Start this driver on Controller by opening a Serial IO protocol,\r
   reading Device Path, and creating a child handle with a Simple Text In,\r
@@ -256,9 +436,22 @@ TerminalDriverBindingStart (
   UINTN                               Index;\r
   EFI_DEVICE_PATH_PROTOCOL            *DevicePath;\r
   EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL     *SimpleTextOutput;\r
-\r
-  TerminalDevice = NULL;\r
-  DefaultNode    = NULL;\r
+  EFI_SIMPLE_TEXT_INPUT_PROTOCOL      *SimpleTextInput;\r
+  BOOLEAN                             ConInSelected;\r
+  BOOLEAN                             ConOutSelected;\r
+  BOOLEAN                             NullRemaining;\r
+  BOOLEAN                             SimTxtInInstalled;\r
+  BOOLEAN                             SimTxtOutInstalled;\r
+  BOOLEAN                             FirstEnter;\r
+\r
+  TerminalDevice     = NULL;\r
+  DefaultNode        = NULL;\r
+  ConInSelected       = FALSE;\r
+  ConOutSelected      = FALSE;\r
+  NullRemaining      = TRUE;\r
+  SimTxtInInstalled  = FALSE;\r
+  SimTxtOutInstalled = FALSE;\r
+  FirstEnter         = FALSE;\r
   //\r
   // Get the Device Path Protocol to build the device path of the child device\r
   //\r
@@ -291,373 +484,543 @@ TerminalDriverBindingStart (
 \r
   if (Status != EFI_ALREADY_STARTED) {\r
     //\r
-    // If Serial I/O is not already open by this driver, then tag the handle\r
-    // with the Terminal Driver GUID and update the ConInDev, ConOutDev, and\r
-    // StdErrDev variables with the list of possible terminal types on this\r
-    // serial port.\r
+    // the serial I/O protocol never be opened before, it is the first\r
+    // time to start the serial Io controller\r
     //\r
-    Status = gBS->OpenProtocol (\r
-                    Controller,\r
-                    &gEfiCallerIdGuid,\r
-                    NULL,\r
-                    This->DriverBindingHandle,\r
-                    Controller,\r
-                    EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
-                    );\r
-    if (EFI_ERROR (Status)) {\r
-      Status = gBS->InstallMultipleProtocolInterfaces (\r
-                      &Controller,\r
-                      &gEfiCallerIdGuid,\r
-                      DuplicateDevicePath (ParentDevicePath),\r
-                      NULL\r
-                      );\r
-      if (EFI_ERROR (Status)) {\r
-        goto Error;\r
-      }\r
-\r
-      if (!IsHotPlugDevice (ParentDevicePath)) {\r
-        //\r
-        // if the serial device is a hot plug device, do not update the\r
-        // ConInDev, ConOutDev, and StdErrDev variables.\r
-        //\r
-        TerminalUpdateConsoleDevVariable (L"ConInDev", ParentDevicePath);\r
-        TerminalUpdateConsoleDevVariable (L"ConOutDev", ParentDevicePath);\r
-        TerminalUpdateConsoleDevVariable (L"ErrOutDev", ParentDevicePath);\r
-      }\r
-    }\r
+    FirstEnter = TRUE;\r
   }\r
+\r
   //\r
-  // Make sure a child handle does not already exist.  This driver can only\r
-  // produce one child per serial port.\r
+  // Serial I/O is not already open by this driver, then tag the handle\r
+  // with the Terminal Driver GUID and update the ConInDev, ConOutDev, and\r
+  // StdErrDev variables with the list of possible terminal types on this\r
+  // serial port.\r
   //\r
-  Status = gBS->OpenProtocolInformation (\r
+  Status = gBS->OpenProtocol (\r
                   Controller,\r
-                  &gEfiSerialIoProtocolGuid,\r
-                  &OpenInfoBuffer,\r
-                  &EntryCount\r
+                  &gEfiCallerIdGuid,\r
+                  NULL,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
                   );\r
-  if (!EFI_ERROR (Status)) {\r
-    Status = EFI_SUCCESS;\r
-    for (Index = 0; Index < EntryCount; Index++) {\r
-      if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
-        Status = EFI_ALREADY_STARTED;\r
-      }\r
+  if (EFI_ERROR (Status)) {\r
+    Status = gBS->InstallMultipleProtocolInterfaces (\r
+                    &Controller,\r
+                    &gEfiCallerIdGuid,\r
+                    DuplicateDevicePath (ParentDevicePath),\r
+                    NULL\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      goto Error;\r
     }\r
 \r
-    FreePool (OpenInfoBuffer);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
+    if (!IsHotPlugDevice (ParentDevicePath)) {\r
+      //\r
+      // if the serial device is a hot plug device, do not update the\r
+      // ConInDev, ConOutDev, and StdErrDev variables.\r
+      //\r
+      TerminalUpdateConsoleDevVariable (L"ConInDev", ParentDevicePath);\r
+      TerminalUpdateConsoleDevVariable (L"ConOutDev", ParentDevicePath);\r
+      TerminalUpdateConsoleDevVariable (L"ErrOutDev", ParentDevicePath);\r
     }\r
   }\r
+\r
+  //\r
+  // Check the requirement for the SimpleTxtIn and SimpleTxtOut protocols\r
   //\r
-  // If RemainingDevicePath is NULL, then create default device path node\r
+  // Simple In/Out Protocol will not be installed onto the handle if the\r
+  // device path to the handle is not present in the ConIn/ConOut\r
+  // environment variable. But If RemainingDevicePath is NULL, then always\r
+  // produce both Simple In and Simple Text Output Protocols. This is required\r
+  // for the connect all sequences to make sure all possible consoles are\r
+  // produced no matter what the current values of ConIn, ConOut, or StdErr are.\r
   //\r
   if (RemainingDevicePath == NULL) {\r
-    DefaultNode = AllocateZeroPool (sizeof (VENDOR_DEVICE_PATH));\r
-    if (DefaultNode == NULL) {\r
+    NullRemaining = TRUE;\r
+  }\r
+\r
+  DevicePath = BuildTerminalDevpath (ParentDevicePath, RemainingDevicePath);\r
+  if (DevicePath != NULL) {\r
+    ConInSelected  = IsTerminalInConsoleVariable (L"ConIn", DevicePath);\r
+    ConOutSelected = IsTerminalInConsoleVariable (L"ConOut", DevicePath);\r
+    FreePool (DevicePath);\r
+  } else {\r
+    goto Error;\r
+  }\r
+  //\r
+  // Not create the child terminal handle if both Simple In/In Ex and\r
+  // Simple text Out protocols are not required to be published\r
+  //\r
+  if ((!ConInSelected)&&(!ConOutSelected)&&(!NullRemaining)) {\r
+    goto Error;\r
+  }\r
+\r
+  //\r
+  // create the child terminal handle during first entry\r
+  //\r
+  if (FirstEnter) {\r
+    //\r
+    // First enther the start funciton\r
+    //\r
+    FirstEnter = FALSE;\r
+    //\r
+    // Make sure a child handle does not already exist.  This driver can only\r
+    // produce one child per serial port.\r
+    //\r
+    Status = gBS->OpenProtocolInformation (\r
+                    Controller,\r
+                    &gEfiSerialIoProtocolGuid,\r
+                    &OpenInfoBuffer,\r
+                    &EntryCount\r
+                    );\r
+    if (!EFI_ERROR (Status)) {\r
+      Status = EFI_SUCCESS;\r
+      for (Index = 0; Index < EntryCount; Index++) {\r
+        if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
+          Status = EFI_ALREADY_STARTED;\r
+        }\r
+      }\r
+\r
+      FreePool (OpenInfoBuffer);\r
+      if (EFI_ERROR (Status)) {\r
+          goto Error;\r
+      }\r
+    }\r
+\r
+    //\r
+    // If RemainingDevicePath is NULL, then create default device path node\r
+    //\r
+    if (RemainingDevicePath == NULL) {\r
+      DefaultNode = AllocateZeroPool (sizeof (VENDOR_DEVICE_PATH));\r
+      if (DefaultNode == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Error;\r
+      }\r
+\r
+      TerminalType = PcdGet8 (PcdDefaultTerminalType);\r
+      //\r
+      // Must be between PCANSITYPE (0) and VTUTF8TYPE (3)\r
+      //\r
+      ASSERT (TerminalType <= VTUTF8TYPE);\r
+\r
+      CopyMem (&DefaultNode->Guid, gTerminalType[TerminalType], sizeof (EFI_GUID));\r
+      RemainingDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) DefaultNode;\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 = PCANSITYPE;\r
+      } else if (CompareGuid (&Node->Guid, &gEfiVT100Guid)) {\r
+        TerminalType = VT100TYPE;\r
+      } else if (CompareGuid (&Node->Guid, &gEfiVT100PlusGuid)) {\r
+        TerminalType = VT100PLUSTYPE;\r
+      } else if (CompareGuid (&Node->Guid, &gEfiVTUTF8Guid)) {\r
+        TerminalType = VTUTF8TYPE;\r
+      } else {\r
+        goto Error;\r
+      }\r
+    } else {\r
+      //\r
+      // If RemainingDevicePath is the End of Device Path Node,\r
+      // skip enumerate any device and return EFI_SUCESSS\r
+      //\r
+      return EFI_SUCCESS;\r
+    }\r
+\r
+    //\r
+    // Initialize the Terminal Dev\r
+    //\r
+    TerminalDevice = AllocateCopyPool (sizeof (TERMINAL_DEV), &mTerminalDevTemplate);\r
+    if (TerminalDevice == NULL) {\r
       Status = EFI_OUT_OF_RESOURCES;\r
       goto Error;\r
     }\r
 \r
-    TerminalType = FixedPcdGet8 (PcdDefaultTerminalType);\r
+    TerminalDevice->TerminalType  = TerminalType;\r
+    TerminalDevice->SerialIo      = SerialIo;\r
+\r
+    InitializeListHead (&TerminalDevice->NotifyList);\r
+    Status = gBS->CreateEvent (\r
+                    EVT_NOTIFY_WAIT,\r
+                    TPL_NOTIFY,\r
+                    TerminalConInWaitForKeyEx,\r
+                    &TerminalDevice->SimpleInputEx,\r
+                    &TerminalDevice->SimpleInputEx.WaitForKeyEx\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      goto Error;\r
+    }\r
+\r
+    Status = gBS->CreateEvent (\r
+                    EVT_NOTIFY_WAIT,\r
+                    TPL_NOTIFY,\r
+                    TerminalConInWaitForKey,\r
+                    &TerminalDevice->SimpleInput,\r
+                    &TerminalDevice->SimpleInput.WaitForKey\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      goto Error;\r
+    }\r
     //\r
-    // Must be between PCANSITYPE (0) and VTUTF8TYPE (3)\r
+    // Allocates and initializes the FIFO buffer to be zero, used for accommodating\r
+    // the pre-read pending characters.\r
     //\r
-    ASSERT (TerminalType <= VTUTF8TYPE);\r
+    TerminalDevice->RawFiFo     = AllocateZeroPool (sizeof (RAW_DATA_FIFO));\r
+    if (TerminalDevice->RawFiFo == NULL) {\r
+      goto Error;\r
+    }\r
+    TerminalDevice->UnicodeFiFo = AllocateZeroPool (sizeof (UNICODE_FIFO));\r
+    if (TerminalDevice->UnicodeFiFo == NULL) {\r
+      goto Error;\r
+    }\r
+    TerminalDevice->EfiKeyFiFo  = AllocateZeroPool (sizeof (EFI_KEY_FIFO));\r
+    if (TerminalDevice->EfiKeyFiFo == NULL) {\r
+      goto Error;\r
+    }\r
 \r
-    CopyMem (&DefaultNode->Guid, gTerminalType[TerminalType], sizeof (EFI_GUID));\r
-    RemainingDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) DefaultNode;\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
+    // Set the timeout value of serial buffer for\r
+    // keystroke response performance issue\r
     //\r
-    Node = (VENDOR_DEVICE_PATH *)RemainingDevicePath;\r
-    if (CompareGuid (&Node->Guid, &gEfiPcAnsiGuid)) {\r
-      TerminalType = PCANSITYPE;\r
-    } else if (CompareGuid (&Node->Guid, &gEfiVT100Guid)) {\r
-      TerminalType = VT100TYPE;\r
-    } else if (CompareGuid (&Node->Guid, &gEfiVT100PlusGuid)) {\r
-      TerminalType = VT100PLUSTYPE;\r
-    } else if (CompareGuid (&Node->Guid, &gEfiVTUTF8Guid)) {\r
-      TerminalType = VTUTF8TYPE;\r
+    Mode            = TerminalDevice->SerialIo->Mode;\r
+\r
+    SerialInTimeOut = 0;\r
+    if (Mode->BaudRate != 0) {\r
+      SerialInTimeOut = (1 + Mode->DataBits + Mode->StopBits) * 2 * 1000000 / (UINTN) Mode->BaudRate;\r
+    }\r
+\r
+    Status = TerminalDevice->SerialIo->SetAttributes (\r
+                                        TerminalDevice->SerialIo,\r
+                                        Mode->BaudRate,\r
+                                        Mode->ReceiveFifoDepth,\r
+                                        (UINT32) SerialInTimeOut,\r
+                                        (EFI_PARITY_TYPE) (Mode->Parity),\r
+                                        (UINT8) Mode->DataBits,\r
+                                        (EFI_STOP_BITS_TYPE) (Mode->StopBits)\r
+                                        );\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // if set attributes operation fails, invalidate\r
+      // the value of SerialInTimeOut,thus make it\r
+      // inconsistent with the default timeout value\r
+      // of serial buffer. This will invoke the recalculation\r
+      // in the readkeystroke routine.\r
+      //\r
+      TerminalDevice->SerialInTimeOut = 0;\r
     } else {\r
-      goto Error;\r
+      TerminalDevice->SerialInTimeOut = SerialInTimeOut;\r
     }\r
-  } else {\r
     //\r
-    // If RemainingDevicePath is the End of Device Path Node,\r
-    // skip enumerate any device and return EFI_SUCESSS\r
-    // \r
-    return EFI_SUCCESS;\r
-  }\r
+    // Set Simple Text Output Protocol from template.\r
+    //\r
+    SimpleTextOutput = CopyMem (\r
+                         &TerminalDevice->SimpleTextOutput,\r
+                         &mTerminalDevTemplate.SimpleTextOutput,\r
+                         sizeof (mTerminalDevTemplate.SimpleTextOutput)\r
+                         );\r
+    SimpleTextOutput->Mode = &TerminalDevice->SimpleTextOutputMode;\r
+\r
+    TerminalDevice->SimpleTextOutputMode.MaxMode = 3;\r
+    //\r
+    // For terminal devices, cursor is always visible\r
+    //\r
+    TerminalDevice->SimpleTextOutputMode.CursorVisible = TRUE;\r
+    Status = TerminalConOutSetAttribute (\r
+               SimpleTextOutput,\r
+               EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      goto ReportError;\r
+    }\r
 \r
-  //\r
-  // Initialize the Terminal Dev\r
-  //\r
-  TerminalDevice = AllocateCopyPool (sizeof (TERMINAL_DEV), &mTerminalDevTemplate);\r
-  if (TerminalDevice == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Error;\r
-  }\r
+    Status = TerminalConOutReset (SimpleTextOutput, FALSE);\r
+    if (EFI_ERROR (Status)) {\r
+      goto ReportError;\r
+    }\r
 \r
-  TerminalDevice->TerminalType  = TerminalType;\r
-  TerminalDevice->SerialIo      = SerialIo;\r
+    Status = TerminalConOutSetMode (SimpleTextOutput, 0);\r
+    if (EFI_ERROR (Status)) {\r
+      goto ReportError;\r
+    }\r
 \r
-  InitializeListHead (&TerminalDevice->NotifyList);\r
-  Status = gBS->CreateEvent (\r
-                  EVT_NOTIFY_WAIT,\r
-                  TPL_NOTIFY,\r
-                  TerminalConInWaitForKeyEx,\r
-                  &TerminalDevice->SimpleInputEx,\r
-                  &TerminalDevice->SimpleInputEx.WaitForKeyEx\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    goto Error;\r
-  }\r
+    Status = TerminalConOutEnableCursor (SimpleTextOutput, TRUE);\r
+    if (EFI_ERROR (Status)) {\r
+      goto ReportError;\r
+    }\r
 \r
+    Status = gBS->CreateEvent (\r
+                    EVT_TIMER,\r
+                    TPL_CALLBACK,\r
+                    NULL,\r
+                    NULL,\r
+                    &TerminalDevice->TwoSecondTimeOut\r
+                    );\r
 \r
-  Status = gBS->CreateEvent (\r
-                  EVT_NOTIFY_WAIT,\r
-                  TPL_NOTIFY,\r
-                  TerminalConInWaitForKey,\r
-                  &TerminalDevice->SimpleInput,\r
-                  &TerminalDevice->SimpleInput.WaitForKey\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    goto Error;\r
-  }\r
-  //\r
-  // Allocates and initializes the FIFO buffer to be zero, used for accommodating\r
-  // the pre-read pending characters.\r
-  //\r
-  TerminalDevice->RawFiFo     = AllocateZeroPool (sizeof (RAW_DATA_FIFO));\r
-  if (TerminalDevice->RawFiFo == NULL) {\r
-    goto Error;\r
-  }\r
-  TerminalDevice->UnicodeFiFo = AllocateZeroPool (sizeof (UNICODE_FIFO));\r
-  if (TerminalDevice->UnicodeFiFo == NULL) {\r
-    goto Error;\r
-  }\r
-  TerminalDevice->EfiKeyFiFo  = AllocateZeroPool (sizeof (EFI_KEY_FIFO));\r
-  if (TerminalDevice->EfiKeyFiFo == NULL) {\r
-    goto Error;\r
-  }\r
+    //\r
+    // Build the component name for the child device\r
+    //\r
+    TerminalDevice->ControllerNameTable = NULL;\r
+    switch (TerminalDevice->TerminalType) {\r
+    case PCANSITYPE:\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
-  //\r
-  // Set the timeout value of serial buffer for\r
-  // keystroke response performance issue\r
-  //\r
-  Mode            = TerminalDevice->SerialIo->Mode;\r
+      break;\r
 \r
-  SerialInTimeOut = 0;\r
-  if (Mode->BaudRate != 0) {\r
-    SerialInTimeOut = (1 + Mode->DataBits + Mode->StopBits) * 2 * 1000000 / (UINTN) Mode->BaudRate;\r
-  }\r
+    case VT100TYPE:\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 VT100PLUSTYPE:\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 VTUTF8TYPE:\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
 \r
-  Status = TerminalDevice->SerialIo->SetAttributes (\r
-                                      TerminalDevice->SerialIo,\r
-                                      Mode->BaudRate,\r
-                                      Mode->ReceiveFifoDepth,\r
-                                      (UINT32) SerialInTimeOut,\r
-                                      (EFI_PARITY_TYPE) (Mode->Parity),\r
-                                      (UINT8) Mode->DataBits,\r
-                                      (EFI_STOP_BITS_TYPE) (Mode->StopBits)\r
-                                      );\r
-  if (EFI_ERROR (Status)) {\r
     //\r
-    // if set attributes operation fails, invalidate\r
-    // the value of SerialInTimeOut,thus make it\r
-    // inconsistent with the default timeout value\r
-    // of serial buffer. This will invoke the recalculation\r
-    // in the readkeystroke routine.\r
+    // Build the device path for the child device\r
     //\r
-    TerminalDevice->SerialInTimeOut = 0;\r
-  } else {\r
-    TerminalDevice->SerialInTimeOut = SerialInTimeOut;\r
-  }\r
-  //\r
-  // Build the device path for the child device\r
-  //\r
-  Status = SetTerminalDevicePath (\r
-            TerminalDevice->TerminalType,\r
-            ParentDevicePath,\r
-            &TerminalDevice->DevicePath\r
-            );\r
-  if (EFI_ERROR (Status)) {\r
-    goto Error;\r
-  }\r
+    Status = SetTerminalDevicePath (\r
+              TerminalDevice->TerminalType,\r
+              ParentDevicePath,\r
+              &TerminalDevice->DevicePath\r
+              );\r
+    if (EFI_ERROR (Status)) {\r
+      goto Error;\r
+    }\r
 \r
-  DevicePath = TerminalDevice->DevicePath;\r
+    Status = gBS->InstallProtocolInterface (\r
+                    &TerminalDevice->Handle,\r
+                    &gEfiDevicePathProtocolGuid,\r
+                    EFI_NATIVE_INTERFACE,\r
+                    TerminalDevice->DevicePath\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      goto Error;\r
+    }\r
 \r
-  Status = TerminalDevice->SimpleInput.Reset (\r
-                                        &TerminalDevice->SimpleInput,\r
-                                        FALSE\r
-                                        );\r
-  if (EFI_ERROR (Status)) {\r
     //\r
-    // Need to report Error Code first\r
+    // Register the Parent-Child relationship via\r
+    // EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
     //\r
-    goto ReportError;\r
+    Status = gBS->OpenProtocol (\r
+                    Controller,\r
+                    &gEfiSerialIoProtocolGuid,\r
+                    (VOID **) &TerminalDevice->SerialIo,\r
+                    This->DriverBindingHandle,\r
+                    TerminalDevice->Handle,\r
+                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      goto Error;\r
+    }\r
   }\r
-  //\r
-  // Set Simple Text Output Protocol from template.\r
-  //\r
-  SimpleTextOutput = CopyMem (\r
-                       &TerminalDevice->SimpleTextOutput,\r
-                       &mTerminalDevTemplate.SimpleTextOutput,\r
-                       sizeof (mTerminalDevTemplate.SimpleTextOutput)\r
-                       );\r
-  SimpleTextOutput->Mode = &TerminalDevice->SimpleTextOutputMode;\r
 \r
-  TerminalDevice->SimpleTextOutputMode.MaxMode        = 3;\r
   //\r
-  // For terminal devices, cursor is always visible\r
+  // Find the child handle, and get its TerminalDevice private data\r
   //\r
-  TerminalDevice->SimpleTextOutputMode.CursorVisible  = TRUE;\r
-  Status = TerminalConOutSetAttribute (\r
-             SimpleTextOutput,\r
-             EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    goto ReportError;\r
-  }\r
+  Status = gBS->OpenProtocolInformation (\r
+                  Controller,\r
+                  &gEfiSerialIoProtocolGuid,\r
+                  &OpenInfoBuffer,\r
+                  &EntryCount\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = EFI_NOT_FOUND;\r
+    ASSERT (OpenInfoBuffer != NULL);\r
+    for (Index = 0; Index < EntryCount; Index++) {\r
+      if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
+        //\r
+        // Find the child terminal handle.\r
+        // Test whether the SimpleTxtIn and SimpleTxtOut have been published\r
+        //\r
+        Status = gBS->OpenProtocol (\r
+                        OpenInfoBuffer[Index].ControllerHandle,\r
+                        &gEfiSimpleTextInProtocolGuid,\r
+                        (VOID **) &SimpleTextInput,\r
+                        This->DriverBindingHandle,\r
+                        OpenInfoBuffer[Index].ControllerHandle,\r
+                        EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                        );\r
+        if (!EFI_ERROR (Status)) {\r
+          SimTxtInInstalled = TRUE;\r
+          TerminalDevice = TERMINAL_CON_IN_DEV_FROM_THIS (SimpleTextInput);\r
+        }\r
 \r
-  Status = TerminalConOutReset (SimpleTextOutput, FALSE);\r
-  if (EFI_ERROR (Status)) {\r
-    goto ReportError;\r
-  }\r
+        Status = gBS->OpenProtocol (\r
+                        OpenInfoBuffer[Index].ControllerHandle,\r
+                        &gEfiSimpleTextOutProtocolGuid,\r
+                        (VOID **) &SimpleTextOutput,\r
+                        This->DriverBindingHandle,\r
+                        OpenInfoBuffer[Index].ControllerHandle,\r
+                        EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                        );\r
+        if (!EFI_ERROR (Status)) {\r
+          SimTxtOutInstalled = TRUE;\r
+          TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);\r
+        }\r
+        Status = EFI_SUCCESS;\r
+        break;\r
+      }\r
+    }\r
 \r
-  Status = TerminalConOutSetMode (SimpleTextOutput, 0);\r
-  if (EFI_ERROR (Status)) {\r
+    FreePool (OpenInfoBuffer);\r
+    if (EFI_ERROR (Status)) {\r
+      goto ReportError;\r
+    }\r
+  } else {\r
     goto ReportError;\r
   }\r
 \r
-  Status = TerminalConOutEnableCursor (SimpleTextOutput, TRUE);\r
-  if (EFI_ERROR (Status)) {\r
-    goto ReportError;\r
+  ASSERT (TerminalDevice != NULL);\r
+  //\r
+  // Only do the reset if the device path is in the Conout variable\r
+  //\r
+  if (ConInSelected && !SimTxtInInstalled) {\r
+    Status = TerminalDevice->SimpleInput.Reset (\r
+                                          &TerminalDevice->SimpleInput,\r
+                                          FALSE\r
+                                          );\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Need to report Error Code first\r
+      //\r
+      goto ReportError;\r
+    }\r
   }\r
 \r
-  Status = gBS->CreateEvent (\r
-                  EVT_TIMER,\r
-                  TPL_CALLBACK,\r
-                  NULL,\r
-                  NULL,\r
-                  &TerminalDevice->TwoSecondTimeOut\r
-                  );\r
-\r
   //\r
-  // Build the component name for the child device\r
+  // Only output the configure string to remote terminal if the device path\r
+  // is in the Conout variable\r
   //\r
-  TerminalDevice->ControllerNameTable = NULL;\r
-  switch (TerminalDevice->TerminalType) {\r
-  case PCANSITYPE:\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 VT100TYPE:\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 VT100PLUSTYPE:\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
+  if (ConOutSelected && !SimTxtOutInstalled) {\r
+    Status = TerminalDevice->SimpleTextOutput.SetAttribute (\r
+                                                        &TerminalDevice->SimpleTextOutput,\r
+                                                        EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)\r
+                                                        );\r
+    if (EFI_ERROR (Status)) {\r
+      goto ReportError;\r
+    }\r
 \r
-    break;\r
+    Status = TerminalDevice->SimpleTextOutput.Reset (\r
+                                                &TerminalDevice->SimpleTextOutput,\r
+                                                FALSE\r
+                                                );\r
+    if (EFI_ERROR (Status)) {\r
+      goto ReportError;\r
+    }\r
 \r
-  case VTUTF8TYPE:\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
+    Status = TerminalDevice->SimpleTextOutput.SetMode (\r
+                                                &TerminalDevice->SimpleTextOutput,\r
+                                                0\r
+                                                );\r
+    if (EFI_ERROR (Status)) {\r
+      goto ReportError;\r
+    }\r
 \r
-    break;\r
-  }\r
-  //\r
-  // Install protocol interfaces for the serial device.\r
-  //\r
-  Status = gBS->InstallMultipleProtocolInterfaces (\r
-                  &TerminalDevice->Handle,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  TerminalDevice->DevicePath,\r
-                  &gEfiSimpleTextInProtocolGuid,\r
-                  &TerminalDevice->SimpleInput,\r
-                  &gEfiSimpleTextInputExProtocolGuid,\r
-                  &TerminalDevice->SimpleInputEx,\r
-                  &gEfiSimpleTextOutProtocolGuid,\r
-                  &TerminalDevice->SimpleTextOutput,\r
-                  NULL\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    goto Error;\r
+    Status = TerminalDevice->SimpleTextOutput.EnableCursor (\r
+                                                &TerminalDevice->SimpleTextOutput,\r
+                                                TRUE\r
+                                                );\r
+    if (EFI_ERROR (Status)) {\r
+      goto ReportError;\r
+    }\r
   }\r
 \r
   //\r
-  // Register the Parent-Child relationship via\r
-  // EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
+  // Simple In/Out Protocol will not be installed onto the handle if the\r
+  // device path to the handle is not present in the ConIn/ConOut\r
+  // environment variable. But If RemainingDevicePath is NULL, then always\r
+  // produce both Simple In and Simple Text Output Protocols. This is required\r
+  // for the connect all sequences to make sure all possible consoles are\r
+  // produced no matter what the current values of ConIn, ConOut, or StdErr are.\r
   //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiSerialIoProtocolGuid,\r
-                  (VOID **) &TerminalDevice->SerialIo,\r
-                  This->DriverBindingHandle,\r
-                  TerminalDevice->Handle,\r
-                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    goto Error;\r
+  if (!SimTxtInInstalled && (ConInSelected || NullRemaining)) {\r
+    Status = gBS->InstallMultipleProtocolInterfaces (\r
+                    &TerminalDevice->Handle,\r
+                    &gEfiSimpleTextInProtocolGuid,\r
+                    &TerminalDevice->SimpleInput,\r
+                    &gEfiSimpleTextInputExProtocolGuid,\r
+                    &TerminalDevice->SimpleInputEx,\r
+                    NULL\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      goto Error;\r
+    }\r
   }\r
 \r
+  if (!SimTxtOutInstalled && (ConOutSelected || NullRemaining)) {\r
+    Status = gBS->InstallProtocolInterface (\r
+                    &TerminalDevice->Handle,\r
+                    &gEfiSimpleTextOutProtocolGuid,\r
+                    EFI_NATIVE_INTERFACE,\r
+                    &TerminalDevice->SimpleTextOutput\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      goto Error;\r
+    }\r
+  }\r
   if (DefaultNode != NULL) {\r
     FreePool (DefaultNode);\r
   }\r
@@ -668,6 +1031,7 @@ ReportError:
   //\r
   // Report error code before exiting\r
   //\r
+  DevicePath = ParentDevicePath;\r
   REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
     EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
     (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_CONTROLLER_ERROR),\r
@@ -902,41 +1266,6 @@ TerminalDriverBindingStop (
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
-/**\r
-  Free notify functions list.\r
-\r
-  @param  ListHead               The list head\r
-\r
-  @retval EFI_SUCCESS            Free the notify list successfully.\r
-  @retval EFI_INVALID_PARAMETER  ListHead is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-TerminalFreeNotifyList (\r
-  IN OUT LIST_ENTRY           *ListHead\r
-  )\r
-{\r
-  TERMINAL_CONSOLE_IN_EX_NOTIFY *NotifyNode;\r
-\r
-  if (ListHead == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  while (!IsListEmpty (ListHead)) {\r
-    NotifyNode = CR (\r
-                   ListHead->ForwardLink,\r
-                   TERMINAL_CONSOLE_IN_EX_NOTIFY,\r
-                   NotifyEntry,\r
-                   TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
-                   );\r
-    RemoveEntryList (ListHead->ForwardLink);\r
-    FreePool (NotifyNode);\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
 /**\r
   Update terminal device path in Console Device Environment Variables.\r
 \r
@@ -957,16 +1286,14 @@ TerminalUpdateConsoleDevVariable (
   EFI_DEVICE_PATH_PROTOCOL  *NewVariable;\r
   EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;\r
 \r
-  Variable = NULL;\r
-\r
   //\r
   // Get global variable and its size according to the name given.\r
   //\r
-  Variable = TerminalGetVariableAndSize (\r
-              VariableName,\r
-              &gEfiGlobalVariableGuid,\r
-              &VariableSize\r
-              );\r
+  Variable = GetEfiGlobalVariable (VariableName);\r
+  if (Variable == NULL) {\r
+    return;\r
+  }\r
+\r
   //\r
   // Append terminal device path onto the variable.\r
   //\r
@@ -1026,17 +1353,12 @@ TerminalRemoveConsoleDevVariable (
   EFI_DEVICE_PATH_PROTOCOL  *SavedNewVariable;\r
   EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;\r
 \r
-  Variable  = NULL;\r
   Instance  = NULL;\r
 \r
   //\r
   // Get global variable and its size according to the name given.\r
   //\r
-  Variable = TerminalGetVariableAndSize (\r
-              VariableName,\r
-              &gEfiGlobalVariableGuid,\r
-              &VariableSize\r
-              );\r
+  Variable = GetEfiGlobalVariable (VariableName);\r
   if (Variable == NULL) {\r
     return ;\r
   }\r
@@ -1116,81 +1438,6 @@ TerminalRemoveConsoleDevVariable (
   return ;\r
 }\r
 \r
-\r
-/**\r
-  Read the EFI variable (VendorGuid/Name) and return a dynamically allocated\r
-  buffer, and the size of the buffer. On failure return NULL.\r
-\r
-  @param  Name                   String part of EFI variable name\r
-  @param  VendorGuid             GUID part of EFI variable name\r
-  @param  VariableSize           Returns the size of the EFI variable that was read\r
-\r
-  @return Dynamically allocated memory that contains a copy of the EFI variable.\r
-          Caller is responsible freeing the buffer. If variable was not read,\r
-          NULL returned.\r
-\r
-**/\r
-VOID *\r
-TerminalGetVariableAndSize (\r
-  IN  CHAR16              *Name,\r
-  IN  EFI_GUID            *VendorGuid,\r
-  OUT UINTN               *VariableSize\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  UINTN       BufferSize;\r
-  VOID        *Buffer;\r
-\r
-  Buffer = NULL;\r
-\r
-  //\r
-  // Pass in a small size buffer to find the actual variable size.\r
-  //\r
-  BufferSize  = 1;\r
-  Buffer      = AllocatePool (BufferSize);\r
-  if (Buffer == NULL) {\r
-    *VariableSize = 0;\r
-    return NULL;\r
-  }\r
-\r
-  Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);\r
-\r
-  if (Status == EFI_SUCCESS) {\r
-    *VariableSize = BufferSize;\r
-    return Buffer;\r
-\r
-  } else if (Status == EFI_BUFFER_TOO_SMALL) {\r
-    //\r
-    // Allocate the buffer to return\r
-    //\r
-    FreePool (Buffer);\r
-    Buffer = AllocatePool (BufferSize);\r
-    if (Buffer == NULL) {\r
-      *VariableSize = 0;\r
-      return NULL;\r
-    }\r
-    //\r
-    // Read variable into the allocated buffer.\r
-    //\r
-    Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);\r
-    if (EFI_ERROR (Status)) {\r
-      BufferSize = 0;\r
-      FreePool (Buffer);\r
-      Buffer = NULL;\r
-    }\r
-  } else {\r
-    //\r
-    // Variable not found or other errors met.\r
-    //\r
-    BufferSize = 0;\r
-    FreePool (Buffer);\r
-    Buffer = NULL;\r
-  }\r
-\r
-  *VariableSize = BufferSize;\r
-  return Buffer;\r
-}\r
-\r
 /**\r
   Build terminal device path according to terminal type.\r
 \r
@@ -1322,7 +1569,7 @@ IsHotPlugDevice (
   while (!IsDevicePathEnd (CheckDevicePath)) {\r
     //\r
     // Check device whether is hot plug device or not throught Device Path\r
-    // \r
+    //\r
     if ((DevicePathType (CheckDevicePath) == MESSAGING_DEVICE_PATH) &&\r
         (DevicePathSubType (CheckDevicePath) == MSG_USB_DP ||\r
          DevicePathSubType (CheckDevicePath) == MSG_USB_CLASS_DP ||\r
@@ -1339,7 +1586,7 @@ IsHotPlugDevice (
       //\r
       return TRUE;\r
     }\r
-  \r
+\r
     CheckDevicePath = NextDevicePathNode (CheckDevicePath);\r
   }\r
 \r