1 /** @file
2   Serial I/O Port library functions with no library constructor/destructor
3 
4   Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
5   Copyright (c) 2012 - 2016, ARM Ltd. All rights reserved.<BR>
6   Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
7 
8   SPDX-License-Identifier: BSD-2-Clause-Patent
9 
10 **/
11 
12 #include <Base.h>
13 
14 #include <Library/IoLib.h>
15 #include <Library/PcdLib.h>
16 #include <Library/PL011UartClockLib.h>
17 #include <Library/PL011UartLib.h>
18 #include <Library/SerialPortLib.h>
19 
20 /** Initialise the serial device hardware with default settings.
21 
22   @retval RETURN_SUCCESS            The serial device was initialised.
23   @retval RETURN_INVALID_PARAMETER  One or more of the default settings
24                                     has an unsupported value.
25  **/
26 RETURN_STATUS
27 EFIAPI
SerialPortInitialize(VOID)28 SerialPortInitialize (
29   VOID
30   )
31 {
32   UINT64              BaudRate;
33   UINT32              ReceiveFifoDepth;
34   EFI_PARITY_TYPE     Parity;
35   UINT8               DataBits;
36   EFI_STOP_BITS_TYPE  StopBits;
37 
38   BaudRate = FixedPcdGet64 (PcdUartDefaultBaudRate);
39   ReceiveFifoDepth = 0;         // Use default FIFO depth
40   Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity);
41   DataBits = FixedPcdGet8 (PcdUartDefaultDataBits);
42   StopBits = (EFI_STOP_BITS_TYPE) FixedPcdGet8 (PcdUartDefaultStopBits);
43 
44   return PL011UartInitializePort (
45            (UINTN)PcdGet64 (PcdSerialRegisterBase),
46            PL011UartClockGetFreq(),
47            &BaudRate,
48            &ReceiveFifoDepth,
49            &Parity,
50            &DataBits,
51            &StopBits
52            );
53 }
54 
55 /**
56   Write data to serial device.
57 
58   @param  Buffer           Point of data buffer which need to be written.
59   @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
60 
61   @retval 0                Write data failed.
62   @retval !0               Actual number of bytes written to serial device.
63 
64 **/
65 UINTN
66 EFIAPI
SerialPortWrite(IN UINT8 * Buffer,IN UINTN NumberOfBytes)67 SerialPortWrite (
68   IN UINT8     *Buffer,
69   IN UINTN     NumberOfBytes
70   )
71 {
72   return PL011UartWrite ((UINTN)PcdGet64 (PcdSerialRegisterBase), Buffer, NumberOfBytes);
73 }
74 
75 /**
76   Read data from serial device and save the data in buffer.
77 
78   @param  Buffer           Point of data buffer which need to be written.
79   @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
80 
81   @retval 0                Read data failed.
82   @retval !0               Actual number of bytes read from serial device.
83 
84 **/
85 UINTN
86 EFIAPI
SerialPortRead(OUT UINT8 * Buffer,IN UINTN NumberOfBytes)87 SerialPortRead (
88   OUT UINT8     *Buffer,
89   IN  UINTN     NumberOfBytes
90 )
91 {
92   return PL011UartRead ((UINTN)PcdGet64 (PcdSerialRegisterBase), Buffer, NumberOfBytes);
93 }
94 
95 /**
96   Check to see if any data is available to be read from the debug device.
97 
98   @retval TRUE       At least one byte of data is available to be read
99   @retval FALSE      No data is available to be read
100 
101 **/
102 BOOLEAN
103 EFIAPI
SerialPortPoll(VOID)104 SerialPortPoll (
105   VOID
106   )
107 {
108   return PL011UartPoll ((UINTN)PcdGet64 (PcdSerialRegisterBase));
109 }
110 /**
111   Set new attributes to PL011.
112 
113   @param  BaudRate                The baud rate of the serial device. If the
114                                   baud rate is not supported, the speed will
115                                   be reduced down to the nearest supported one
116                                   and the variable's value will be updated
117                                   accordingly.
118   @param  ReceiveFifoDepth        The number of characters the device will
119                                   buffer on input. If the specified value is
120                                   not supported, the variable's value will
121                                   be reduced down to the nearest supported one.
122   @param  Timeout                 If applicable, the number of microseconds the
123                                   device will wait before timing out a Read or
124                                   a Write operation.
125   @param  Parity                  If applicable, this is the EFI_PARITY_TYPE
126                                   that is computed or checked as each character
127                                   is transmitted or received. If the device
128                                   does not support parity, the value is the
129                                   default parity value.
130   @param  DataBits                The number of data bits in each character
131   @param  StopBits                If applicable, the EFI_STOP_BITS_TYPE number
132                                   of stop bits per character. If the device
133                                   does not support stop bits, the value is the
134                                   default stop bit value.
135 
136   @retval EFI_SUCCESS             All attributes were set correctly.
137   @retval EFI_INVALID_PARAMETERS  One or more attributes has an unsupported
138                                   value.
139 
140 **/
141 RETURN_STATUS
142 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)143 SerialPortSetAttributes (
144   IN OUT UINT64              *BaudRate,
145   IN OUT UINT32              *ReceiveFifoDepth,
146   IN OUT UINT32              *Timeout,
147   IN OUT EFI_PARITY_TYPE     *Parity,
148   IN OUT UINT8               *DataBits,
149   IN OUT EFI_STOP_BITS_TYPE  *StopBits
150   )
151 {
152   return PL011UartInitializePort (
153            (UINTN)PcdGet64 (PcdSerialRegisterBase),
154            PL011UartClockGetFreq(),
155            BaudRate,
156            ReceiveFifoDepth,
157            Parity,
158            DataBits,
159            StopBits
160            );
161 }
162 
163 /**
164 
165   Assert or deassert the control signals on a serial port.
166   The following control signals are set according their bit settings :
167   . Request to Send
168   . Data Terminal Ready
169 
170   @param[in]  Control  The following bits are taken into account :
171                        . EFI_SERIAL_REQUEST_TO_SEND : assert/deassert the
172                          "Request To Send" control signal if this bit is
173                          equal to one/zero.
174                        . EFI_SERIAL_DATA_TERMINAL_READY : assert/deassert
175                          the "Data Terminal Ready" control signal if this
176                          bit is equal to one/zero.
177                        . EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE : enable/disable
178                          the hardware loopback if this bit is equal to
179                          one/zero.
180                        . EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE : not supported.
181                        . EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE : enable/
182                          disable the hardware flow control based on CTS (Clear
183                          To Send) and RTS (Ready To Send) control signals.
184 
185   @retval  RETURN_SUCCESS      The new control bits were set on the device.
186   @retval  RETURN_UNSUPPORTED  The device does not support this operation.
187 
188 **/
189 RETURN_STATUS
190 EFIAPI
SerialPortSetControl(IN UINT32 Control)191 SerialPortSetControl (
192   IN UINT32  Control
193   )
194 {
195   return PL011UartSetControl ((UINTN)PcdGet64 (PcdSerialRegisterBase), Control);
196 }
197 
198 /**
199 
200   Retrieve the status of the control bits on a serial device.
201 
202   @param[out]  Control  Status of the control bits on a serial device :
203 
204                         . EFI_SERIAL_DATA_CLEAR_TO_SEND,
205                           EFI_SERIAL_DATA_SET_READY,
206                           EFI_SERIAL_RING_INDICATE,
207                           EFI_SERIAL_CARRIER_DETECT,
208                           EFI_SERIAL_REQUEST_TO_SEND,
209                           EFI_SERIAL_DATA_TERMINAL_READY
210                           are all related to the DTE (Data Terminal Equipment)
211                           and DCE (Data Communication Equipment) modes of
212                           operation of the serial device.
213                         . EFI_SERIAL_INPUT_BUFFER_EMPTY : equal to one if the
214                           receive buffer is empty, 0 otherwise.
215                         . EFI_SERIAL_OUTPUT_BUFFER_EMPTY : equal to one if the
216                           transmit buffer is empty, 0 otherwise.
217                         . EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE : equal to one if
218                           the hardware loopback is enabled (the output feeds
219                           the receive buffer), 0 otherwise.
220                         . EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE : equal to one
221                           if a loopback is accomplished by software, else 0.
222                         . EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE : equal to
223                           one if the hardware flow control based on CTS (Clear
224                           To Send) and RTS (Ready To Send) control signals is
225                           enabled, 0 otherwise.
226 
227   @retval RETURN_SUCCESS  The control bits were read from the device.
228 
229 **/
230 RETURN_STATUS
231 EFIAPI
SerialPortGetControl(OUT UINT32 * Control)232 SerialPortGetControl (
233   OUT UINT32  *Control
234   )
235 {
236   return PL011UartGetControl ((UINTN)PcdGet64 (PcdSerialRegisterBase), Control);
237 }
238