EmbeddedPkg: Introduced 'SerialPortExtLib.h'

EmbeddedPkg/SerialDxe was not allowing to set/get the control of the
Serial connection because the needed functions were not exposed in
SerialPortLib.h.
This commit introduces an additional library to extend the SerialPort
features.

Signed-off-by: Olivier Martin <olivier.martin@arm.com>



git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13773 6f19259b-4bc3-4df7-8a09-765794883524
diff --git a/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c b/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c
index 2395ffd..7ccd09b 100644
--- a/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c
+++ b/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c
@@ -19,11 +19,12 @@
 #include <Library/IoLib.h>
 #include <Library/PcdLib.h>
 #include <Library/SerialPortLib.h>
+#include <Library/SerialPortExtLib.h>
 
 #include <Drivers/PL011Uart.h>
 
 
-/*
+/**
 
   Programmed hardware of Serial port.
 
@@ -101,3 +102,83 @@
 {
   return PL011UartPoll ((UINTN)PcdGet64 (PcdSerialRegisterBase));
 }
+
+/**
+  Set new attributes to PL011.
+
+  @param  BaudRate                The baud rate of the serial device. If the baud rate is not supported,
+                                  the speed will be reduced down to the nearest supported one and the
+                                  variable's value will be updated accordingly.
+  @param  ReceiveFifoDepth        The number of characters the device will buffer on input. If the specified
+                                  value is not supported, the variable's value will be reduced down to the
+                                  nearest supported one.
+  @param  Timeout                 If applicable, the number of microseconds the device will wait
+                                  before timing out a Read or a Write operation.
+  @param  Parity                  If applicable, this is the EFI_PARITY_TYPE that is computer or checked
+                                  as each character is transmitted or received. If the device does not
+                                  support parity, the value is the default parity value.
+  @param  DataBits                The number of data bits in each character
+  @param  StopBits                If applicable, the EFI_STOP_BITS_TYPE number of stop bits per character.
+                                  If the device does not support stop bits, the value is the default stop
+                                  bit value.
+
+  @retval EFI_SUCCESS             All attributes were set correctly on the serial device.
+  @retval EFI_INVALID_PARAMETERS  One or more of the attributes has an unsupported value.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetAttributes (
+  IN UINT64              BaudRate,
+  IN UINT32              ReceiveFifoDepth,
+  IN UINT32              Timeout,
+  IN EFI_PARITY_TYPE     Parity,
+  IN UINT8               DataBits,
+  IN EFI_STOP_BITS_TYPE  StopBits
+  )
+{
+  return PL011UartInitializePort (
+        (UINTN)PcdGet64 (PcdSerialRegisterBase),
+        BaudRate,
+        ReceiveFifoDepth,
+        Parity,
+        DataBits,
+        StopBits);
+}
+
+/**
+  Set the serial device control bits.
+
+  @param  Control                 Control bits which are to be set on the serial device.
+
+  @retval EFI_SUCCESS             The new control bits were set on the serial device.
+  @retval EFI_UNSUPPORTED         The serial device does not support this operation.
+  @retval EFI_DEVICE_ERROR        The serial device is not functioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetControl (
+  IN UINT32                  Control
+  )
+{
+  return PL011UartSetControl((UINTN)PcdGet64 (PcdSerialRegisterBase), Control);
+}
+
+/**
+  Get the serial device control bits.
+
+  @param  Control                 Control signals read from the serial device.
+
+  @retval EFI_SUCCESS             The control bits were read from the serial device.
+  @retval EFI_DEVICE_ERROR        The serial device is not functioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortGetControl (
+  OUT UINT32                  *Control
+  )
+{
+  return PL011UartGetControl((UINTN)PcdGet64 (PcdSerialRegisterBase), Control);
+}
diff --git a/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf b/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
index f3c7285..13168df 100644
--- a/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
+++ b/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
@@ -30,6 +30,7 @@
   PcdLib

 

 [Packages]

+  EmbeddedPkg/EmbeddedPkg.dec

   MdePkg/MdePkg.dec

   MdeModulePkg/MdeModulePkg.dec

   ArmPlatformPkg/ArmPlatformPkg.dec

diff --git a/EmbeddedPkg/Include/Library/SerialPortExtLib.h b/EmbeddedPkg/Include/Library/SerialPortExtLib.h
new file mode 100644
index 0000000..74f5e4c
--- /dev/null
+++ b/EmbeddedPkg/Include/Library/SerialPortExtLib.h
@@ -0,0 +1,66 @@
+/** @file
+
+  Copyright (c) 2012, ARM Ltd. All rights reserved.
+  
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __SERIAL_PORT_EXT_LIB_H__
+#define __SERIAL_PORT_EXT_LIB_H__
+
+#include <Uefi/UefiBaseType.h>
+#include <Protocol/SerialIo.h>
+
+/**
+  Set the serial device control bits.
+
+  @return    Always return EFI_UNSUPPORTED.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetControl (
+  IN UINT32                   Control
+  );
+
+/**
+  Get the serial device control bits.
+
+  @param  Control                 Control signals read from the serial device.
+
+  @retval EFI_SUCCESS             The control bits were read from the serial device.
+  @retval EFI_DEVICE_ERROR        The serial device is not functioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortGetControl (
+  OUT UINT32                  *Control
+  );
+
+/**
+  Set the serial device attributes.
+
+  @return    Always return EFI_UNSUPPORTED.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetAttributes (
+  IN UINT64              BaudRate,
+  IN UINT32              ReceiveFifoDepth,
+  IN UINT32              Timeout,
+  IN EFI_PARITY_TYPE     Parity,
+  IN UINT8               DataBits,
+  IN EFI_STOP_BITS_TYPE  StopBits
+  );
+
+#endif
+
diff --git a/EmbeddedPkg/Library/TemplateSerialPortLib/TemplateSerialPortLib.c b/EmbeddedPkg/Library/TemplateSerialPortLib/TemplateSerialPortLib.c
index 9cc2b79..0110189 100644
--- a/EmbeddedPkg/Library/TemplateSerialPortLib/TemplateSerialPortLib.c
+++ b/EmbeddedPkg/Library/TemplateSerialPortLib/TemplateSerialPortLib.c
@@ -2,6 +2,7 @@
   Serial I/O Port library functions with no library constructor/destructor

 

   Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  Copyright (c) 2012, ARM Ltd. All rights reserved.

   

   This program and the accompanying materials

   are licensed and made available under the terms and conditions of the BSD License

@@ -17,8 +18,9 @@
 

 

 #include <Library/SerialPortLib.h>

+#include <Library/SerialPortExtLib.h>

 

-/*

+/**

 

   Programmed hardware of Serial port.

 

@@ -35,6 +37,65 @@
 }

 

 /**

+  Set the serial device control bits.

+

+  @return    Always return EFI_UNSUPPORTED.

+

+**/

+RETURN_STATUS

+EFIAPI

+SerialPortSetControl (

+    IN UINT32                   Control

+  )

+{

+  return RETURN_UNSUPPORTED;

+}

+

+/**

+  Get the serial device control bits.

+

+  @param  Control                 Control signals read from the serial device.

+

+  @retval EFI_SUCCESS             The control bits were read from the serial device.

+  @retval EFI_DEVICE_ERROR        The serial device is not functioning correctly.

+

+**/

+RETURN_STATUS

+EFIAPI

+SerialPortGetControl (

+  OUT UINT32                  *Control

+  )

+{

+  if (SerialPortPoll ()) {

+    // If a character is pending don't set EFI_SERIAL_INPUT_BUFFER_EMPTY

+    *Control = EFI_SERIAL_OUTPUT_BUFFER_EMPTY;

+  } else {

+    *Control = EFI_SERIAL_INPUT_BUFFER_EMPTY | EFI_SERIAL_OUTPUT_BUFFER_EMPTY;

+  }

+  return EFI_SUCCESS;

+}

+

+/**

+  Set the serial device attributes.

+

+  @return    Always return EFI_UNSUPPORTED.

+

+**/

+RETURN_STATUS

+EFIAPI

+SerialPortSetAttributes (

+  IN OUT  UINT64              *BaudRate,

+  IN OUT  UINT32              *ReceiveFifoDepth,

+  IN OUT  UINT32              *Timeout,

+  IN OUT  EFI_PARITY_TYPE     *Parity,

+  IN OUT  UINT8               *DataBits,

+  IN OUT  EFI_STOP_BITS_TYPE  *StopBits

+  )

+{

+  return RETURN_UNSUPPORTED;

+}

+

+/**

   Write data to serial device.

 

   @param  Buffer           Point of data buffer which need to be written.

@@ -49,7 +110,7 @@
 SerialPortWrite (

   IN UINT8     *Buffer,

   IN UINTN     NumberOfBytes

-)

+  )

 {

   return 0;

 }

@@ -70,7 +131,7 @@
 SerialPortRead (

   OUT UINT8     *Buffer,

   IN  UINTN     NumberOfBytes

-)

+  )

 {

   return 0;

 }

diff --git a/EmbeddedPkg/SerialDxe/SerialDxe.inf b/EmbeddedPkg/SerialDxe/SerialDxe.inf
index e0aa57d..37e8e0e 100644
--- a/EmbeddedPkg/SerialDxe/SerialDxe.inf
+++ b/EmbeddedPkg/SerialDxe/SerialDxe.inf
@@ -22,13 +22,12 @@
 

   ENTRY_POINT                    = SerialDxeInitialize

 

-

 [Sources.common]

   SerialIo.c

 

-

 [Packages]

   MdePkg/MdePkg.dec

+  EmbeddedPkg/EmbeddedPkg.dec

 

 [LibraryClasses]

   BaseLib

@@ -41,9 +40,6 @@
   UefiDriverEntryPoint

   SerialPortLib

 

-[Guids]

-  

-

 [Protocols]

   gEfiSerialIoProtocolGuid    

   gEfiDevicePathProtocolGuid

@@ -54,6 +50,5 @@
   gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity

   gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits

 

-  

 [Depex] 

   TRUE

diff --git a/EmbeddedPkg/SerialDxe/SerialIo.c b/EmbeddedPkg/SerialDxe/SerialIo.c
index ef4e6a1..a94baca 100644
--- a/EmbeddedPkg/SerialDxe/SerialIo.c
+++ b/EmbeddedPkg/SerialDxe/SerialIo.c
@@ -23,10 +23,35 @@
 #include <Library/UefiBootServicesTableLib.h>

 #include <Library/DebugLib.h>

 #include <Library/SerialPortLib.h>

+#include <Library/SerialPortExtLib.h>

 #include <Library/PcdLib.h>

 

 #include <Protocol/SerialIo.h>

 

+typedef struct {

+  VENDOR_DEVICE_PATH        Guid;

+  UART_DEVICE_PATH          Uart;

+  EFI_DEVICE_PATH_PROTOCOL  End;

+} SIMPLE_TEXT_OUT_DEVICE_PATH;

+

+SIMPLE_TEXT_OUT_DEVICE_PATH mDevicePath = {

+  {

+    { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, sizeof (VENDOR_DEVICE_PATH), 0},

+    EFI_CALLER_ID_GUID // Use the drivers GUID

+  },

+  {

+    { MESSAGING_DEVICE_PATH, MSG_UART_DP, sizeof (UART_DEVICE_PATH), 0},

+    0,        // Reserved

+    FixedPcdGet64 (PcdUartDefaultBaudRate),   // BaudRate

+    FixedPcdGet8 (PcdUartDefaultDataBits),    // DataBits

+    FixedPcdGet8 (PcdUartDefaultParity),      // Parity (N)

+    FixedPcdGet8 (PcdUartDefaultStopBits)     // StopBits

+  },

+  { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, sizeof (EFI_DEVICE_PATH_PROTOCOL), 0}

+};

+

+EFI_HANDLE  gHandle = NULL;

+

 /**

   Reset the serial device.

 

@@ -42,8 +67,60 @@
   IN EFI_SERIAL_IO_PROTOCOL  *This

   )

 {

-  SerialPortInitialize ();

-  return EFI_SUCCESS;

+  EFI_STATUS  Status;

+  EFI_TPL     Tpl;

+

+  Status = SerialPortInitialize ();

+  if (EFI_ERROR(Status)) {

+    return Status;

+  }

+

+  //

+  // Set the Serial I/O mode and update the device path

+  //

+

+  Tpl = gBS->RaiseTPL (TPL_NOTIFY);

+

+  //

+  // Set the Serial I/O mode

+  //

+  This->Mode->ReceiveFifoDepth  = 0;

+  This->Mode->Timeout           = 1000000;

+  This->Mode->BaudRate          = PcdGet64 (PcdUartDefaultBaudRate);

+  This->Mode->DataBits          = (UINT32)PcdGet8 (PcdUartDefaultDataBits);

+  This->Mode->Parity            = (UINT32)PcdGet8 (PcdUartDefaultParity);

+  This->Mode->StopBits          = (UINT32)PcdGet8 (PcdUartDefaultStopBits);

+

+  //

+  // Check if the device path has actually changed

+  //

+  if (mDevicePath.Uart.BaudRate == This->Mode->BaudRate &&

+      mDevicePath.Uart.DataBits == (UINT8)This->Mode->DataBits &&

+      mDevicePath.Uart.Parity   == (UINT8)This->Mode->Parity &&

+      mDevicePath.Uart.StopBits == (UINT8)This->Mode->StopBits

+     ) {

+    gBS->RestoreTPL (Tpl);

+    return EFI_SUCCESS;

+  }

+

+  //

+  // Update the device path

+  //

+  mDevicePath.Uart.BaudRate = This->Mode->BaudRate;

+  mDevicePath.Uart.DataBits = (UINT8)This->Mode->DataBits;

+  mDevicePath.Uart.Parity   = (UINT8)This->Mode->Parity;

+  mDevicePath.Uart.StopBits = (UINT8)This->Mode->StopBits;

+

+  Status = gBS->ReinstallProtocolInterface (

+                  gHandle,

+                  &gEfiDevicePathProtocolGuid,

+                  &mDevicePath,

+                  &mDevicePath

+                  );

+

+  gBS->RestoreTPL (Tpl);

+

+  return Status;

 }

 

 

@@ -85,7 +162,60 @@
   IN EFI_STOP_BITS_TYPE      StopBits

   )

 {

-  return EFI_UNSUPPORTED;

+  EFI_STATUS  Status;

+  EFI_TPL     Tpl;

+

+  Status = SerialPortSetAttributes (BaudRate, ReceiveFifoDepth, Timeout, Parity, DataBits, StopBits);

+  if (EFI_ERROR(Status)) {

+    return Status;

+  }

+

+  //

+  // Set the Serial I/O mode and update the device path

+  //

+

+  Tpl = gBS->RaiseTPL (TPL_NOTIFY);

+

+  //

+  // Set the Serial I/O mode

+  //

+  This->Mode->BaudRate          = BaudRate;

+  This->Mode->ReceiveFifoDepth  = ReceiveFifoDepth;

+  This->Mode->Timeout           = Timeout;

+  This->Mode->Parity            = (UINT32)Parity;

+  This->Mode->DataBits          = (UINT32)DataBits;

+  This->Mode->StopBits          = (UINT32)StopBits;

+

+  //

+  // Check if the device path has actually changed

+  //

+  if (mDevicePath.Uart.BaudRate == BaudRate &&

+      mDevicePath.Uart.Parity   == (UINT8)Parity &&

+      mDevicePath.Uart.DataBits == DataBits &&

+      mDevicePath.Uart.StopBits == (UINT8)StopBits

+     ) {

+    gBS->RestoreTPL (Tpl);

+    return EFI_SUCCESS;

+  }

+

+  //

+  // Update the device path

+  //

+  mDevicePath.Uart.BaudRate = BaudRate;

+  mDevicePath.Uart.DataBits = DataBits;

+  mDevicePath.Uart.Parity   = (UINT8) Parity;

+  mDevicePath.Uart.StopBits = (UINT8) StopBits;

+

+  Status = gBS->ReinstallProtocolInterface (

+                  gHandle,

+                  &gEfiDevicePathProtocolGuid,

+                  &mDevicePath,

+                  &mDevicePath

+                  );

+

+  gBS->RestoreTPL (Tpl);

+

+  return Status;

 }

 

 

@@ -107,7 +237,7 @@
   IN UINT32                  Control

   )

 {

-  return EFI_UNSUPPORTED;

+  return SerialPortSetControl(Control);

 }

 

 

@@ -128,13 +258,7 @@
   OUT UINT32                 *Control

   )

 {

-  if (SerialPortPoll ()) {

-    // If a character is pending don't set EFI_SERIAL_INPUT_BUFFER_EMPTY

-    *Control = EFI_SERIAL_OUTPUT_BUFFER_EMPTY;

-  } else {

-    *Control = EFI_SERIAL_INPUT_BUFFER_EMPTY | EFI_SERIAL_OUTPUT_BUFFER_EMPTY;

-  }

-  return EFI_SUCCESS;

+  return SerialPortGetControl(Control);

 }

 

 

@@ -162,8 +286,13 @@
   UINTN Count;

   

   Count = SerialPortWrite (Buffer, *BufferSize);

-  *BufferSize = Count;

-  return (Count == 0) ? EFI_DEVICE_ERROR : EFI_SUCCESS;

+

+  if (Count != *BufferSize) {

+    *BufferSize = Count;

+    return EFI_TIMEOUT;

+  }

+

+  return EFI_SUCCESS;

 }

 

 /**

@@ -202,9 +331,6 @@
   return EFI_SUCCESS;

 }

 

-

-EFI_HANDLE  gHandle = NULL;

-

 // 

 // Template used to initialize the GDB Serial IO protocols

 //

@@ -229,29 +355,6 @@
   SerialRead,

   &gSerialIoMode

 };

-  

-typedef struct {

-  VENDOR_DEVICE_PATH        Guid;

-  UART_DEVICE_PATH          Uart;

-  EFI_DEVICE_PATH_PROTOCOL  End;

-} SIMPLE_TEXT_OUT_DEVICE_PATH;

-

-SIMPLE_TEXT_OUT_DEVICE_PATH mDevicePath = {

-  {

-    { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, sizeof (VENDOR_DEVICE_PATH), 0},

-    EFI_CALLER_ID_GUID // Use the drivers GUID

-  },

-  {

-    { MESSAGING_DEVICE_PATH, MSG_UART_DP, sizeof (UART_DEVICE_PATH), 0},

-    0,        // Reserved

-    FixedPcdGet64 (PcdUartDefaultBaudRate),   // BaudRate

-    FixedPcdGet8 (PcdUartDefaultDataBits),    // DataBits

-    FixedPcdGet8 (PcdUartDefaultParity),      // Parity (N)

-    FixedPcdGet8 (PcdUartDefaultStopBits)     // StopBits

-  },

-  { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, sizeof (EFI_DEVICE_PATH_PROTOCOL), 0}

-};

-

 

 /**

   Initialize the state information for the Serial Io Protocol

@@ -273,7 +376,6 @@
 {

   EFI_STATUS      Status;

 

-

   // Make a new handle with Serial IO protocol and its device path on it.

   Status = gBS->InstallMultipleProtocolInterfaces (

                   &gHandle, 

diff --git a/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.c b/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.c
index 2f93140..9a70593 100644
--- a/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.c
+++ b/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.c
@@ -17,6 +17,7 @@
 #include <Base.h>

 #include <Library/DebugLib.h>

 #include <Library/SerialPortLib.h>

+#include <Library/SerialPortExtLib.h>

 #include <Library/PcdLib.h>

 #include <Library/IoLib.h>

 #include <Library/OmapLib.h>

@@ -122,3 +123,57 @@
   }

 }

 

+/**

+  Set the serial device control bits.

+

+  @return    Always return EFI_UNSUPPORTED.

+

+**/

+RETURN_STATUS

+EFIAPI

+SerialPortSetControl (

+  IN UINT32                   Control

+  )

+{

+  return RETURN_SUCCESS;

+}

+

+/**

+  Get the serial device control bits.

+

+  @param  Control                 Control signals read from the serial device.

+

+  @retval EFI_SUCCESS             The control bits were read from the serial device.

+  @retval EFI_DEVICE_ERROR        The serial device is not functioning correctly.

+

+**/

+RETURN_STATUS

+EFIAPI

+SerialPortGetControl (

+  OUT UINT32                  *Control

+  )

+{

+  return RETURN_SUCCESS;

+}

+

+

+/**

+  Set the serial device attributes.

+

+  @return    Always return EFI_UNSUPPORTED.

+

+**/

+RETURN_STATUS

+EFIAPI

+SerialPortSetAttributes (

+  IN UINT64              BaudRate,

+  IN UINT32              ReceiveFifoDepth,

+  IN UINT32              Timeout,

+  IN EFI_PARITY_TYPE     Parity,

+  IN UINT8               DataBits,

+  IN EFI_STOP_BITS_TYPE  StopBits

+  )

+{

+  return RETURN_SUCCESS;

+}

+

diff --git a/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.inf b/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.inf
index c595777..a7d4fad 100644
--- a/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.inf
+++ b/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.inf
@@ -35,6 +35,7 @@
   OmapLib

 

 [Packages]

+  EmbeddedPkg/EmbeddedPkg.dec

   MdePkg/MdePkg.dec

   Omap35xxPkg/Omap35xxPkg.dec