ArmPlatformPkg/PL011Uart: Create PL011 UART driver
authoroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 3 Jun 2011 09:31:02 +0000 (09:31 +0000)
committeroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 3 Jun 2011 09:31:02 +0000 (09:31 +0000)
This library makes the interface with the PL011 UART controller.
This library can be linked to different types of driver (Serial Console,
debugger, etc) using PL011 UART controller.

ArmPlatformPkg/PL011SerialPortLib: Use Drivers/PL011Uart

Remove the direct accesses to the PL011 UART controller to use the PL011Uart
library.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11743 6f19259b-4bc3-4df7-8a09-765794883524

ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A8.dsc
ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A9x2.dsc
ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc
ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c [new file with mode: 0644]
ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf [new file with mode: 0644]
ArmPlatformPkg/Include/Drivers/PL011Uart.h
ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c
ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf

index edd2356..7387bcc 100644 (file)
   GdbSerialLib|ArmPlatformPkg/ArmRealViewEbPkg/Library/GdbSerialLib/GdbSerialLib.inf\r
   DmaLib|ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf\r
   \r
+  # ARM PL011 UART Driver\r
+  PL011UartLib|ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf\r
+\r
   BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf\r
 \r
 [LibraryClasses.common.SEC]\r
index 537bc95..5f91b3b 100644 (file)
   GdbSerialLib|ArmPlatformPkg/ArmRealViewEbPkg/Library/GdbSerialLib/GdbSerialLib.inf
   DmaLib|ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
   
+  # ARM PL011 UART Driver
+  PL011UartLib|ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
+
   BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
 
 [LibraryClasses.common.SEC]
index bd33125..2adbf2d 100644 (file)
@@ -99,6 +99,8 @@
   PL341DmcLib|ArmPkg/Drivers/PL34xDmc/PL341Dmc.inf
   # ARM PL301 Axi Driver
   PL301AxiLib|ArmPkg/Drivers/PL301Axi/PL301Axi.inf
+  # ARM PL011 UART Driver
+  PL011UartLib|ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
 
 #
 # Assume everything is fixed at build
   gArmTokenSpaceGuid.PcdPL180SysMciRegAddress|0x10000048
   gArmTokenSpaceGuid.PcdPL180MciBaseAddress|0x10005000
 
+  #
+  # ARM PL011 - Serial Terminal
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x10009000
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|38400
+  
   #
   # ARM PL390 General Interrupt Controller
   #
diff --git a/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c b/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c
new file mode 100644 (file)
index 0000000..6e15c97
--- /dev/null
@@ -0,0 +1,137 @@
+/** @file
+  Serial I/O Port library functions with no library constructor/destructor
+
+
+  Copyright (c) 2008 - 2010, Apple Inc. 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 <Include/Uefi.h>
+
+#include <Library/IoLib.h>
+
+#include <Drivers/PL011Uart.h>
+
+/*
+
+  Programmed hardware of Serial port.
+
+  @return    Always return EFI_UNSUPPORTED.
+
+**/
+RETURN_STATUS
+EFIAPI
+PL011UartInitialize (
+  IN  UINTN       UartBase,
+  IN  UINTN       BaudRate,
+  IN  UINTN       LineControl
+  )
+{
+       if (BaudRate == 115200) {
+               // Initialize baud rate generator
+               MmioWrite32 (UartBase + UARTIBRD, UART_115200_IDIV);
+               MmioWrite32 (UartBase + UARTFBRD, UART_115200_FDIV);
+       } else if (BaudRate == 38400) {
+               // Initialize baud rate generator
+               MmioWrite32 (UartBase + UARTIBRD, UART_38400_IDIV);
+               MmioWrite32 (UartBase + UARTFBRD, UART_38400_FDIV);
+       } else if (BaudRate == 19200) {
+               // Initialize baud rate generator
+               MmioWrite32 (UartBase + UARTIBRD, UART_19200_IDIV);
+               MmioWrite32 (UartBase + UARTFBRD, UART_19200_FDIV);
+       } else {
+               return EFI_INVALID_PARAMETER;
+       }
+
+  // No parity, 1 stop, no fifo, 8 data bits
+  MmioWrite32 (UartBase + UARTLCR_H, LineControl);
+
+  // Clear any pending errors
+  MmioWrite32 (UartBase + UARTECR, 0);
+
+  // Enable tx, rx, and uart overall
+  MmioWrite32 (UartBase + UARTCR, PL011_UARTCR_RXE | PL011_UARTCR_TXE | PL011_UARTCR_UARTEN);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+PL011UartWrite (
+  IN  UINTN    UartBase,
+  IN UINT8     *Buffer,
+  IN UINTN     NumberOfBytes
+  )
+{
+       UINTN  Count;
+
+       for (Count = 0; Count < NumberOfBytes; Count++, Buffer++) {
+               while ((MmioRead32 (UartBase + UARTFR) & UART_TX_EMPTY_FLAG_MASK) == 0);
+               MmioWrite8 (UartBase + UARTDR, *Buffer);
+       }
+
+       return NumberOfBytes;
+}
+
+/**
+  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
+PL011UartRead (
+  IN  UINTN     UartBase,
+  OUT UINT8     *Buffer,
+  IN  UINTN     NumberOfBytes
+  )
+{
+  UINTN   Count;
+
+       for (Count = 0; Count < NumberOfBytes; Count++, Buffer++) {
+               while ((MmioRead32 (UartBase + UARTFR) & UART_RX_EMPTY_FLAG_MASK) != 0);
+               *Buffer = MmioRead8 (UartBase + UARTDR);
+       }
+
+       return NumberOfBytes;
+}
+
+/**
+  Check to see if any data is available to be read from the debug device.
+
+  @retval EFI_SUCCESS       At least one byte of data is available to be read
+  @retval EFI_NOT_READY     No data is available to be read
+  @retval EFI_DEVICE_ERROR  The serial device is not functioning properly
+
+**/
+BOOLEAN
+EFIAPI
+PL011UartPoll (
+  IN  UINTN     UartBase
+  )
+{
+  return ((MmioRead32 (UartBase + UARTFR) & UART_RX_EMPTY_FLAG_MASK) == 0);
+}
diff --git a/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf b/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
new file mode 100644 (file)
index 0000000..618c833
--- /dev/null
@@ -0,0 +1,35 @@
+#/** @file
+#  
+#  Component discription file for NorFlashDxe module
+#  
+#  Copyright (c) 2011, 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                      = PL011Uart
+  FILE_GUID                      = 4ec8b120-8307-11e0-bc91-0002a5d5c51b 
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PL011UartLib
+
+[Sources.common]
+  PL011Uart.c
+
+[LibraryClasses]
+  IoLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+#  MdeModulePkg/MdeModulePkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+
+[Pcd]
index 237dc15..a9ff2e9 100644 (file)
@@ -15,8 +15,6 @@
 #ifndef __PL011_UART_H__
 #define __PL011_UART_H__
 
-#define SERIAL_PORT_MAX_TIMEOUT            100000000    // 100 seconds
-
 // PL011 Registers
 #define UARTDR          0x000
 #define UARTRSR         0x004
 #define UART_19200_IDIV       12
 #define UART_19200_FDIV       37
 
-// data status bits
+// Data status bits
 #define UART_DATA_ERROR_MASK      0x0F00
 
-// status reg bits
+// Status reg bits
 #define UART_STATUS_ERROR_MASK    0x0F
 
-// flag reg bits
+// Flag reg bits
 #define UART_TX_EMPTY_FLAG_MASK   0x80
 #define UART_RX_FULL_FLAG_MASK    0x40
 #define UART_TX_FULL_FLAG_MASK    0x20
 #define UART_RX_EMPTY_FLAG_MASK   0x10
 #define UART_BUSY_FLAG_MASK       0x08
 
-// control reg bits
-#define UART_CTSEN_CONTROL_MASK   0x8000
-#define UART_RTSEN_CONTROL_MASK   0x4000
-#define UART_RTS_CONTROL_MASK     0x0800
-#define UART_DTR_CONTROL_MASK     0x0400
+// Control reg bits
+#define PL011_UARTCR_CTSEN        (1 << 15) // CTS hardware flow control enable
+#define PL011_UARTCR_RTSEN        (1 << 14) // RTS hardware flow control enable
+#define PL011_UARTCR_RTS          (1 << 11) // Request to send
+#define PL011_UARTCR_DTR          (1 << 10) // Data transmit ready.
+#define PL011_UARTCR_RXE          (1 << 9)  // Receive enable
+#define PL011_UARTCR_TXE          (1 << 8)  // Transmit enable
+#define PL011_UARTCR_UARTEN       (1 << 0)  // UART Enable
+
+// Line Control Register Bits
+#define PL011_UARTLCR_H_SPS       (1 << 7)  // Stick parity select
+#define PL011_UARTLCR_H_WLEN_8    (3 << 5)
+#define PL011_UARTLCR_H_WLEN_7    (2 << 5)
+#define PL011_UARTLCR_H_WLEN_6    (1 << 5)
+#define PL011_UARTLCR_H_WLEN_5    (0 << 5)
+#define PL011_UARTLCR_H_FEN       (1 << 4)  // FIFOs Enable
+#define PL011_UARTLCR_H_STP2      (1 << 3)  // Two stop bits select
+#define PL011_UARTLCR_H_EPS       (1 << 2)  // Even parity select
+#define PL011_UARTLCR_H_PEN       (1 << 1)  // Parity Enable
+#define PL011_UARTLCR_H_BRK       (1 << 0)  // Send break
+
+/*
+
+  Programmed hardware of Serial port.
+
+  @return    Always return EFI_UNSUPPORTED.
+
+**/
+RETURN_STATUS
+EFIAPI
+PL011UartInitialize (
+  IN  UINTN       UartBase,
+  IN  UINTN       BaudRate,
+  IN  UINTN       LineControl
+  );
+
+/**
+  Write data to serial device.
+
+  @param  Buffer           Point of data buffer which need to be writed.
+  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
+
+  @retval 0                Write data failed.
+  @retval !0               Actual number of bytes writed to serial device.
+
+**/
+UINTN
+EFIAPI
+PL011UartWrite (
+  IN  UINTN       UartBase,
+  IN UINT8     *Buffer,
+  IN UINTN     NumberOfBytes
+  );
+
+/**
+  Read data from serial device and save the datas in buffer.
+
+  @param  Buffer           Point of data buffer which need to be writed.
+  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
+
+  @retval 0                Read data failed.
+  @retval !0               Aactual number of bytes read from serial device.
+
+**/
+UINTN
+EFIAPI
+PL011UartRead (
+  IN  UINTN       UartBase,
+  OUT UINT8     *Buffer,
+  IN  UINTN     NumberOfBytes
+  );
+
+/**
+  Check to see if any data is avaiable to be read from the debug device.
+
+  @retval EFI_SUCCESS       At least one byte of data is avaiable to be read
+  @retval EFI_NOT_READY     No data is avaiable to be read
+  @retval EFI_DEVICE_ERROR  The serial device is not functioning properly
+
+**/
+BOOLEAN
+EFIAPI
+PL011UartPoll (
+  IN  UINTN     UartBase
+  );
 
 #endif
index 54ea28a..842bbe0 100644 (file)
 **/
 
 #include <Include/Uefi.h>
-#include <Library/SerialPortLib.h>
+
 #include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/SerialPortLib.h>
+
 #include <Drivers/PL011Uart.h>
+
 #include <ArmPlatform.h>
 
 /*
@@ -33,32 +37,11 @@ SerialPortInitialize (
   VOID
   )
 {
-       if (PL011_CONSOLE_UART_SPEED == 115200) {
-               // Initialize baud rate generator
-               MmioWrite32 (PL011_CONSOLE_UART_BASE + UARTIBRD, UART_115200_IDIV);
-               MmioWrite32 (PL011_CONSOLE_UART_BASE + UARTFBRD, UART_115200_FDIV);
-       } else if (PL011_CONSOLE_UART_SPEED == 38400) {
-               // Initialize baud rate generator
-               MmioWrite32 (PL011_CONSOLE_UART_BASE + UARTIBRD, UART_38400_IDIV);
-               MmioWrite32 (PL011_CONSOLE_UART_BASE + UARTFBRD, UART_38400_FDIV);
-       } else if (PL011_CONSOLE_UART_SPEED == 19200) {
-               // Initialize baud rate generator
-               MmioWrite32 (PL011_CONSOLE_UART_BASE + UARTIBRD, UART_19200_IDIV);
-               MmioWrite32 (PL011_CONSOLE_UART_BASE + UARTFBRD, UART_19200_FDIV);
-       } else {
-               return EFI_INVALID_PARAMETER;
-       }
-
   // No parity, 1 stop, no fifo, 8 data bits
-  MmioWrite32 (PL011_CONSOLE_UART_BASE + UARTLCR_H, 0x60);
-
-  // Clear any pending errors
-  MmioWrite32 (PL011_CONSOLE_UART_BASE + UARTECR, 0);
-
-  // enable tx, rx, and uart overall
-  MmioWrite32 (PL011_CONSOLE_UART_BASE + UARTCR, 0x301);
-
-  return EFI_SUCCESS;
+  return PL011UartInitialize (
+      (UINTN)PcdGet64 (PcdSerialRegisterBase),
+      (UINTN)PcdGet64 (PcdUartDefaultBaudRate),
+      PL011_UARTLCR_H_WLEN_8);
 }
 
 /**
@@ -76,16 +59,9 @@ EFIAPI
 SerialPortWrite (
   IN UINT8     *Buffer,
   IN UINTN     NumberOfBytes
-)
+  )
 {
-       UINTN  Count;
-
-       for (Count = 0; Count < NumberOfBytes; Count++, Buffer++) {
-               while ((MmioRead32 (PL011_CONSOLE_UART_BASE + UARTFR) & UART_TX_EMPTY_FLAG_MASK) == 0);
-               MmioWrite8 (PL011_CONSOLE_UART_BASE + UARTDR, *Buffer);
-       }
-
-       return NumberOfBytes;
+  return PL011UartWrite ((UINTN)PcdGet64 (PcdSerialRegisterBase), Buffer, NumberOfBytes);
 }
 
 /**
@@ -105,14 +81,7 @@ SerialPortRead (
   IN  UINTN     NumberOfBytes
 )
 {
-  UINTN   Count;
-
-       for (Count = 0; Count < NumberOfBytes; Count++, Buffer++) {
-               while ((MmioRead32 (PL011_CONSOLE_UART_BASE + UARTFR) & UART_RX_EMPTY_FLAG_MASK) != 0);
-               *Buffer = MmioRead8 (PL011_CONSOLE_UART_BASE + UARTDR);
-       }
-
-       return NumberOfBytes;
+  return PL011UartRead ((UINTN)PcdGet64 (PcdSerialRegisterBase), Buffer, NumberOfBytes);
 }
 
 /**
@@ -129,5 +98,5 @@ SerialPortPoll (
   VOID
   )
 {
-  return ((MmioRead32 (PL011_CONSOLE_UART_BASE + UARTFR) & UART_RX_EMPTY_FLAG_MASK) == 0);
+  return PL011UartPoll ((UINTN)PcdGet64 (PcdSerialRegisterBase));
 }
index b9d8694..94222fe 100644 (file)
@@ -2,7 +2,7 @@
 #  
 #  Component discription file for NorFlashDxe module
 #  
-#  Copyright (c) 2010, ARM Ltd. All rights reserved.<BR>
+#  Copyright (c) 2011, 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
   PL011SerialPortLib.c
 
 [LibraryClasses]
-  IoLib
+  PL011UartLib
+  PcdLib
 
 [Packages]
   MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
   ArmPlatformPkg/ArmPlatformPkg.dec
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate