]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmbeddedPkg/SerialDxe/SerialIo.c
EmbeddedPkg: Introduced 'SerialPortExtLib.h'
[mirror_edk2.git] / EmbeddedPkg / SerialDxe / SerialIo.c
index e61338836701795d9c6f82290d079bef7db36f42..a94bacaf409510fe4bf5bac22d2cb343ad6ad14a 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
   Serial IO Abstraction for GDB stub. This allows an EFI consoles that shows up on the system \r
-  running GDB. One consle for error information and another console for user input/output.\r
+  running GDB. One console for error information and another console for user input/output.\r
   \r
-  Basic packet format is $packet-data#checksum. So every comand has 4 bytes of overhead: $, \r
+  Basic packet format is $packet-data#checksum. So every command has 4 bytes of overhead: $,\r
   #, 0, 0. The 0 and 0 are the ascii characters for the checksum. \r
   \r
 \r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/SerialPortLib.h>\r
+#include <Library/SerialPortExtLib.h>\r
 #include <Library/PcdLib.h>\r
 \r
 #include <Protocol/SerialIo.h>\r
 \r
+typedef struct {\r
+  VENDOR_DEVICE_PATH        Guid;\r
+  UART_DEVICE_PATH          Uart;\r
+  EFI_DEVICE_PATH_PROTOCOL  End;\r
+} SIMPLE_TEXT_OUT_DEVICE_PATH;\r
+\r
+SIMPLE_TEXT_OUT_DEVICE_PATH mDevicePath = {\r
+  {\r
+    { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, sizeof (VENDOR_DEVICE_PATH), 0},\r
+    EFI_CALLER_ID_GUID // Use the drivers GUID\r
+  },\r
+  {\r
+    { MESSAGING_DEVICE_PATH, MSG_UART_DP, sizeof (UART_DEVICE_PATH), 0},\r
+    0,        // Reserved\r
+    FixedPcdGet64 (PcdUartDefaultBaudRate),   // BaudRate\r
+    FixedPcdGet8 (PcdUartDefaultDataBits),    // DataBits\r
+    FixedPcdGet8 (PcdUartDefaultParity),      // Parity (N)\r
+    FixedPcdGet8 (PcdUartDefaultStopBits)     // StopBits\r
+  },\r
+  { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, sizeof (EFI_DEVICE_PATH_PROTOCOL), 0}\r
+};\r
+\r
+EFI_HANDLE  gHandle = NULL;\r
+\r
 /**\r
   Reset the serial device.\r
 \r
@@ -42,21 +67,73 @@ SerialReset (
   IN EFI_SERIAL_IO_PROTOCOL  *This\r
   )\r
 {\r
-  SerialPortInitialize ();\r
-  return EFI_SUCCESS;\r
+  EFI_STATUS  Status;\r
+  EFI_TPL     Tpl;\r
+\r
+  Status = SerialPortInitialize ();\r
+  if (EFI_ERROR(Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Set the Serial I/O mode and update the device path\r
+  //\r
+\r
+  Tpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+  //\r
+  // Set the Serial I/O mode\r
+  //\r
+  This->Mode->ReceiveFifoDepth  = 0;\r
+  This->Mode->Timeout           = 1000000;\r
+  This->Mode->BaudRate          = PcdGet64 (PcdUartDefaultBaudRate);\r
+  This->Mode->DataBits          = (UINT32)PcdGet8 (PcdUartDefaultDataBits);\r
+  This->Mode->Parity            = (UINT32)PcdGet8 (PcdUartDefaultParity);\r
+  This->Mode->StopBits          = (UINT32)PcdGet8 (PcdUartDefaultStopBits);\r
+\r
+  //\r
+  // Check if the device path has actually changed\r
+  //\r
+  if (mDevicePath.Uart.BaudRate == This->Mode->BaudRate &&\r
+      mDevicePath.Uart.DataBits == (UINT8)This->Mode->DataBits &&\r
+      mDevicePath.Uart.Parity   == (UINT8)This->Mode->Parity &&\r
+      mDevicePath.Uart.StopBits == (UINT8)This->Mode->StopBits\r
+     ) {\r
+    gBS->RestoreTPL (Tpl);\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Update the device path\r
+  //\r
+  mDevicePath.Uart.BaudRate = This->Mode->BaudRate;\r
+  mDevicePath.Uart.DataBits = (UINT8)This->Mode->DataBits;\r
+  mDevicePath.Uart.Parity   = (UINT8)This->Mode->Parity;\r
+  mDevicePath.Uart.StopBits = (UINT8)This->Mode->StopBits;\r
+\r
+  Status = gBS->ReinstallProtocolInterface (\r
+                  gHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  &mDevicePath,\r
+                  &mDevicePath\r
+                  );\r
+\r
+  gBS->RestoreTPL (Tpl);\r
+\r
+  return Status;\r
 }\r
 \r
 \r
 /**\r
-  Sets the baud rate, receive FIFO depth, transmit/receice time out, parity, \r
+  Sets the baud rate, receive FIFO depth, transmit/receive time out, parity,\r
   data buts, and stop bits on a serial device.\r
 \r
   @param  This             Protocol instance pointer.\r
   @param  BaudRate         The requested baud rate. A BaudRate value of 0 will use the the\r
                            device's default interface speed.\r
-  @param  ReveiveFifoDepth The requested depth of the FIFO on the receive side of the\r
+  @param  ReceiveFifoDepth The requested depth of the FIFO on the receive side of the\r
                            serial interface. A ReceiveFifoDepth value of 0 will use\r
-                           the device's dfault FIFO depth.\r
+                           the device's default FIFO depth.\r
   @param  Timeout          The requested time out for a single character in microseconds.\r
                            This timeout applies to both the transmit and receive side of the\r
                            interface. A Timeout value of 0 will use the device's default time\r
@@ -64,7 +141,7 @@ SerialReset (
   @param  Parity           The type of parity to use on this serial device. A Parity value of\r
                            DefaultParity will use the device's default parity value.\r
   @param  DataBits         The number of data bits to use on the serial device. A DataBits\r
-                           vaule of 0 will use the device's default data bit setting.\r
+                           value of 0 will use the device's default data bit setting.\r
   @param  StopBits         The number of stop bits to use on this serial device. A StopBits\r
                            value of DefaultStopBits will use the device's default number of\r
                            stop bits.\r
@@ -85,7 +162,60 @@ SerialSetAttributes (
   IN EFI_STOP_BITS_TYPE      StopBits\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  EFI_STATUS  Status;\r
+  EFI_TPL     Tpl;\r
+\r
+  Status = SerialPortSetAttributes (BaudRate, ReceiveFifoDepth, Timeout, Parity, DataBits, StopBits);\r
+  if (EFI_ERROR(Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Set the Serial I/O mode and update the device path\r
+  //\r
+\r
+  Tpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+  //\r
+  // Set the Serial I/O mode\r
+  //\r
+  This->Mode->BaudRate          = BaudRate;\r
+  This->Mode->ReceiveFifoDepth  = ReceiveFifoDepth;\r
+  This->Mode->Timeout           = Timeout;\r
+  This->Mode->Parity            = (UINT32)Parity;\r
+  This->Mode->DataBits          = (UINT32)DataBits;\r
+  This->Mode->StopBits          = (UINT32)StopBits;\r
+\r
+  //\r
+  // Check if the device path has actually changed\r
+  //\r
+  if (mDevicePath.Uart.BaudRate == BaudRate &&\r
+      mDevicePath.Uart.Parity   == (UINT8)Parity &&\r
+      mDevicePath.Uart.DataBits == DataBits &&\r
+      mDevicePath.Uart.StopBits == (UINT8)StopBits\r
+     ) {\r
+    gBS->RestoreTPL (Tpl);\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Update the device path\r
+  //\r
+  mDevicePath.Uart.BaudRate = BaudRate;\r
+  mDevicePath.Uart.DataBits = DataBits;\r
+  mDevicePath.Uart.Parity   = (UINT8) Parity;\r
+  mDevicePath.Uart.StopBits = (UINT8) StopBits;\r
+\r
+  Status = gBS->ReinstallProtocolInterface (\r
+                  gHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  &mDevicePath,\r
+                  &mDevicePath\r
+                  );\r
+\r
+  gBS->RestoreTPL (Tpl);\r
+\r
+  return Status;\r
 }\r
 \r
 \r
@@ -107,12 +237,12 @@ SerialSetControl (
   IN UINT32                  Control\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  return SerialPortSetControl(Control);\r
 }\r
 \r
 \r
 /**\r
-  Retrieves the status of thecontrol bits on a serial device\r
+  Retrieves the status of the control bits on a serial device\r
 \r
   @param  This              Protocol instance pointer.\r
   @param  Control           A pointer to return the current Control signals from the serial device.\r
@@ -128,13 +258,7 @@ SerialGetControl (
   OUT UINT32                 *Control\r
   )\r
 {\r
-  if (SerialPortPoll ()) {\r
-    // If a character is pending don't set EFI_SERIAL_INPUT_BUFFER_EMPTY\r
-    *Control = EFI_SERIAL_OUTPUT_BUFFER_EMPTY;\r
-  } else {\r
-    *Control = EFI_SERIAL_INPUT_BUFFER_EMPTY | EFI_SERIAL_OUTPUT_BUFFER_EMPTY;\r
-  }\r
-  return EFI_SUCCESS;\r
+  return SerialPortGetControl(Control);\r
 }\r
 \r
 \r
@@ -162,12 +286,17 @@ SerialWrite (
   UINTN Count;\r
   \r
   Count = SerialPortWrite (Buffer, *BufferSize);\r
-  *BufferSize = Count;\r
-  return (Count == 0) ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
+\r
+  if (Count != *BufferSize) {\r
+    *BufferSize = Count;\r
+    return EFI_TIMEOUT;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
-  Writes data to a serial device.\r
+  Reads data from a serial device.\r
 \r
   @param  This              Protocol instance pointer.\r
   @param  BufferSize        On input, the size of the Buffer. On output, the amount of\r
@@ -188,24 +317,28 @@ SerialRead (
   OUT VOID                   *Buffer\r
   )\r
 {\r
-  UINTN Count;\r
-  \r
-  Count = SerialPortRead (Buffer, *BufferSize);\r
-  *BufferSize = Count;\r
-  return (Count == 0) ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
-}\r
+  UINTN Count = 0;\r
 \r
+  if (SerialPortPoll()) {\r
+    Count = SerialPortRead (Buffer, *BufferSize);\r
+  }\r
 \r
-EFI_HANDLE  gHandle = NULL;\r
+  if (Count != *BufferSize) {\r
+    *BufferSize = Count;\r
+    return EFI_TIMEOUT;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
 \r
 // \r
-// Template used to initailize the GDB Serial IO protocols\r
+// Template used to initialize the GDB Serial IO protocols\r
 //\r
 EFI_SERIAL_IO_MODE gSerialIoMode = {\r
   0,                                          // ControlMask\r
   0,                                          // Timeout\r
   FixedPcdGet64 (PcdUartDefaultBaudRate),     // BaudRate\r
-  1,                                          // RceiveFifoDepth\r
+  1,                                          // ReceiveFifoDepth\r
   FixedPcdGet8 (PcdUartDefaultDataBits),      // DataBits\r
   FixedPcdGet8 (PcdUartDefaultParity),        // Parity\r
   FixedPcdGet8 (PcdUartDefaultStopBits)       // StopBits\r
@@ -222,29 +355,6 @@ EFI_SERIAL_IO_PROTOCOL gSerialIoTemplate = {
   SerialRead,\r
   &gSerialIoMode\r
 };\r
-  \r
-typedef struct {\r
-  VENDOR_DEVICE_PATH        Guid;\r
-  UART_DEVICE_PATH          Uart;\r
-  EFI_DEVICE_PATH_PROTOCOL  End;\r
-} SIMPLE_TEXT_OUT_DEVICE_PATH;\r
-\r
-SIMPLE_TEXT_OUT_DEVICE_PATH mDevicePath = {\r
-  {\r
-    { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, sizeof (VENDOR_DEVICE_PATH), 0},\r
-    EFI_CALLER_ID_GUID // Use the drivers GUID\r
-  },\r
-  {\r
-    { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, sizeof (UART_DEVICE_PATH), 0},\r
-    0,        // Reserved\r
-    FixedPcdGet64 (PcdUartDefaultBaudRate),   // BaudRate\r
-    FixedPcdGet8 (PcdUartDefaultDataBits),    // DataBits\r
-    FixedPcdGet8 (PcdUartDefaultParity),      // Parity (N)\r
-    FixedPcdGet8 (PcdUartDefaultStopBits)     // StopBits\r
-  },\r
-  { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, sizeof (EFI_DEVICE_PATH_PROTOCOL), 0}\r
-};\r
-\r
 \r
 /**\r
   Initialize the state information for the Serial Io Protocol\r
@@ -266,7 +376,6 @@ SerialDxeInitialize (
 {\r
   EFI_STATUS      Status;\r
 \r
-\r
   // Make a new handle with Serial IO protocol and its device path on it.\r
   Status = gBS->InstallMultipleProtocolInterfaces (\r
                   &gHandle, \r