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
= EfiLibInstallAllDriverProtocols (
114 &gSerialControllerDriver
,
116 &gIsaSerialComponentName
,
120 ASSERT_EFI_ERROR (Status
);
129 SerialControllerDriverSupported (
130 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
131 IN EFI_HANDLE Controller
,
132 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
138 Check to see if this driver supports the given controller
142 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
143 Controller - The handle of the controller to test.
144 RemainingDevicePath - A pointer to the remaining portion of a device path.
148 EFI_SUCCESS - This driver can support the given controller
153 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
154 EFI_ISA_IO_PROTOCOL
*IsaIo
;
155 UART_DEVICE_PATH UartNode
;
158 // Ignore the RemainingDevicePath
161 // Open the IO Abstraction(s) needed to perform the supported test
163 Status
= gBS
->OpenProtocol (
165 &gEfiDevicePathProtocolGuid
,
166 (VOID
**) &ParentDevicePath
,
167 This
->DriverBindingHandle
,
169 EFI_OPEN_PROTOCOL_BY_DRIVER
171 if (Status
== EFI_ALREADY_STARTED
) {
175 if (EFI_ERROR (Status
)) {
181 &gEfiDevicePathProtocolGuid
,
182 This
->DriverBindingHandle
,
186 Status
= gBS
->OpenProtocol (
188 &gEfiIsaIoProtocolGuid
,
190 This
->DriverBindingHandle
,
192 EFI_OPEN_PROTOCOL_BY_DRIVER
195 if (Status
== EFI_ALREADY_STARTED
) {
199 if (EFI_ERROR (Status
)) {
203 // Use the ISA I/O Protocol to see if Controller is standard ISA UART that
204 // can be managed by this driver.
206 Status
= EFI_SUCCESS
;
207 if (IsaIo
->ResourceList
->Device
.HID
!= EISA_PNP_ID (0x501)) {
208 Status
= EFI_UNSUPPORTED
;
212 // Make sure RemainingDevicePath is valid
214 if (RemainingDevicePath
!= NULL
) {
215 Status
= EFI_UNSUPPORTED
;
218 (UART_DEVICE_PATH
*) RemainingDevicePath
,
219 sizeof (UART_DEVICE_PATH
)
221 if (UartNode
.Header
.Type
!= MESSAGING_DEVICE_PATH
||
222 UartNode
.Header
.SubType
!= MSG_UART_DP
||
223 sizeof (UART_DEVICE_PATH
) != DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL
*) &UartNode
)
228 if (UartNode
.BaudRate
> SERIAL_PORT_MAX_BAUD_RATE
) {
232 if (UartNode
.Parity
< NoParity
|| UartNode
.Parity
> SpaceParity
) {
236 if (UartNode
.DataBits
< 5 || UartNode
.DataBits
> 8) {
240 if (UartNode
.StopBits
< OneStopBit
|| UartNode
.StopBits
> TwoStopBits
) {
244 if ((UartNode
.DataBits
== 5) && (UartNode
.StopBits
== TwoStopBits
)) {
248 if ((UartNode
.DataBits
>= 6) && (UartNode
.DataBits
<= 8) && (UartNode
.StopBits
== OneFiveStopBits
)) {
252 Status
= EFI_SUCCESS
;
257 // Close the I/O Abstraction(s) used to perform the supported test
261 &gEfiIsaIoProtocolGuid
,
262 This
->DriverBindingHandle
,
271 SerialControllerDriverStart (
272 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
273 IN EFI_HANDLE Controller
,
274 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
280 Start to management the controller passed in
284 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
285 Controller - The handle of the controller to test.
286 RemainingDevicePath - A pointer to the remaining portion of a device path.
290 EFI_SUCCESS - Driver is started successfully
295 EFI_ISA_IO_PROTOCOL
*IsaIo
;
296 SERIAL_DEV
*SerialDevice
;
298 UART_DEVICE_PATH Node
;
299 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
300 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
302 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
306 // Get the Parent Device Path
308 Status
= gBS
->OpenProtocol (
310 &gEfiDevicePathProtocolGuid
,
311 (VOID
**) &ParentDevicePath
,
312 This
->DriverBindingHandle
,
314 EFI_OPEN_PROTOCOL_BY_DRIVER
316 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
320 // Report status code enable the serial
322 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
324 EFI_P_PC_ENABLE
| EFI_PERIPHERAL_SERIAL_PORT
,
329 // Grab the IO abstraction we need to get any work done
331 Status
= gBS
->OpenProtocol (
333 &gEfiIsaIoProtocolGuid
,
335 This
->DriverBindingHandle
,
337 EFI_OPEN_PROTOCOL_BY_DRIVER
339 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
343 if (Status
== EFI_ALREADY_STARTED
) {
345 if (RemainingDevicePath
== NULL
) {
349 // Make sure a child handle does not already exist. This driver can only
350 // produce one child per serial port.
352 Status
= gBS
->OpenProtocolInformation (
354 &gEfiIsaIoProtocolGuid
,
358 if (EFI_ERROR (Status
)) {
362 Status
= EFI_ALREADY_STARTED
;
363 for (Index
= 0; Index
< EntryCount
; Index
++) {
364 if (OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) {
365 Status
= gBS
->OpenProtocol (
366 OpenInfoBuffer
[Index
].ControllerHandle
,
367 &gEfiSerialIoProtocolGuid
,
369 This
->DriverBindingHandle
,
371 EFI_OPEN_PROTOCOL_GET_PROTOCOL
373 if (!EFI_ERROR (Status
)) {
374 CopyMem (&Node
, RemainingDevicePath
, sizeof (UART_DEVICE_PATH
));
375 Status
= SerialIo
->SetAttributes (
378 SerialIo
->Mode
->ReceiveFifoDepth
,
379 SerialIo
->Mode
->Timeout
,
380 (EFI_PARITY_TYPE
) Node
.Parity
,
382 (EFI_STOP_BITS_TYPE
) Node
.StopBits
389 gBS
->FreePool (OpenInfoBuffer
);
393 // Initialize the serial device instance
395 SerialDevice
= AllocateCopyPool (sizeof (SERIAL_DEV
), &gSerialDevTempate
);
396 if (SerialDevice
== NULL
) {
397 Status
= EFI_OUT_OF_RESOURCES
;
401 SerialDevice
->SerialIo
.Mode
= &(SerialDevice
->SerialMode
);
402 SerialDevice
->IsaIo
= IsaIo
;
403 SerialDevice
->ParentDevicePath
= ParentDevicePath
;
405 ADD_SERIAL_NAME (SerialDevice
, IsaIo
);
407 for (Index
= 0; SerialDevice
->IsaIo
->ResourceList
->ResourceItem
[Index
].Type
!= EfiIsaAcpiResourceEndOfList
; Index
++) {
408 if (SerialDevice
->IsaIo
->ResourceList
->ResourceItem
[Index
].Type
== EfiIsaAcpiResourceIo
) {
409 SerialDevice
->BaseAddress
= (UINT16
) SerialDevice
->IsaIo
->ResourceList
->ResourceItem
[Index
].StartRange
;
413 // Report status code the serial present
415 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
417 EFI_P_PC_PRESENCE_DETECT
| EFI_PERIPHERAL_SERIAL_PORT
,
421 if (!IsaSerialPortPresent (SerialDevice
)) {
422 Status
= EFI_DEVICE_ERROR
;
423 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
425 EFI_P_EC_NOT_DETECTED
| EFI_PERIPHERAL_SERIAL_PORT
,
431 if (RemainingDevicePath
!= NULL
) {
433 // Match the configuration of the RemainingDevicePath. IsHandleSupported()
434 // already checked to make sure the RemainingDevicePath contains settings
435 // that we can support.
437 CopyMem (&SerialDevice
->UartDevicePath
, RemainingDevicePath
, sizeof (UART_DEVICE_PATH
));
440 // Use the values from the gSerialDevTempate as no remaining device path was
445 // Build the device path by appending the UART node to the ParentDevicePath
446 // from the WinNtIo handle. The Uart setings are zero here, since
447 // SetAttribute() will update them to match the current setings.
449 SerialDevice
->DevicePath
= AppendDevicePathNode (
451 (EFI_DEVICE_PATH_PROTOCOL
*)&SerialDevice
->UartDevicePath
453 if (SerialDevice
->DevicePath
== NULL
) {
454 Status
= EFI_DEVICE_ERROR
;
459 // Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults.
461 SerialDevice
->SerialMode
.BaudRate
= SerialDevice
->UartDevicePath
.BaudRate
;
462 SerialDevice
->SerialMode
.DataBits
= SerialDevice
->UartDevicePath
.DataBits
;
463 SerialDevice
->SerialMode
.Parity
= SerialDevice
->UartDevicePath
.Parity
;
464 SerialDevice
->SerialMode
.StopBits
= SerialDevice
->UartDevicePath
.StopBits
;
467 // Issue a reset to initialize the COM port
469 Status
= SerialDevice
->SerialIo
.Reset (&SerialDevice
->SerialIo
);
470 if (EFI_ERROR (Status
)) {
471 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
473 EFI_P_EC_CONTROLLER_ERROR
| EFI_PERIPHERAL_SERIAL_PORT
,
479 // Install protocol interfaces for the serial device.
481 Status
= gBS
->InstallMultipleProtocolInterfaces (
482 &SerialDevice
->Handle
,
483 &gEfiDevicePathProtocolGuid
,
484 SerialDevice
->DevicePath
,
485 &gEfiSerialIoProtocolGuid
,
486 &SerialDevice
->SerialIo
,
489 if (EFI_ERROR (Status
)) {
493 // Open For Child Device
495 Status
= gBS
->OpenProtocol (
497 &gEfiIsaIoProtocolGuid
,
499 This
->DriverBindingHandle
,
500 SerialDevice
->Handle
,
501 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
505 if (EFI_ERROR (Status
)) {
508 &gEfiDevicePathProtocolGuid
,
509 This
->DriverBindingHandle
,
514 &gEfiIsaIoProtocolGuid
,
515 This
->DriverBindingHandle
,
519 if (SerialDevice
->DevicePath
) {
520 gBS
->FreePool (SerialDevice
->DevicePath
);
523 FreeUnicodeStringTable (SerialDevice
->ControllerNameTable
);
524 gBS
->FreePool (SerialDevice
);
533 SerialControllerDriverStop (
534 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
535 IN EFI_HANDLE Controller
,
536 IN UINTN NumberOfChildren
,
537 IN EFI_HANDLE
*ChildHandleBuffer
543 Disconnect this driver with the controller, uninstall related protocol instance
547 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
548 Controller - The handle of the controller to test.
549 NumberOfChildren - Number of child device.
550 RemainingDevicePath - A pointer to the remaining portion of a device path.
554 EFI_SUCCESS - Operation successfully
555 EFI_DEVICE_ERROR - Cannot stop the driver successfully
561 BOOLEAN AllChildrenStopped
;
562 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
563 SERIAL_DEV
*SerialDevice
;
564 EFI_ISA_IO_PROTOCOL
*IsaIo
;
565 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
567 Status
= gBS
->HandleProtocol (
569 &gEfiDevicePathProtocolGuid
,
570 (VOID
**) &DevicePath
574 // Report the status code disable the serial
576 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
578 EFI_P_PC_DISABLE
| EFI_PERIPHERAL_SERIAL_PORT
,
583 // Complete all outstanding transactions to Controller.
584 // Don't allow any new transaction to Controller to be started.
586 if (NumberOfChildren
== 0) {
588 // Close the bus driver
590 Status
= gBS
->CloseProtocol (
592 &gEfiIsaIoProtocolGuid
,
593 This
->DriverBindingHandle
,
597 Status
= gBS
->CloseProtocol (
599 &gEfiDevicePathProtocolGuid
,
600 This
->DriverBindingHandle
,
606 AllChildrenStopped
= TRUE
;
608 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
610 Status
= gBS
->OpenProtocol (
611 ChildHandleBuffer
[Index
],
612 &gEfiSerialIoProtocolGuid
,
614 This
->DriverBindingHandle
,
616 EFI_OPEN_PROTOCOL_GET_PROTOCOL
618 if (!EFI_ERROR (Status
)) {
620 SerialDevice
= SERIAL_DEV_FROM_THIS (SerialIo
);
622 Status
= gBS
->CloseProtocol (
624 &gEfiIsaIoProtocolGuid
,
625 This
->DriverBindingHandle
,
626 ChildHandleBuffer
[Index
]
629 Status
= gBS
->UninstallMultipleProtocolInterfaces (
630 ChildHandleBuffer
[Index
],
631 &gEfiDevicePathProtocolGuid
,
632 SerialDevice
->DevicePath
,
633 &gEfiSerialIoProtocolGuid
,
634 &SerialDevice
->SerialIo
,
637 if (EFI_ERROR (Status
)) {
640 &gEfiIsaIoProtocolGuid
,
642 This
->DriverBindingHandle
,
643 ChildHandleBuffer
[Index
],
644 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
647 if (SerialDevice
->DevicePath
) {
648 gBS
->FreePool (SerialDevice
->DevicePath
);
651 FreeUnicodeStringTable (SerialDevice
->ControllerNameTable
);
652 gBS
->FreePool (SerialDevice
);
656 if (EFI_ERROR (Status
)) {
657 AllChildrenStopped
= FALSE
;
661 if (!AllChildrenStopped
) {
662 return EFI_DEVICE_ERROR
;
670 IN SERIAL_DEV_FIFO
*Fifo
676 Detect whether specific FIFO is full or not
680 Fifo - A pointer to the Data Structure SERIAL_DEV_FIFO
684 TRUE - the FIFO is full
685 FALSE - the FIFO is not full
689 if (Fifo
->Surplus
== 0) {
698 IN SERIAL_DEV_FIFO
*Fifo
704 Detect whether specific FIFO is empty or not
708 Fifo - A pointer to the Data Structure SERIAL_DEV_FIFO
712 TRUE - the FIFO is empty
713 FALSE - the FIFO is not empty
717 if (Fifo
->Surplus
== SERIAL_MAX_BUFFER_SIZE
) {
726 IN SERIAL_DEV_FIFO
*Fifo
,
733 Add data to specific FIFO
737 Fifo - A pointer to the Data Structure SERIAL_DEV_FIFO
738 Data - the data added to FIFO
742 EFI_SUCCESS - Add data to specific FIFO successfully
743 EFI_OUT_OF_RESOURCE - Failed to add data because FIFO is already full
748 // if FIFO full can not add data
750 if (IsaSerialFifoFull (Fifo
)) {
751 return EFI_OUT_OF_RESOURCES
;
754 // FIFO is not full can add data
756 Fifo
->Data
[Fifo
->Last
] = Data
;
759 if (Fifo
->Last
== SERIAL_MAX_BUFFER_SIZE
) {
767 IsaSerialFifoRemove (
768 IN SERIAL_DEV_FIFO
*Fifo
,
775 Remove data from specific FIFO
779 Fifo - A pointer to the Data Structure SERIAL_DEV_FIFO
780 Data - the data removed from FIFO
783 EFI_SUCCESS - Remove data from specific FIFO successfully
784 EFI_OUT_OF_RESOURCE - Failed to remove data because FIFO is empty
789 // if FIFO is empty, no data can remove
791 if (IsaSerialFifoEmpty (Fifo
)) {
792 return EFI_OUT_OF_RESOURCES
;
795 // FIFO is not empty, can remove data
797 *Data
= Fifo
->Data
[Fifo
->First
];
800 if (Fifo
->First
== SERIAL_MAX_BUFFER_SIZE
) {
808 IsaSerialReceiveTransmit (
809 IN SERIAL_DEV
*SerialDevice
815 Reads and writes all avaliable data.
819 SerialDevice - The device to flush
823 EFI_SUCCESS - Data was read/written successfully.
824 EFI_OUT_OF_RESOURCE - Failed because software receive FIFO is full. Note, when
825 this happens, pending writes are not done.
831 BOOLEAN ReceiveFifoFull
;
839 // Begin the read or write
841 if (SerialDevice
->SoftwareLoopbackEnable
) {
843 ReceiveFifoFull
= IsaSerialFifoFull (&SerialDevice
->Receive
);
844 if (!IsaSerialFifoEmpty (&SerialDevice
->Transmit
)) {
845 IsaSerialFifoRemove (&SerialDevice
->Transmit
, &Data
);
846 if (ReceiveFifoFull
) {
847 return EFI_OUT_OF_RESOURCES
;
850 IsaSerialFifoAdd (&SerialDevice
->Receive
, Data
);
852 } while (!IsaSerialFifoEmpty (&SerialDevice
->Transmit
));
854 ReceiveFifoFull
= IsaSerialFifoFull (&SerialDevice
->Receive
);
856 Lsr
.Data
= READ_LSR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
858 if (FeaturePcdGet (PcdNtEmulatorEnable
)) {
860 // This is required for NT to avoid a forever-spin...
861 // This would be better if READ_LSR was a polling operation
862 // that would timeout.
867 // Flush incomming data to prevent a an overrun during a long write
869 if (Lsr
.Bits
.DR
&& !ReceiveFifoFull
) {
870 ReceiveFifoFull
= IsaSerialFifoFull (&SerialDevice
->Receive
);
871 if (!ReceiveFifoFull
) {
872 if (Lsr
.Bits
.FIFOE
|| Lsr
.Bits
.OE
|| Lsr
.Bits
.PE
|| Lsr
.Bits
.FE
|| Lsr
.Bits
.BI
) {
873 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
875 EFI_P_EC_INPUT_ERROR
| EFI_PERIPHERAL_SERIAL_PORT
,
876 SerialDevice
->DevicePath
878 if (Lsr
.Bits
.FIFOE
|| Lsr
.Bits
.PE
|| Lsr
.Bits
.FE
|| Lsr
.Bits
.BI
) {
879 Data
= READ_RBR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
884 // Make sure the receive data will not be missed, Assert DTR
886 if (SerialDevice
->HardwareFlowControl
) {
887 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
889 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
892 Data
= READ_RBR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
897 if (SerialDevice
->HardwareFlowControl
) {
898 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
900 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
903 IsaSerialFifoAdd (&SerialDevice
->Receive
, Data
);
907 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
909 EFI_P_SERIAL_PORT_PC_CLEAR_BUFFER
| EFI_PERIPHERAL_SERIAL_PORT
,
910 SerialDevice
->DevicePath
917 if (Lsr
.Bits
.THRE
&& !IsaSerialFifoEmpty (&SerialDevice
->Transmit
)) {
919 // Make sure the transmit data will not be missed
921 if (SerialDevice
->HardwareFlowControl
) {
925 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
927 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
932 Msr
.Data
= READ_MSR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
933 while (!Msr
.Bits
.CTS
) {
934 gBS
->Stall (TIMEOUT_STALL_INTERVAL
);
940 Msr
.Data
= READ_MSR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
944 IsaSerialFifoRemove (&SerialDevice
->Transmit
, &Data
);
945 WRITE_THR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Data
);
949 // write the data out
951 if (!SerialDevice
->HardwareFlowControl
) {
952 IsaSerialFifoRemove (&SerialDevice
->Transmit
, &Data
);
953 WRITE_THR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Data
);
956 // Make sure the transmit data will not be missed
958 if (SerialDevice
->HardwareFlowControl
) {
962 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
964 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
967 } while (Lsr
.Bits
.THRE
&& !IsaSerialFifoEmpty (&SerialDevice
->Transmit
));
973 // Interface Functions
978 IN EFI_SERIAL_IO_PROTOCOL
*This
988 This - Pointer to EFI_SERIAL_IO_PROTOCOL
992 EFI_SUCCESS - Reset successfully
993 EFI_DEVICE_ERROR - Failed to reset
998 SERIAL_DEV
*SerialDevice
;
1000 SERIAL_PORT_IER Ier
;
1001 SERIAL_PORT_MCR Mcr
;
1002 SERIAL_PORT_FCR Fcr
;
1005 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1008 // Report the status code reset the serial
1010 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1012 EFI_P_PC_RESET
| EFI_PERIPHERAL_SERIAL_PORT
,
1013 SerialDevice
->DevicePath
1016 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1019 // Make sure DLAB is 0.
1021 Lcr
.Data
= READ_LCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1023 WRITE_LCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Lcr
.Data
);
1026 // Turn off all interrupts
1028 Ier
.Data
= READ_IER (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1033 WRITE_IER (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Ier
.Data
);
1036 // Disable the FIFO.
1038 Fcr
.Bits
.TRFIFOE
= 0;
1039 WRITE_FCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Fcr
.Data
);
1042 // Turn off loopback and disable device interrupt.
1044 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1048 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
1051 // Clear the scratch pad register
1053 WRITE_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, 0);
1056 // Go set the current attributes
1058 Status
= This
->SetAttributes (
1060 This
->Mode
->BaudRate
,
1061 This
->Mode
->ReceiveFifoDepth
,
1062 This
->Mode
->Timeout
,
1063 (EFI_PARITY_TYPE
) This
->Mode
->Parity
,
1064 (UINT8
) This
->Mode
->DataBits
,
1065 (EFI_STOP_BITS_TYPE
) This
->Mode
->StopBits
1068 if (EFI_ERROR (Status
)) {
1069 gBS
->RestoreTPL (Tpl
);
1070 return EFI_DEVICE_ERROR
;
1073 // Go set the current control bits
1075 Status
= This
->SetControl (
1077 This
->Mode
->ControlMask
1080 if (EFI_ERROR (Status
)) {
1081 gBS
->RestoreTPL (Tpl
);
1082 return EFI_DEVICE_ERROR
;
1085 // for 16550A enable FIFO, 16550 disable FIFO
1087 Fcr
.Bits
.TRFIFOE
= 1;
1088 Fcr
.Bits
.RESETRF
= 1;
1089 Fcr
.Bits
.RESETTF
= 1;
1090 WRITE_FCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Fcr
.Data
);
1093 // Reset the software FIFO
1095 SerialDevice
->Receive
.First
= 0;
1096 SerialDevice
->Receive
.Last
= 0;
1097 SerialDevice
->Receive
.Surplus
= SERIAL_MAX_BUFFER_SIZE
;
1098 SerialDevice
->Transmit
.First
= 0;
1099 SerialDevice
->Transmit
.Last
= 0;
1100 SerialDevice
->Transmit
.Surplus
= SERIAL_MAX_BUFFER_SIZE
;
1102 gBS
->RestoreTPL (Tpl
);
1105 // Device reset is complete
1112 IsaSerialSetAttributes (
1113 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1115 IN UINT32 ReceiveFifoDepth
,
1117 IN EFI_PARITY_TYPE Parity
,
1119 IN EFI_STOP_BITS_TYPE StopBits
1123 Routine Description:
1125 Set new attributes to a serial device
1129 This - Pointer to EFI_SERIAL_IO_PROTOCOL
1130 BaudRate - The baudrate of the serial device
1131 ReceiveFifoDepth - The depth of receive FIFO buffer
1132 Timeout - The request timeout for a single char
1133 Parity - The type of parity used in serial device
1134 DataBits - Number of databits used in serial device
1135 StopBits - Number of stopbits used in serial device
1139 EFI_SUCCESS - The new attributes were set
1140 EFI_INVALID_PARAMETERS - One or more attributes have an unsupported value
1141 EFI_UNSUPPORTED - Data Bits can not set to 5 or 6
1142 EFI_DEVICE_ERROR - The serial device is not functioning correctly (no return)
1147 SERIAL_DEV
*SerialDevice
;
1150 SERIAL_PORT_LCR Lcr
;
1151 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
1154 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1157 // Check for default settings and fill in actual values.
1159 if (BaudRate
== 0) {
1160 BaudRate
= FixedPcdGet64 (PcdUartDefaultBaudRate
);
1163 if (ReceiveFifoDepth
== 0) {
1164 ReceiveFifoDepth
= SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH
;
1168 Timeout
= SERIAL_PORT_DEFAULT_TIMEOUT
;
1171 if (Parity
== DefaultParity
) {
1172 Parity
= (EFI_PARITY_TYPE
)FixedPcdGet8 (PcdUartDefaultParity
);
1175 if (DataBits
== 0) {
1176 DataBits
= FixedPcdGet8 (PcdUartDefaultDataBits
);
1179 if (StopBits
== DefaultStopBits
) {
1180 StopBits
= (EFI_STOP_BITS_TYPE
) FixedPcdGet8 (PcdUartDefaultStopBits
);
1183 // 5 and 6 data bits can not be verified on a 16550A UART
1184 // Return EFI_INVALID_PARAMETER if an attempt is made to use these settings.
1186 if ((DataBits
== 5) || (DataBits
== 6)) {
1187 return EFI_INVALID_PARAMETER
;
1190 // Make sure all parameters are valid
1192 if ((BaudRate
> SERIAL_PORT_MAX_BAUD_RATE
) || (BaudRate
< SERIAL_PORT_MIN_BAUD_RATE
)) {
1193 return EFI_INVALID_PARAMETER
;
1196 // 50,75,110,134,150,300,600,1200,1800,2000,2400,3600,4800,7200,9600,19200,
1197 // 38400,57600,115200
1199 if (BaudRate
< 75) {
1201 } else if (BaudRate
< 110) {
1203 } else if (BaudRate
< 134) {
1205 } else if (BaudRate
< 150) {
1207 } else if (BaudRate
< 300) {
1209 } else if (BaudRate
< 600) {
1211 } else if (BaudRate
< 1200) {
1213 } else if (BaudRate
< 1800) {
1215 } else if (BaudRate
< 2000) {
1217 } else if (BaudRate
< 2400) {
1219 } else if (BaudRate
< 3600) {
1221 } else if (BaudRate
< 4800) {
1223 } else if (BaudRate
< 7200) {
1225 } else if (BaudRate
< 9600) {
1227 } else if (BaudRate
< 19200) {
1229 } else if (BaudRate
< 38400) {
1231 } else if (BaudRate
< 57600) {
1233 } else if (BaudRate
< 115200) {
1235 } else if (BaudRate
<= SERIAL_PORT_MAX_BAUD_RATE
) {
1239 if ((ReceiveFifoDepth
< 1) || (ReceiveFifoDepth
> SERIAL_PORT_MAX_RECEIVE_FIFO_DEPTH
)) {
1240 return EFI_INVALID_PARAMETER
;
1243 if ((Timeout
< SERIAL_PORT_MIN_TIMEOUT
) || (Timeout
> SERIAL_PORT_MAX_TIMEOUT
)) {
1244 return EFI_INVALID_PARAMETER
;
1247 if ((Parity
< NoParity
) || (Parity
> SpaceParity
)) {
1248 return EFI_INVALID_PARAMETER
;
1251 if ((DataBits
< 5) || (DataBits
> 8)) {
1252 return EFI_INVALID_PARAMETER
;
1255 if ((StopBits
< OneStopBit
) || (StopBits
> TwoStopBits
)) {
1256 return EFI_INVALID_PARAMETER
;
1259 // for DataBits = 5, StopBits can not set TwoStopBits
1261 // if ((DataBits == 5) && (StopBits == TwoStopBits)) {
1262 // return EFI_INVALID_PARAMETER;
1265 // for DataBits = 6,7,8, StopBits can not set OneFiveStopBits
1267 if ((DataBits
>= 6) && (DataBits
<= 8) && (StopBits
== OneFiveStopBits
)) {
1268 return EFI_INVALID_PARAMETER
;
1272 // Compute divisor use to program the baud rate using a round determination
1274 Divisor
= (UINT32
) DivU64x32Remainder (
1275 SERIAL_PORT_INPUT_CLOCK
,
1276 ((UINT32
) BaudRate
* 16),
1283 if ((Divisor
== 0) || (Divisor
& 0xffff0000)) {
1284 return EFI_INVALID_PARAMETER
;
1287 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1290 // Compute the actual baud rate that the serial port will be programmed for.
1292 BaudRate
= SERIAL_PORT_INPUT_CLOCK
/ Divisor
/ 16;
1295 // Put serial port on Divisor Latch Mode
1297 Lcr
.Data
= READ_LCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1299 WRITE_LCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Lcr
.Data
);
1302 // Write the divisor to the serial port
1304 WRITE_DLL (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, (UINT8
) (Divisor
& 0xff));
1305 WRITE_DLM (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, (UINT8
) ((Divisor
>> 8) & 0xff));
1308 // Put serial port back in normal mode and set remaining attributes.
1315 Lcr
.Bits
.EVENPAR
= 0;
1316 Lcr
.Bits
.STICPAR
= 0;
1321 Lcr
.Bits
.EVENPAR
= 1;
1322 Lcr
.Bits
.STICPAR
= 0;
1327 Lcr
.Bits
.EVENPAR
= 0;
1328 Lcr
.Bits
.STICPAR
= 0;
1333 Lcr
.Bits
.EVENPAR
= 1;
1334 Lcr
.Bits
.STICPAR
= 1;
1339 Lcr
.Bits
.EVENPAR
= 0;
1340 Lcr
.Bits
.STICPAR
= 1;
1352 case OneFiveStopBits
:
1363 Lcr
.Bits
.SERIALDB
= (UINT8
) ((DataBits
- 5) & 0x03);
1364 WRITE_LCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Lcr
.Data
);
1367 // Set the Serial I/O mode
1369 This
->Mode
->BaudRate
= BaudRate
;
1370 This
->Mode
->ReceiveFifoDepth
= ReceiveFifoDepth
;
1371 This
->Mode
->Timeout
= Timeout
;
1372 This
->Mode
->Parity
= Parity
;
1373 This
->Mode
->DataBits
= DataBits
;
1374 This
->Mode
->StopBits
= StopBits
;
1377 // See if Device Path Node has actually changed
1379 if (SerialDevice
->UartDevicePath
.BaudRate
== BaudRate
&&
1380 SerialDevice
->UartDevicePath
.DataBits
== DataBits
&&
1381 SerialDevice
->UartDevicePath
.Parity
== Parity
&&
1382 SerialDevice
->UartDevicePath
.StopBits
== StopBits
1384 gBS
->RestoreTPL (Tpl
);
1388 // Update the device path
1390 SerialDevice
->UartDevicePath
.BaudRate
= BaudRate
;
1391 SerialDevice
->UartDevicePath
.DataBits
= DataBits
;
1392 SerialDevice
->UartDevicePath
.Parity
= (UINT8
) Parity
;
1393 SerialDevice
->UartDevicePath
.StopBits
= (UINT8
) StopBits
;
1395 NewDevicePath
= AppendDevicePathNode (
1396 SerialDevice
->ParentDevicePath
,
1397 (EFI_DEVICE_PATH_PROTOCOL
*) &SerialDevice
->UartDevicePath
1399 if (NewDevicePath
== NULL
) {
1400 gBS
->RestoreTPL (Tpl
);
1401 return EFI_DEVICE_ERROR
;
1404 if (SerialDevice
->Handle
!= NULL
) {
1405 Status
= gBS
->ReinstallProtocolInterface (
1406 SerialDevice
->Handle
,
1407 &gEfiDevicePathProtocolGuid
,
1408 SerialDevice
->DevicePath
,
1411 if (EFI_ERROR (Status
)) {
1412 gBS
->RestoreTPL (Tpl
);
1417 if (SerialDevice
->DevicePath
) {
1418 gBS
->FreePool (SerialDevice
->DevicePath
);
1421 SerialDevice
->DevicePath
= NewDevicePath
;
1423 gBS
->RestoreTPL (Tpl
);
1430 IsaSerialSetControl (
1431 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1436 Routine Description:
1442 This - Pointer to EFI_SERIAL_IO_PROTOCOL
1443 Control - Control bits that can be settable
1447 EFI_SUCCESS - New Control bits were set successfully
1448 EFI_UNSUPPORTED - The Control bits wanted to set are not supported
1452 SERIAL_DEV
*SerialDevice
;
1453 SERIAL_PORT_MCR Mcr
;
1457 // The control bits that can be set are :
1458 // EFI_SERIAL_DATA_TERMINAL_READY: 0x0001 // WO
1459 // EFI_SERIAL_REQUEST_TO_SEND: 0x0002 // WO
1460 // EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE: 0x1000 // RW
1461 // EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE: 0x2000 // RW
1463 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1466 // first determine the parameter is invalid
1468 if (Control
& 0xffff8ffc) {
1469 return EFI_UNSUPPORTED
;
1472 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1474 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1478 SerialDevice
->SoftwareLoopbackEnable
= FALSE
;
1479 SerialDevice
->HardwareFlowControl
= FALSE
;
1481 if (Control
& EFI_SERIAL_DATA_TERMINAL_READY
) {
1485 if (Control
& EFI_SERIAL_REQUEST_TO_SEND
) {
1489 if (Control
& EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
) {
1493 if (Control
& EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
) {
1494 SerialDevice
->HardwareFlowControl
= TRUE
;
1497 WRITE_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Mcr
.Data
);
1499 if (Control
& EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
) {
1500 SerialDevice
->SoftwareLoopbackEnable
= TRUE
;
1503 gBS
->RestoreTPL (Tpl
);
1510 IsaSerialGetControl (
1511 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1516 Routine Description:
1522 This - Pointer to EFI_SERIAL_IO_PROTOCOL
1523 Control - Control signals of the serial device
1527 EFI_SUCCESS - Get Control signals successfully
1531 SERIAL_DEV
*SerialDevice
;
1532 SERIAL_PORT_MSR Msr
;
1533 SERIAL_PORT_MCR Mcr
;
1536 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1538 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1543 // Read the Modem Status Register
1545 Msr
.Data
= READ_MSR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1548 *Control
|= EFI_SERIAL_CLEAR_TO_SEND
;
1552 *Control
|= EFI_SERIAL_DATA_SET_READY
;
1556 *Control
|= EFI_SERIAL_RING_INDICATE
;
1560 *Control
|= EFI_SERIAL_CARRIER_DETECT
;
1563 // Read the Modem Control Register
1565 Mcr
.Data
= READ_MCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1567 if (Mcr
.Bits
.DTRC
) {
1568 *Control
|= EFI_SERIAL_DATA_TERMINAL_READY
;
1572 *Control
|= EFI_SERIAL_REQUEST_TO_SEND
;
1576 *Control
|= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
;
1579 if (SerialDevice
->HardwareFlowControl
) {
1580 *Control
|= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
;
1583 // See if the Transmit FIFO is empty
1585 IsaSerialReceiveTransmit (SerialDevice
);
1587 if (IsaSerialFifoEmpty (&SerialDevice
->Transmit
)) {
1588 *Control
|= EFI_SERIAL_OUTPUT_BUFFER_EMPTY
;
1591 // See if the Receive FIFO is empty.
1593 IsaSerialReceiveTransmit (SerialDevice
);
1595 if (IsaSerialFifoEmpty (&SerialDevice
->Receive
)) {
1596 *Control
|= EFI_SERIAL_INPUT_BUFFER_EMPTY
;
1599 if (SerialDevice
->SoftwareLoopbackEnable
) {
1600 *Control
|= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
;
1603 gBS
->RestoreTPL (Tpl
);
1611 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1612 IN OUT UINTN
*BufferSize
,
1617 Routine Description:
1619 Write the specified number of bytes to serial device
1623 This - Pointer to EFI_SERIAL_IO_PROTOCOL
1624 BufferSize - On input the size of Buffer, on output the amount of
1625 data actually written
1626 Buffer - The buffer of data to write
1630 EFI_SUCCESS - The data were written successfully
1631 EFI_DEVICE_ERROR - The device reported an error
1632 EFI_TIMEOUT - The write operation was stopped due to timeout
1636 SERIAL_DEV
*SerialDevice
;
1643 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1647 if (*BufferSize
== 0) {
1652 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1654 EFI_P_EC_OUTPUT_ERROR
| EFI_PERIPHERAL_SERIAL_PORT
,
1655 SerialDevice
->DevicePath
1658 return EFI_DEVICE_ERROR
;
1661 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1663 CharBuffer
= (UINT8
*) Buffer
;
1665 for (Index
= 0; Index
< *BufferSize
; Index
++) {
1666 IsaSerialFifoAdd (&SerialDevice
->Transmit
, CharBuffer
[Index
]);
1668 while (IsaSerialReceiveTransmit (SerialDevice
) != EFI_SUCCESS
|| !IsaSerialFifoEmpty (&SerialDevice
->Transmit
)) {
1670 // Unsuccessful write so check if timeout has expired, if not,
1671 // stall for a bit, increment time elapsed, and try again
1673 if (Elapsed
>= This
->Mode
->Timeout
) {
1674 *BufferSize
= ActualWrite
;
1675 gBS
->RestoreTPL (Tpl
);
1679 gBS
->Stall (TIMEOUT_STALL_INTERVAL
);
1681 Elapsed
+= TIMEOUT_STALL_INTERVAL
;
1686 // Successful write so reset timeout
1691 gBS
->RestoreTPL (Tpl
);
1699 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1700 IN OUT UINTN
*BufferSize
,
1705 Routine Description:
1707 Read the specified number of bytes from serial device
1711 This - Pointer to EFI_SERIAL_IO_PROTOCOL
1712 BufferSize - On input the size of Buffer, on output the amount of
1713 data returned in buffer
1714 Buffer - The buffer to return the data into
1718 EFI_SUCCESS - The data were read successfully
1719 EFI_DEVICE_ERROR - The device reported an error
1720 EFI_TIMEOUT - The read operation was stopped due to timeout
1724 SERIAL_DEV
*SerialDevice
;
1731 SerialDevice
= SERIAL_DEV_FROM_THIS (This
);
1734 if (*BufferSize
== 0) {
1739 return EFI_DEVICE_ERROR
;
1742 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1744 Status
= IsaSerialReceiveTransmit (SerialDevice
);
1746 if (EFI_ERROR (Status
)) {
1749 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1751 EFI_P_EC_INPUT_ERROR
| EFI_PERIPHERAL_SERIAL_PORT
,
1752 SerialDevice
->DevicePath
1755 gBS
->RestoreTPL (Tpl
);
1757 return EFI_DEVICE_ERROR
;
1760 CharBuffer
= (UINT8
*) Buffer
;
1761 for (Index
= 0; Index
< *BufferSize
; Index
++) {
1762 while (IsaSerialFifoRemove (&SerialDevice
->Receive
, &(CharBuffer
[Index
])) != EFI_SUCCESS
) {
1764 // Unsuccessful read so check if timeout has expired, if not,
1765 // stall for a bit, increment time elapsed, and try again
1766 // Need this time out to get conspliter to work.
1768 if (Elapsed
>= This
->Mode
->Timeout
) {
1769 *BufferSize
= Index
;
1770 gBS
->RestoreTPL (Tpl
);
1774 gBS
->Stall (TIMEOUT_STALL_INTERVAL
);
1775 Elapsed
+= TIMEOUT_STALL_INTERVAL
;
1777 Status
= IsaSerialReceiveTransmit (SerialDevice
);
1778 if (Status
== EFI_DEVICE_ERROR
) {
1779 *BufferSize
= Index
;
1780 gBS
->RestoreTPL (Tpl
);
1781 return EFI_DEVICE_ERROR
;
1785 // Successful read so reset timeout
1790 IsaSerialReceiveTransmit (SerialDevice
);
1792 gBS
->RestoreTPL (Tpl
);
1798 IsaSerialPortPresent (
1799 IN SERIAL_DEV
*SerialDevice
1803 Routine Description:
1805 Use scratchpad register to test if this serial port is present
1809 SerialDevice - Pointer to serial device structure
1813 TRUE - The serial port is present
1814 FALSE - The serial port is NOT present
1826 Temp
= READ_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
);
1827 WRITE_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, 0xAA);
1829 if (READ_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
) != 0xAA) {
1830 if (!FeaturePcdGet (PcdNtEmulatorEnable
)) {
1835 WRITE_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, 0x55);
1837 if (READ_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
) != 0x55) {
1838 if (!FeaturePcdGet (PcdNtEmulatorEnable
)) {
1845 WRITE_SCR (SerialDevice
->IsaIo
, SerialDevice
->BaseAddress
, Temp
);
1851 IN EFI_ISA_IO_PROTOCOL
*IsaIo
,
1852 IN UINT16 BaseAddress
,
1857 Routine Description:
1859 Use IsaIo protocol to read serial port
1863 IsaIo - Pointer to EFI_ISA_IO_PROTOCOL instance
1864 BaseAddress - Serial port register group base address
1865 Offset - Offset in register group
1869 Data read from serial port
1876 // Use IsaIo to access IO
1881 BaseAddress
+ Offset
,
1889 IsaSerialWritePort (
1890 IN EFI_ISA_IO_PROTOCOL
*IsaIo
,
1891 IN UINT16 BaseAddress
,
1897 Routine Description:
1899 Use IsaIo protocol to write serial port
1903 IsaIo - Pointer to EFI_ISA_IO_PROTOCOL instance
1904 BaseAddress - Serial port register group base address
1905 Offset - Offset in register group
1906 Data - data which is to be written to some serial port register
1915 // Use IsaIo to access IO
1920 BaseAddress
+ Offset
,