2 Serial driver for standard UARTS on an ISA bus.
4 Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved. <BR>
5 This software and associated documentation (if any) is furnished
6 under a license and may only be used or copied in accordance
7 with the terms of the license. Except as permitted by such
8 license, no part of this software or documentation may be
9 reproduced, stored in a retrieval system, or transmitted in any
10 form or by any means without the express written consent of
18 // ISA Serial Driver Global Variables
20 EFI_DRIVER_BINDING_PROTOCOL gSerialControllerDriver
= {
21 SerialControllerDriverSupported
,
22 SerialControllerDriverStart
,
23 SerialControllerDriverStop
,
31 The user Entry Point for module IsaSerial. The user code starts with this function.
33 @param[in] ImageHandle The firmware allocated handle for the EFI image.
34 @param[in] SystemTable A pointer to the EFI System Table.
36 @retval EFI_SUCCESS The entry point is executed successfully.
37 @retval other Some error occurs when executing this entry point.
43 IN EFI_HANDLE ImageHandle
,
44 IN EFI_SYSTEM_TABLE
*SystemTable
50 // Install driver model protocol(s).
52 Status
= EfiLibInstallAllDriverProtocols (
55 &gSerialControllerDriver
,
57 &gIsaSerialComponentName
,
61 ASSERT_EFI_ERROR (Status
);
70 SerialControllerDriverSupported (
71 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
72 IN EFI_HANDLE Controller
,
73 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
79 Check to see if this driver supports the given controller
83 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
84 Controller - The handle of the controller to test.
85 RemainingDevicePath - A pointer to the remaining portion of a device path.
89 EFI_SUCCESS - This driver can support the given controller
94 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
95 EFI_ISA_IO_PROTOCOL
*IsaIo
;
96 UART_DEVICE_PATH UartNode
;
99 // Ignore the RemainingDevicePath
102 // Open the IO Abstraction(s) needed to perform the supported test
104 Status
= gBS
->OpenProtocol (
106 &gEfiDevicePathProtocolGuid
,
107 (VOID
**) &ParentDevicePath
,
108 This
->DriverBindingHandle
,
110 EFI_OPEN_PROTOCOL_BY_DRIVER
112 if (Status
== EFI_ALREADY_STARTED
) {
116 if (EFI_ERROR (Status
)) {
122 &gEfiDevicePathProtocolGuid
,
123 This
->DriverBindingHandle
,
127 Status
= gBS
->OpenProtocol (
129 &gEfiIsaIoProtocolGuid
,
131 This
->DriverBindingHandle
,
133 EFI_OPEN_PROTOCOL_BY_DRIVER
136 if (Status
== EFI_ALREADY_STARTED
) {
140 if (EFI_ERROR (Status
)) {
144 // Use the ISA I/O Protocol to see if Controller is standard ISA UART that
145 // can be managed by this driver.
147 Status
= EFI_SUCCESS
;
148 if (IsaIo
->ResourceList
->Device
.HID
!= EISA_PNP_ID (0x501)) {
149 Status
= EFI_UNSUPPORTED
;
153 // Make sure RemainingDevicePath is valid
155 if (RemainingDevicePath
!= NULL
) {
156 Status
= EFI_UNSUPPORTED
;
159 (UART_DEVICE_PATH
*) RemainingDevicePath
,
160 sizeof (UART_DEVICE_PATH
)
162 if (UartNode
.Header
.Type
!= MESSAGING_DEVICE_PATH
||
163 UartNode
.Header
.SubType
!= MSG_UART_DP
||
164 sizeof (UART_DEVICE_PATH
) != DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL
*) &UartNode
)
169 if (UartNode
.BaudRate
> SERIAL_PORT_MAX_BAUD_RATE
) {
173 if (UartNode
.Parity
< NoParity
|| UartNode
.Parity
> SpaceParity
) {
177 if (UartNode
.DataBits
< 5 || UartNode
.DataBits
> 8) {
181 if (UartNode
.StopBits
< OneStopBit
|| UartNode
.StopBits
> TwoStopBits
) {
185 if ((UartNode
.DataBits
== 5) && (UartNode
.StopBits
== TwoStopBits
)) {
189 if ((UartNode
.DataBits
>= 6) && (UartNode
.DataBits
<= 8) && (UartNode
.StopBits
== OneFiveStopBits
)) {
193 Status
= EFI_SUCCESS
;
198 // Close the I/O Abstraction(s) used to perform the supported test
202 &gEfiIsaIoProtocolGuid
,
203 This
->DriverBindingHandle
,
212 SerialControllerDriverStart (
213 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
214 IN EFI_HANDLE Controller
,
215 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
221 Start to management the controller passed in
225 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
226 Controller - The handle of the controller to test.
227 RemainingDevicePath - A pointer to the remaining portion of a device path.
231 EFI_SUCCESS - Driver is started successfully
236 EFI_ISA_IO_PROTOCOL
*IsaIo
;
237 SERIAL_DEV
*SerialDevice
;
239 UART_DEVICE_PATH Node
;
240 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
241 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
243 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
247 // Get the Parent Device Path
249 Status
= gBS
->OpenProtocol (
251 &gEfiDevicePathProtocolGuid
,
252 (VOID
**) &ParentDevicePath
,
253 This
->DriverBindingHandle
,
255 EFI_OPEN_PROTOCOL_BY_DRIVER
257 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
261 // Report status code enable the serial
263 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
265 EFI_P_PC_ENABLE
| EFI_PERIPHERAL_SERIAL_PORT
,
270 // Grab the IO abstraction we need to get any work done
272 Status
= gBS
->OpenProtocol (
274 &gEfiIsaIoProtocolGuid
,
276 This
->DriverBindingHandle
,
278 EFI_OPEN_PROTOCOL_BY_DRIVER
280 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
284 if (Status
== EFI_ALREADY_STARTED
) {
286 if (RemainingDevicePath
== NULL
) {
290 // Make sure a child handle does not already exist. This driver can only
291 // produce one child per serial port.
293 Status
= gBS
->OpenProtocolInformation (
295 &gEfiIsaIoProtocolGuid
,
299 if (EFI_ERROR (Status
)) {
303 Status
= EFI_ALREADY_STARTED
;
304 for (Index
= 0; Index
< EntryCount
; Index
++) {
305 if (OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) {
306 Status
= gBS
->OpenProtocol (
307 OpenInfoBuffer
[Index
].ControllerHandle
,
308 &gEfiSerialIoProtocolGuid
,
310 This
->DriverBindingHandle
,
312 EFI_OPEN_PROTOCOL_GET_PROTOCOL
314 if (!EFI_ERROR (Status
)) {
315 CopyMem (&Node
, RemainingDevicePath
, sizeof (UART_DEVICE_PATH
));
316 Status
= SerialIo
->SetAttributes (
319 SerialIo
->Mode
->ReceiveFifoDepth
,
320 SerialIo
->Mode
->Timeout
,
321 (EFI_PARITY_TYPE
) Node
.Parity
,
323 (EFI_STOP_BITS_TYPE
) Node
.StopBits
330 gBS
->FreePool (OpenInfoBuffer
);
334 // Initialize the serial device instance
336 SerialDevice
= AllocatePool (sizeof (SERIAL_DEV
));
337 if (SerialDevice
== NULL
) {
338 Status
= EFI_OUT_OF_RESOURCES
;
342 ZeroMem (SerialDevice
, sizeof (SERIAL_DEV
));
344 SerialDevice
->IsaIo
= IsaIo
;
345 SerialDevice
->ParentDevicePath
= ParentDevicePath
;
346 SerialDevice
->ControllerNameTable
= NULL
;
348 ADD_SERIAL_NAME (SerialDevice
, IsaIo
);
350 for (Index
= 0; SerialDevice
->IsaIo
->ResourceList
->ResourceItem
[Index
].Type
!= EfiIsaAcpiResourceEndOfList
; Index
++) {
351 if (SerialDevice
->IsaIo
->ResourceList
->ResourceItem
[Index
].Type
== EfiIsaAcpiResourceIo
) {
352 SerialDevice
->BaseAddress
= (UINT16
) SerialDevice
->IsaIo
->ResourceList
->ResourceItem
[Index
].StartRange
;
356 // Report status code the serial present
358 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
360 EFI_P_PC_PRESENCE_DETECT
| EFI_PERIPHERAL_SERIAL_PORT
,
364 if (!IsaSerialPortPresent (SerialDevice
)) {
365 Status
= EFI_DEVICE_ERROR
;
366 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
368 EFI_P_EC_NOT_DETECTED
| EFI_PERIPHERAL_SERIAL_PORT
,
374 SerialDevice
->Signature
= SERIAL_DEV_SIGNATURE
;
375 SerialDevice
->Type
= UART16550A
;
376 SerialDevice
->SoftwareLoopbackEnable
= FALSE
;
377 SerialDevice
->HardwareFlowControl
= FALSE
;
378 SerialDevice
->Handle
= NULL
;
379 SerialDevice
->Receive
.First
= 0;
380 SerialDevice
->Receive
.Last
= 0;
381 SerialDevice
->Receive
.Surplus
= SERIAL_MAX_BUFFER_SIZE
;
382 SerialDevice
->Transmit
.First
= 0;
383 SerialDevice
->Transmit
.Last
= 0;
384 SerialDevice
->Transmit
.Surplus
= SERIAL_MAX_BUFFER_SIZE
;
389 SerialDevice
->SerialIo
.Revision
= SERIAL_IO_INTERFACE_REVISION
;
390 SerialDevice
->SerialIo
.Reset
= IsaSerialReset
;
391 SerialDevice
->SerialIo
.SetAttributes
= IsaSerialSetAttributes
;
392 SerialDevice
->SerialIo
.SetControl
= IsaSerialSetControl
;
393 SerialDevice
->SerialIo
.GetControl
= IsaSerialGetControl
;
394 SerialDevice
->SerialIo
.Write
= IsaSerialWrite
;
395 SerialDevice
->SerialIo
.Read
= IsaSerialRead
;
396 SerialDevice
->SerialIo
.Mode
= &(SerialDevice
->SerialMode
);
398 if (RemainingDevicePath
!= NULL
) {
400 // Match the configuration of the RemainingDevicePath. IsHandleSupported()
401 // already checked to make sure the RemainingDevicePath contains settings
402 // that we can support.
404 CopyMem (&SerialDevice
->UartDevicePath
, RemainingDevicePath
, sizeof (UART_DEVICE_PATH
));
407 // Build the device path by appending the UART node to the ParentDevicePath
408 // from the WinNtIo handle. The Uart setings are zero here, since
409 // SetAttribute() will update them to match the default setings.
411 ZeroMem (&SerialDevice
->UartDevicePath
, sizeof (UART_DEVICE_PATH
));
412 SerialDevice
->UartDevicePath
.Header
.Type
= MESSAGING_DEVICE_PATH
;
413 SerialDevice
->UartDevicePath
.Header
.SubType
= MSG_UART_DP
;
414 SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL
*) &SerialDevice
->UartDevicePath
, sizeof (UART_DEVICE_PATH
));
417 // Build the device path by appending the UART node to the ParentDevicePath
418 // from the WinNtIo handle. The Uart setings are zero here, since
419 // SetAttribute() will update them to match the current setings.
421 SerialDevice
->DevicePath
= AppendDevicePathNode (
423 (EFI_DEVICE_PATH_PROTOCOL
*) &SerialDevice
->UartDevicePath
426 if (SerialDevice
->DevicePath
== NULL
) {
427 Status
= EFI_DEVICE_ERROR
;
431 // Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults.
433 SerialDevice
->SerialMode
.ControlMask
= SERIAL_PORT_DEFAULT_CONTROL_MASK
;
434 SerialDevice
->SerialMode
.Timeout
= SERIAL_PORT_DEFAULT_TIMEOUT
;
435 SerialDevice
->SerialMode
.BaudRate
= SerialDevice
->UartDevicePath
.BaudRate
;
436 SerialDevice
->SerialMode
.ReceiveFifoDepth
= SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH
;
437 SerialDevice
->SerialMode
.DataBits
= SerialDevice
->UartDevicePath
.DataBits
;
438 SerialDevice
->SerialMode
.Parity
= SerialDevice
->UartDevicePath
.Parity
;
439 SerialDevice
->SerialMode
.StopBits
= SerialDevice
->UartDevicePath
.StopBits
;
442 // Issue a reset to initialize the COM port
444 Status
= SerialDevice
->SerialIo
.Reset (&SerialDevice
->SerialIo
);
445 if (EFI_ERROR (Status
)) {
446 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
448 EFI_P_EC_CONTROLLER_ERROR
| EFI_PERIPHERAL_SERIAL_PORT
,
454 // Install protocol interfaces for the serial device.
456 Status
= gBS
->InstallMultipleProtocolInterfaces (
457 &SerialDevice
->Handle
,
458 &gEfiDevicePathProtocolGuid
,
459 SerialDevice
->DevicePath
,
460 &gEfiSerialIoProtocolGuid
,
461 &SerialDevice
->SerialIo
,
464 if (EFI_ERROR (Status
)) {
468 // Open For Child Device
470 Status
= gBS
->OpenProtocol (
472 &gEfiIsaIoProtocolGuid
,
474 This
->DriverBindingHandle
,
475 SerialDevice
->Handle
,
476 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
480 if (EFI_ERROR (Status
)) {
483 &gEfiDevicePathProtocolGuid
,
484 This
->DriverBindingHandle
,
489 &gEfiIsaIoProtocolGuid
,
490 This
->DriverBindingHandle
,
494 if (SerialDevice
->DevicePath
) {
495 gBS
->FreePool (SerialDevice
->DevicePath
);
498 FreeUnicodeStringTable (SerialDevice
->ControllerNameTable
);
499 gBS
->FreePool (SerialDevice
);
508 SerialControllerDriverStop (
509 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
510 IN EFI_HANDLE Controller
,
511 IN UINTN NumberOfChildren
,
512 IN EFI_HANDLE
*ChildHandleBuffer
518 Disconnect this driver with the controller, uninstall related protocol instance
522 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
523 Controller - The handle of the controller to test.
524 NumberOfChildren - Number of child device.
525 RemainingDevicePath - A pointer to the remaining portion of a device path.
529 EFI_SUCCESS - Operation successfully
530 EFI_DEVICE_ERROR - Cannot stop the driver successfully
536 BOOLEAN AllChildrenStopped
;
537 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
538 SERIAL_DEV
*SerialDevice
;
539 EFI_ISA_IO_PROTOCOL
*IsaIo
;
540 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
542 Status
= gBS
->HandleProtocol (
544 &gEfiDevicePathProtocolGuid
,
545 (VOID
**) &DevicePath
549 // Report the status code disable the serial
551 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
553 EFI_P_PC_DISABLE
| EFI_PERIPHERAL_SERIAL_PORT
,
558 // Complete all outstanding transactions to Controller.
559 // Don't allow any new transaction to Controller to be started.
561 if (NumberOfChildren
== 0) {
563 // Close the bus driver
565 Status
= gBS
->CloseProtocol (
567 &gEfiIsaIoProtocolGuid
,
568 This
->DriverBindingHandle
,
572 Status
= gBS
->CloseProtocol (
574 &gEfiDevicePathProtocolGuid
,
575 This
->DriverBindingHandle
,
581 AllChildrenStopped
= TRUE
;
583 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
585 Status
= gBS
->OpenProtocol (
586 ChildHandleBuffer
[Index
],
587 &gEfiSerialIoProtocolGuid
,
589 This
->DriverBindingHandle
,
591 EFI_OPEN_PROTOCOL_GET_PROTOCOL
593 if (!EFI_ERROR (Status
)) {
595 SerialDevice
= SERIAL_DEV_FROM_THIS (SerialIo
);
597 Status
= gBS
->CloseProtocol (
599 &gEfiIsaIoProtocolGuid
,
600 This
->DriverBindingHandle
,
601 ChildHandleBuffer
[Index
]
604 Status
= gBS
->UninstallMultipleProtocolInterfaces (
605 ChildHandleBuffer
[Index
],
606 &gEfiDevicePathProtocolGuid
,
607 SerialDevice
->DevicePath
,
608 &gEfiSerialIoProtocolGuid
,
609 &SerialDevice
->SerialIo
,
612 if (EFI_ERROR (Status
)) {
615 &gEfiIsaIoProtocolGuid
,
617 This
->DriverBindingHandle
,
618 ChildHandleBuffer
[Index
],
619 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
622 if (SerialDevice
->DevicePath
) {
623 gBS
->FreePool (SerialDevice
->DevicePath
);
626 FreeUnicodeStringTable (SerialDevice
->ControllerNameTable
);
627 gBS
->FreePool (SerialDevice
);
631 if (EFI_ERROR (Status
)) {
632 AllChildrenStopped
= FALSE
;
636 if (!AllChildrenStopped
) {
637 return EFI_DEVICE_ERROR
;
645 IN SERIAL_DEV_FIFO
*Fifo
651 Detect whether specific FIFO is full or not
655 Fifo - A pointer to the Data Structure SERIAL_DEV_FIFO
659 TRUE - the FIFO is full
660 FALSE - the FIFO is not full
664 if (Fifo
->Surplus
== 0) {
673 IN SERIAL_DEV_FIFO
*Fifo
679 Detect whether specific FIFO is empty or not
683 Fifo - A pointer to the Data Structure SERIAL_DEV_FIFO
687 TRUE - the FIFO is empty
688 FALSE - the FIFO is not empty
692 if (Fifo
->Surplus
== SERIAL_MAX_BUFFER_SIZE
) {
701 IN SERIAL_DEV_FIFO
*Fifo
,
708 Add data to specific FIFO
712 Fifo - A pointer to the Data Structure SERIAL_DEV_FIFO
713 Data - the data added to FIFO
717 EFI_SUCCESS - Add data to specific FIFO successfully
718 EFI_OUT_OF_RESOURCE - Failed to add data because FIFO is already full
723 // if FIFO full can not add data
725 if (IsaSerialFifoFull (Fifo
)) {
726 return EFI_OUT_OF_RESOURCES
;
729 // FIFO is not full can add data
731 Fifo
->Data
[Fifo
->Last
] = Data
;
734 if (Fifo
->Last
== SERIAL_MAX_BUFFER_SIZE
) {
742 IsaSerialFifoRemove (
743 IN SERIAL_DEV_FIFO
*Fifo
,
750 Remove data from specific FIFO
754 Fifo - A pointer to the Data Structure SERIAL_DEV_FIFO
755 Data - the data removed from FIFO
758 EFI_SUCCESS - Remove data from specific FIFO successfully
759 EFI_OUT_OF_RESOURCE - Failed to remove data because FIFO is empty
764 // if FIFO is empty, no data can remove
766 if (IsaSerialFifoEmpty (Fifo
)) {
767 return EFI_OUT_OF_RESOURCES
;
770 // FIFO is not empty, can remove data
772 *Data
= Fifo
->Data
[Fifo
->First
];
775 if (Fifo
->First
== SERIAL_MAX_BUFFER_SIZE
) {
783 IsaSerialReceiveTransmit (
784 IN SERIAL_DEV
*SerialDevice
790 Reads and writes all avaliable data.
794 SerialDevice - The device to flush
798 EFI_SUCCESS - Data was read/written successfully.
799 EFI_OUT_OF_RESOURCE - Failed because software receive FIFO is full. Note, when
800 this happens, pending writes are not done.
806 BOOLEAN ReceiveFifoFull
;
814 // Begin the read or write
816 if (SerialDevice
->SoftwareLoopbackEnable
) {
818 ReceiveFifoFull
= IsaSerialFifoFull (&SerialDevice
->Receive
);
819 if (!IsaSerialFifoEmpty (&SerialDevice
->Transmit
)) {
820 IsaSerialFifoRemove (&SerialDevice
->Transmit
, &Data
);
821 if (ReceiveFifoFull
) {
822 return EFI_OUT_OF_RESOURCES
;
825 IsaSerialFifoAdd (&SerialDevice
->Receive
, Data
);
827 } while (!IsaSerialFifoEmpty (&SerialDevice
->Transmit
));
829 ReceiveFifoFull
= IsaSerialFifoFull (&SerialDevice
->Receive
);
831 Lsr
.Data
= READ_LSR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
833 if (FeaturePcdGet (PcdNtEmulatorEnable
)) {
835 // This is required for NT to avoid a forever-spin...
836 // This would be better if READ_LSR was a polling operation
837 // that would timeout.
842 // Flush incomming data to prevent a an overrun during a long write
844 if (Lsr
.Bits
.DR
&& !ReceiveFifoFull
) {
845 ReceiveFifoFull
= IsaSerialFifoFull (&SerialDevice
->Receive
);
846 if (!ReceiveFifoFull
) {
847 if (Lsr
.Bits
.FIFOE
|| Lsr
.Bits
.OE
|| Lsr
.Bits
.PE
|| Lsr
.Bits
.FE
|| Lsr
.Bits
.BI
) {
848 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
850 EFI_P_EC_INPUT_ERROR
| EFI_PERIPHERAL_SERIAL_PORT
,
851 SerialDevice
->DevicePath
853 if (Lsr
.Bits
.FIFOE
|| Lsr
.Bits
.PE
|| Lsr
.Bits
.FE
|| Lsr
.Bits
.BI
) {
854 Data
= READ_RBR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
859 // Make sure the receive data will not be missed, Assert DTR
861 if (SerialDevice
->HardwareFlowControl
) {
862 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
864 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
867 Data
= READ_RBR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
872 if (SerialDevice
->HardwareFlowControl
) {
873 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
875 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
878 IsaSerialFifoAdd (&SerialDevice
->Receive
, Data
);
882 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
884 EFI_P_SERIAL_PORT_PC_CLEAR_BUFFER
| EFI_PERIPHERAL_SERIAL_PORT
,
885 SerialDevice
->DevicePath
892 if (Lsr
.Bits
.THRE
&& !IsaSerialFifoEmpty (&SerialDevice
->Transmit
)) {
894 // Make sure the transmit data will not be missed
896 if (SerialDevice
->HardwareFlowControl
) {
900 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
902 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
907 Msr
.Data
= READ_MSR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
908 while (!Msr
.Bits
.CTS
) {
909 gBS
->Stall (TIMEOUT_STALL_INTERVAL
);
915 Msr
.Data
= READ_MSR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
919 IsaSerialFifoRemove (&SerialDevice
->Transmit
, &Data
);
920 WRITE_THR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Data
);
924 // write the data out
926 if (!SerialDevice
->HardwareFlowControl
) {
927 IsaSerialFifoRemove (&SerialDevice
->Transmit
, &Data
);
928 WRITE_THR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Data
);
931 // Make sure the transmit data will not be missed
933 if (SerialDevice
->HardwareFlowControl
) {
937 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
939 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
942 } while (Lsr
.Bits
.THRE
&& !IsaSerialFifoEmpty (&SerialDevice
->Transmit
));
948 // Interface Functions
953 IN EFI_SERIAL_IO_PROTOCOL
*This
963 This - Pointer to EFI_SERIAL_IO_PROTOCOL
967 EFI_SUCCESS - Reset successfully
968 EFI_DEVICE_ERROR - Failed to reset
973 SERIAL_DEV
*SerialDevice
;
980 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
983 // Report the status code reset the serial
985 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
987 EFI_P_PC_RESET
| EFI_PERIPHERAL_SERIAL_PORT
,
988 SerialDevice
->DevicePath
991 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
994 // Make sure DLAB is 0.
996 Lcr
.Data
= READ_LCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
998 WRITE_LCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Lcr
.Data
);
1001 // Turn off all interrupts
1003 Ier
.Data
= READ_IER (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1008 WRITE_IER (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Ier
.Data
);
1011 // Disable the FIFO.
1013 Fcr
.Bits
.TRFIFOE
= 0;
1014 WRITE_FCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Fcr
.Data
);
1017 // Turn off loopback and disable device interrupt.
1019 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1023 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
1026 // Clear the scratch pad register
1028 WRITE_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, 0);
1031 // Go set the current attributes
1033 Status
= This
->SetAttributes (
1035 This
->Mode
->BaudRate
,
1036 This
->Mode
->ReceiveFifoDepth
,
1037 This
->Mode
->Timeout
,
1038 (EFI_PARITY_TYPE
) This
->Mode
->Parity
,
1039 (UINT8
) This
->Mode
->DataBits
,
1040 (EFI_STOP_BITS_TYPE
) This
->Mode
->StopBits
1043 if (EFI_ERROR (Status
)) {
1044 gBS
->RestoreTPL (Tpl
);
1045 return EFI_DEVICE_ERROR
;
1048 // Go set the current control bits
1050 Status
= This
->SetControl (
1052 This
->Mode
->ControlMask
1055 if (EFI_ERROR (Status
)) {
1056 gBS
->RestoreTPL (Tpl
);
1057 return EFI_DEVICE_ERROR
;
1060 // for 16550A enable FIFO, 16550 disable FIFO
1062 Fcr
.Bits
.TRFIFOE
= 1;
1063 Fcr
.Bits
.RESETRF
= 1;
1064 Fcr
.Bits
.RESETTF
= 1;
1065 WRITE_FCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Fcr
.Data
);
1068 // Reset the software FIFO
1070 SerialDevice
->Receive
.First
= 0;
1071 SerialDevice
->Receive
.Last
= 0;
1072 SerialDevice
->Receive
.Surplus
= SERIAL_MAX_BUFFER_SIZE
;
1073 SerialDevice
->Transmit
.First
= 0;
1074 SerialDevice
->Transmit
.Last
= 0;
1075 SerialDevice
->Transmit
.Surplus
= SERIAL_MAX_BUFFER_SIZE
;
1077 gBS
->RestoreTPL (Tpl
);
1080 // Device reset is complete
1087 IsaSerialSetAttributes (
1088 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1090 IN UINT32 ReceiveFifoDepth
,
1092 IN EFI_PARITY_TYPE Parity
,
1094 IN EFI_STOP_BITS_TYPE StopBits
1098 Routine Description:
1100 Set new attributes to a serial device
1104 This - Pointer to EFI_SERIAL_IO_PROTOCOL
1105 BaudRate - The baudrate of the serial device
1106 ReceiveFifoDepth - The depth of receive FIFO buffer
1107 Timeout - The request timeout for a single char
1108 Parity - The type of parity used in serial device
1109 DataBits - Number of databits used in serial device
1110 StopBits - Number of stopbits used in serial device
1114 EFI_SUCCESS - The new attributes were set
1115 EFI_INVALID_PARAMETERS - One or more attributes have an unsupported value
1116 EFI_UNSUPPORTED - Data Bits can not set to 5 or 6
1117 EFI_DEVICE_ERROR - The serial device is not functioning correctly (no return)
1122 SERIAL_DEV
*SerialDevice
;
1125 SERIAL_PORT_LCR Lcr
;
1126 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
1129 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1132 // Check for default settings and fill in actual values.
1134 if (BaudRate
== 0) {
1135 BaudRate
= SERIAL_PORT_DEFAULT_BAUD_RATE
;
1138 if (ReceiveFifoDepth
== 0) {
1139 ReceiveFifoDepth
= SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH
;
1143 Timeout
= SERIAL_PORT_DEFAULT_TIMEOUT
;
1146 if (Parity
== DefaultParity
) {
1147 Parity
= SERIAL_PORT_DEFAULT_PARITY
;
1150 if (DataBits
== 0) {
1151 DataBits
= SERIAL_PORT_DEFAULT_DATA_BITS
;
1154 if (StopBits
== DefaultStopBits
) {
1155 StopBits
= (EFI_STOP_BITS_TYPE
) SERIAL_PORT_DEFAULT_STOP_BITS
;
1158 // 5 and 6 data bits can not be verified on a 16550A UART
1159 // Return EFI_INVALID_PARAMETER if an attempt is made to use these settings.
1161 if ((DataBits
== 5) || (DataBits
== 6)) {
1162 return EFI_INVALID_PARAMETER
;
1165 // Make sure all parameters are valid
1167 if ((BaudRate
> SERIAL_PORT_MAX_BAUD_RATE
) || (BaudRate
< SERIAL_PORT_MIN_BAUD_RATE
)) {
1168 return EFI_INVALID_PARAMETER
;
1171 // 50,75,110,134,150,300,600,1200,1800,2000,2400,3600,4800,7200,9600,19200,
1172 // 38400,57600,115200
1174 if (BaudRate
< 75) {
1176 } else if (BaudRate
< 110) {
1178 } else if (BaudRate
< 134) {
1180 } else if (BaudRate
< 150) {
1182 } else if (BaudRate
< 300) {
1184 } else if (BaudRate
< 600) {
1186 } else if (BaudRate
< 1200) {
1188 } else if (BaudRate
< 1800) {
1190 } else if (BaudRate
< 2000) {
1192 } else if (BaudRate
< 2400) {
1194 } else if (BaudRate
< 3600) {
1196 } else if (BaudRate
< 4800) {
1198 } else if (BaudRate
< 7200) {
1200 } else if (BaudRate
< 9600) {
1202 } else if (BaudRate
< 19200) {
1204 } else if (BaudRate
< 38400) {
1206 } else if (BaudRate
< 57600) {
1208 } else if (BaudRate
< 115200) {
1210 } else if (BaudRate
<= SERIAL_PORT_MAX_BAUD_RATE
) {
1214 if ((ReceiveFifoDepth
< 1) || (ReceiveFifoDepth
> SERIAL_PORT_MAX_RECEIVE_FIFO_DEPTH
)) {
1215 return EFI_INVALID_PARAMETER
;
1218 if ((Timeout
< SERIAL_PORT_MIN_TIMEOUT
) || (Timeout
> SERIAL_PORT_MAX_TIMEOUT
)) {
1219 return EFI_INVALID_PARAMETER
;
1222 if ((Parity
< NoParity
) || (Parity
> SpaceParity
)) {
1223 return EFI_INVALID_PARAMETER
;
1226 if ((DataBits
< 5) || (DataBits
> 8)) {
1227 return EFI_INVALID_PARAMETER
;
1230 if ((StopBits
< OneStopBit
) || (StopBits
> TwoStopBits
)) {
1231 return EFI_INVALID_PARAMETER
;
1234 // for DataBits = 5, StopBits can not set TwoStopBits
1236 // if ((DataBits == 5) && (StopBits == TwoStopBits)) {
1237 // return EFI_INVALID_PARAMETER;
1240 // for DataBits = 6,7,8, StopBits can not set OneFiveStopBits
1242 if ((DataBits
>= 6) && (DataBits
<= 8) && (StopBits
== OneFiveStopBits
)) {
1243 return EFI_INVALID_PARAMETER
;
1247 // Compute divisor use to program the baud rate using a round determination
1249 Divisor
= (UINT32
) DivU64x32Remainder (
1250 SERIAL_PORT_INPUT_CLOCK
,
1251 ((UINT32
) BaudRate
* 16),
1258 if ((Divisor
== 0) || (Divisor
& 0xffff0000)) {
1259 return EFI_INVALID_PARAMETER
;
1262 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1265 // Compute the actual baud rate that the serial port will be programmed for.
1267 BaudRate
= SERIAL_PORT_INPUT_CLOCK
/ Divisor
/ 16;
1270 // Put serial port on Divisor Latch Mode
1272 Lcr
.Data
= READ_LCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1274 WRITE_LCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Lcr
.Data
);
1277 // Write the divisor to the serial port
1279 WRITE_DLL (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, (UINT8
) (Divisor
& 0xff));
1280 WRITE_DLM (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, (UINT8
) ((Divisor
>> 8) & 0xff));
1283 // Put serial port back in normal mode and set remaining attributes.
1290 Lcr
.Bits
.EVENPAR
= 0;
1291 Lcr
.Bits
.STICPAR
= 0;
1296 Lcr
.Bits
.EVENPAR
= 1;
1297 Lcr
.Bits
.STICPAR
= 0;
1302 Lcr
.Bits
.EVENPAR
= 0;
1303 Lcr
.Bits
.STICPAR
= 0;
1308 Lcr
.Bits
.EVENPAR
= 1;
1309 Lcr
.Bits
.STICPAR
= 1;
1314 Lcr
.Bits
.EVENPAR
= 0;
1315 Lcr
.Bits
.STICPAR
= 1;
1327 case OneFiveStopBits
:
1338 Lcr
.Bits
.SERIALDB
= (UINT8
) ((DataBits
- 5) & 0x03);
1339 WRITE_LCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Lcr
.Data
);
1342 // Set the Serial I/O mode
1344 This
->Mode
->BaudRate
= BaudRate
;
1345 This
->Mode
->ReceiveFifoDepth
= ReceiveFifoDepth
;
1346 This
->Mode
->Timeout
= Timeout
;
1347 This
->Mode
->Parity
= Parity
;
1348 This
->Mode
->DataBits
= DataBits
;
1349 This
->Mode
->StopBits
= StopBits
;
1352 // See if Device Path Node has actually changed
1354 if (SerialDevice
->UartDevicePath
.BaudRate
== BaudRate
&&
1355 SerialDevice
->UartDevicePath
.DataBits
== DataBits
&&
1356 SerialDevice
->UartDevicePath
.Parity
== Parity
&&
1357 SerialDevice
->UartDevicePath
.StopBits
== StopBits
1359 gBS
->RestoreTPL (Tpl
);
1363 // Update the device path
1365 SerialDevice
->UartDevicePath
.BaudRate
= BaudRate
;
1366 SerialDevice
->UartDevicePath
.DataBits
= DataBits
;
1367 SerialDevice
->UartDevicePath
.Parity
= (UINT8
) Parity
;
1368 SerialDevice
->UartDevicePath
.StopBits
= (UINT8
) StopBits
;
1370 NewDevicePath
= AppendDevicePathNode (
1371 SerialDevice
->ParentDevicePath
,
1372 (EFI_DEVICE_PATH_PROTOCOL
*) &SerialDevice
->UartDevicePath
1374 if (NewDevicePath
== NULL
) {
1375 gBS
->RestoreTPL (Tpl
);
1376 return EFI_DEVICE_ERROR
;
1379 if (SerialDevice
->Handle
!= NULL
) {
1380 Status
= gBS
->ReinstallProtocolInterface (
1381 SerialDevice
->Handle
,
1382 &gEfiDevicePathProtocolGuid
,
1383 SerialDevice
->DevicePath
,
1386 if (EFI_ERROR (Status
)) {
1387 gBS
->RestoreTPL (Tpl
);
1392 if (SerialDevice
->DevicePath
) {
1393 gBS
->FreePool (SerialDevice
->DevicePath
);
1396 SerialDevice
->DevicePath
= NewDevicePath
;
1398 gBS
->RestoreTPL (Tpl
);
1405 IsaSerialSetControl (
1406 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1411 Routine Description:
1417 This - Pointer to EFI_SERIAL_IO_PROTOCOL
1418 Control - Control bits that can be settable
1422 EFI_SUCCESS - New Control bits were set successfully
1423 EFI_UNSUPPORTED - The Control bits wanted to set are not supported
1427 SERIAL_DEV
*SerialDevice
;
1428 SERIAL_PORT_MCR Mcr
;
1432 // The control bits that can be set are :
1433 // EFI_SERIAL_DATA_TERMINAL_READY: 0x0001 // WO
1434 // EFI_SERIAL_REQUEST_TO_SEND: 0x0002 // WO
1435 // EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE: 0x1000 // RW
1436 // EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE: 0x2000 // RW
1438 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1441 // first determine the parameter is invalid
1443 if (Control
& 0xffff8ffc) {
1444 return EFI_UNSUPPORTED
;
1447 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1449 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1453 SerialDevice
->SoftwareLoopbackEnable
= FALSE
;
1454 SerialDevice
->HardwareFlowControl
= FALSE
;
1456 if (Control
& EFI_SERIAL_DATA_TERMINAL_READY
) {
1460 if (Control
& EFI_SERIAL_REQUEST_TO_SEND
) {
1464 if (Control
& EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
) {
1468 if (Control
& EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
) {
1469 SerialDevice
->HardwareFlowControl
= TRUE
;
1472 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
1474 if (Control
& EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
) {
1475 SerialDevice
->SoftwareLoopbackEnable
= TRUE
;
1478 gBS
->RestoreTPL (Tpl
);
1485 IsaSerialGetControl (
1486 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1491 Routine Description:
1497 This - Pointer to EFI_SERIAL_IO_PROTOCOL
1498 Control - Control signals of the serial device
1502 EFI_SUCCESS - Get Control signals successfully
1506 SERIAL_DEV
*SerialDevice
;
1507 SERIAL_PORT_MSR Msr
;
1508 SERIAL_PORT_MCR Mcr
;
1511 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1513 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1518 // Read the Modem Status Register
1520 Msr
.Data
= READ_MSR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1523 *Control
|= EFI_SERIAL_CLEAR_TO_SEND
;
1527 *Control
|= EFI_SERIAL_DATA_SET_READY
;
1531 *Control
|= EFI_SERIAL_RING_INDICATE
;
1535 *Control
|= EFI_SERIAL_CARRIER_DETECT
;
1538 // Read the Modem Control Register
1540 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1542 if (Mcr
.Bits
.DTRC
) {
1543 *Control
|= EFI_SERIAL_DATA_TERMINAL_READY
;
1547 *Control
|= EFI_SERIAL_REQUEST_TO_SEND
;
1551 *Control
|= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
;
1554 if (SerialDevice
->HardwareFlowControl
) {
1555 *Control
|= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
;
1558 // See if the Transmit FIFO is empty
1560 IsaSerialReceiveTransmit (SerialDevice
);
1562 if (IsaSerialFifoEmpty (&SerialDevice
->Transmit
)) {
1563 *Control
|= EFI_SERIAL_OUTPUT_BUFFER_EMPTY
;
1566 // See if the Receive FIFO is empty.
1568 IsaSerialReceiveTransmit (SerialDevice
);
1570 if (IsaSerialFifoEmpty (&SerialDevice
->Receive
)) {
1571 *Control
|= EFI_SERIAL_INPUT_BUFFER_EMPTY
;
1574 if (SerialDevice
->SoftwareLoopbackEnable
) {
1575 *Control
|= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
;
1578 gBS
->RestoreTPL (Tpl
);
1586 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1587 IN OUT UINTN
*BufferSize
,
1592 Routine Description:
1594 Write the specified number of bytes to serial device
1598 This - Pointer to EFI_SERIAL_IO_PROTOCOL
1599 BufferSize - On input the size of Buffer, on output the amount of
1600 data actually written
1601 Buffer - The buffer of data to write
1605 EFI_SUCCESS - The data were written successfully
1606 EFI_DEVICE_ERROR - The device reported an error
1607 EFI_TIMEOUT - The write operation was stopped due to timeout
1611 SERIAL_DEV
*SerialDevice
;
1618 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1622 if (*BufferSize
== 0) {
1627 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1629 EFI_P_EC_OUTPUT_ERROR
| EFI_PERIPHERAL_SERIAL_PORT
,
1630 SerialDevice
->DevicePath
1633 return EFI_DEVICE_ERROR
;
1636 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1638 CharBuffer
= (UINT8
*) Buffer
;
1640 for (Index
= 0; Index
< *BufferSize
; Index
++) {
1641 IsaSerialFifoAdd (&SerialDevice
->Transmit
, CharBuffer
[Index
]);
1643 while (IsaSerialReceiveTransmit (SerialDevice
) != EFI_SUCCESS
|| !IsaSerialFifoEmpty (&SerialDevice
->Transmit
)) {
1645 // Unsuccessful write so check if timeout has expired, if not,
1646 // stall for a bit, increment time elapsed, and try again
1648 if (Elapsed
>= This
->Mode
->Timeout
) {
1649 *BufferSize
= ActualWrite
;
1650 gBS
->RestoreTPL (Tpl
);
1654 gBS
->Stall (TIMEOUT_STALL_INTERVAL
);
1656 Elapsed
+= TIMEOUT_STALL_INTERVAL
;
1661 // Successful write so reset timeout
1666 gBS
->RestoreTPL (Tpl
);
1674 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1675 IN OUT UINTN
*BufferSize
,
1680 Routine Description:
1682 Read the specified number of bytes from serial device
1686 This - Pointer to EFI_SERIAL_IO_PROTOCOL
1687 BufferSize - On input the size of Buffer, on output the amount of
1688 data returned in buffer
1689 Buffer - The buffer to return the data into
1693 EFI_SUCCESS - The data were read successfully
1694 EFI_DEVICE_ERROR - The device reported an error
1695 EFI_TIMEOUT - The read operation was stopped due to timeout
1699 SERIAL_DEV
*SerialDevice
;
1706 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1709 if (*BufferSize
== 0) {
1714 return EFI_DEVICE_ERROR
;
1717 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1719 Status
= IsaSerialReceiveTransmit (SerialDevice
);
1721 if (EFI_ERROR (Status
)) {
1724 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1726 EFI_P_EC_INPUT_ERROR
| EFI_PERIPHERAL_SERIAL_PORT
,
1727 SerialDevice
->DevicePath
1730 gBS
->RestoreTPL (Tpl
);
1732 return EFI_DEVICE_ERROR
;
1735 CharBuffer
= (UINT8
*) Buffer
;
1736 for (Index
= 0; Index
< *BufferSize
; Index
++) {
1737 while (IsaSerialFifoRemove (&SerialDevice
->Receive
, &(CharBuffer
[Index
])) != EFI_SUCCESS
) {
1739 // Unsuccessful read so check if timeout has expired, if not,
1740 // stall for a bit, increment time elapsed, and try again
1741 // Need this time out to get conspliter to work.
1743 if (Elapsed
>= This
->Mode
->Timeout
) {
1744 *BufferSize
= Index
;
1745 gBS
->RestoreTPL (Tpl
);
1749 gBS
->Stall (TIMEOUT_STALL_INTERVAL
);
1750 Elapsed
+= TIMEOUT_STALL_INTERVAL
;
1752 Status
= IsaSerialReceiveTransmit (SerialDevice
);
1753 if (Status
== EFI_DEVICE_ERROR
) {
1754 *BufferSize
= Index
;
1755 gBS
->RestoreTPL (Tpl
);
1756 return EFI_DEVICE_ERROR
;
1760 // Successful read so reset timeout
1765 IsaSerialReceiveTransmit (SerialDevice
);
1767 gBS
->RestoreTPL (Tpl
);
1773 IsaSerialPortPresent (
1774 IN SERIAL_DEV
*SerialDevice
1778 Routine Description:
1780 Use scratchpad register to test if this serial port is present
1784 SerialDevice - Pointer to serial device structure
1788 TRUE - The serial port is present
1789 FALSE - The serial port is NOT present
1801 Temp
= READ_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1802 WRITE_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, 0xAA);
1804 if (READ_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
) != 0xAA)
1806 if (!FeaturePcdGet (PcdNtEmulatorEnable
)) {
1811 WRITE_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, 0x55);
1813 if (READ_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
) != 0x55)
1815 if (!FeaturePcdGet (PcdNtEmulatorEnable
)) {
1822 WRITE_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Temp
);
1828 IN EFI_ISA_IO_PROTOCOL
*IsaIo
,
1829 IN UINT16 BaseAddress
,
1834 Routine Description:
1836 Use IsaIo protocol to read serial port
1840 IsaIo - Pointer to EFI_ISA_IO_PROTOCOL instance
1841 BaseAddress - Serial port register group base address
1842 Offset - Offset in register group
1846 Data read from serial port
1853 // Use IsaIo to access IO
1858 BaseAddress
+ Offset
,
1866 IsaSerialWritePort (
1867 IN EFI_ISA_IO_PROTOCOL
*IsaIo
,
1868 IN UINT16 BaseAddress
,
1874 Routine Description:
1876 Use IsaIo protocol to write serial port
1880 IsaIo - Pointer to EFI_ISA_IO_PROTOCOL instance
1881 BaseAddress - Serial port register group base address
1882 Offset - Offset in register group
1883 Data - data which is to be written to some serial port register
1892 // Use IsaIo to access IO
1897 BaseAddress
+ Offset
,