]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
MdeModulePkg: TerminalDxe: select the UART's default receive FIFO depth
[mirror_edk2.git] / MdeModulePkg / Universal / Console / TerminalDxe / Terminal.c
index 9574390eb0908b76f37800315ac5b55b1f76cf8a..5adaa9745f3e164d496b91a4817bf8fa5aade9ed 100644 (file)
@@ -2,7 +2,7 @@
   Produces Simple Text Input Protocol, Simple Text Input Extended Protocol and\r
   Simple Text Output Protocol upon Serial IO Protocol.\r
 \r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2014, 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
@@ -33,7 +33,8 @@ EFI_GUID  *gTerminalType[] = {
   &gEfiPcAnsiGuid,\r
   &gEfiVT100Guid,\r
   &gEfiVT100PlusGuid,\r
-  &gEfiVTUTF8Guid\r
+  &gEfiVTUTF8Guid,\r
+  &gEfiTtyTermGuid\r
 };\r
 \r
 \r
@@ -68,6 +69,7 @@ TERMINAL_DEV  mTerminalDevTemplate = {
     0,                                           // CursorRow\r
     TRUE                                         // CursorVisible\r
   },\r
+  NULL, // TerminalConsoleModeData\r
   0,  // SerialInTimeOut\r
 \r
   NULL, // RawFifo\r
@@ -79,6 +81,12 @@ TERMINAL_DEV  mTerminalDevTemplate = {
   NULL, // TwoSecondTimeOut\r
   INPUT_STATE_DEFAULT,\r
   RESET_STATE_DEFAULT,\r
+  {\r
+      0,\r
+      0,\r
+      0\r
+  },\r
+  0,\r
   FALSE,\r
   {   // SimpleTextInputEx\r
     TerminalConInResetEx,\r
@@ -94,6 +102,13 @@ TERMINAL_DEV  mTerminalDevTemplate = {
   }\r
 };\r
 \r
+TERMINAL_CONSOLE_MODE_DATA mTerminalConsoleModeData[] = {\r
+  {100, 31},\r
+  //\r
+  // New modes can be added here.\r
+  //\r
+};\r
+\r
 /**\r
   Test to see if this driver supports Controller.\r
 \r
@@ -144,12 +159,13 @@ TerminalDriverBindingSupported (
 \r
       }\r
       //\r
-      // only supports PC ANSI, VT100, VT100+ and VT-UTF8 terminal types\r
+      // only supports PC ANSI, VT100, VT100+, VT-UTF8, and TtyTerm terminal types\r
       //\r
       if (!CompareGuid (&Node->Guid, &gEfiPcAnsiGuid) &&\r
           !CompareGuid (&Node->Guid, &gEfiVT100Guid) &&\r
           !CompareGuid (&Node->Guid, &gEfiVT100PlusGuid) &&\r
-          !CompareGuid (&Node->Guid, &gEfiVTUTF8Guid)) {\r
+          !CompareGuid (&Node->Guid, &gEfiVTUTF8Guid) &&\r
+          !CompareGuid (&Node->Guid, &gEfiTtyTermGuid)) {\r
 \r
         return EFI_UNSUPPORTED;\r
       }\r
@@ -242,14 +258,13 @@ BuildTerminalDevpath  (
   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
+    TerminalType = PcdGet8 (PcdDefaultTerminalType);\r
 \r
   } else if (CompareGuid (&Node->Guid, &gEfiPcAnsiGuid)) {\r
 \r
@@ -267,6 +282,10 @@ BuildTerminalDevpath  (
 \r
     TerminalType = VTUTF8TYPE;\r
 \r
+  } else if (CompareGuid (&Node->Guid, &gEfiTtyTermGuid)) {\r
+\r
+    TerminalType = TTYTERMTYPE;\r
+\r
   } else {\r
     return NULL;\r
   }\r
@@ -350,7 +369,7 @@ IsTerminalInConsoleVariable (
   //\r
   // Get global variable and its size according to the name given.\r
   //\r
-  Variable = GetEfiGlobalVariable (VariableName);\r
+  GetEfiGlobalVariable2 (VariableName, (VOID**)&Variable, NULL);\r
   if (Variable == NULL) {\r
     return FALSE;\r
   }\r
@@ -398,6 +417,104 @@ TerminalFreeNotifyList (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Initialize all the text modes which the terminal console supports.\r
+\r
+  It returns information for available text modes that the terminal can support.\r
+\r
+  @param[out] TextModeCount      The total number of text modes that terminal console supports.\r
+  @param[out] TextModeData       The buffer to the text modes column and row information.\r
+                                 Caller is responsible to free it when it's non-NULL.\r
+\r
+  @retval EFI_SUCCESS            The supporting mode information is returned.\r
+  @retval EFI_INVALID_PARAMETER  The parameters are invalid.\r
+\r
+**/\r
+EFI_STATUS\r
+InitializeTerminalConsoleTextMode (\r
+  OUT UINTN                         *TextModeCount,\r
+  OUT TERMINAL_CONSOLE_MODE_DATA    **TextModeData\r
+  )\r
+{\r
+  UINTN                       Index;\r
+  UINTN                       Count;\r
+  TERMINAL_CONSOLE_MODE_DATA  *ModeBuffer;\r
+  TERMINAL_CONSOLE_MODE_DATA  *NewModeBuffer;\r
+  UINTN                       ValidCount;\r
+  UINTN                       ValidIndex;\r
+  \r
+  if ((TextModeCount == NULL) || (TextModeData == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  \r
+  Count = sizeof (mTerminalConsoleModeData) / sizeof (TERMINAL_CONSOLE_MODE_DATA);\r
+  \r
+  //\r
+  // Get defined mode buffer pointer.\r
+  //\r
+  ModeBuffer = mTerminalConsoleModeData;\r
+    \r
+  //\r
+  // Here we make sure that the final mode exposed does not include the duplicated modes,\r
+  // and does not include the invalid modes which exceed the max column and row.\r
+  // Reserve 2 modes for 80x25, 80x50 of terminal console.\r
+  //\r
+  NewModeBuffer = AllocateZeroPool (sizeof (TERMINAL_CONSOLE_MODE_DATA) * (Count + 2));\r
+  ASSERT (NewModeBuffer != NULL);\r
+\r
+  //\r
+  // Mode 0 and mode 1 is for 80x25, 80x50 according to UEFI spec.\r
+  //\r
+  ValidCount = 0;  \r
+\r
+  NewModeBuffer[ValidCount].Columns = 80;\r
+  NewModeBuffer[ValidCount].Rows    = 25;\r
+  ValidCount++;\r
+\r
+  NewModeBuffer[ValidCount].Columns = 80;\r
+  NewModeBuffer[ValidCount].Rows    = 50;\r
+  ValidCount++;\r
+  \r
+  //\r
+  // Start from mode 2 to put the valid mode other than 80x25 and 80x50 in the output mode buffer.\r
+  //\r
+  for (Index = 0; Index < Count; Index++) {\r
+    if ((ModeBuffer[Index].Columns == 0) || (ModeBuffer[Index].Rows == 0)) {\r
+      //\r
+      // Skip the pre-defined mode which is invalid.\r
+      //\r
+      continue;\r
+    }\r
+    for (ValidIndex = 0; ValidIndex < ValidCount; ValidIndex++) {\r
+      if ((ModeBuffer[Index].Columns == NewModeBuffer[ValidIndex].Columns) &&\r
+          (ModeBuffer[Index].Rows == NewModeBuffer[ValidIndex].Rows)) {\r
+        //\r
+        // Skip the duplicated mode.\r
+        //\r
+        break;\r
+      }\r
+    }\r
+    if (ValidIndex == ValidCount) {\r
+      NewModeBuffer[ValidCount].Columns = ModeBuffer[Index].Columns;\r
+      NewModeBuffer[ValidCount].Rows    = ModeBuffer[Index].Rows;\r
+      ValidCount++;\r
+    }\r
+  }\r
\r
+  DEBUG_CODE (\r
+    for (Index = 0; Index < ValidCount; Index++) {\r
+      DEBUG ((EFI_D_INFO, "Terminal - Mode %d, Column = %d, Row = %d\n", \r
+                           Index, NewModeBuffer[Index].Columns, NewModeBuffer[Index].Rows));  \r
+    }\r
+  );\r
+  \r
+  //\r
+  // Return valid mode count and mode information buffer.\r
+  //\r
+  *TextModeCount = ValidCount;\r
+  *TextModeData  = NewModeBuffer;\r
+  return EFI_SUCCESS;\r
+}\r
 \r
 /**\r
   Start this driver on Controller by opening a Serial IO protocol,\r
@@ -427,7 +544,6 @@ TerminalDriverBindingStart (
   EFI_SERIAL_IO_PROTOCOL              *SerialIo;\r
   EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath;\r
   VENDOR_DEVICE_PATH                  *Node;\r
-  VENDOR_DEVICE_PATH                  *DefaultNode;\r
   EFI_SERIAL_IO_MODE                  *Mode;\r
   UINTN                               SerialInTimeOut;\r
   TERMINAL_DEV                        *TerminalDevice;\r
@@ -444,12 +560,12 @@ TerminalDriverBindingStart (
   BOOLEAN                             SimTxtInInstalled;\r
   BOOLEAN                             SimTxtOutInstalled;\r
   BOOLEAN                             FirstEnter;\r
+  UINTN                               ModeCount;\r
 \r
   TerminalDevice     = NULL;\r
-  DefaultNode        = NULL;\r
-  ConInSelected       = FALSE;\r
-  ConOutSelected      = FALSE;\r
-  NullRemaining      = TRUE;\r
+  ConInSelected      = FALSE;\r
+  ConOutSelected     = FALSE;\r
+  NullRemaining      = FALSE;\r
   SimTxtInInstalled  = FALSE;\r
   SimTxtOutInstalled = FALSE;\r
   FirstEnter         = FALSE;\r
@@ -590,23 +706,14 @@ TerminalDriverBindingStart (
     }\r
 \r
     //\r
-    // If RemainingDevicePath is NULL, then create default device path node\r
+    // If RemainingDevicePath is NULL, use default terminal type\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
+      // Must be between PCANSITYPE (0) and TTYTERMTYPE (4)\r
       //\r
-      ASSERT (TerminalType <= VTUTF8TYPE);\r
-\r
-      CopyMem (&DefaultNode->Guid, gTerminalType[TerminalType], sizeof (EFI_GUID));\r
-      RemainingDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) DefaultNode;\r
+      ASSERT (TerminalType <= TTYTERMTYPE);\r
     } else if (!IsDevicePathEnd (RemainingDevicePath)) {\r
       //\r
       // If RemainingDevicePath isn't the End of Device Path Node,\r
@@ -621,6 +728,8 @@ TerminalDriverBindingStart (
         TerminalType = VT100PLUSTYPE;\r
       } else if (CompareGuid (&Node->Guid, &gEfiVTUTF8Guid)) {\r
         TerminalType = VTUTF8TYPE;\r
+      } else if (CompareGuid (&Node->Guid, &gEfiTtyTermGuid)) {\r
+        TerminalType = TTYTERMTYPE;\r
       } else {\r
         goto Error;\r
       }\r
@@ -697,7 +806,7 @@ TerminalDriverBindingStart (
     Status = TerminalDevice->SerialIo->SetAttributes (\r
                                         TerminalDevice->SerialIo,\r
                                         Mode->BaudRate,\r
-                                        Mode->ReceiveFifoDepth,\r
+                                        0, // the device's default FIFO depth\r
                                         (UINT32) SerialInTimeOut,\r
                                         (EFI_PARITY_TYPE) (Mode->Parity),\r
                                         (UINT8) Mode->DataBits,\r
@@ -724,8 +833,13 @@ TerminalDriverBindingStart (
                          sizeof (mTerminalDevTemplate.SimpleTextOutput)\r
                          );\r
     SimpleTextOutput->Mode = &TerminalDevice->SimpleTextOutputMode;\r
-\r
-    TerminalDevice->SimpleTextOutputMode.MaxMode = TERMINAL_MAX_MODE;\r
+    \r
+    Status = InitializeTerminalConsoleTextMode (&ModeCount, &TerminalDevice->TerminalConsoleModeData);\r
+    if (EFI_ERROR (Status)) {\r
+      goto ReportError;\r
+    }\r
+    TerminalDevice->SimpleTextOutputMode.MaxMode = (INT32) ModeCount;\r
+    \r
     //\r
     // For terminal devices, cursor is always visible\r
     //\r
@@ -814,6 +928,24 @@ TerminalDriverBindingStart (
         );\r
 \r
       break;\r
+\r
+    case TTYTERMTYPE:\r
+      AddUnicodeString2 (\r
+        "eng",\r
+        gTerminalComponentName.SupportedLanguages,\r
+        &TerminalDevice->ControllerNameTable,\r
+        (CHAR16 *)L"Tty Terminal Serial Console",\r
+        TRUE\r
+        );\r
+      AddUnicodeString2 (\r
+        "en",\r
+        gTerminalComponentName2.SupportedLanguages,\r
+        &TerminalDevice->ControllerNameTable,\r
+        (CHAR16 *)L"Tty Terminal Serial Console",\r
+        FALSE\r
+        );\r
+\r
+      break;\r
     }\r
 \r
     //\r
@@ -1039,9 +1171,6 @@ TerminalDriverBindingStart (
       goto Error;\r
     }\r
   }\r
-  if (DefaultNode != NULL) {\r
-    FreePool (DefaultNode);\r
-  }\r
 \r
   return EFI_SUCCESS;\r
 \r
@@ -1102,14 +1231,14 @@ Error:
         FreePool (TerminalDevice->DevicePath);\r
       }\r
 \r
+      if (TerminalDevice->TerminalConsoleModeData != NULL) {\r
+        FreePool (TerminalDevice->TerminalConsoleModeData);\r
+      }\r
+\r
       FreePool (TerminalDevice);\r
     }\r
   }\r
 \r
-  if (DefaultNode != NULL) {\r
-    FreePool (DefaultNode);\r
-  }\r
-\r
   This->Stop (This, Controller, 0, NULL);\r
 \r
   return Status;\r
@@ -1273,6 +1402,9 @@ TerminalDriverBindingStop (
         gBS->CloseEvent (TerminalDevice->SimpleInputEx.WaitForKeyEx);\r
         TerminalFreeNotifyList (&TerminalDevice->NotifyList);\r
         FreePool (TerminalDevice->DevicePath);\r
+        if (TerminalDevice->TerminalConsoleModeData != NULL) {\r
+          FreePool (TerminalDevice->TerminalConsoleModeData);\r
+        }\r
         FreePool (TerminalDevice);\r
       }\r
     }\r
@@ -1303,16 +1435,18 @@ TerminalUpdateConsoleDevVariable (
   )\r
 {\r
   EFI_STATUS                Status;\r
+  UINTN                     NameSize;\r
   UINTN                     VariableSize;\r
   UINT8                     TerminalType;\r
   EFI_DEVICE_PATH_PROTOCOL  *Variable;\r
   EFI_DEVICE_PATH_PROTOCOL  *NewVariable;\r
   EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;\r
+  EDKII_SET_VARIABLE_STATUS *SetVariableStatus;\r
 \r
   //\r
   // Get global variable and its size according to the name given.\r
   //\r
-  Variable = GetEfiGlobalVariable (VariableName);\r
+  GetEfiGlobalVariable2 (VariableName, (VOID**)&Variable, NULL);\r
   if (Variable == NULL) {\r
     return;\r
   }\r
@@ -1320,9 +1454,10 @@ TerminalUpdateConsoleDevVariable (
   //\r
   // Append terminal device path onto the variable.\r
   //\r
-  for (TerminalType = PCANSITYPE; TerminalType <= VTUTF8TYPE; TerminalType++) {\r
+  for (TerminalType = PCANSITYPE; TerminalType <= TTYTERMTYPE; TerminalType++) {\r
     SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);\r
     NewVariable = AppendDevicePathInstance (Variable, TempDevicePath);\r
+    ASSERT (NewVariable != NULL);\r
     if (Variable != NULL) {\r
       FreePool (Variable);\r
     }\r
@@ -1343,7 +1478,33 @@ TerminalUpdateConsoleDevVariable (
                   VariableSize,\r
                   Variable\r
                   );\r
-  ASSERT_EFI_ERROR (Status);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    NameSize = StrSize (VariableName);\r
+    SetVariableStatus = AllocatePool (sizeof (EDKII_SET_VARIABLE_STATUS) + NameSize + VariableSize);\r
+    if (SetVariableStatus != NULL) {\r
+      CopyGuid (&SetVariableStatus->Guid, &gEfiGlobalVariableGuid);\r
+      SetVariableStatus->NameSize   = NameSize;\r
+      SetVariableStatus->DataSize   = VariableSize;\r
+      SetVariableStatus->SetStatus  = Status;\r
+      SetVariableStatus->Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;\r
+      CopyMem (SetVariableStatus + 1,                          VariableName, NameSize);\r
+      CopyMem (((UINT8 *) (SetVariableStatus + 1)) + NameSize, Variable,     VariableSize);\r
+\r
+      REPORT_STATUS_CODE_EX (\r
+        EFI_ERROR_CODE,\r
+        PcdGet32 (PcdErrorCodeSetVariable),\r
+        0,\r
+        NULL,\r
+        &gEdkiiStatusCodeDataTypeVariableGuid,\r
+        SetVariableStatus,\r
+        sizeof (EDKII_SET_VARIABLE_STATUS) + NameSize + VariableSize\r
+        );\r
+\r
+      FreePool (SetVariableStatus);\r
+    }\r
+  }\r
+\r
   FreePool (Variable);\r
 \r
   return ;\r
@@ -1381,7 +1542,7 @@ TerminalRemoveConsoleDevVariable (
   //\r
   // Get global variable and its size according to the name given.\r
   //\r
-  Variable = GetEfiGlobalVariable (VariableName);\r
+  GetEfiGlobalVariable2 (VariableName, (VOID**)&Variable, NULL);\r
   if (Variable == NULL) {\r
     return ;\r
   }\r
@@ -1406,7 +1567,7 @@ TerminalRemoveConsoleDevVariable (
     // Loop through all the terminal types that this driver supports\r
     //\r
     Match = FALSE;\r
-    for (TerminalType = PCANSITYPE; TerminalType <= VTUTF8TYPE; TerminalType++) {\r
+    for (TerminalType = PCANSITYPE; TerminalType <= TTYTERMTYPE; TerminalType++) {\r
 \r
       SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);\r
 \r
@@ -1451,6 +1612,9 @@ TerminalRemoveConsoleDevVariable (
                     VariableSize,\r
                     NewVariable\r
                     );\r
+    //\r
+    // Shrinking variable with existing variable driver implementation shouldn't fail.\r
+    //\r
     ASSERT_EFI_ERROR (Status);\r
   }\r
 \r
@@ -1507,6 +1671,10 @@ SetTerminalDevicePath (
     CopyGuid (&Node.Guid, &gEfiVTUTF8Guid);\r
     break;\r
 \r
+  case TTYTERMTYPE:\r
+    CopyGuid (&Node.Guid, &gEfiTtyTermGuid);\r
+    break;\r
+\r
   default:\r
     return EFI_UNSUPPORTED;\r
   }\r