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
,
58 (UINT8
) (sizeof (UART_DEVICE_PATH
)),
59 (UINT8
) ((sizeof (UART_DEVICE_PATH
)) >> 8),
62 FixedPcdGet64 (PcdUartDefaultBaudRate
),
63 FixedPcdGet8 (PcdUartDefaultDataBits
),
64 FixedPcdGet8 (PcdUartDefaultParity
),
65 FixedPcdGet8 (PcdUartDefaultStopBits
)
72 SERIAL_MAX_BUFFER_SIZE
,
78 SERIAL_MAX_BUFFER_SIZE
,
88 The user Entry Point for module IsaSerial. The user code starts with this function.
90 @param[in] ImageHandle The firmware allocated handle for the EFI image.
91 @param[in] SystemTable A pointer to the EFI System Table.
93 @retval EFI_SUCCESS The entry point is executed successfully.
94 @retval other Some error occurs when executing this entry point.
100 IN EFI_HANDLE ImageHandle
,
101 IN EFI_SYSTEM_TABLE
*SystemTable
107 // Install driver model protocol(s).
109 Status
= EfiLibInstallAllDriverProtocols (
112 &gSerialControllerDriver
,
114 &gIsaSerialComponentName
,
118 ASSERT_EFI_ERROR (Status
);
127 SerialControllerDriverSupported (
128 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
129 IN EFI_HANDLE Controller
,
130 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
136 Check to see if this driver supports the given controller
140 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
141 Controller - The handle of the controller to test.
142 RemainingDevicePath - A pointer to the remaining portion of a device path.
146 EFI_SUCCESS - This driver can support the given controller
151 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
152 EFI_ISA_IO_PROTOCOL
*IsaIo
;
153 UART_DEVICE_PATH UartNode
;
156 // Ignore the RemainingDevicePath
159 // Open the IO Abstraction(s) needed to perform the supported test
161 Status
= gBS
->OpenProtocol (
163 &gEfiDevicePathProtocolGuid
,
164 (VOID
**) &ParentDevicePath
,
165 This
->DriverBindingHandle
,
167 EFI_OPEN_PROTOCOL_BY_DRIVER
169 if (Status
== EFI_ALREADY_STARTED
) {
173 if (EFI_ERROR (Status
)) {
179 &gEfiDevicePathProtocolGuid
,
180 This
->DriverBindingHandle
,
184 Status
= gBS
->OpenProtocol (
186 &gEfiIsaIoProtocolGuid
,
188 This
->DriverBindingHandle
,
190 EFI_OPEN_PROTOCOL_BY_DRIVER
193 if (Status
== EFI_ALREADY_STARTED
) {
197 if (EFI_ERROR (Status
)) {
201 // Use the ISA I/O Protocol to see if Controller is standard ISA UART that
202 // can be managed by this driver.
204 Status
= EFI_SUCCESS
;
205 if (IsaIo
->ResourceList
->Device
.HID
!= EISA_PNP_ID (0x501)) {
206 Status
= EFI_UNSUPPORTED
;
210 // Make sure RemainingDevicePath is valid
212 if (RemainingDevicePath
!= NULL
) {
213 Status
= EFI_UNSUPPORTED
;
216 (UART_DEVICE_PATH
*) RemainingDevicePath
,
217 sizeof (UART_DEVICE_PATH
)
219 if (UartNode
.Header
.Type
!= MESSAGING_DEVICE_PATH
||
220 UartNode
.Header
.SubType
!= MSG_UART_DP
||
221 sizeof (UART_DEVICE_PATH
) != DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL
*) &UartNode
)
226 if (UartNode
.BaudRate
> SERIAL_PORT_MAX_BAUD_RATE
) {
230 if (UartNode
.Parity
< NoParity
|| UartNode
.Parity
> SpaceParity
) {
234 if (UartNode
.DataBits
< 5 || UartNode
.DataBits
> 8) {
238 if (UartNode
.StopBits
< OneStopBit
|| UartNode
.StopBits
> TwoStopBits
) {
242 if ((UartNode
.DataBits
== 5) && (UartNode
.StopBits
== TwoStopBits
)) {
246 if ((UartNode
.DataBits
>= 6) && (UartNode
.DataBits
<= 8) && (UartNode
.StopBits
== OneFiveStopBits
)) {
250 Status
= EFI_SUCCESS
;
255 // Close the I/O Abstraction(s) used to perform the supported test
259 &gEfiIsaIoProtocolGuid
,
260 This
->DriverBindingHandle
,
269 SerialControllerDriverStart (
270 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
271 IN EFI_HANDLE Controller
,
272 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
278 Start to management the controller passed in
282 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
283 Controller - The handle of the controller to test.
284 RemainingDevicePath - A pointer to the remaining portion of a device path.
288 EFI_SUCCESS - Driver is started successfully
293 EFI_ISA_IO_PROTOCOL
*IsaIo
;
294 SERIAL_DEV
*SerialDevice
;
296 UART_DEVICE_PATH Node
;
297 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
298 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
300 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
304 // Get the Parent Device Path
306 Status
= gBS
->OpenProtocol (
308 &gEfiDevicePathProtocolGuid
,
309 (VOID
**) &ParentDevicePath
,
310 This
->DriverBindingHandle
,
312 EFI_OPEN_PROTOCOL_BY_DRIVER
314 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
318 // Report status code enable the serial
320 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
322 EFI_P_PC_ENABLE
| EFI_PERIPHERAL_SERIAL_PORT
,
327 // Grab the IO abstraction we need to get any work done
329 Status
= gBS
->OpenProtocol (
331 &gEfiIsaIoProtocolGuid
,
333 This
->DriverBindingHandle
,
335 EFI_OPEN_PROTOCOL_BY_DRIVER
337 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
341 if (Status
== EFI_ALREADY_STARTED
) {
343 if (RemainingDevicePath
== NULL
) {
347 // Make sure a child handle does not already exist. This driver can only
348 // produce one child per serial port.
350 Status
= gBS
->OpenProtocolInformation (
352 &gEfiIsaIoProtocolGuid
,
356 if (EFI_ERROR (Status
)) {
360 Status
= EFI_ALREADY_STARTED
;
361 for (Index
= 0; Index
< EntryCount
; Index
++) {
362 if (OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) {
363 Status
= gBS
->OpenProtocol (
364 OpenInfoBuffer
[Index
].ControllerHandle
,
365 &gEfiSerialIoProtocolGuid
,
367 This
->DriverBindingHandle
,
369 EFI_OPEN_PROTOCOL_GET_PROTOCOL
371 if (!EFI_ERROR (Status
)) {
372 CopyMem (&Node
, RemainingDevicePath
, sizeof (UART_DEVICE_PATH
));
373 Status
= SerialIo
->SetAttributes (
376 SerialIo
->Mode
->ReceiveFifoDepth
,
377 SerialIo
->Mode
->Timeout
,
378 (EFI_PARITY_TYPE
) Node
.Parity
,
380 (EFI_STOP_BITS_TYPE
) Node
.StopBits
387 gBS
->FreePool (OpenInfoBuffer
);
391 // Initialize the serial device instance
393 SerialDevice
= AllocateCopyPool (sizeof (SERIAL_DEV
), &gSerialDevTempate
);
394 if (SerialDevice
== NULL
) {
395 Status
= EFI_OUT_OF_RESOURCES
;
399 SerialDevice
->SerialIo
.Mode
= &(SerialDevice
->SerialMode
);
400 SerialDevice
->IsaIo
= IsaIo
;
401 SerialDevice
->ParentDevicePath
= ParentDevicePath
;
403 ADD_SERIAL_NAME (SerialDevice
, IsaIo
);
405 for (Index
= 0; SerialDevice
->IsaIo
->ResourceList
->ResourceItem
[Index
].Type
!= EfiIsaAcpiResourceEndOfList
; Index
++) {
406 if (SerialDevice
->IsaIo
->ResourceList
->ResourceItem
[Index
].Type
== EfiIsaAcpiResourceIo
) {
407 SerialDevice
->BaseAddress
= (UINT16
) SerialDevice
->IsaIo
->ResourceList
->ResourceItem
[Index
].StartRange
;
411 // Report status code the serial present
413 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
415 EFI_P_PC_PRESENCE_DETECT
| EFI_PERIPHERAL_SERIAL_PORT
,
419 if (!IsaSerialPortPresent (SerialDevice
)) {
420 Status
= EFI_DEVICE_ERROR
;
421 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
423 EFI_P_EC_NOT_DETECTED
| EFI_PERIPHERAL_SERIAL_PORT
,
429 if (RemainingDevicePath
!= NULL
) {
431 // Match the configuration of the RemainingDevicePath. IsHandleSupported()
432 // already checked to make sure the RemainingDevicePath contains settings
433 // that we can support.
435 CopyMem (&SerialDevice
->UartDevicePath
, RemainingDevicePath
, sizeof (UART_DEVICE_PATH
));
438 // Use the values from the gSerialDevTempate as no remaining device path was
443 // Build the device path by appending the UART node to the ParentDevicePath
444 // from the WinNtIo handle. The Uart setings are zero here, since
445 // SetAttribute() will update them to match the current setings.
447 SerialDevice
->DevicePath
= AppendDevicePathNode (
449 (EFI_DEVICE_PATH_PROTOCOL
*)&SerialDevice
->UartDevicePath
451 if (SerialDevice
->DevicePath
== NULL
) {
452 Status
= EFI_DEVICE_ERROR
;
457 // Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults.
459 SerialDevice
->SerialMode
.BaudRate
= SerialDevice
->UartDevicePath
.BaudRate
;
460 SerialDevice
->SerialMode
.DataBits
= SerialDevice
->UartDevicePath
.DataBits
;
461 SerialDevice
->SerialMode
.Parity
= SerialDevice
->UartDevicePath
.Parity
;
462 SerialDevice
->SerialMode
.StopBits
= SerialDevice
->UartDevicePath
.StopBits
;
465 // Issue a reset to initialize the COM port
467 Status
= SerialDevice
->SerialIo
.Reset (&SerialDevice
->SerialIo
);
468 if (EFI_ERROR (Status
)) {
469 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
471 EFI_P_EC_CONTROLLER_ERROR
| EFI_PERIPHERAL_SERIAL_PORT
,
477 // Install protocol interfaces for the serial device.
479 Status
= gBS
->InstallMultipleProtocolInterfaces (
480 &SerialDevice
->Handle
,
481 &gEfiDevicePathProtocolGuid
,
482 SerialDevice
->DevicePath
,
483 &gEfiSerialIoProtocolGuid
,
484 &SerialDevice
->SerialIo
,
487 if (EFI_ERROR (Status
)) {
491 // Open For Child Device
493 Status
= gBS
->OpenProtocol (
495 &gEfiIsaIoProtocolGuid
,
497 This
->DriverBindingHandle
,
498 SerialDevice
->Handle
,
499 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
503 if (EFI_ERROR (Status
)) {
506 &gEfiDevicePathProtocolGuid
,
507 This
->DriverBindingHandle
,
512 &gEfiIsaIoProtocolGuid
,
513 This
->DriverBindingHandle
,
517 if (SerialDevice
->DevicePath
) {
518 gBS
->FreePool (SerialDevice
->DevicePath
);
521 FreeUnicodeStringTable (SerialDevice
->ControllerNameTable
);
522 gBS
->FreePool (SerialDevice
);
531 SerialControllerDriverStop (
532 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
533 IN EFI_HANDLE Controller
,
534 IN UINTN NumberOfChildren
,
535 IN EFI_HANDLE
*ChildHandleBuffer
541 Disconnect this driver with the controller, uninstall related protocol instance
545 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
546 Controller - The handle of the controller to test.
547 NumberOfChildren - Number of child device.
548 RemainingDevicePath - A pointer to the remaining portion of a device path.
552 EFI_SUCCESS - Operation successfully
553 EFI_DEVICE_ERROR - Cannot stop the driver successfully
559 BOOLEAN AllChildrenStopped
;
560 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
561 SERIAL_DEV
*SerialDevice
;
562 EFI_ISA_IO_PROTOCOL
*IsaIo
;
563 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
565 Status
= gBS
->HandleProtocol (
567 &gEfiDevicePathProtocolGuid
,
568 (VOID
**) &DevicePath
572 // Report the status code disable the serial
574 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
576 EFI_P_PC_DISABLE
| EFI_PERIPHERAL_SERIAL_PORT
,
581 // Complete all outstanding transactions to Controller.
582 // Don't allow any new transaction to Controller to be started.
584 if (NumberOfChildren
== 0) {
586 // Close the bus driver
588 Status
= gBS
->CloseProtocol (
590 &gEfiIsaIoProtocolGuid
,
591 This
->DriverBindingHandle
,
595 Status
= gBS
->CloseProtocol (
597 &gEfiDevicePathProtocolGuid
,
598 This
->DriverBindingHandle
,
604 AllChildrenStopped
= TRUE
;
606 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
608 Status
= gBS
->OpenProtocol (
609 ChildHandleBuffer
[Index
],
610 &gEfiSerialIoProtocolGuid
,
612 This
->DriverBindingHandle
,
614 EFI_OPEN_PROTOCOL_GET_PROTOCOL
616 if (!EFI_ERROR (Status
)) {
618 SerialDevice
= SERIAL_DEV_FROM_THIS (SerialIo
);
620 Status
= gBS
->CloseProtocol (
622 &gEfiIsaIoProtocolGuid
,
623 This
->DriverBindingHandle
,
624 ChildHandleBuffer
[Index
]
627 Status
= gBS
->UninstallMultipleProtocolInterfaces (
628 ChildHandleBuffer
[Index
],
629 &gEfiDevicePathProtocolGuid
,
630 SerialDevice
->DevicePath
,
631 &gEfiSerialIoProtocolGuid
,
632 &SerialDevice
->SerialIo
,
635 if (EFI_ERROR (Status
)) {
638 &gEfiIsaIoProtocolGuid
,
640 This
->DriverBindingHandle
,
641 ChildHandleBuffer
[Index
],
642 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
645 if (SerialDevice
->DevicePath
) {
646 gBS
->FreePool (SerialDevice
->DevicePath
);
649 FreeUnicodeStringTable (SerialDevice
->ControllerNameTable
);
650 gBS
->FreePool (SerialDevice
);
654 if (EFI_ERROR (Status
)) {
655 AllChildrenStopped
= FALSE
;
659 if (!AllChildrenStopped
) {
660 return EFI_DEVICE_ERROR
;
668 IN SERIAL_DEV_FIFO
*Fifo
674 Detect whether specific FIFO is full or not
678 Fifo - A pointer to the Data Structure SERIAL_DEV_FIFO
682 TRUE - the FIFO is full
683 FALSE - the FIFO is not full
687 if (Fifo
->Surplus
== 0) {
696 IN SERIAL_DEV_FIFO
*Fifo
702 Detect whether specific FIFO is empty or not
706 Fifo - A pointer to the Data Structure SERIAL_DEV_FIFO
710 TRUE - the FIFO is empty
711 FALSE - the FIFO is not empty
715 if (Fifo
->Surplus
== SERIAL_MAX_BUFFER_SIZE
) {
724 IN SERIAL_DEV_FIFO
*Fifo
,
731 Add data to specific FIFO
735 Fifo - A pointer to the Data Structure SERIAL_DEV_FIFO
736 Data - the data added to FIFO
740 EFI_SUCCESS - Add data to specific FIFO successfully
741 EFI_OUT_OF_RESOURCE - Failed to add data because FIFO is already full
746 // if FIFO full can not add data
748 if (IsaSerialFifoFull (Fifo
)) {
749 return EFI_OUT_OF_RESOURCES
;
752 // FIFO is not full can add data
754 Fifo
->Data
[Fifo
->Last
] = Data
;
757 if (Fifo
->Last
== SERIAL_MAX_BUFFER_SIZE
) {
765 IsaSerialFifoRemove (
766 IN SERIAL_DEV_FIFO
*Fifo
,
773 Remove data from specific FIFO
777 Fifo - A pointer to the Data Structure SERIAL_DEV_FIFO
778 Data - the data removed from FIFO
781 EFI_SUCCESS - Remove data from specific FIFO successfully
782 EFI_OUT_OF_RESOURCE - Failed to remove data because FIFO is empty
787 // if FIFO is empty, no data can remove
789 if (IsaSerialFifoEmpty (Fifo
)) {
790 return EFI_OUT_OF_RESOURCES
;
793 // FIFO is not empty, can remove data
795 *Data
= Fifo
->Data
[Fifo
->First
];
798 if (Fifo
->First
== SERIAL_MAX_BUFFER_SIZE
) {
806 IsaSerialReceiveTransmit (
807 IN SERIAL_DEV
*SerialDevice
813 Reads and writes all avaliable data.
817 SerialDevice - The device to flush
821 EFI_SUCCESS - Data was read/written successfully.
822 EFI_OUT_OF_RESOURCE - Failed because software receive FIFO is full. Note, when
823 this happens, pending writes are not done.
829 BOOLEAN ReceiveFifoFull
;
837 // Begin the read or write
839 if (SerialDevice
->SoftwareLoopbackEnable
) {
841 ReceiveFifoFull
= IsaSerialFifoFull (&SerialDevice
->Receive
);
842 if (!IsaSerialFifoEmpty (&SerialDevice
->Transmit
)) {
843 IsaSerialFifoRemove (&SerialDevice
->Transmit
, &Data
);
844 if (ReceiveFifoFull
) {
845 return EFI_OUT_OF_RESOURCES
;
848 IsaSerialFifoAdd (&SerialDevice
->Receive
, Data
);
850 } while (!IsaSerialFifoEmpty (&SerialDevice
->Transmit
));
852 ReceiveFifoFull
= IsaSerialFifoFull (&SerialDevice
->Receive
);
854 Lsr
.Data
= READ_LSR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
856 if (FeaturePcdGet (PcdNtEmulatorEnable
)) {
858 // This is required for NT to avoid a forever-spin...
859 // This would be better if READ_LSR was a polling operation
860 // that would timeout.
865 // Flush incomming data to prevent a an overrun during a long write
867 if (Lsr
.Bits
.DR
&& !ReceiveFifoFull
) {
868 ReceiveFifoFull
= IsaSerialFifoFull (&SerialDevice
->Receive
);
869 if (!ReceiveFifoFull
) {
870 if (Lsr
.Bits
.FIFOE
|| Lsr
.Bits
.OE
|| Lsr
.Bits
.PE
|| Lsr
.Bits
.FE
|| Lsr
.Bits
.BI
) {
871 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
873 EFI_P_EC_INPUT_ERROR
| EFI_PERIPHERAL_SERIAL_PORT
,
874 SerialDevice
->DevicePath
876 if (Lsr
.Bits
.FIFOE
|| Lsr
.Bits
.PE
|| Lsr
.Bits
.FE
|| Lsr
.Bits
.BI
) {
877 Data
= READ_RBR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
882 // Make sure the receive data will not be missed, Assert DTR
884 if (SerialDevice
->HardwareFlowControl
) {
885 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
887 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
890 Data
= READ_RBR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
895 if (SerialDevice
->HardwareFlowControl
) {
896 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
898 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
901 IsaSerialFifoAdd (&SerialDevice
->Receive
, Data
);
905 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
907 EFI_P_SERIAL_PORT_PC_CLEAR_BUFFER
| EFI_PERIPHERAL_SERIAL_PORT
,
908 SerialDevice
->DevicePath
915 if (Lsr
.Bits
.THRE
&& !IsaSerialFifoEmpty (&SerialDevice
->Transmit
)) {
917 // Make sure the transmit data will not be missed
919 if (SerialDevice
->HardwareFlowControl
) {
923 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
925 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
930 Msr
.Data
= READ_MSR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
931 while (!Msr
.Bits
.CTS
) {
932 gBS
->Stall (TIMEOUT_STALL_INTERVAL
);
938 Msr
.Data
= READ_MSR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
942 IsaSerialFifoRemove (&SerialDevice
->Transmit
, &Data
);
943 WRITE_THR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Data
);
947 // write the data out
949 if (!SerialDevice
->HardwareFlowControl
) {
950 IsaSerialFifoRemove (&SerialDevice
->Transmit
, &Data
);
951 WRITE_THR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Data
);
954 // Make sure the transmit data will not be missed
956 if (SerialDevice
->HardwareFlowControl
) {
960 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
962 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
965 } while (Lsr
.Bits
.THRE
&& !IsaSerialFifoEmpty (&SerialDevice
->Transmit
));
971 // Interface Functions
976 IN EFI_SERIAL_IO_PROTOCOL
*This
986 This - Pointer to EFI_SERIAL_IO_PROTOCOL
990 EFI_SUCCESS - Reset successfully
991 EFI_DEVICE_ERROR - Failed to reset
996 SERIAL_DEV
*SerialDevice
;
1000 SERIAL_PORT_FCR Fcr
;
1003 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1006 // Report the status code reset the serial
1008 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1010 EFI_P_PC_RESET
| EFI_PERIPHERAL_SERIAL_PORT
,
1011 SerialDevice
->DevicePath
1014 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1017 // Make sure DLAB is 0.
1019 Lcr
.Data
= READ_LCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1021 WRITE_LCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Lcr
.Data
);
1024 // Turn off all interrupts
1026 Ier
.Data
= READ_IER (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1031 WRITE_IER (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Ier
.Data
);
1034 // Disable the FIFO.
1036 Fcr
.Bits
.TRFIFOE
= 0;
1037 WRITE_FCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Fcr
.Data
);
1040 // Turn off loopback and disable device interrupt.
1042 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1046 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
1049 // Clear the scratch pad register
1051 WRITE_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, 0);
1054 // Go set the current attributes
1056 Status
= This
->SetAttributes (
1058 This
->Mode
->BaudRate
,
1059 This
->Mode
->ReceiveFifoDepth
,
1060 This
->Mode
->Timeout
,
1061 (EFI_PARITY_TYPE
) This
->Mode
->Parity
,
1062 (UINT8
) This
->Mode
->DataBits
,
1063 (EFI_STOP_BITS_TYPE
) This
->Mode
->StopBits
1066 if (EFI_ERROR (Status
)) {
1067 gBS
->RestoreTPL (Tpl
);
1068 return EFI_DEVICE_ERROR
;
1071 // Go set the current control bits
1073 Status
= This
->SetControl (
1075 This
->Mode
->ControlMask
1078 if (EFI_ERROR (Status
)) {
1079 gBS
->RestoreTPL (Tpl
);
1080 return EFI_DEVICE_ERROR
;
1083 // for 16550A enable FIFO, 16550 disable FIFO
1085 Fcr
.Bits
.TRFIFOE
= 1;
1086 Fcr
.Bits
.RESETRF
= 1;
1087 Fcr
.Bits
.RESETTF
= 1;
1088 WRITE_FCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Fcr
.Data
);
1091 // Reset the software FIFO
1093 SerialDevice
->Receive
.First
= 0;
1094 SerialDevice
->Receive
.Last
= 0;
1095 SerialDevice
->Receive
.Surplus
= SERIAL_MAX_BUFFER_SIZE
;
1096 SerialDevice
->Transmit
.First
= 0;
1097 SerialDevice
->Transmit
.Last
= 0;
1098 SerialDevice
->Transmit
.Surplus
= SERIAL_MAX_BUFFER_SIZE
;
1100 gBS
->RestoreTPL (Tpl
);
1103 // Device reset is complete
1110 IsaSerialSetAttributes (
1111 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1113 IN UINT32 ReceiveFifoDepth
,
1115 IN EFI_PARITY_TYPE Parity
,
1117 IN EFI_STOP_BITS_TYPE StopBits
1121 Routine Description:
1123 Set new attributes to a serial device
1127 This - Pointer to EFI_SERIAL_IO_PROTOCOL
1128 BaudRate - The baudrate of the serial device
1129 ReceiveFifoDepth - The depth of receive FIFO buffer
1130 Timeout - The request timeout for a single char
1131 Parity - The type of parity used in serial device
1132 DataBits - Number of databits used in serial device
1133 StopBits - Number of stopbits used in serial device
1137 EFI_SUCCESS - The new attributes were set
1138 EFI_INVALID_PARAMETERS - One or more attributes have an unsupported value
1139 EFI_UNSUPPORTED - Data Bits can not set to 5 or 6
1140 EFI_DEVICE_ERROR - The serial device is not functioning correctly (no return)
1145 SERIAL_DEV
*SerialDevice
;
1148 SERIAL_PORT_LCR Lcr
;
1149 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
1152 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1155 // Check for default settings and fill in actual values.
1157 if (BaudRate
== 0) {
1158 BaudRate
= FixedPcdGet64 (PcdUartDefaultBaudRate
);
1161 if (ReceiveFifoDepth
== 0) {
1162 ReceiveFifoDepth
= SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH
;
1166 Timeout
= SERIAL_PORT_DEFAULT_TIMEOUT
;
1169 if (Parity
== DefaultParity
) {
1170 Parity
= (EFI_PARITY_TYPE
)FixedPcdGet8 (PcdUartDefaultParity
);
1173 if (DataBits
== 0) {
1174 DataBits
= FixedPcdGet8 (PcdUartDefaultDataBits
);
1177 if (StopBits
== DefaultStopBits
) {
1178 StopBits
= (EFI_STOP_BITS_TYPE
) FixedPcdGet8 (PcdUartDefaultStopBits
);
1181 // 5 and 6 data bits can not be verified on a 16550A UART
1182 // Return EFI_INVALID_PARAMETER if an attempt is made to use these settings.
1184 if ((DataBits
== 5) || (DataBits
== 6)) {
1185 return EFI_INVALID_PARAMETER
;
1188 // Make sure all parameters are valid
1190 if ((BaudRate
> SERIAL_PORT_MAX_BAUD_RATE
) || (BaudRate
< SERIAL_PORT_MIN_BAUD_RATE
)) {
1191 return EFI_INVALID_PARAMETER
;
1194 // 50,75,110,134,150,300,600,1200,1800,2000,2400,3600,4800,7200,9600,19200,
1195 // 38400,57600,115200
1197 if (BaudRate
< 75) {
1199 } else if (BaudRate
< 110) {
1201 } else if (BaudRate
< 134) {
1203 } else if (BaudRate
< 150) {
1205 } else if (BaudRate
< 300) {
1207 } else if (BaudRate
< 600) {
1209 } else if (BaudRate
< 1200) {
1211 } else if (BaudRate
< 1800) {
1213 } else if (BaudRate
< 2000) {
1215 } else if (BaudRate
< 2400) {
1217 } else if (BaudRate
< 3600) {
1219 } else if (BaudRate
< 4800) {
1221 } else if (BaudRate
< 7200) {
1223 } else if (BaudRate
< 9600) {
1225 } else if (BaudRate
< 19200) {
1227 } else if (BaudRate
< 38400) {
1229 } else if (BaudRate
< 57600) {
1231 } else if (BaudRate
< 115200) {
1233 } else if (BaudRate
<= SERIAL_PORT_MAX_BAUD_RATE
) {
1237 if ((ReceiveFifoDepth
< 1) || (ReceiveFifoDepth
> SERIAL_PORT_MAX_RECEIVE_FIFO_DEPTH
)) {
1238 return EFI_INVALID_PARAMETER
;
1241 if ((Timeout
< SERIAL_PORT_MIN_TIMEOUT
) || (Timeout
> SERIAL_PORT_MAX_TIMEOUT
)) {
1242 return EFI_INVALID_PARAMETER
;
1245 if ((Parity
< NoParity
) || (Parity
> SpaceParity
)) {
1246 return EFI_INVALID_PARAMETER
;
1249 if ((DataBits
< 5) || (DataBits
> 8)) {
1250 return EFI_INVALID_PARAMETER
;
1253 if ((StopBits
< OneStopBit
) || (StopBits
> TwoStopBits
)) {
1254 return EFI_INVALID_PARAMETER
;
1257 // for DataBits = 5, StopBits can not set TwoStopBits
1259 // if ((DataBits == 5) && (StopBits == TwoStopBits)) {
1260 // return EFI_INVALID_PARAMETER;
1263 // for DataBits = 6,7,8, StopBits can not set OneFiveStopBits
1265 if ((DataBits
>= 6) && (DataBits
<= 8) && (StopBits
== OneFiveStopBits
)) {
1266 return EFI_INVALID_PARAMETER
;
1270 // Compute divisor use to program the baud rate using a round determination
1272 Divisor
= (UINT32
) DivU64x32Remainder (
1273 SERIAL_PORT_INPUT_CLOCK
,
1274 ((UINT32
) BaudRate
* 16),
1281 if ((Divisor
== 0) || (Divisor
& 0xffff0000)) {
1282 return EFI_INVALID_PARAMETER
;
1285 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1288 // Compute the actual baud rate that the serial port will be programmed for.
1290 BaudRate
= SERIAL_PORT_INPUT_CLOCK
/ Divisor
/ 16;
1293 // Put serial port on Divisor Latch Mode
1295 Lcr
.Data
= READ_LCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1297 WRITE_LCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Lcr
.Data
);
1300 // Write the divisor to the serial port
1302 WRITE_DLL (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, (UINT8
) (Divisor
& 0xff));
1303 WRITE_DLM (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, (UINT8
) ((Divisor
>> 8) & 0xff));
1306 // Put serial port back in normal mode and set remaining attributes.
1313 Lcr
.Bits
.EVENPAR
= 0;
1314 Lcr
.Bits
.STICPAR
= 0;
1319 Lcr
.Bits
.EVENPAR
= 1;
1320 Lcr
.Bits
.STICPAR
= 0;
1325 Lcr
.Bits
.EVENPAR
= 0;
1326 Lcr
.Bits
.STICPAR
= 0;
1331 Lcr
.Bits
.EVENPAR
= 1;
1332 Lcr
.Bits
.STICPAR
= 1;
1337 Lcr
.Bits
.EVENPAR
= 0;
1338 Lcr
.Bits
.STICPAR
= 1;
1350 case OneFiveStopBits
:
1361 Lcr
.Bits
.SERIALDB
= (UINT8
) ((DataBits
- 5) & 0x03);
1362 WRITE_LCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Lcr
.Data
);
1365 // Set the Serial I/O mode
1367 This
->Mode
->BaudRate
= BaudRate
;
1368 This
->Mode
->ReceiveFifoDepth
= ReceiveFifoDepth
;
1369 This
->Mode
->Timeout
= Timeout
;
1370 This
->Mode
->Parity
= Parity
;
1371 This
->Mode
->DataBits
= DataBits
;
1372 This
->Mode
->StopBits
= StopBits
;
1375 // See if Device Path Node has actually changed
1377 if (SerialDevice
->UartDevicePath
.BaudRate
== BaudRate
&&
1378 SerialDevice
->UartDevicePath
.DataBits
== DataBits
&&
1379 SerialDevice
->UartDevicePath
.Parity
== Parity
&&
1380 SerialDevice
->UartDevicePath
.StopBits
== StopBits
1382 gBS
->RestoreTPL (Tpl
);
1386 // Update the device path
1388 SerialDevice
->UartDevicePath
.BaudRate
= BaudRate
;
1389 SerialDevice
->UartDevicePath
.DataBits
= DataBits
;
1390 SerialDevice
->UartDevicePath
.Parity
= (UINT8
) Parity
;
1391 SerialDevice
->UartDevicePath
.StopBits
= (UINT8
) StopBits
;
1393 NewDevicePath
= AppendDevicePathNode (
1394 SerialDevice
->ParentDevicePath
,
1395 (EFI_DEVICE_PATH_PROTOCOL
*) &SerialDevice
->UartDevicePath
1397 if (NewDevicePath
== NULL
) {
1398 gBS
->RestoreTPL (Tpl
);
1399 return EFI_DEVICE_ERROR
;
1402 if (SerialDevice
->Handle
!= NULL
) {
1403 Status
= gBS
->ReinstallProtocolInterface (
1404 SerialDevice
->Handle
,
1405 &gEfiDevicePathProtocolGuid
,
1406 SerialDevice
->DevicePath
,
1409 if (EFI_ERROR (Status
)) {
1410 gBS
->RestoreTPL (Tpl
);
1415 if (SerialDevice
->DevicePath
) {
1416 gBS
->FreePool (SerialDevice
->DevicePath
);
1419 SerialDevice
->DevicePath
= NewDevicePath
;
1421 gBS
->RestoreTPL (Tpl
);
1428 IsaSerialSetControl (
1429 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1434 Routine Description:
1440 This - Pointer to EFI_SERIAL_IO_PROTOCOL
1441 Control - Control bits that can be settable
1445 EFI_SUCCESS - New Control bits were set successfully
1446 EFI_UNSUPPORTED - The Control bits wanted to set are not supported
1450 SERIAL_DEV
*SerialDevice
;
1451 SERIAL_PORT_MCR Mcr
;
1455 // The control bits that can be set are :
1456 // EFI_SERIAL_DATA_TERMINAL_READY: 0x0001 // WO
1457 // EFI_SERIAL_REQUEST_TO_SEND: 0x0002 // WO
1458 // EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE: 0x1000 // RW
1459 // EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE: 0x2000 // RW
1461 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1464 // first determine the parameter is invalid
1466 if (Control
& 0xffff8ffc) {
1467 return EFI_UNSUPPORTED
;
1470 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1472 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1476 SerialDevice
->SoftwareLoopbackEnable
= FALSE
;
1477 SerialDevice
->HardwareFlowControl
= FALSE
;
1479 if (Control
& EFI_SERIAL_DATA_TERMINAL_READY
) {
1483 if (Control
& EFI_SERIAL_REQUEST_TO_SEND
) {
1487 if (Control
& EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
) {
1491 if (Control
& EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
) {
1492 SerialDevice
->HardwareFlowControl
= TRUE
;
1495 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
1497 if (Control
& EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
) {
1498 SerialDevice
->SoftwareLoopbackEnable
= TRUE
;
1501 gBS
->RestoreTPL (Tpl
);
1508 IsaSerialGetControl (
1509 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1514 Routine Description:
1520 This - Pointer to EFI_SERIAL_IO_PROTOCOL
1521 Control - Control signals of the serial device
1525 EFI_SUCCESS - Get Control signals successfully
1529 SERIAL_DEV
*SerialDevice
;
1530 SERIAL_PORT_MSR Msr
;
1531 SERIAL_PORT_MCR Mcr
;
1534 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1536 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1541 // Read the Modem Status Register
1543 Msr
.Data
= READ_MSR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1546 *Control
|= EFI_SERIAL_CLEAR_TO_SEND
;
1550 *Control
|= EFI_SERIAL_DATA_SET_READY
;
1554 *Control
|= EFI_SERIAL_RING_INDICATE
;
1558 *Control
|= EFI_SERIAL_CARRIER_DETECT
;
1561 // Read the Modem Control Register
1563 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1565 if (Mcr
.Bits
.DTRC
) {
1566 *Control
|= EFI_SERIAL_DATA_TERMINAL_READY
;
1570 *Control
|= EFI_SERIAL_REQUEST_TO_SEND
;
1574 *Control
|= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
;
1577 if (SerialDevice
->HardwareFlowControl
) {
1578 *Control
|= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
;
1581 // See if the Transmit FIFO is empty
1583 IsaSerialReceiveTransmit (SerialDevice
);
1585 if (IsaSerialFifoEmpty (&SerialDevice
->Transmit
)) {
1586 *Control
|= EFI_SERIAL_OUTPUT_BUFFER_EMPTY
;
1589 // See if the Receive FIFO is empty.
1591 IsaSerialReceiveTransmit (SerialDevice
);
1593 if (IsaSerialFifoEmpty (&SerialDevice
->Receive
)) {
1594 *Control
|= EFI_SERIAL_INPUT_BUFFER_EMPTY
;
1597 if (SerialDevice
->SoftwareLoopbackEnable
) {
1598 *Control
|= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
;
1601 gBS
->RestoreTPL (Tpl
);
1609 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1610 IN OUT UINTN
*BufferSize
,
1615 Routine Description:
1617 Write the specified number of bytes to serial device
1621 This - Pointer to EFI_SERIAL_IO_PROTOCOL
1622 BufferSize - On input the size of Buffer, on output the amount of
1623 data actually written
1624 Buffer - The buffer of data to write
1628 EFI_SUCCESS - The data were written successfully
1629 EFI_DEVICE_ERROR - The device reported an error
1630 EFI_TIMEOUT - The write operation was stopped due to timeout
1634 SERIAL_DEV
*SerialDevice
;
1641 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1645 if (*BufferSize
== 0) {
1650 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1652 EFI_P_EC_OUTPUT_ERROR
| EFI_PERIPHERAL_SERIAL_PORT
,
1653 SerialDevice
->DevicePath
1656 return EFI_DEVICE_ERROR
;
1659 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1661 CharBuffer
= (UINT8
*) Buffer
;
1663 for (Index
= 0; Index
< *BufferSize
; Index
++) {
1664 IsaSerialFifoAdd (&SerialDevice
->Transmit
, CharBuffer
[Index
]);
1666 while (IsaSerialReceiveTransmit (SerialDevice
) != EFI_SUCCESS
|| !IsaSerialFifoEmpty (&SerialDevice
->Transmit
)) {
1668 // Unsuccessful write so check if timeout has expired, if not,
1669 // stall for a bit, increment time elapsed, and try again
1671 if (Elapsed
>= This
->Mode
->Timeout
) {
1672 *BufferSize
= ActualWrite
;
1673 gBS
->RestoreTPL (Tpl
);
1677 gBS
->Stall (TIMEOUT_STALL_INTERVAL
);
1679 Elapsed
+= TIMEOUT_STALL_INTERVAL
;
1684 // Successful write so reset timeout
1689 gBS
->RestoreTPL (Tpl
);
1697 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1698 IN OUT UINTN
*BufferSize
,
1703 Routine Description:
1705 Read the specified number of bytes from serial device
1709 This - Pointer to EFI_SERIAL_IO_PROTOCOL
1710 BufferSize - On input the size of Buffer, on output the amount of
1711 data returned in buffer
1712 Buffer - The buffer to return the data into
1716 EFI_SUCCESS - The data were read successfully
1717 EFI_DEVICE_ERROR - The device reported an error
1718 EFI_TIMEOUT - The read operation was stopped due to timeout
1722 SERIAL_DEV
*SerialDevice
;
1729 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1732 if (*BufferSize
== 0) {
1737 return EFI_DEVICE_ERROR
;
1740 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1742 Status
= IsaSerialReceiveTransmit (SerialDevice
);
1744 if (EFI_ERROR (Status
)) {
1747 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1749 EFI_P_EC_INPUT_ERROR
| EFI_PERIPHERAL_SERIAL_PORT
,
1750 SerialDevice
->DevicePath
1753 gBS
->RestoreTPL (Tpl
);
1755 return EFI_DEVICE_ERROR
;
1758 CharBuffer
= (UINT8
*) Buffer
;
1759 for (Index
= 0; Index
< *BufferSize
; Index
++) {
1760 while (IsaSerialFifoRemove (&SerialDevice
->Receive
, &(CharBuffer
[Index
])) != EFI_SUCCESS
) {
1762 // Unsuccessful read so check if timeout has expired, if not,
1763 // stall for a bit, increment time elapsed, and try again
1764 // Need this time out to get conspliter to work.
1766 if (Elapsed
>= This
->Mode
->Timeout
) {
1767 *BufferSize
= Index
;
1768 gBS
->RestoreTPL (Tpl
);
1772 gBS
->Stall (TIMEOUT_STALL_INTERVAL
);
1773 Elapsed
+= TIMEOUT_STALL_INTERVAL
;
1775 Status
= IsaSerialReceiveTransmit (SerialDevice
);
1776 if (Status
== EFI_DEVICE_ERROR
) {
1777 *BufferSize
= Index
;
1778 gBS
->RestoreTPL (Tpl
);
1779 return EFI_DEVICE_ERROR
;
1783 // Successful read so reset timeout
1788 IsaSerialReceiveTransmit (SerialDevice
);
1790 gBS
->RestoreTPL (Tpl
);
1796 IsaSerialPortPresent (
1797 IN SERIAL_DEV
*SerialDevice
1801 Routine Description:
1803 Use scratchpad register to test if this serial port is present
1807 SerialDevice - Pointer to serial device structure
1811 TRUE - The serial port is present
1812 FALSE - The serial port is NOT present
1824 Temp
= READ_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1825 WRITE_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, 0xAA);
1827 if (READ_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
) != 0xAA) {
1828 if (!FeaturePcdGet (PcdNtEmulatorEnable
)) {
1833 WRITE_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, 0x55);
1835 if (READ_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
) != 0x55) {
1836 if (!FeaturePcdGet (PcdNtEmulatorEnable
)) {
1843 WRITE_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Temp
);
1849 IN EFI_ISA_IO_PROTOCOL
*IsaIo
,
1850 IN UINT16 BaseAddress
,
1855 Routine Description:
1857 Use IsaIo protocol to read serial port
1861 IsaIo - Pointer to EFI_ISA_IO_PROTOCOL instance
1862 BaseAddress - Serial port register group base address
1863 Offset - Offset in register group
1867 Data read from serial port
1874 // Use IsaIo to access IO
1879 BaseAddress
+ Offset
,
1887 IsaSerialWritePort (
1888 IN EFI_ISA_IO_PROTOCOL
*IsaIo
,
1889 IN UINT16 BaseAddress
,
1895 Routine Description:
1897 Use IsaIo protocol to write serial port
1901 IsaIo - Pointer to EFI_ISA_IO_PROTOCOL instance
1902 BaseAddress - Serial port register group base address
1903 Offset - Offset in register group
1904 Data - data which is to be written to some serial port register
1913 // Use IsaIo to access IO
1918 BaseAddress
+ Offset
,