]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmbeddedPkg/SerialDxe/SerialIo.c
BaseTools/Build: Add all support skuid to the Pcd DB system skuid table
[mirror_edk2.git] / EmbeddedPkg / SerialDxe / SerialIo.c
index ef4e6a1910f42a94ccdb80d53f583a4886c8a143..7a849b7a01392bf7e51f74c5a23fbe08798ff8bf 100644 (file)
@@ -1,13 +1,13 @@
 /** @file\r
-  Serial IO Abstraction for GDB stub. This allows an EFI consoles that shows up on the system \r
+  Serial IO Abstraction for GDB stub. This allows an EFI consoles that shows up on the system\r
   running GDB. One console for error information and another console for user input/output.\r
-  \r
+\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
+  #, 0, 0. The 0 and 0 are the ascii characters for the checksum.\r
 \r
   Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
-  \r
+  Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>\r
+\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
 #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
   @param  This              Protocol instance pointer.\r
-                            \r
+\r
   @retval EFI_SUCCESS       The device was reset.\r
   @retval EFI_DEVICE_ERROR  The serial device could not be reset.\r
 \r
@@ -42,8 +67,60 @@ 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
@@ -85,7 +162,61 @@ SerialSetAttributes (
   IN EFI_STOP_BITS_TYPE      StopBits\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  RETURN_STATUS  ReturnStatus;\r
+  EFI_STATUS     Status;\r
+  EFI_TPL        Tpl;\r
+\r
+  ReturnStatus = SerialPortSetAttributes (&BaudRate, &ReceiveFifoDepth, &Timeout, &Parity, &DataBits, &StopBits);\r
+  if (RETURN_ERROR (ReturnStatus)) {\r
+    return EFI_DEVICE_ERROR;\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,7 +238,7 @@ SerialSetControl (
   IN UINT32                  Control\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  return SerialPortSetControl(Control);\r
 }\r
 \r
 \r
@@ -116,7 +247,7 @@ SerialSetControl (
 \r
   @param  This              Protocol instance pointer.\r
   @param  Control           A pointer to return the current Control signals from the serial device.\r
-                            \r
+\r
   @retval EFI_SUCCESS       The control bits were read from the serial device.\r
   @retval EFI_DEVICE_ERROR  The serial device is not functioning correctly.\r
 \r
@@ -128,13 +259,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
@@ -160,10 +285,15 @@ SerialWrite (
   )\r
 {\r
   UINTN Count;\r
-  \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
@@ -202,10 +332,7 @@ SerialRead (
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
-EFI_HANDLE  gHandle = NULL;\r
-\r
-// \r
+//\r
 // Template used to initialize the GDB Serial IO protocols\r
 //\r
 EFI_SERIAL_IO_MODE gSerialIoMode = {\r
@@ -229,29 +356,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
-    { 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
 \r
 /**\r
   Initialize the state information for the Serial Io Protocol\r
@@ -273,16 +377,15 @@ 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
+                  &gHandle,\r
                   &gEfiSerialIoProtocolGuid,   &gSerialIoTemplate,\r
-                  &gEfiDevicePathProtocolGuid, &mDevicePath, \r
+                  &gEfiDevicePathProtocolGuid, &mDevicePath,\r
                   NULL\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
-  \r
+\r
   return Status;\r
 }\r
 \r