From 9dcfb8e5c8edb262a8e941d119af553205d38b2e Mon Sep 17 00:00:00 2001 From: oliviermartin Date: Fri, 3 Jun 2011 09:31:02 +0000 Subject: [PATCH] ArmPlatformPkg/PL011Uart: Create PL011 UART driver 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 --- .../ArmRealViewEb-RTSM-A8.dsc | 3 + .../ArmRealViewEb-RTSM-A9x2.dsc | 3 + .../ArmVExpressPkg/ArmVExpress-CTA9x4.dsc | 8 + ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c | 137 ++++++++++++++++++ .../Drivers/PL011Uart/PL011Uart.inf | 35 +++++ ArmPlatformPkg/Include/Drivers/PL011Uart.h | 98 +++++++++++-- .../PL011SerialPortLib/PL011SerialPortLib.c | 57 ++------ .../PL011SerialPortLib/PL011SerialPortLib.inf | 10 +- 8 files changed, 295 insertions(+), 56 deletions(-) create mode 100644 ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c create mode 100644 ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf diff --git a/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A8.dsc b/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A8.dsc index edd23569e0..7387bcc037 100644 --- a/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A8.dsc +++ b/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A8.dsc @@ -107,6 +107,9 @@ 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] diff --git a/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A9x2.dsc b/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A9x2.dsc index 537bc95730..5f91b3bc7a 100644 --- a/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A9x2.dsc +++ b/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A9x2.dsc @@ -108,6 +108,9 @@ 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] diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc index bd331259f7..2adbf2dad5 100644 --- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc +++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc @@ -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 @@ -385,6 +387,12 @@ 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 index 0000000000..6e15c97277 --- /dev/null +++ b/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c @@ -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.
+ + 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 + +#include + +/* + + 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 index 0000000000..618c833727 --- /dev/null +++ b/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf @@ -0,0 +1,35 @@ +#/** @file +# +# Component discription file for NorFlashDxe module +# +# Copyright (c) 2011, 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. +# +#**/ + +[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] diff --git a/ArmPlatformPkg/Include/Drivers/PL011Uart.h b/ArmPlatformPkg/Include/Drivers/PL011Uart.h index 237dc15c28..a9ff2e9eb5 100644 --- a/ArmPlatformPkg/Include/Drivers/PL011Uart.h +++ b/ArmPlatformPkg/Include/Drivers/PL011Uart.h @@ -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 @@ -41,23 +39,103 @@ #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 diff --git a/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c b/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c index 54ea28a769..842bbe005b 100644 --- a/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c +++ b/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c @@ -15,9 +15,13 @@ **/ #include -#include + #include +#include +#include + #include + #include /* @@ -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)); } diff --git a/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf b/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf index b9d86946c4..94222fee8c 100644 --- a/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf +++ b/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf @@ -2,7 +2,7 @@ # # Component discription file for NorFlashDxe module # -# Copyright (c) 2010, ARM Ltd. All rights reserved.
+# Copyright (c) 2011, 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 @@ -25,8 +25,14 @@ PL011SerialPortLib.c [LibraryClasses] - IoLib + PL011UartLib + PcdLib [Packages] MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec ArmPlatformPkg/ArmPlatformPkg.dec + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate -- 2.39.2