On Mon, 2019-10-28 at 12:20 +0800, Abner Chang wrote: > Serial Port library for U5 series platform. > > Signed-off-by: Abner Chang <abner.ch...@hpe.com> > > Cc: Michael D Kinney <michael.d.kin...@intel.com> > Cc: Ard Biesheuvel <ard.biesheu...@linaro.org> > Cc: Leif Lindholm <leif.lindh...@linaro.org> > Cc: Gilbert Chen <gilbert.c...@hpe.com> > Cc: Palmer Dabbelt <pal...@sifive.com> > Signed-off-by: Abner Chang <abner.ch...@hpe.com> > --- > .../Library/SerialIoLib/SerialIoLib.inf | 38 ++++ > .../Library/SerialIoLib/SerialPortLib.c | 253 > +++++++++++++++++++++ > .../Library/SerialIoLib/U5SerialPortLib.uni | 16 ++ > 3 files changed, 307 insertions(+) > create mode 100644 > Platform/SiFive/U5SeriesPkg/Library/SerialIoLib/SerialIoLib.inf > create mode 100644 > Platform/SiFive/U5SeriesPkg/Library/SerialIoLib/SerialPortLib.c > create mode 100644 > Platform/SiFive/U5SeriesPkg/Library/SerialIoLib/U5SerialPortLib.uni > > diff --git a/Platform/SiFive/U5SeriesPkg/Library/SerialIoLib/SerialIoLib.inf > b/Platform/SiFive/U5SeriesPkg/Library/SerialIoLib/SerialIoLib.inf > new file mode 100644 > index 0000000..0044f84 > --- /dev/null > +++ b/Platform/SiFive/U5SeriesPkg/Library/SerialIoLib/SerialIoLib.inf > @@ -0,0 +1,38 @@ > +## @file > +# Library instance for SerialIo library class > +# > +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights > reserved.<BR> > +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION = 0x0001001b > + BASE_NAME = U5SerialPortLib > + MODULE_UNI_FILE = U5SerialPortLib.uni > + FILE_GUID = FCC4FD2B-2FF6-4FFA-B363-7C1111E5DCE9 > + MODULE_TYPE = BASE > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = SerialPortLib > +# > +# The following information is for reference only and not required by the > build tools. > +# > +# VALID_ARCHITECTURES = RISCV64 > +# > +[Packages] > + MdePkg/MdePkg.dec > + RiscVPlatformPkg/RiscVPlatformPkg.dec > + RiscVPkg/RiscVPkg.dec > + Platform/SiFive/U5SeriesPkg/U5SeriesPkg.dec > + > +[LibraryClasses] > + BaseLib > + IoLib > + RiscVOpensbiLib > + > +[FixedPcd] > + gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdU5UartBase > + > +[Sources] > + SerialPortLib.c > diff --git a/Platform/SiFive/U5SeriesPkg/Library/SerialIoLib/SerialPortLib.c > b/Platform/SiFive/U5SeriesPkg/Library/SerialIoLib/SerialPortLib.c > new file mode 100644 > index 0000000..5e06515 > --- /dev/null > +++ b/Platform/SiFive/U5SeriesPkg/Library/SerialIoLib/SerialPortLib.c > @@ -0,0 +1,253 @@ > +/** @file > + UART Serial Port library functions > + > + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights > reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include <Base.h> > +#include <Library/IoLib.h> > +#include <Library/SerialPortLib.h> > +#include <include/sbi_utils/serial/sifive-uart.h> // Reference to header > file in opensbi > + > +//--------------------------------------------- > +// UART Register Offsets > +//--------------------------------------------- > + > +#define UART_REG_IP 5 > +#define UART_IP_RXWM 0x02 > + > +//--------------------------------------------- > +// UART Settings > +//--------------------------------------------- > + > +#define UART_BAUDRATE 115200 > +#define SYS_CLK 100000000 ^^^^^^^^^^ This should be 1000000000 1GHz, not 100MHz
> + > +BOOLEAN Initiated = FALSE; > + > +/** > + Initialize the serial device hardware. > + > + If no initialization is required, then return RETURN_SUCCESS. > + If the serial device was successfuly initialized, then return > RETURN_SUCCESS. > + If the serial device could not be initialized, then return > RETURN_DEVICE_ERROR. > + > + @retval RETURN_SUCCESS The serial device was initialized. > + @retval RETURN_DEVICE_ERROR The serail device could not be initialized. > + > +**/ > +RETURN_STATUS > +EFIAPI > +SerialPortInitialize ( > + VOID > + ) > +{ > + if (Initiated) { > + return RETURN_SUCCESS; > + } > + if (sifive_uart_init(FixedPcdGet32(PcdU5UartBase), SYS_CLK / 2, > UART_BAUDRATE) != 0) { > + return EFI_DEVICE_ERROR; > + } > + Initiated = TRUE; > + return RETURN_SUCCESS; > +} > + > +/** > + Write data from buffer to serial device. > + > + Writes NumberOfBytes data bytes from Buffer to the serial device. > + The number of bytes actually written to the serial device is returned. > + If the return value is less than NumberOfBytes, then the write operation > failed. > + > + If Buffer is NULL, then ASSERT(). > + > + If NumberOfBytes is zero, then return 0. > + > + @param Buffer Pointer to the data buffer to be written. > + @param NumberOfBytes Number of bytes to written to the serial device. > + > + @retval 0 NumberOfBytes is 0. > + @retval >0 The number of bytes written to the serial device. > + If this value is less than NumberOfBytes, then > the write operation failed. > + > +**/ > +UINTN > +EFIAPI > +SerialPortWrite ( > + IN UINT8 *Buffer, > + IN UINTN NumberOfBytes > + ) > +{ > + UINTN Index; > + > + if (Buffer == NULL || Initiated == FALSE) { > + return 0; > + } > + > + for(Index = 0; Index < NumberOfBytes; Index ++) { > + sifive_uart_putc (Buffer [Index]); > + } > + > + return Index; > +} > + > +/** > + Reads data from a serial device into a buffer. > + > + @param Buffer Pointer to the data buffer to store the data read > from the serial device. > + @param NumberOfBytes Number of bytes to read from the serial device. > + > + @retval 0 NumberOfBytes is 0. > + @retval >0 The number of bytes read from the serial device. > + If this value is less than NumberOfBytes, then > the read operation failed. > + > +**/ > +UINTN > +EFIAPI > +SerialPortRead ( > + OUT UINT8 *Buffer, > + IN UINTN NumberOfBytes > + ) > +{ > + UINTN Index; > + > + if (NULL == Buffer || Initiated == FALSE) { > + return 0; > + } > + > + for(Index = 0; Index < NumberOfBytes; Index ++) { > + Buffer [Index] = (UINT8)sifive_uart_getc (); > + } > + > + return Index; > +} > + > +/** > + Polls a serial device to see if there is any data waiting to be read. > + > + Polls aserial device to see if there is any data waiting to be read. > + If there is data waiting to be read from the serial device, then TRUE is > returned. > + If there is no data waiting to be read from the serial device, then FALSE > is returned. > + > + @retval TRUE Data is waiting to be read from the serial device. > + @retval FALSE There is no data waiting to be read from the > serial device. > + > +**/ > +BOOLEAN > +EFIAPI > +SerialPortPoll ( > + VOID > + ) > +{ > + STATIC volatile UINT32 * const uart = (UINT32 > *)FixedPcdGet32(PcdU5UartBase); > + UINT32 IP; > + > + if (Initiated == FALSE) { > + return FALSE; > + } > + IP = MmioRead32 ((UINTN)(uart + UART_REG_IP)); > + if(IP & UART_IP_RXWM) { > + return TRUE; > + } > + else { > + return FALSE; > + } > +} > + > +/** > + Sets the control bits on a serial device. > + > + @param Control Sets the bits of Control that are settable. > + > + @retval RETURN_SUCCESS The new control bits were set on the serial > device. > + @retval RETURN_UNSUPPORTED The serial device does not support this > operation. > + @retval RETURN_DEVICE_ERROR The serial device is not functioning > correctly. > + > +**/ > +RETURN_STATUS > +EFIAPI > +SerialPortSetControl ( > + IN UINT32 Control > + ) > +{ > + if (Initiated == FALSE) { > + return EFI_NOT_READY; > + } > + return RETURN_SUCCESS; > +} > + > +/** > + Retrieve the status of the control bits on a serial device. > + > + @param Control A pointer to return the current control > signals from the serial device. > + > + @retval RETURN_SUCCESS The control bits were read from the serial > device. > + @retval RETURN_UNSUPPORTED The serial device does not support this > operation. > + @retval RETURN_DEVICE_ERROR The serial device is not functioning > correctly. > + > +**/ > +RETURN_STATUS > +EFIAPI > +SerialPortGetControl ( > + OUT UINT32 *Control > + ) > +{ > + if (Initiated == FALSE) { > + return EFI_NOT_READY; > + } > + *Control = 0; > + return RETURN_SUCCESS; > +} > + > +/** > + Sets the baud rate, receive FIFO depth, transmit/receice time out, parity, > + data bits, and stop bits on a serial device. > + > + @param BaudRate The requested baud rate. A BaudRate value of 0 > will use the > + device's default interface speed. > + On output, the value actually set. > + @param ReveiveFifoDepth The requested depth of the FIFO on the receive > side of the > + serial interface. A ReceiveFifoDepth value of 0 > will use > + the device's default FIFO depth. > + On output, the value actually set. > + @param Timeout The requested time out for a single character in > microseconds. > + This timeout applies to both the transmit and > receive side of the > + interface. A Timeout value of 0 will use the > device's default time > + out value. > + On output, the value actually set. > + @param Parity The type of parity to use on this serial device. > A Parity value of > + DefaultParity will use the device's default > parity value. > + On output, the value actually set. > + @param DataBits The number of data bits to use on the serial > device. A DataBits > + vaule of 0 will use the device's default data > bit setting. > + On output, the value actually set. > + @param StopBits The number of stop bits to use on this serial > device. A StopBits > + value of DefaultStopBits will use the device's > default number of > + stop bits. > + On output, the value actually set. > + > + @retval RETURN_SUCCESS The new attributes were set on the > serial device. > + @retval RETURN_UNSUPPORTED The serial device does not support this > operation. > + @retval RETURN_INVALID_PARAMETER One or more of the attributes has an > unsupported value. > + @retval RETURN_DEVICE_ERROR The serial device is not functioning > correctly. > + > +**/ > +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 > + ) > +{ > + if (Initiated == FALSE) { > + return EFI_NOT_READY; > + } > + return RETURN_SUCCESS; > +} > diff --git > a/Platform/SiFive/U5SeriesPkg/Library/SerialIoLib/U5SerialPortLib.uni > b/Platform/SiFive/U5SeriesPkg/Library/SerialIoLib/U5SerialPortLib.uni > new file mode 100644 > index 0000000..49163bd > --- /dev/null > +++ b/Platform/SiFive/U5SeriesPkg/Library/SerialIoLib/U5SerialPortLib.uni > @@ -0,0 +1,16 @@ > +// /** @file > +// Library instance for SerialIo library class > +// > +// Library instance for SerialIO library class. > +// > +// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR> > +// > +// SPDX-License-Identifier: BSD-2-Clause-Patent > +// > +// **/ > + > + > +#string STR_MODULE_ABSTRACT #language en-US "Library instance > for SerialIO library class" > + > +#string STR_MODULE_DESCRIPTION #language en-US "Library instance > for SerialIO library class." > + -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#50908): https://edk2.groups.io/g/devel/message/50908 Mute This Topic: https://groups.io/mt/38832096/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-