2 Serial driver that layers on top of a Serial Port Library instance.
4 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
5 Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
6 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
8 This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include <Library/UefiBootServicesTableLib.h>
19 #include <Library/SerialPortLib.h>
20 #include <Library/DebugLib.h>
21 #include <Library/PcdLib.h>
22 #include <Protocol/SerialIo.h>
23 #include <Protocol/DevicePath.h>
26 VENDOR_DEVICE_PATH Guid
;
27 UART_DEVICE_PATH Uart
;
28 EFI_DEVICE_PATH_PROTOCOL End
;
32 Reset the serial device.
34 @param This Protocol instance pointer.
36 @retval EFI_SUCCESS The device was reset.
37 @retval EFI_DEVICE_ERROR The serial device could not be reset.
43 IN EFI_SERIAL_IO_PROTOCOL
*This
47 Sets the baud rate, receive FIFO depth, transmit/receive time out, parity,
48 data bits, and stop bits on a serial device.
50 @param This Protocol instance pointer.
51 @param BaudRate The requested baud rate. A BaudRate value of 0 will use the the
52 device's default interface speed.
53 @param ReceiveFifoDepth The requested depth of the FIFO on the receive side of the
54 serial interface. A ReceiveFifoDepth value of 0 will use
55 the device's default FIFO depth.
56 @param Timeout The requested time out for a single character in microseconds.
57 This timeout applies to both the transmit and receive side of the
58 interface. A Timeout value of 0 will use the device's default time
60 @param Parity The type of parity to use on this serial device. A Parity value of
61 DefaultParity will use the device's default parity value.
62 @param DataBits The number of data bits to use on the serial device. A DataBits
63 value of 0 will use the device's default data bit setting.
64 @param StopBits The number of stop bits to use on this serial device. A StopBits
65 value of DefaultStopBits will use the device's default number of
68 @retval EFI_SUCCESS The device was reset.
69 @retval EFI_DEVICE_ERROR The serial device could not be reset.
75 IN EFI_SERIAL_IO_PROTOCOL
*This
,
77 IN UINT32 ReceiveFifoDepth
,
79 IN EFI_PARITY_TYPE Parity
,
81 IN EFI_STOP_BITS_TYPE StopBits
85 Set the control bits on a serial device
87 @param This Protocol instance pointer.
88 @param Control Set the bits of Control that are settable.
90 @retval EFI_SUCCESS The new control bits were set on the serial device.
91 @retval EFI_UNSUPPORTED The serial device does not support this operation.
92 @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
98 IN EFI_SERIAL_IO_PROTOCOL
*This
,
103 Retrieves the status of the control bits on a serial device
105 @param This Protocol instance pointer.
106 @param Control A pointer to return the current Control signals from the serial device.
108 @retval EFI_SUCCESS The control bits were read from the serial device.
109 @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
115 IN EFI_SERIAL_IO_PROTOCOL
*This
,
120 Writes data to a serial device.
122 @param This Protocol instance pointer.
123 @param BufferSize On input, the size of the Buffer. On output, the amount of
124 data actually written.
125 @param Buffer The buffer of data to write
127 @retval EFI_SUCCESS The data was written.
128 @retval EFI_DEVICE_ERROR The device reported an error.
129 @retval EFI_TIMEOUT The data write was stopped due to a timeout.
135 IN EFI_SERIAL_IO_PROTOCOL
*This
,
136 IN OUT UINTN
*BufferSize
,
141 Reads data from a serial device.
143 @param This Protocol instance pointer.
144 @param BufferSize On input, the size of the Buffer. On output, the amount of
145 data returned in Buffer.
146 @param Buffer The buffer to return the data into.
148 @retval EFI_SUCCESS The data was read.
149 @retval EFI_DEVICE_ERROR The device reported an error.
150 @retval EFI_TIMEOUT The data write was stopped due to a timeout.
156 IN EFI_SERIAL_IO_PROTOCOL
*This
,
157 IN OUT UINTN
*BufferSize
,
161 EFI_HANDLE mSerialHandle
= NULL
;
163 SERIAL_DEVICE_PATH mSerialDevicePath
= {
165 { HARDWARE_DEVICE_PATH
, HW_VENDOR_DP
, { sizeof (VENDOR_DEVICE_PATH
), 0} },
166 EFI_CALLER_ID_GUID
// Use the driver's GUID
169 { MESSAGING_DEVICE_PATH
, MSG_UART_DP
, { sizeof (UART_DEVICE_PATH
), 0} },
176 { END_DEVICE_PATH_TYPE
, END_ENTIRE_DEVICE_PATH_SUBTYPE
, { sizeof (EFI_DEVICE_PATH_PROTOCOL
), 0 } }
180 // Template used to initialize the Serial IO protocols.
182 EFI_SERIAL_IO_MODE mSerialIoMode
= {
184 // value field set in SerialDxeInitialize()?
185 //--------- ------------------- -----------------------------
187 1000 * 1000, // Timeout
189 1, // ReceiveFifoDepth
195 EFI_SERIAL_IO_PROTOCOL mSerialIoTemplate
= {
196 SERIAL_IO_INTERFACE_REVISION
,
207 Reset the serial device.
209 @param This Protocol instance pointer.
211 @retval EFI_SUCCESS The device was reset.
212 @retval EFI_DEVICE_ERROR The serial device could not be reset.
218 IN EFI_SERIAL_IO_PROTOCOL
*This
224 Status
= SerialPortInitialize ();
225 if (EFI_ERROR (Status
)) {
230 // Set the Serial I/O mode and update the device path
233 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
236 // Set the Serial I/O mode
238 This
->Mode
->ReceiveFifoDepth
= 1;
239 This
->Mode
->Timeout
= 1000 * 1000;
240 This
->Mode
->BaudRate
= PcdGet64 (PcdUartDefaultBaudRate
);
241 This
->Mode
->DataBits
= (UINT32
) PcdGet8 (PcdUartDefaultDataBits
);
242 This
->Mode
->Parity
= (UINT32
) PcdGet8 (PcdUartDefaultParity
);
243 This
->Mode
->StopBits
= (UINT32
) PcdGet8 (PcdUartDefaultStopBits
);
246 // Check if the device path has actually changed
248 if (mSerialDevicePath
.Uart
.BaudRate
== This
->Mode
->BaudRate
&&
249 mSerialDevicePath
.Uart
.DataBits
== (UINT8
) This
->Mode
->DataBits
&&
250 mSerialDevicePath
.Uart
.Parity
== (UINT8
) This
->Mode
->Parity
&&
251 mSerialDevicePath
.Uart
.StopBits
== (UINT8
) This
->Mode
->StopBits
253 gBS
->RestoreTPL (Tpl
);
258 // Update the device path
260 mSerialDevicePath
.Uart
.BaudRate
= This
->Mode
->BaudRate
;
261 mSerialDevicePath
.Uart
.DataBits
= (UINT8
) This
->Mode
->DataBits
;
262 mSerialDevicePath
.Uart
.Parity
= (UINT8
) This
->Mode
->Parity
;
263 mSerialDevicePath
.Uart
.StopBits
= (UINT8
) This
->Mode
->StopBits
;
265 Status
= gBS
->ReinstallProtocolInterface (
267 &gEfiDevicePathProtocolGuid
,
272 gBS
->RestoreTPL (Tpl
);
278 Sets the baud rate, receive FIFO depth, transmit/receive time out, parity,
279 data bits, and stop bits on a serial device.
281 @param This Protocol instance pointer.
282 @param BaudRate The requested baud rate. A BaudRate value of 0 will use the the
283 device's default interface speed.
284 @param ReceiveFifoDepth The requested depth of the FIFO on the receive side of the
285 serial interface. A ReceiveFifoDepth value of 0 will use
286 the device's default FIFO depth.
287 @param Timeout The requested time out for a single character in microseconds.
288 This timeout applies to both the transmit and receive side of the
289 interface. A Timeout value of 0 will use the device's default time
291 @param Parity The type of parity to use on this serial device. A Parity value of
292 DefaultParity will use the device's default parity value.
293 @param DataBits The number of data bits to use on the serial device. A DataBits
294 value of 0 will use the device's default data bit setting.
295 @param StopBits The number of stop bits to use on this serial device. A StopBits
296 value of DefaultStopBits will use the device's default number of
299 @retval EFI_SUCCESS The device was reset.
300 @retval EFI_DEVICE_ERROR The serial device could not be reset.
305 SerialSetAttributes (
306 IN EFI_SERIAL_IO_PROTOCOL
*This
,
308 IN UINT32 ReceiveFifoDepth
,
310 IN EFI_PARITY_TYPE Parity
,
312 IN EFI_STOP_BITS_TYPE StopBits
318 Status
= SerialPortSetAttributes (&BaudRate
, &ReceiveFifoDepth
, &Timeout
, &Parity
, &DataBits
, &StopBits
);
319 if (EFI_ERROR (Status
)) {
324 // Set the Serial I/O mode and update the device path
327 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
330 // Set the Serial I/O mode
332 This
->Mode
->ReceiveFifoDepth
= ReceiveFifoDepth
;
333 This
->Mode
->Timeout
= Timeout
;
334 This
->Mode
->BaudRate
= BaudRate
;
335 This
->Mode
->DataBits
= (UINT32
) DataBits
;
336 This
->Mode
->Parity
= (UINT32
) Parity
;
337 This
->Mode
->StopBits
= (UINT32
) StopBits
;
340 // Check if the device path has actually changed
342 if (mSerialDevicePath
.Uart
.BaudRate
== BaudRate
&&
343 mSerialDevicePath
.Uart
.DataBits
== DataBits
&&
344 mSerialDevicePath
.Uart
.Parity
== (UINT8
) Parity
&&
345 mSerialDevicePath
.Uart
.StopBits
== (UINT8
) StopBits
347 gBS
->RestoreTPL (Tpl
);
352 // Update the device path
354 mSerialDevicePath
.Uart
.BaudRate
= BaudRate
;
355 mSerialDevicePath
.Uart
.DataBits
= DataBits
;
356 mSerialDevicePath
.Uart
.Parity
= (UINT8
) Parity
;
357 mSerialDevicePath
.Uart
.StopBits
= (UINT8
) StopBits
;
359 Status
= gBS
->ReinstallProtocolInterface (
361 &gEfiDevicePathProtocolGuid
,
366 gBS
->RestoreTPL (Tpl
);
372 Set the control bits on a serial device
374 @param This Protocol instance pointer.
375 @param Control Set the bits of Control that are settable.
377 @retval EFI_SUCCESS The new control bits were set on the serial device.
378 @retval EFI_UNSUPPORTED The serial device does not support this operation.
379 @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
385 IN EFI_SERIAL_IO_PROTOCOL
*This
,
389 return SerialPortSetControl (Control
);
393 Retrieves the status of the control bits on a serial device
395 @param This Protocol instance pointer.
396 @param Control A pointer to return the current Control signals from the serial device.
398 @retval EFI_SUCCESS The control bits were read from the serial device.
399 @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
405 IN EFI_SERIAL_IO_PROTOCOL
*This
,
409 return SerialPortGetControl (Control
);
413 Writes data to a serial device.
415 @param This Protocol instance pointer.
416 @param BufferSize On input, the size of the Buffer. On output, the amount of
417 data actually written.
418 @param Buffer The buffer of data to write
420 @retval EFI_SUCCESS The data was written.
421 @retval EFI_DEVICE_ERROR The device reported an error.
422 @retval EFI_TIMEOUT The data write was stopped due to a timeout.
428 IN EFI_SERIAL_IO_PROTOCOL
*This
,
429 IN OUT UINTN
*BufferSize
,
435 Count
= SerialPortWrite (Buffer
, *BufferSize
);
437 if (Count
!= *BufferSize
) {
446 Reads data from a serial device.
448 @param This Protocol instance pointer.
449 @param BufferSize On input, the size of the Buffer. On output, the amount of
450 data returned in Buffer.
451 @param Buffer The buffer to return the data into.
453 @retval EFI_SUCCESS The data was read.
454 @retval EFI_DEVICE_ERROR The device reported an error.
455 @retval EFI_TIMEOUT The data write was stopped due to a timeout.
461 IN EFI_SERIAL_IO_PROTOCOL
*This
,
462 IN OUT UINTN
*BufferSize
,
470 if (SerialPortPoll ()) {
471 Count
= SerialPortRead (Buffer
, *BufferSize
);
474 if (Count
!= *BufferSize
) {
483 Initialization for the Serial Io Protocol.
485 @param[in] ImageHandle The firmware allocated handle for the EFI image.
486 @param[in] SystemTable A pointer to the EFI System Table.
488 @retval EFI_SUCCESS The entry point is executed successfully.
489 @retval other Some error occurs when executing this entry point.
494 SerialDxeInitialize (
495 IN EFI_HANDLE ImageHandle
,
496 IN EFI_SYSTEM_TABLE
*SystemTable
501 Status
= SerialPortInitialize ();
502 if (EFI_ERROR (Status
)) {
506 mSerialIoMode
.BaudRate
= PcdGet64 (PcdUartDefaultBaudRate
);
507 mSerialIoMode
.DataBits
= (UINT32
) PcdGet8 (PcdUartDefaultDataBits
);
508 mSerialIoMode
.Parity
= (UINT32
) PcdGet8 (PcdUartDefaultParity
);
509 mSerialIoMode
.StopBits
= (UINT32
) PcdGet8 (PcdUartDefaultStopBits
);
510 mSerialDevicePath
.Uart
.BaudRate
= PcdGet64 (PcdUartDefaultBaudRate
);
511 mSerialDevicePath
.Uart
.DataBits
= PcdGet8 (PcdUartDefaultDataBits
);
512 mSerialDevicePath
.Uart
.Parity
= PcdGet8 (PcdUartDefaultParity
);
513 mSerialDevicePath
.Uart
.StopBits
= PcdGet8 (PcdUartDefaultStopBits
);
516 // Make a new handle with Serial IO protocol and its device path on it.
518 Status
= gBS
->InstallMultipleProtocolInterfaces (
520 &gEfiSerialIoProtocolGuid
, &mSerialIoTemplate
,
521 &gEfiDevicePathProtocolGuid
, &mSerialDevicePath
,
524 ASSERT_EFI_ERROR (Status
);