This adds 2 implementations of SerialPortLib for device tree based platforms
using a PL011 UART:
- an 'early' one which is completely stateless and uses only fixed PCDs
- a normal one which takes its base address from a HOB containing the base
  address discovered in the PEI phase

A NULL SerialPortExtLib instance is also provided.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <ler...@redhat.com>
Signed-off-by: Ard Biesheuvel <ard.biesheu...@linaro.org>
---
 .../EarlyFdtPL011SerialPortLib.c                   | 186 +++++++++++++++++++++
 .../EarlyFdtPL011SerialPortLib.inf                 |  45 +++++
 .../FdtPL011SerialPortLib/FdtPL011SerialPortLib.c  | 150 +++++++++++++++++
 .../FdtPL011SerialPortLib.inf                      |  48 ++++++
 .../FdtPL011SerialPortLib/NullSerialPortExtLib.c   |  47 ++++++
 .../FdtPL011SerialPortLib/NullSerialPortExtLib.inf |  30 ++++
 6 files changed, 506 insertions(+)
 create mode 100644 
ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/EarlyFdtPL011SerialPortLib.c
 create mode 100644 
ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/EarlyFdtPL011SerialPortLib.inf
 create mode 100644 
ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c
 create mode 100644 
ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf
 create mode 100644 
ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/NullSerialPortExtLib.c
 create mode 100644 
ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/NullSerialPortExtLib.inf

diff --git 
a/ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/EarlyFdtPL011SerialPortLib.c
 
b/ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/EarlyFdtPL011SerialPortLib.c
new file mode 100644
index 000000000000..67c80003bde5
--- /dev/null
+++ 
b/ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/EarlyFdtPL011SerialPortLib.c
@@ -0,0 +1,186 @@
+/** @file
+  Serial I/O Port library functions with base address discovered from FDT
+
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+  Copyright (c) 2012 - 2013, ARM Ltd. All rights reserved.<BR>
+  Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#include <Base.h>
+
+#include <Library/PcdLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/SerialPortExtLib.h>
+#include <libfdt.h>
+
+#include <Drivers/PL011Uart.h>
+
+RETURN_STATUS
+EFIAPI
+SerialPortInitialize (
+  VOID
+  )
+{
+  //
+  // This SerialPortInitialize() function is completely empty, for a number of
+  // reasons:
+  // - if we are executing from flash, it is hard to keep state (i.e., store 
the
+  //   discovered base address in a global), and the most robust way to deal
+  //   with this is to discover the base address at every Write ();
+  // - calls to the Write() function in this module may be issued before this
+  //   initialization function is called: this is not a problem when the base
+  //   address of the UART is hardcoded, and only the baud rate may be wrong,
+  //   but if we don't know the base address yet, we may be poking into memory
+  //   that does not tolerate being poked into;
+  // - SEC and PEI phases produce debug output only, so with debug disabled, no
+  //   initialization (or device tree parsing) is performed at all.
+  //
+  // Note that this means that on *every* Write () call, the device tree will 
be
+  // parsed and the UART re-initialized. However, this is a small price to pay
+  // for having serial debug output on a UART with no fixed base address.
+  //
+  return RETURN_SUCCESS;
+}
+
+STATIC
+UINT64
+SerialPortGetBaseAddress (
+  VOID
+  )
+{
+  UINT64              BaudRate;
+  UINT32              ReceiveFifoDepth;
+  EFI_PARITY_TYPE     Parity;
+  UINT8               DataBits;
+  EFI_STOP_BITS_TYPE  StopBits;
+  VOID                *DeviceTreeBase;
+  INT32               Node, Prev;
+
+  DeviceTreeBase = (VOID *)(UINTN)FixedPcdGet64 
(PcdDeviceTreeInitialBaseAddress);
+
+  if (DeviceTreeBase == NULL || fdt_check_header (DeviceTreeBase) != 0) {
+    return 0;
+  }
+
+  //
+  // Enumerate all FDT nodes looking for a PL011 and capture its base address
+  //
+  for (Prev = 0;; Prev = Node) {
+    INT32        Len;
+    CONST CHAR8  *Compatible;
+    CONST CHAR8  *CompItem;
+
+    Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
+    if (Node < 0) {
+      break;
+    }
+
+    Compatible = fdt_getprop (DeviceTreeBase, Node, "compatible", &Len);
+    if (Compatible == NULL) {
+      continue;
+    }
+
+    //
+    // Iterate over the NULL-separated items in the compatible string
+    //
+    for (CompItem = Compatible; CompItem < Compatible + Len;
+      CompItem += 1 + AsciiStrLen (CompItem)) {
+
+      if (AsciiStrCmp (CompItem, "arm,pl011") == 0) {
+        CONST UINT64   *RegProp;
+        UINTN         UartBase;
+        RETURN_STATUS  Status;
+
+        RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
+        if (Len != 16) {
+          return 0;
+        }
+        UartBase = (UINTN)fdt64_to_cpu(RegProp[0]);
+
+        BaudRate = (UINTN)FixedPcdGet64 (PcdUartDefaultBaudRate);
+        ReceiveFifoDepth = 0; // Use the default value for Fifo depth
+        Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity);
+        DataBits = FixedPcdGet8 (PcdUartDefaultDataBits);
+        StopBits = (EFI_STOP_BITS_TYPE) FixedPcdGet8 (PcdUartDefaultStopBits);
+
+        Status = PL011UartInitializePort (
+                   UartBase,
+                   &BaudRate, &ReceiveFifoDepth, &Parity, &DataBits, 
&StopBits);
+        if (Status == RETURN_SUCCESS) {
+          return UartBase;
+        }
+      }
+    }
+  }
+  return 0;
+}
+
+/**
+  Write data to serial device.
+
+  @param  Buffer           Point of data buffer which need to be written.
+  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
+
+  @retval 0                Write data failed.
+  @retval !0               Actual number of bytes written to serial device.
+
+**/
+UINTN
+EFIAPI
+SerialPortWrite (
+  IN UINT8     *Buffer,
+  IN UINTN     NumberOfBytes
+  )
+{
+  UINT64 SerialRegisterBase;
+
+  SerialRegisterBase = SerialPortGetBaseAddress ();
+  if (SerialRegisterBase != 0);
+    return PL011UartWrite ((UINTN)SerialRegisterBase, Buffer, NumberOfBytes);
+  return 0;
+}
+
+/**
+  Read data from serial device and save the data in buffer.
+
+  @param  Buffer           Point of data buffer which need to be written.
+  @param  NumberOfBytes    Size of Buffer[].
+
+  @retval 0                Read data failed.
+  @retval !0               Actual number of bytes read from serial device.
+
+**/
+UINTN
+EFIAPI
+SerialPortRead (
+  OUT UINT8     *Buffer,
+  IN  UINTN     NumberOfBytes
+)
+{
+  return 0;
+}
+
+/**
+  Check to see if any data is available to be read from the debug device.
+
+  @retval TRUE       At least one byte of data is available to be read
+  @retval FALSE      No data is available to be read
+
+**/
+BOOLEAN
+EFIAPI
+SerialPortPoll (
+  VOID
+  )
+{
+  return FALSE;
+}
diff --git 
a/ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/EarlyFdtPL011SerialPortLib.inf
 
b/ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/EarlyFdtPL011SerialPortLib.inf
new file mode 100644
index 000000000000..d62f87bc302d
--- /dev/null
+++ 
b/ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/EarlyFdtPL011SerialPortLib.inf
@@ -0,0 +1,45 @@
+#/** @file
+#
+#  Component description file for EarlyFdtPL011SerialPortLib module
+#
+#  Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+#
+#  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.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = EarlyFdtPL011SerialPortLib
+  FILE_GUID                      = 0983616A-49BC-4732-B531-4AF98D2056F0
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SerialPortLib|SEC PEI_CORE PEIM
+
+[Sources.common]
+  EarlyFdtPL011SerialPortLib.c
+
+[LibraryClasses]
+  PL011UartLib
+  PcdLib
+  FdtLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
+
+[FixedPcd]
+  gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
+
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits
diff --git 
a/ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c
 
b/ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c
new file mode 100644
index 000000000000..f46293181b33
--- /dev/null
+++ 
b/ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c
@@ -0,0 +1,150 @@
+/** @file
+  Serial I/O Port library functions with base address discovered from FDT
+
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+  Copyright (c) 2012 - 2013, ARM Ltd. All rights reserved.<BR>
+  Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
+  Copyright (c) 2014, Red Hat, Inc.<BR>
+
+  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.
+
+**/
+
+#include <Base.h>
+
+#include <Library/PcdLib.h>
+#include <Library/SerialPortLib.h>
+#include <Pi/PiBootMode.h>
+#include <Uefi/UefiBaseType.h>
+#include <Uefi/UefiMultiPhase.h>
+#include <Pi/PiHob.h>
+#include <Library/HobLib.h>
+#include <Guid/EarlyPL011BaseAddress.h>
+
+#include <Drivers/PL011Uart.h>
+
+UINTN mSerialBaseAddress;
+
+RETURN_STATUS
+EFIAPI
+SerialPortInitialize (
+  VOID
+  )
+{
+  return RETURN_SUCCESS;
+}
+
+/**
+
+  Program hardware of Serial port
+
+  @return    RETURN_NOT_FOUND if no PL011 base address could be found
+             Otherwise, result of PL011UartInitializePort () is returned
+
+**/
+RETURN_STATUS
+EFIAPI
+FdtPL011SerialPortLibInitialize (
+  VOID
+  )
+{
+  VOID                *Hob;
+  CONST UINT64        *UartBase;
+  UINT64              BaudRate;
+  UINT32              ReceiveFifoDepth;
+  EFI_PARITY_TYPE     Parity;
+  UINT8               DataBits;
+  EFI_STOP_BITS_TYPE  StopBits;
+
+  Hob = GetFirstGuidHob (&gEarlyPL011BaseAddressGuid);
+  if (Hob == NULL || GET_GUID_HOB_DATA_SIZE (Hob) != sizeof *UartBase) {
+    return RETURN_NOT_FOUND;
+  }
+  UartBase = GET_GUID_HOB_DATA (Hob);
+
+  mSerialBaseAddress = (UINTN)*UartBase;
+  if (mSerialBaseAddress == 0) {
+    return RETURN_NOT_FOUND;
+  }
+
+  BaudRate = (UINTN)PcdGet64 (PcdUartDefaultBaudRate);
+  ReceiveFifoDepth = 0; // Use the default value for Fifo depth
+  Parity = (EFI_PARITY_TYPE)PcdGet8 (PcdUartDefaultParity);
+  DataBits = PcdGet8 (PcdUartDefaultDataBits);
+  StopBits = (EFI_STOP_BITS_TYPE) PcdGet8 (PcdUartDefaultStopBits);
+
+  return PL011UartInitializePort (
+           mSerialBaseAddress, &BaudRate, &ReceiveFifoDepth,
+           &Parity, &DataBits, &StopBits);
+}
+
+/**
+  Write data to serial device.
+
+  @param  Buffer           Point of data buffer which need to be written.
+  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
+
+  @retval 0                Write data failed.
+  @retval !0               Actual number of bytes written to serial device.
+
+**/
+UINTN
+EFIAPI
+SerialPortWrite (
+  IN UINT8     *Buffer,
+  IN UINTN     NumberOfBytes
+  )
+{
+  if (mSerialBaseAddress != 0) {
+    return PL011UartWrite (mSerialBaseAddress, Buffer, NumberOfBytes);
+  }
+  return 0;
+}
+
+/**
+  Read data from serial device and save the data in buffer.
+
+  @param  Buffer           Point of data buffer which need to be written.
+  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
+
+  @retval 0                Read data failed.
+  @retval !0               Actual number of bytes read from serial device.
+
+**/
+UINTN
+EFIAPI
+SerialPortRead (
+  OUT UINT8     *Buffer,
+  IN  UINTN     NumberOfBytes
+)
+{
+  if (mSerialBaseAddress != 0) {
+    return PL011UartRead (mSerialBaseAddress, Buffer, NumberOfBytes);
+  }
+  return 0;
+}
+
+/**
+  Check to see if any data is available to be read from the debug device.
+
+  @retval TRUE       At least one byte of data is available to be read
+  @retval FALSE      No data is available to be read
+
+**/
+BOOLEAN
+EFIAPI
+SerialPortPoll (
+  VOID
+  )
+{
+  if (mSerialBaseAddress != 0) {
+    return PL011UartPoll (mSerialBaseAddress);
+  }
+  return FALSE;
+}
diff --git 
a/ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf
 
b/ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf
new file mode 100644
index 000000000000..81c47f1aec4b
--- /dev/null
+++ 
b/ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf
@@ -0,0 +1,48 @@
+#/** @file
+#
+#  Component description file for PL011SerialPortLib module
+#
+#  Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+#
+#  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.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = FdtPL011SerialPortLib
+  FILE_GUID                      = 0983616A-49BC-4732-B531-4AF98D2056F0
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SerialPortLib|DXE_CORE DXE_DRIVER 
UEFI_DRIVER DXE_RUNTIME_DRIVER
+  CONSTRUCTOR                    = FdtPL011SerialPortLibInitialize
+
+[Sources.common]
+  FdtPL011SerialPortLib.c
+
+[LibraryClasses]
+  PL011UartLib
+  HobLib
+
+[Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
+  ArmPkg/ArmPkg.dec
+
+[FixedPcd]
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits
+
+[Guids]
+  gEarlyPL011BaseAddressGuid
diff --git 
a/ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/NullSerialPortExtLib.c
 
b/ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/NullSerialPortExtLib.c
new file mode 100644
index 000000000000..5e0f06852584
--- /dev/null
+++ 
b/ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/NullSerialPortExtLib.c
@@ -0,0 +1,47 @@
+/** @file
+
+  Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#include <Library/SerialPortExtLib.h>
+
+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_SUCCESS;
+}
+
+RETURN_STATUS
+EFIAPI
+SerialPortSetControl (
+  IN UINT32                  Control
+  )
+{
+  return RETURN_SUCCESS;
+}
+
+RETURN_STATUS
+EFIAPI
+SerialPortGetControl (
+  OUT UINT32                  *Control
+  )
+{
+  return RETURN_SUCCESS;
+}
diff --git 
a/ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/NullSerialPortExtLib.inf
 
b/ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/NullSerialPortExtLib.inf
new file mode 100644
index 000000000000..6985c15c66e6
--- /dev/null
+++ 
b/ArmPlatformPkg/ArmVirtualizationPkg/Library/FdtPL011SerialPortLib/NullSerialPortExtLib.inf
@@ -0,0 +1,30 @@
+#/** @file
+#
+#  Component description file for PL011SerialPortLib module
+#
+#  Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+#
+#  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.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = NullSerialPortExtLib
+  FILE_GUID                      = BD396D28-085E-477A-A5DE-A8D91DD1F752
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SerialPortExtLib
+
+[Sources.common]
+  NullSerialPortExtLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
-- 
1.8.3.2


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to