2 Serial driver for standard UARTS on an ISA bus.
4 Copyright (c) 2006 - 2007, Intel Corporation<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 // ISA Serial Driver Global Variables
20 EFI_DRIVER_BINDING_PROTOCOL gSerialControllerDriver
= {
21 SerialControllerDriverSupported
,
22 SerialControllerDriverStart
,
23 SerialControllerDriverStop
,
30 SERIAL_DEV gSerialDevTempate
= {
34 SERIAL_IO_INTERFACE_REVISION
,
36 IsaSerialSetAttributes
,
44 SERIAL_PORT_DEFAULT_CONTROL_MASK
,
45 SERIAL_PORT_DEFAULT_TIMEOUT
,
46 FixedPcdGet64 (PcdUartDefaultBaudRate
), // BaudRate
47 SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH
,
48 FixedPcdGet8 (PcdUartDefaultDataBits
), // DataBits
49 FixedPcdGet8 (PcdUartDefaultParity
), // Parity
50 FixedPcdGet8 (PcdUartDefaultStopBits
) // StopBits
56 MESSAGING_DEVICE_PATH
,
59 (UINT8
) (sizeof (UART_DEVICE_PATH
)),
60 (UINT8
) ((sizeof (UART_DEVICE_PATH
)) >> 8)
64 FixedPcdGet64 (PcdUartDefaultBaudRate
),
65 FixedPcdGet8 (PcdUartDefaultDataBits
),
66 FixedPcdGet8 (PcdUartDefaultParity
),
67 FixedPcdGet8 (PcdUartDefaultStopBits
)
74 SERIAL_MAX_BUFFER_SIZE
,
80 SERIAL_MAX_BUFFER_SIZE
,
90 The user Entry Point for module IsaSerial. The user code starts with this function.
92 @param[in] ImageHandle The firmware allocated handle for the EFI image.
93 @param[in] SystemTable A pointer to the EFI System Table.
95 @retval EFI_SUCCESS The entry point is executed successfully.
96 @retval other Some error occurs when executing this entry point.
101 InitializeIsaSerial (
102 IN EFI_HANDLE ImageHandle
,
103 IN EFI_SYSTEM_TABLE
*SystemTable
109 // Install driver model protocol(s).
111 Status
= EfiLibInstallDriverBindingComponentName2 (
114 &gSerialControllerDriver
,
116 &gIsaSerialComponentName
,
117 &gIsaSerialComponentName2
119 ASSERT_EFI_ERROR (Status
);
128 SerialControllerDriverSupported (
129 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
130 IN EFI_HANDLE Controller
,
131 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
137 Check to see if this driver supports the given controller
141 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
142 Controller - The handle of the controller to test.
143 RemainingDevicePath - A pointer to the remaining portion of a device path.
147 EFI_SUCCESS - This driver can support the given controller
152 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
153 EFI_ISA_IO_PROTOCOL
*IsaIo
;
154 UART_DEVICE_PATH UartNode
;
157 // Ignore the RemainingDevicePath
160 // Open the IO Abstraction(s) needed to perform the supported test
162 Status
= gBS
->OpenProtocol (
164 &gEfiDevicePathProtocolGuid
,
165 (VOID
**) &ParentDevicePath
,
166 This
->DriverBindingHandle
,
168 EFI_OPEN_PROTOCOL_BY_DRIVER
170 if (Status
== EFI_ALREADY_STARTED
) {
174 if (EFI_ERROR (Status
)) {
180 &gEfiDevicePathProtocolGuid
,
181 This
->DriverBindingHandle
,
185 Status
= gBS
->OpenProtocol (
187 &gEfiIsaIoProtocolGuid
,
189 This
->DriverBindingHandle
,
191 EFI_OPEN_PROTOCOL_BY_DRIVER
194 if (Status
== EFI_ALREADY_STARTED
) {
198 if (EFI_ERROR (Status
)) {
202 // Use the ISA I/O Protocol to see if Controller is standard ISA UART that
203 // can be managed by this driver.
205 Status
= EFI_SUCCESS
;
206 if (IsaIo
->ResourceList
->Device
.HID
!= EISA_PNP_ID (0x501)) {
207 Status
= EFI_UNSUPPORTED
;
211 // Make sure RemainingDevicePath is valid
213 if (RemainingDevicePath
!= NULL
) {
214 Status
= EFI_UNSUPPORTED
;
217 (UART_DEVICE_PATH
*) RemainingDevicePath
,
218 sizeof (UART_DEVICE_PATH
)
220 if (UartNode
.Header
.Type
!= MESSAGING_DEVICE_PATH
||
221 UartNode
.Header
.SubType
!= MSG_UART_DP
||
222 sizeof (UART_DEVICE_PATH
) != DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL
*) &UartNode
)
227 if (UartNode
.BaudRate
> SERIAL_PORT_MAX_BAUD_RATE
) {
231 if (UartNode
.Parity
< NoParity
|| UartNode
.Parity
> SpaceParity
) {
235 if (UartNode
.DataBits
< 5 || UartNode
.DataBits
> 8) {
239 if (UartNode
.StopBits
< OneStopBit
|| UartNode
.StopBits
> TwoStopBits
) {
243 if ((UartNode
.DataBits
== 5) && (UartNode
.StopBits
== TwoStopBits
)) {
247 if ((UartNode
.DataBits
>= 6) && (UartNode
.DataBits
<= 8) && (UartNode
.StopBits
== OneFiveStopBits
)) {
251 Status
= EFI_SUCCESS
;
256 // Close the I/O Abstraction(s) used to perform the supported test
260 &gEfiIsaIoProtocolGuid
,
261 This
->DriverBindingHandle
,
270 SerialControllerDriverStart (
271 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
272 IN EFI_HANDLE Controller
,
273 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
279 Start to management the controller passed in
283 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
284 Controller - The handle of the controller to test.
285 RemainingDevicePath - A pointer to the remaining portion of a device path.
289 EFI_SUCCESS - Driver is started successfully
294 EFI_ISA_IO_PROTOCOL
*IsaIo
;
295 SERIAL_DEV
*SerialDevice
;
297 UART_DEVICE_PATH Node
;
298 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
299 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
301 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
305 // Get the Parent Device Path
307 Status
= gBS
->OpenProtocol (
309 &gEfiDevicePathProtocolGuid
,
310 (VOID
**) &ParentDevicePath
,
311 This
->DriverBindingHandle
,
313 EFI_OPEN_PROTOCOL_BY_DRIVER
315 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
319 // Report status code enable the serial
321 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
323 EFI_P_PC_ENABLE
| EFI_PERIPHERAL_SERIAL_PORT
,
328 // Grab the IO abstraction we need to get any work done
330 Status
= gBS
->OpenProtocol (
332 &gEfiIsaIoProtocolGuid
,
334 This
->DriverBindingHandle
,
336 EFI_OPEN_PROTOCOL_BY_DRIVER
338 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
342 if (Status
== EFI_ALREADY_STARTED
) {
344 if (RemainingDevicePath
== NULL
) {
348 // Make sure a child handle does not already exist. This driver can only
349 // produce one child per serial port.
351 Status
= gBS
->OpenProtocolInformation (
353 &gEfiIsaIoProtocolGuid
,
357 if (EFI_ERROR (Status
)) {
361 Status
= EFI_ALREADY_STARTED
;
362 for (Index
= 0; Index
< EntryCount
; Index
++) {
363 if (OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) {
364 Status
= gBS
->OpenProtocol (
365 OpenInfoBuffer
[Index
].ControllerHandle
,
366 &gEfiSerialIoProtocolGuid
,
368 This
->DriverBindingHandle
,
370 EFI_OPEN_PROTOCOL_GET_PROTOCOL
372 if (!EFI_ERROR (Status
)) {
373 CopyMem (&Node
, RemainingDevicePath
, sizeof (UART_DEVICE_PATH
));
374 Status
= SerialIo
->SetAttributes (
377 SerialIo
->Mode
->ReceiveFifoDepth
,
378 SerialIo
->Mode
->Timeout
,
379 (EFI_PARITY_TYPE
) Node
.Parity
,
381 (EFI_STOP_BITS_TYPE
) Node
.StopBits
388 gBS
->FreePool (OpenInfoBuffer
);
392 // Initialize the serial device instance
394 SerialDevice
= AllocateCopyPool (sizeof (SERIAL_DEV
), &gSerialDevTempate
);
395 if (SerialDevice
== NULL
) {
396 Status
= EFI_OUT_OF_RESOURCES
;
400 SerialDevice
->SerialIo
.Mode
= &(SerialDevice
->SerialMode
);
401 SerialDevice
->IsaIo
= IsaIo
;
402 SerialDevice
->ParentDevicePath
= ParentDevicePath
;
404 ADD_SERIAL_NAME (SerialDevice
, IsaIo
);
406 for (Index
= 0; SerialDevice
->IsaIo
->ResourceList
->ResourceItem
[Index
].Type
!= EfiIsaAcpiResourceEndOfList
; Index
++) {
407 if (SerialDevice
->IsaIo
->ResourceList
->ResourceItem
[Index
].Type
== EfiIsaAcpiResourceIo
) {
408 SerialDevice
->BaseAddress
= (UINT16
) SerialDevice
->IsaIo
->ResourceList
->ResourceItem
[Index
].StartRange
;
412 // Report status code the serial present
414 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
416 EFI_P_PC_PRESENCE_DETECT
| EFI_PERIPHERAL_SERIAL_PORT
,
420 if (!IsaSerialPortPresent (SerialDevice
)) {
421 Status
= EFI_DEVICE_ERROR
;
422 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
424 EFI_P_EC_NOT_DETECTED
| EFI_PERIPHERAL_SERIAL_PORT
,
430 if (RemainingDevicePath
!= NULL
) {
432 // Match the configuration of the RemainingDevicePath. IsHandleSupported()
433 // already checked to make sure the RemainingDevicePath contains settings
434 // that we can support.
436 CopyMem (&SerialDevice
->UartDevicePath
, RemainingDevicePath
, sizeof (UART_DEVICE_PATH
));
439 // Use the values from the gSerialDevTempate as no remaining device path was
444 // Build the device path by appending the UART node to the ParentDevicePath
445 // from the WinNtIo handle. The Uart setings are zero here, since
446 // SetAttribute() will update them to match the current setings.
448 SerialDevice
->DevicePath
= AppendDevicePathNode (
450 (EFI_DEVICE_PATH_PROTOCOL
*)&SerialDevice
->UartDevicePath
452 if (SerialDevice
->DevicePath
== NULL
) {
453 Status
= EFI_DEVICE_ERROR
;
458 // Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults.
460 SerialDevice
->SerialMode
.BaudRate
= SerialDevice
->UartDevicePath
.BaudRate
;
461 SerialDevice
->SerialMode
.DataBits
= SerialDevice
->UartDevicePath
.DataBits
;
462 SerialDevice
->SerialMode
.Parity
= SerialDevice
->UartDevicePath
.Parity
;
463 SerialDevice
->SerialMode
.StopBits
= SerialDevice
->UartDevicePath
.StopBits
;
466 // Issue a reset to initialize the COM port
468 Status
= SerialDevice
->SerialIo
.Reset (&SerialDevice
->SerialIo
);
469 if (EFI_ERROR (Status
)) {
470 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
472 EFI_P_EC_CONTROLLER_ERROR
| EFI_PERIPHERAL_SERIAL_PORT
,
478 // Install protocol interfaces for the serial device.
480 Status
= gBS
->InstallMultipleProtocolInterfaces (
481 &SerialDevice
->Handle
,
482 &gEfiDevicePathProtocolGuid
,
483 SerialDevice
->DevicePath
,
484 &gEfiSerialIoProtocolGuid
,
485 &SerialDevice
->SerialIo
,
488 if (EFI_ERROR (Status
)) {
492 // Open For Child Device
494 Status
= gBS
->OpenProtocol (
496 &gEfiIsaIoProtocolGuid
,
498 This
->DriverBindingHandle
,
499 SerialDevice
->Handle
,
500 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
504 if (EFI_ERROR (Status
)) {
507 &gEfiDevicePathProtocolGuid
,
508 This
->DriverBindingHandle
,
513 &gEfiIsaIoProtocolGuid
,
514 This
->DriverBindingHandle
,
518 if (SerialDevice
->DevicePath
) {
519 gBS
->FreePool (SerialDevice
->DevicePath
);
522 FreeUnicodeStringTable (SerialDevice
->ControllerNameTable
);
523 gBS
->FreePool (SerialDevice
);
532 SerialControllerDriverStop (
533 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
534 IN EFI_HANDLE Controller
,
535 IN UINTN NumberOfChildren
,
536 IN EFI_HANDLE
*ChildHandleBuffer
542 Disconnect this driver with the controller, uninstall related protocol instance
546 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
547 Controller - The handle of the controller to test.
548 NumberOfChildren - Number of child device.
549 RemainingDevicePath - A pointer to the remaining portion of a device path.
553 EFI_SUCCESS - Operation successfully
554 EFI_DEVICE_ERROR - Cannot stop the driver successfully
560 BOOLEAN AllChildrenStopped
;
561 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
562 SERIAL_DEV
*SerialDevice
;
563 EFI_ISA_IO_PROTOCOL
*IsaIo
;
564 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
566 Status
= gBS
->HandleProtocol (
568 &gEfiDevicePathProtocolGuid
,
569 (VOID
**) &DevicePath
573 // Report the status code disable the serial
575 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
577 EFI_P_PC_DISABLE
| EFI_PERIPHERAL_SERIAL_PORT
,
582 // Complete all outstanding transactions to Controller.
583 // Don't allow any new transaction to Controller to be started.
585 if (NumberOfChildren
== 0) {
587 // Close the bus driver
589 Status
= gBS
->CloseProtocol (
591 &gEfiIsaIoProtocolGuid
,
592 This
->DriverBindingHandle
,
596 Status
= gBS
->CloseProtocol (
598 &gEfiDevicePathProtocolGuid
,
599 This
->DriverBindingHandle
,
605 AllChildrenStopped
= TRUE
;
607 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
609 Status
= gBS
->OpenProtocol (
610 ChildHandleBuffer
[Index
],
611 &gEfiSerialIoProtocolGuid
,
613 This
->DriverBindingHandle
,
615 EFI_OPEN_PROTOCOL_GET_PROTOCOL
617 if (!EFI_ERROR (Status
)) {
619 SerialDevice
= SERIAL_DEV_FROM_THIS (SerialIo
);
621 Status
= gBS
->CloseProtocol (
623 &gEfiIsaIoProtocolGuid
,
624 This
->DriverBindingHandle
,
625 ChildHandleBuffer
[Index
]
628 Status
= gBS
->UninstallMultipleProtocolInterfaces (
629 ChildHandleBuffer
[Index
],
630 &gEfiDevicePathProtocolGuid
,
631 SerialDevice
->DevicePath
,
632 &gEfiSerialIoProtocolGuid
,
633 &SerialDevice
->SerialIo
,
636 if (EFI_ERROR (Status
)) {
639 &gEfiIsaIoProtocolGuid
,
641 This
->DriverBindingHandle
,
642 ChildHandleBuffer
[Index
],
643 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
646 if (SerialDevice
->DevicePath
) {
647 gBS
->FreePool (SerialDevice
->DevicePath
);
650 FreeUnicodeStringTable (SerialDevice
->ControllerNameTable
);
651 gBS
->FreePool (SerialDevice
);
655 if (EFI_ERROR (Status
)) {
656 AllChildrenStopped
= FALSE
;
660 if (!AllChildrenStopped
) {
661 return EFI_DEVICE_ERROR
;
669 IN SERIAL_DEV_FIFO
*Fifo
675 Detect whether specific FIFO is full or not
679 Fifo - A pointer to the Data Structure SERIAL_DEV_FIFO
683 TRUE - the FIFO is full
684 FALSE - the FIFO is not full
688 if (Fifo
->Surplus
== 0) {
697 IN SERIAL_DEV_FIFO
*Fifo
703 Detect whether specific FIFO is empty or not
707 Fifo - A pointer to the Data Structure SERIAL_DEV_FIFO
711 TRUE - the FIFO is empty
712 FALSE - the FIFO is not empty
716 if (Fifo
->Surplus
== SERIAL_MAX_BUFFER_SIZE
) {
725 IN SERIAL_DEV_FIFO
*Fifo
,
732 Add data to specific FIFO
736 Fifo - A pointer to the Data Structure SERIAL_DEV_FIFO
737 Data - the data added to FIFO
741 EFI_SUCCESS - Add data to specific FIFO successfully
742 EFI_OUT_OF_RESOURCE - Failed to add data because FIFO is already full
747 // if FIFO full can not add data
749 if (IsaSerialFifoFull (Fifo
)) {
750 return EFI_OUT_OF_RESOURCES
;
753 // FIFO is not full can add data
755 Fifo
->Data
[Fifo
->Last
] = Data
;
758 if (Fifo
->Last
== SERIAL_MAX_BUFFER_SIZE
) {
766 IsaSerialFifoRemove (
767 IN SERIAL_DEV_FIFO
*Fifo
,
774 Remove data from specific FIFO
778 Fifo - A pointer to the Data Structure SERIAL_DEV_FIFO
779 Data - the data removed from FIFO
782 EFI_SUCCESS - Remove data from specific FIFO successfully
783 EFI_OUT_OF_RESOURCE - Failed to remove data because FIFO is empty
788 // if FIFO is empty, no data can remove
790 if (IsaSerialFifoEmpty (Fifo
)) {
791 return EFI_OUT_OF_RESOURCES
;
794 // FIFO is not empty, can remove data
796 *Data
= Fifo
->Data
[Fifo
->First
];
799 if (Fifo
->First
== SERIAL_MAX_BUFFER_SIZE
) {
807 IsaSerialReceiveTransmit (
808 IN SERIAL_DEV
*SerialDevice
814 Reads and writes all avaliable data.
818 SerialDevice - The device to flush
822 EFI_SUCCESS - Data was read/written successfully.
823 EFI_OUT_OF_RESOURCE - Failed because software receive FIFO is full. Note, when
824 this happens, pending writes are not done.
830 BOOLEAN ReceiveFifoFull
;
838 // Begin the read or write
840 if (SerialDevice
->SoftwareLoopbackEnable
) {
842 ReceiveFifoFull
= IsaSerialFifoFull (&SerialDevice
->Receive
);
843 if (!IsaSerialFifoEmpty (&SerialDevice
->Transmit
)) {
844 IsaSerialFifoRemove (&SerialDevice
->Transmit
, &Data
);
845 if (ReceiveFifoFull
) {
846 return EFI_OUT_OF_RESOURCES
;
849 IsaSerialFifoAdd (&SerialDevice
->Receive
, Data
);
851 } while (!IsaSerialFifoEmpty (&SerialDevice
->Transmit
));
853 ReceiveFifoFull
= IsaSerialFifoFull (&SerialDevice
->Receive
);
855 Lsr
.Data
= READ_LSR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
857 if (FeaturePcdGet (PcdNtEmulatorEnable
)) {
859 // This is required for NT to avoid a forever-spin...
860 // This would be better if READ_LSR was a polling operation
861 // that would timeout.
866 // Flush incomming data to prevent a an overrun during a long write
868 if (Lsr
.Bits
.DR
&& !ReceiveFifoFull
) {
869 ReceiveFifoFull
= IsaSerialFifoFull (&SerialDevice
->Receive
);
870 if (!ReceiveFifoFull
) {
871 if (Lsr
.Bits
.FIFOE
|| Lsr
.Bits
.OE
|| Lsr
.Bits
.PE
|| Lsr
.Bits
.FE
|| Lsr
.Bits
.BI
) {
872 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
874 EFI_P_EC_INPUT_ERROR
| EFI_PERIPHERAL_SERIAL_PORT
,
875 SerialDevice
->DevicePath
877 if (Lsr
.Bits
.FIFOE
|| Lsr
.Bits
.PE
|| Lsr
.Bits
.FE
|| Lsr
.Bits
.BI
) {
878 Data
= READ_RBR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
883 // Make sure the receive data will not be missed, Assert DTR
885 if (SerialDevice
->HardwareFlowControl
) {
886 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
888 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
891 Data
= READ_RBR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
896 if (SerialDevice
->HardwareFlowControl
) {
897 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
899 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
902 IsaSerialFifoAdd (&SerialDevice
->Receive
, Data
);
906 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
908 EFI_P_SERIAL_PORT_PC_CLEAR_BUFFER
| EFI_PERIPHERAL_SERIAL_PORT
,
909 SerialDevice
->DevicePath
916 if (Lsr
.Bits
.THRE
&& !IsaSerialFifoEmpty (&SerialDevice
->Transmit
)) {
918 // Make sure the transmit data will not be missed
920 if (SerialDevice
->HardwareFlowControl
) {
924 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
926 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
931 Msr
.Data
= READ_MSR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
932 while (!Msr
.Bits
.CTS
) {
933 gBS
->Stall (TIMEOUT_STALL_INTERVAL
);
939 Msr
.Data
= READ_MSR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
943 IsaSerialFifoRemove (&SerialDevice
->Transmit
, &Data
);
944 WRITE_THR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Data
);
948 // write the data out
950 if (!SerialDevice
->HardwareFlowControl
) {
951 IsaSerialFifoRemove (&SerialDevice
->Transmit
, &Data
);
952 WRITE_THR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Data
);
955 // Make sure the transmit data will not be missed
957 if (SerialDevice
->HardwareFlowControl
) {
961 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
963 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
966 } while (Lsr
.Bits
.THRE
&& !IsaSerialFifoEmpty (&SerialDevice
->Transmit
));
972 // Interface Functions
977 IN EFI_SERIAL_IO_PROTOCOL
*This
987 This - Pointer to EFI_SERIAL_IO_PROTOCOL
991 EFI_SUCCESS - Reset successfully
992 EFI_DEVICE_ERROR - Failed to reset
997 SERIAL_DEV
*SerialDevice
;
1000 SERIAL_PORT_MCR Mcr
;
1001 SERIAL_PORT_FCR Fcr
;
1004 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1007 // Report the status code reset the serial
1009 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1011 EFI_P_PC_RESET
| EFI_PERIPHERAL_SERIAL_PORT
,
1012 SerialDevice
->DevicePath
1015 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1018 // Make sure DLAB is 0.
1020 Lcr
.Data
= READ_LCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1022 WRITE_LCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Lcr
.Data
);
1025 // Turn off all interrupts
1027 Ier
.Data
= READ_IER (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1032 WRITE_IER (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Ier
.Data
);
1035 // Disable the FIFO.
1037 Fcr
.Bits
.TRFIFOE
= 0;
1038 WRITE_FCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Fcr
.Data
);
1041 // Turn off loopback and disable device interrupt.
1043 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1047 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
1050 // Clear the scratch pad register
1052 WRITE_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, 0);
1055 // Go set the current attributes
1057 Status
= This
->SetAttributes (
1059 This
->Mode
->BaudRate
,
1060 This
->Mode
->ReceiveFifoDepth
,
1061 This
->Mode
->Timeout
,
1062 (EFI_PARITY_TYPE
) This
->Mode
->Parity
,
1063 (UINT8
) This
->Mode
->DataBits
,
1064 (EFI_STOP_BITS_TYPE
) This
->Mode
->StopBits
1067 if (EFI_ERROR (Status
)) {
1068 gBS
->RestoreTPL (Tpl
);
1069 return EFI_DEVICE_ERROR
;
1072 // Go set the current control bits
1074 Status
= This
->SetControl (
1076 This
->Mode
->ControlMask
1079 if (EFI_ERROR (Status
)) {
1080 gBS
->RestoreTPL (Tpl
);
1081 return EFI_DEVICE_ERROR
;
1084 // for 16550A enable FIFO, 16550 disable FIFO
1086 Fcr
.Bits
.TRFIFOE
= 1;
1087 Fcr
.Bits
.RESETRF
= 1;
1088 Fcr
.Bits
.RESETTF
= 1;
1089 WRITE_FCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Fcr
.Data
);
1092 // Reset the software FIFO
1094 SerialDevice
->Receive
.First
= 0;
1095 SerialDevice
->Receive
.Last
= 0;
1096 SerialDevice
->Receive
.Surplus
= SERIAL_MAX_BUFFER_SIZE
;
1097 SerialDevice
->Transmit
.First
= 0;
1098 SerialDevice
->Transmit
.Last
= 0;
1099 SerialDevice
->Transmit
.Surplus
= SERIAL_MAX_BUFFER_SIZE
;
1101 gBS
->RestoreTPL (Tpl
);
1104 // Device reset is complete
1111 IsaSerialSetAttributes (
1112 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1114 IN UINT32 ReceiveFifoDepth
,
1116 IN EFI_PARITY_TYPE Parity
,
1118 IN EFI_STOP_BITS_TYPE StopBits
1122 Routine Description:
1124 Set new attributes to a serial device
1128 This - Pointer to EFI_SERIAL_IO_PROTOCOL
1129 BaudRate - The baudrate of the serial device
1130 ReceiveFifoDepth - The depth of receive FIFO buffer
1131 Timeout - The request timeout for a single char
1132 Parity - The type of parity used in serial device
1133 DataBits - Number of databits used in serial device
1134 StopBits - Number of stopbits used in serial device
1138 EFI_SUCCESS - The new attributes were set
1139 EFI_INVALID_PARAMETERS - One or more attributes have an unsupported value
1140 EFI_UNSUPPORTED - Data Bits can not set to 5 or 6
1141 EFI_DEVICE_ERROR - The serial device is not functioning correctly (no return)
1146 SERIAL_DEV
*SerialDevice
;
1149 SERIAL_PORT_LCR Lcr
;
1150 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
1153 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1156 // Check for default settings and fill in actual values.
1158 if (BaudRate
== 0) {
1159 BaudRate
= FixedPcdGet64 (PcdUartDefaultBaudRate
);
1162 if (ReceiveFifoDepth
== 0) {
1163 ReceiveFifoDepth
= SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH
;
1167 Timeout
= SERIAL_PORT_DEFAULT_TIMEOUT
;
1170 if (Parity
== DefaultParity
) {
1171 Parity
= (EFI_PARITY_TYPE
)FixedPcdGet8 (PcdUartDefaultParity
);
1174 if (DataBits
== 0) {
1175 DataBits
= FixedPcdGet8 (PcdUartDefaultDataBits
);
1178 if (StopBits
== DefaultStopBits
) {
1179 StopBits
= (EFI_STOP_BITS_TYPE
) FixedPcdGet8 (PcdUartDefaultStopBits
);
1182 // 5 and 6 data bits can not be verified on a 16550A UART
1183 // Return EFI_INVALID_PARAMETER if an attempt is made to use these settings.
1185 if ((DataBits
== 5) || (DataBits
== 6)) {
1186 return EFI_INVALID_PARAMETER
;
1189 // Make sure all parameters are valid
1191 if ((BaudRate
> SERIAL_PORT_MAX_BAUD_RATE
) || (BaudRate
< SERIAL_PORT_MIN_BAUD_RATE
)) {
1192 return EFI_INVALID_PARAMETER
;
1195 // 50,75,110,134,150,300,600,1200,1800,2000,2400,3600,4800,7200,9600,19200,
1196 // 38400,57600,115200
1198 if (BaudRate
< 75) {
1200 } else if (BaudRate
< 110) {
1202 } else if (BaudRate
< 134) {
1204 } else if (BaudRate
< 150) {
1206 } else if (BaudRate
< 300) {
1208 } else if (BaudRate
< 600) {
1210 } else if (BaudRate
< 1200) {
1212 } else if (BaudRate
< 1800) {
1214 } else if (BaudRate
< 2000) {
1216 } else if (BaudRate
< 2400) {
1218 } else if (BaudRate
< 3600) {
1220 } else if (BaudRate
< 4800) {
1222 } else if (BaudRate
< 7200) {
1224 } else if (BaudRate
< 9600) {
1226 } else if (BaudRate
< 19200) {
1228 } else if (BaudRate
< 38400) {
1230 } else if (BaudRate
< 57600) {
1232 } else if (BaudRate
< 115200) {
1234 } else if (BaudRate
<= SERIAL_PORT_MAX_BAUD_RATE
) {
1238 if ((ReceiveFifoDepth
< 1) || (ReceiveFifoDepth
> SERIAL_PORT_MAX_RECEIVE_FIFO_DEPTH
)) {
1239 return EFI_INVALID_PARAMETER
;
1242 if ((Timeout
< SERIAL_PORT_MIN_TIMEOUT
) || (Timeout
> SERIAL_PORT_MAX_TIMEOUT
)) {
1243 return EFI_INVALID_PARAMETER
;
1246 if ((Parity
< NoParity
) || (Parity
> SpaceParity
)) {
1247 return EFI_INVALID_PARAMETER
;
1250 if ((DataBits
< 5) || (DataBits
> 8)) {
1251 return EFI_INVALID_PARAMETER
;
1254 if ((StopBits
< OneStopBit
) || (StopBits
> TwoStopBits
)) {
1255 return EFI_INVALID_PARAMETER
;
1258 // for DataBits = 5, StopBits can not set TwoStopBits
1260 // if ((DataBits == 5) && (StopBits == TwoStopBits)) {
1261 // return EFI_INVALID_PARAMETER;
1264 // for DataBits = 6,7,8, StopBits can not set OneFiveStopBits
1266 if ((DataBits
>= 6) && (DataBits
<= 8) && (StopBits
== OneFiveStopBits
)) {
1267 return EFI_INVALID_PARAMETER
;
1271 // Compute divisor use to program the baud rate using a round determination
1273 Divisor
= (UINT32
) DivU64x32Remainder (
1274 SERIAL_PORT_INPUT_CLOCK
,
1275 ((UINT32
) BaudRate
* 16),
1282 if ((Divisor
== 0) || (Divisor
& 0xffff0000)) {
1283 return EFI_INVALID_PARAMETER
;
1286 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1289 // Compute the actual baud rate that the serial port will be programmed for.
1291 BaudRate
= SERIAL_PORT_INPUT_CLOCK
/ Divisor
/ 16;
1294 // Put serial port on Divisor Latch Mode
1296 Lcr
.Data
= READ_LCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1298 WRITE_LCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Lcr
.Data
);
1301 // Write the divisor to the serial port
1303 WRITE_DLL (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, (UINT8
) (Divisor
& 0xff));
1304 WRITE_DLM (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, (UINT8
) ((Divisor
>> 8) & 0xff));
1307 // Put serial port back in normal mode and set remaining attributes.
1314 Lcr
.Bits
.EVENPAR
= 0;
1315 Lcr
.Bits
.STICPAR
= 0;
1320 Lcr
.Bits
.EVENPAR
= 1;
1321 Lcr
.Bits
.STICPAR
= 0;
1326 Lcr
.Bits
.EVENPAR
= 0;
1327 Lcr
.Bits
.STICPAR
= 0;
1332 Lcr
.Bits
.EVENPAR
= 1;
1333 Lcr
.Bits
.STICPAR
= 1;
1338 Lcr
.Bits
.EVENPAR
= 0;
1339 Lcr
.Bits
.STICPAR
= 1;
1351 case OneFiveStopBits
:
1362 Lcr
.Bits
.SERIALDB
= (UINT8
) ((DataBits
- 5) & 0x03);
1363 WRITE_LCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Lcr
.Data
);
1366 // Set the Serial I/O mode
1368 This
->Mode
->BaudRate
= BaudRate
;
1369 This
->Mode
->ReceiveFifoDepth
= ReceiveFifoDepth
;
1370 This
->Mode
->Timeout
= Timeout
;
1371 This
->Mode
->Parity
= Parity
;
1372 This
->Mode
->DataBits
= DataBits
;
1373 This
->Mode
->StopBits
= StopBits
;
1376 // See if Device Path Node has actually changed
1378 if (SerialDevice
->UartDevicePath
.BaudRate
== BaudRate
&&
1379 SerialDevice
->UartDevicePath
.DataBits
== DataBits
&&
1380 SerialDevice
->UartDevicePath
.Parity
== Parity
&&
1381 SerialDevice
->UartDevicePath
.StopBits
== StopBits
1383 gBS
->RestoreTPL (Tpl
);
1387 // Update the device path
1389 SerialDevice
->UartDevicePath
.BaudRate
= BaudRate
;
1390 SerialDevice
->UartDevicePath
.DataBits
= DataBits
;
1391 SerialDevice
->UartDevicePath
.Parity
= (UINT8
) Parity
;
1392 SerialDevice
->UartDevicePath
.StopBits
= (UINT8
) StopBits
;
1394 NewDevicePath
= AppendDevicePathNode (
1395 SerialDevice
->ParentDevicePath
,
1396 (EFI_DEVICE_PATH_PROTOCOL
*) &SerialDevice
->UartDevicePath
1398 if (NewDevicePath
== NULL
) {
1399 gBS
->RestoreTPL (Tpl
);
1400 return EFI_DEVICE_ERROR
;
1403 if (SerialDevice
->Handle
!= NULL
) {
1404 Status
= gBS
->ReinstallProtocolInterface (
1405 SerialDevice
->Handle
,
1406 &gEfiDevicePathProtocolGuid
,
1407 SerialDevice
->DevicePath
,
1410 if (EFI_ERROR (Status
)) {
1411 gBS
->RestoreTPL (Tpl
);
1416 if (SerialDevice
->DevicePath
) {
1417 gBS
->FreePool (SerialDevice
->DevicePath
);
1420 SerialDevice
->DevicePath
= NewDevicePath
;
1422 gBS
->RestoreTPL (Tpl
);
1429 IsaSerialSetControl (
1430 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1435 Routine Description:
1441 This - Pointer to EFI_SERIAL_IO_PROTOCOL
1442 Control - Control bits that can be settable
1446 EFI_SUCCESS - New Control bits were set successfully
1447 EFI_UNSUPPORTED - The Control bits wanted to set are not supported
1451 SERIAL_DEV
*SerialDevice
;
1452 SERIAL_PORT_MCR Mcr
;
1456 // The control bits that can be set are :
1457 // EFI_SERIAL_DATA_TERMINAL_READY: 0x0001 // WO
1458 // EFI_SERIAL_REQUEST_TO_SEND: 0x0002 // WO
1459 // EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE: 0x1000 // RW
1460 // EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE: 0x2000 // RW
1462 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1465 // first determine the parameter is invalid
1467 if (Control
& 0xffff8ffc) {
1468 return EFI_UNSUPPORTED
;
1471 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1473 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1477 SerialDevice
->SoftwareLoopbackEnable
= FALSE
;
1478 SerialDevice
->HardwareFlowControl
= FALSE
;
1480 if (Control
& EFI_SERIAL_DATA_TERMINAL_READY
) {
1484 if (Control
& EFI_SERIAL_REQUEST_TO_SEND
) {
1488 if (Control
& EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
) {
1492 if (Control
& EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
) {
1493 SerialDevice
->HardwareFlowControl
= TRUE
;
1496 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
1498 if (Control
& EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
) {
1499 SerialDevice
->SoftwareLoopbackEnable
= TRUE
;
1502 gBS
->RestoreTPL (Tpl
);
1509 IsaSerialGetControl (
1510 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1515 Routine Description:
1521 This - Pointer to EFI_SERIAL_IO_PROTOCOL
1522 Control - Control signals of the serial device
1526 EFI_SUCCESS - Get Control signals successfully
1530 SERIAL_DEV
*SerialDevice
;
1531 SERIAL_PORT_MSR Msr
;
1532 SERIAL_PORT_MCR Mcr
;
1535 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1537 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1542 // Read the Modem Status Register
1544 Msr
.Data
= READ_MSR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1547 *Control
|= EFI_SERIAL_CLEAR_TO_SEND
;
1551 *Control
|= EFI_SERIAL_DATA_SET_READY
;
1555 *Control
|= EFI_SERIAL_RING_INDICATE
;
1559 *Control
|= EFI_SERIAL_CARRIER_DETECT
;
1562 // Read the Modem Control Register
1564 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1566 if (Mcr
.Bits
.DTRC
) {
1567 *Control
|= EFI_SERIAL_DATA_TERMINAL_READY
;
1571 *Control
|= EFI_SERIAL_REQUEST_TO_SEND
;
1575 *Control
|= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
;
1578 if (SerialDevice
->HardwareFlowControl
) {
1579 *Control
|= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
;
1582 // See if the Transmit FIFO is empty
1584 IsaSerialReceiveTransmit (SerialDevice
);
1586 if (IsaSerialFifoEmpty (&SerialDevice
->Transmit
)) {
1587 *Control
|= EFI_SERIAL_OUTPUT_BUFFER_EMPTY
;
1590 // See if the Receive FIFO is empty.
1592 IsaSerialReceiveTransmit (SerialDevice
);
1594 if (IsaSerialFifoEmpty (&SerialDevice
->Receive
)) {
1595 *Control
|= EFI_SERIAL_INPUT_BUFFER_EMPTY
;
1598 if (SerialDevice
->SoftwareLoopbackEnable
) {
1599 *Control
|= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
;
1602 gBS
->RestoreTPL (Tpl
);
1610 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1611 IN OUT UINTN
*BufferSize
,
1616 Routine Description:
1618 Write the specified number of bytes to serial device
1622 This - Pointer to EFI_SERIAL_IO_PROTOCOL
1623 BufferSize - On input the size of Buffer, on output the amount of
1624 data actually written
1625 Buffer - The buffer of data to write
1629 EFI_SUCCESS - The data were written successfully
1630 EFI_DEVICE_ERROR - The device reported an error
1631 EFI_TIMEOUT - The write operation was stopped due to timeout
1635 SERIAL_DEV
*SerialDevice
;
1642 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1646 if (*BufferSize
== 0) {
1651 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1653 EFI_P_EC_OUTPUT_ERROR
| EFI_PERIPHERAL_SERIAL_PORT
,
1654 SerialDevice
->DevicePath
1657 return EFI_DEVICE_ERROR
;
1660 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1662 CharBuffer
= (UINT8
*) Buffer
;
1664 for (Index
= 0; Index
< *BufferSize
; Index
++) {
1665 IsaSerialFifoAdd (&SerialDevice
->Transmit
, CharBuffer
[Index
]);
1667 while (IsaSerialReceiveTransmit (SerialDevice
) != EFI_SUCCESS
|| !IsaSerialFifoEmpty (&SerialDevice
->Transmit
)) {
1669 // Unsuccessful write so check if timeout has expired, if not,
1670 // stall for a bit, increment time elapsed, and try again
1672 if (Elapsed
>= This
->Mode
->Timeout
) {
1673 *BufferSize
= ActualWrite
;
1674 gBS
->RestoreTPL (Tpl
);
1678 gBS
->Stall (TIMEOUT_STALL_INTERVAL
);
1680 Elapsed
+= TIMEOUT_STALL_INTERVAL
;
1685 // Successful write so reset timeout
1690 gBS
->RestoreTPL (Tpl
);
1698 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1699 IN OUT UINTN
*BufferSize
,
1704 Routine Description:
1706 Read the specified number of bytes from serial device
1710 This - Pointer to EFI_SERIAL_IO_PROTOCOL
1711 BufferSize - On input the size of Buffer, on output the amount of
1712 data returned in buffer
1713 Buffer - The buffer to return the data into
1717 EFI_SUCCESS - The data were read successfully
1718 EFI_DEVICE_ERROR - The device reported an error
1719 EFI_TIMEOUT - The read operation was stopped due to timeout
1723 SERIAL_DEV
*SerialDevice
;
1730 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1733 if (*BufferSize
== 0) {
1738 return EFI_DEVICE_ERROR
;
1741 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1743 Status
= IsaSerialReceiveTransmit (SerialDevice
);
1745 if (EFI_ERROR (Status
)) {
1748 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1750 EFI_P_EC_INPUT_ERROR
| EFI_PERIPHERAL_SERIAL_PORT
,
1751 SerialDevice
->DevicePath
1754 gBS
->RestoreTPL (Tpl
);
1756 return EFI_DEVICE_ERROR
;
1759 CharBuffer
= (UINT8
*) Buffer
;
1760 for (Index
= 0; Index
< *BufferSize
; Index
++) {
1761 while (IsaSerialFifoRemove (&SerialDevice
->Receive
, &(CharBuffer
[Index
])) != EFI_SUCCESS
) {
1763 // Unsuccessful read so check if timeout has expired, if not,
1764 // stall for a bit, increment time elapsed, and try again
1765 // Need this time out to get conspliter to work.
1767 if (Elapsed
>= This
->Mode
->Timeout
) {
1768 *BufferSize
= Index
;
1769 gBS
->RestoreTPL (Tpl
);
1773 gBS
->Stall (TIMEOUT_STALL_INTERVAL
);
1774 Elapsed
+= TIMEOUT_STALL_INTERVAL
;
1776 Status
= IsaSerialReceiveTransmit (SerialDevice
);
1777 if (Status
== EFI_DEVICE_ERROR
) {
1778 *BufferSize
= Index
;
1779 gBS
->RestoreTPL (Tpl
);
1780 return EFI_DEVICE_ERROR
;
1784 // Successful read so reset timeout
1789 IsaSerialReceiveTransmit (SerialDevice
);
1791 gBS
->RestoreTPL (Tpl
);
1797 IsaSerialPortPresent (
1798 IN SERIAL_DEV
*SerialDevice
1802 Routine Description:
1804 Use scratchpad register to test if this serial port is present
1808 SerialDevice - Pointer to serial device structure
1812 TRUE - The serial port is present
1813 FALSE - The serial port is NOT present
1825 Temp
= READ_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1826 WRITE_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, 0xAA);
1828 if (READ_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
) != 0xAA) {
1829 if (!FeaturePcdGet (PcdNtEmulatorEnable
)) {
1834 WRITE_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, 0x55);
1836 if (READ_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
) != 0x55) {
1837 if (!FeaturePcdGet (PcdNtEmulatorEnable
)) {
1844 WRITE_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Temp
);
1850 IN EFI_ISA_IO_PROTOCOL
*IsaIo
,
1851 IN UINT16 BaseAddress
,
1856 Routine Description:
1858 Use IsaIo protocol to read serial port
1862 IsaIo - Pointer to EFI_ISA_IO_PROTOCOL instance
1863 BaseAddress - Serial port register group base address
1864 Offset - Offset in register group
1868 Data read from serial port
1875 // Use IsaIo to access IO
1880 BaseAddress
+ Offset
,
1888 IsaSerialWritePort (
1889 IN EFI_ISA_IO_PROTOCOL
*IsaIo
,
1890 IN UINT16 BaseAddress
,
1896 Routine Description:
1898 Use IsaIo protocol to write serial port
1902 IsaIo - Pointer to EFI_ISA_IO_PROTOCOL instance
1903 BaseAddress - Serial port register group base address
1904 Offset - Offset in register group
1905 Data - data which is to be written to some serial port register
1914 // Use IsaIo to access IO
1919 BaseAddress
+ Offset
,