]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.c
IntelFrameworkModulePkg: Clean up source files
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Isa / IsaSerialDxe / Serial.c
index b8421122307e31aef795a042a285ea893b2658fd..56c2d4dda7158fa654dbd32f0500187c3c47fe94 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
   Serial driver for standard UARTS on an ISA bus.\r
 \r
-Copyright (c) 2006 - 2010, Intel Corporation<BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
 http://opensource.org/licenses/bsd-license.php\r
@@ -43,11 +43,11 @@ SERIAL_DEV  gSerialDevTempate = {
   { // SerialMode\r
     SERIAL_PORT_SUPPORT_CONTROL_MASK,\r
     SERIAL_PORT_DEFAULT_TIMEOUT,\r
-    FixedPcdGet64 (PcdUartDefaultBaudRate),     // BaudRate\r
+    0,\r
     SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH,\r
-    FixedPcdGet8 (PcdUartDefaultDataBits),      // DataBits\r
-    FixedPcdGet8 (PcdUartDefaultParity),        // Parity\r
-    FixedPcdGet8 (PcdUartDefaultStopBits)       // StopBits\r
+    0,\r
+    0,\r
+    0\r
   },\r
   NULL,\r
   NULL,\r
@@ -61,10 +61,10 @@ SERIAL_DEV  gSerialDevTempate = {
       }\r
     },\r
     0,\r
-    FixedPcdGet64 (PcdUartDefaultBaudRate),    \r
-    FixedPcdGet8 (PcdUartDefaultDataBits),\r
-    FixedPcdGet8 (PcdUartDefaultParity),\r
-    FixedPcdGet8 (PcdUartDefaultStopBits)\r
+    0,\r
+    0,\r
+    0,\r
+    0\r
   },\r
   NULL,\r
   0,    //BaseAddress\r
@@ -90,7 +90,7 @@ SERIAL_DEV  gSerialDevTempate = {
   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
+\r
   @retval TRUE              It's the Flow Control node.\r
   @retval FALSE             It's not.\r
 \r
@@ -111,7 +111,7 @@ IsUartFlowControlNode (
   Check the device path node whether it contains Flow Control node or not.\r
 \r
   @param[in] DevicePath     The device path to be checked.\r
-  \r
+\r
   @retval TRUE              It contains the Flow Control node.\r
   @retval FALSE             It doesn't.\r
 \r
@@ -134,9 +134,9 @@ ContainsFlowControl (
 /**\r
   The user Entry Point for module IsaSerial. The user code starts with this function.\r
 \r
-  @param[in] ImageHandle    The firmware allocated handle for the EFI image.  \r
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.\r
   @param[in] SystemTable    A pointer to the EFI System Table.\r
-  \r
+\r
   @retval EFI_SUCCESS       The entry point is executed successfully.\r
   @retval other             Some error occurs when executing this entry point.\r
 \r
@@ -163,6 +163,17 @@ InitializeIsaSerial (
              );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  //\r
+  // Initialize UART default setting in gSerialDevTempate\r
+  //\r
+  gSerialDevTempate.SerialMode.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);\r
+  gSerialDevTempate.SerialMode.DataBits = PcdGet8 (PcdUartDefaultDataBits);\r
+  gSerialDevTempate.SerialMode.Parity   = PcdGet8 (PcdUartDefaultParity);\r
+  gSerialDevTempate.SerialMode.StopBits = PcdGet8 (PcdUartDefaultStopBits);\r
+  gSerialDevTempate.UartDevicePath.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);\r
+  gSerialDevTempate.UartDevicePath.DataBits = PcdGet8 (PcdUartDefaultDataBits);\r
+  gSerialDevTempate.UartDevicePath.Parity   = PcdGet8 (PcdUartDefaultParity);\r
+  gSerialDevTempate.UartDevicePath.StopBits = PcdGet8 (PcdUartDefaultStopBits);\r
 \r
   return Status;\r
 }\r
@@ -195,13 +206,14 @@ SerialControllerDriverSupported (
   EFI_OPEN_PROTOCOL_INFORMATION_ENTRY       *OpenInfoBuffer;\r
   UINTN                                     EntryCount;\r
   UINTN                                     Index;\r
+  BOOLEAN                                   HasFlowControl;\r
 \r
   //\r
   // Check RemainingDevicePath validation\r
   //\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
@@ -218,27 +230,27 @@ SerialControllerDriverSupported (
                                         ) {\r
         goto Error;\r
       }\r
-  \r
+\r
       if (UartNode->BaudRate > SERIAL_PORT_MAX_BAUD_RATE) {\r
         goto Error;\r
       }\r
-  \r
+\r
       if (UartNode->Parity < NoParity || UartNode->Parity > SpaceParity) {\r
         goto Error;\r
       }\r
-  \r
+\r
       if (UartNode->DataBits < 5 || UartNode->DataBits > 8) {\r
         goto Error;\r
       }\r
-  \r
+\r
       if (UartNode->StopBits < OneStopBit || UartNode->StopBits > TwoStopBits) {\r
         goto Error;\r
       }\r
-  \r
+\r
       if ((UartNode->DataBits == 5) && (UartNode->StopBits == TwoStopBits)) {\r
         goto Error;\r
       }\r
-  \r
+\r
       if ((UartNode->DataBits >= 6) && (UartNode->DataBits <= 8) && (UartNode->StopBits == OneFiveStopBits)) {\r
         goto Error;\r
       }\r
@@ -298,9 +310,11 @@ SerialControllerDriverSupported (
                         Controller,\r
                         EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
                         );\r
-        if (!EFI_ERROR (Status) &&\r
-            (ContainsFlowControl (RemainingDevicePath) ^ ContainsFlowControl (DevicePath))) {\r
-          Status = EFI_UNSUPPORTED;\r
+        if (!EFI_ERROR (Status)) {\r
+          HasFlowControl = ContainsFlowControl (RemainingDevicePath);\r
+          if (HasFlowControl ^ ContainsFlowControl (DevicePath)) {\r
+            Status = EFI_UNSUPPORTED;\r
+          }\r
         }\r
         break;\r
       }\r
@@ -496,7 +510,7 @@ SerialControllerDriverStart (
               // Clear the bits that are not allowed to pass to SetControl\r
               //\r
               Control &= (EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY |\r
-                          EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE | EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE | \r
+                          EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE | EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE |\r
                           EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE);\r
               Status = SerialIo->SetControl (SerialIo, Control);\r
             }\r
@@ -515,7 +529,7 @@ SerialControllerDriverStart (
       //\r
       // If RemainingDevicePath is the End of Device Path Node,\r
       // skip enumerate any device and return EFI_SUCESSS\r
-      // \r
+      //\r
       return EFI_SUCCESS;\r
     }\r
   }\r
@@ -536,13 +550,13 @@ SerialControllerDriverStart (
   FlowControlMap                    = 0;\r
 \r
   //\r
-  // Check if RemainingDevicePath is NULL, \r
+  // Check if RemainingDevicePath is NULL,\r
   // if yes, use the values from the gSerialDevTempate as no remaining device path was\r
   // passed in.\r
   //\r
   if (RemainingDevicePath != NULL) {\r
     //\r
-    // If RemainingDevicePath isn't NULL, \r
+    // If RemainingDevicePath isn't NULL,\r
     // match the configuration of the RemainingDevicePath. IsHandleSupported()\r
     // already checked to make sure the RemainingDevicePath contains settings\r
     // that we can support.\r
@@ -563,7 +577,7 @@ SerialControllerDriverStart (
       SerialDevice->BaseAddress = (UINT16) SerialDevice->IsaIo->ResourceList->ResourceItem[Index].StartRange;\r
     }\r
   }\r
-  \r
+\r
   SerialDevice->HardwareFlowControl = (BOOLEAN) (FlowControlMap == UART_FLOW_CONTROL_HARDWARE);\r
 \r
   //\r
@@ -587,7 +601,7 @@ SerialControllerDriverStart (
 \r
   //\r
   // Build the device path by appending the UART node to the ParentDevicePath.\r
-  // The Uart setings are zero here, since  SetAttribute() will update them to match \r
+  // The Uart setings are zero here, since  SetAttribute() will update them to match\r
   // the default setings.\r
   //\r
   SerialDevice->DevicePath = AppendDevicePathNode (\r
@@ -839,7 +853,7 @@ IsaSerialFifoFull (
 \r
 /**\r
   Detect whether specific FIFO is empty or not.\r
\r
+\r
   @param  Fifo    A pointer to the Data Structure SERIAL_DEV_FIFO\r
 \r
   @return whether specific FIFO is empty or not\r
@@ -1008,7 +1022,7 @@ IsaSerialReceiveTransmit (
           Data = READ_RBR (SerialDevice->IsaIo, SerialDevice->BaseAddress);\r
 \r
           IsaSerialFifoAdd (&SerialDevice->Receive, Data);\r
-          \r
+\r
           //\r
           // For full handshake flow control, if receive buffer full\r
           // tell the peer to stop sending data.\r
@@ -1379,11 +1393,11 @@ IsaSerialSetAttributes (
   // Compute divisor use to program the baud rate using a round determination\r
   //\r
   Divisor = (UINT32) DivU64x32Remainder (\r
-                       SERIAL_PORT_INPUT_CLOCK,\r
+                       PcdGet32 (PcdSerialClockRate),\r
                        ((UINT32) BaudRate * 16),\r
                        &Remained\r
                        );\r
-  if (Remained != 0) {\r
+  if (Remained >= ((UINT32) BaudRate * 8)) {\r
     Divisor += 1;\r
   }\r
 \r
@@ -1396,7 +1410,7 @@ IsaSerialSetAttributes (
   //\r
   // Compute the actual baud rate that the serial port will be programmed for.\r
   //\r
-  BaudRate = SERIAL_PORT_INPUT_CLOCK / Divisor / 16;\r
+  BaudRate = PcdGet32 (PcdSerialClockRate) / Divisor / 16;\r
 \r
   //\r
   // Put serial port on Divisor Latch Mode\r
@@ -1556,9 +1570,9 @@ IsaSerialSetControl (
   //\r
   // first determine the parameter is invalid\r
   //\r
-  if (Control & (~(EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY |\r
-                   EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE | EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE | \r
-                   EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) {\r
+  if ((Control & (~(EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY |\r
+                    EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE | EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE |\r
+                    EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) != 0) {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -1741,6 +1755,8 @@ IsaSerialWrite (
   UINTN       Elapsed;\r
   UINTN       ActualWrite;\r
   EFI_TPL     Tpl;\r
+  UINTN       Timeout;\r
+  UINTN       BitsPerCharacter;\r
 \r
   SerialDevice  = SERIAL_DEV_FROM_THIS (This);\r
   Elapsed       = 0;\r
@@ -1764,6 +1780,36 @@ IsaSerialWrite (
 \r
   CharBuffer  = (UINT8 *) Buffer;\r
 \r
+  //\r
+  // Compute the number of bits in a single character.  This is a start bit,\r
+  // followed by the number of data bits, followed by the number of stop bits.\r
+  // The number of stop bits is specified by an enumeration that includes\r
+  // support for 1.5 stop bits.  Treat 1.5 stop bits as 2 stop bits.\r
+  //\r
+  BitsPerCharacter =\r
+    1 +\r
+    This->Mode->DataBits +\r
+    ((This->Mode->StopBits == TwoStopBits) ? 2 : This->Mode->StopBits);\r
+\r
+  //\r
+  // Compute the timeout in microseconds to wait for a single byte to be\r
+  // transmitted.  The Mode structure contans a Timeout field that is the\r
+  // maximum time to transmit or receive a character.  However, many UARTs\r
+  // have a FIFO for transmits, so the time required to add one new character\r
+  // to the transmit FIFO may be the time required to flush a full FIFO.  If\r
+  // the Timeout in the Mode structure is smaller than the time required to\r
+  // flush a full FIFO at the current baud rate, then use a timeout value that\r
+  // is required to flush a full transmit FIFO.\r
+  //\r
+  Timeout = MAX (\r
+              This->Mode->Timeout,\r
+              (UINTN)DivU64x64Remainder (\r
+                BitsPerCharacter * (SERIAL_PORT_MAX_RECEIVE_FIFO_DEPTH + 1) * 1000000,\r
+                This->Mode->BaudRate,\r
+                NULL\r
+                )\r
+              );\r
+\r
   for (Index = 0; Index < *BufferSize; Index++) {\r
     IsaSerialFifoAdd (&SerialDevice->Transmit, CharBuffer[Index]);\r
 \r
@@ -1772,7 +1818,7 @@ IsaSerialWrite (
       //  Unsuccessful write so check if timeout has expired, if not,\r
       //  stall for a bit, increment time elapsed, and try again\r
       //\r
-      if (Elapsed >= This->Mode->Timeout) {\r
+      if (Elapsed >= Timeout) {\r
         *BufferSize = ActualWrite;\r
         gBS->RestoreTPL (Tpl);\r
         return EFI_TIMEOUT;\r