summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf1
-rw-r--r--IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.c77
-rw-r--r--IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.h1
-rw-r--r--IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec3
-rw-r--r--IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc3
5 files changed, 49 insertions, 36 deletions
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf b/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf
index aa7c315e1d..4c8c08fd53 100644
--- a/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf
+++ b/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf
@@ -65,3 +65,4 @@
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|8
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdIsaBusSerialUseHalfHandshake|FALSE
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.c b/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.c
index f9d08ce3a0..65f072356b 100644
--- a/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.c
+++ b/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.c
@@ -83,7 +83,8 @@ SERIAL_DEV gSerialDevTempate = {
FALSE,
FALSE,
Uart16550A,
- NULL
+ NULL,
+ FixedPcdGetBool (PcdIsaBusSerialUseHalfHandshake) //UseHalfHandshake
};
/**
@@ -801,6 +802,18 @@ IsaSerialReceiveTransmit (
} while (!IsaSerialFifoEmpty (&SerialDevice->Transmit));
} else {
ReceiveFifoFull = IsaSerialFifoFull (&SerialDevice->Receive);
+ //
+ // For full handshake flow control, tell the peer to send data
+ // if receive buffer is available.
+ //
+ if (SerialDevice->HardwareFlowControl &&
+ !SerialDevice->UseHalfHandshake &&
+ !ReceiveFifoFull
+ ) {
+ Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
+ Mcr.Bits.Rts = 1;
+ WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);
+ }
do {
Lsr.Data = READ_LSR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
@@ -821,23 +834,21 @@ IsaSerialReceiveTransmit (
continue;
}
}
- //
- // Make sure the receive data will not be missed, Assert DTR
- //
- if (SerialDevice->HardwareFlowControl) {
- Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
- Mcr.Bits.DtrC &= 0;
- WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);
- }
Data = READ_RBR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
+ IsaSerialFifoAdd (&SerialDevice->Receive, Data);
+
//
- // Deassert DTR
+ // For full handshake flow control, if receive buffer full
+ // tell the peer to stop sending data.
//
- if (SerialDevice->HardwareFlowControl) {
- Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
- Mcr.Bits.DtrC |= 1;
+ if (SerialDevice->HardwareFlowControl &&
+ !SerialDevice->UseHalfHandshake &&
+ IsaSerialFifoFull (&SerialDevice->Receive)
+ ) {
+ Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
+ Mcr.Bits.Rts = 0;
WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);
}
@@ -861,17 +872,19 @@ IsaSerialReceiveTransmit (
//
if (SerialDevice->HardwareFlowControl) {
//
- // Send RTS
+ // For half handshake flow control assert RTS before sending.
//
- Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
- Mcr.Bits.Rts |= 1;
- WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);
+ if (SerialDevice->UseHalfHandshake) {
+ Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
+ Mcr.Bits.Rts= 0;
+ WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);
+ }
//
// Wait for CTS
//
TimeOut = 0;
Msr.Data = READ_MSR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
- while (Msr.Bits.Cts == 0) {
+ while (Msr.Bits.Dcd == 1 && (!Msr.Bits.Cts ^ SerialDevice->UseHalfHandshake)) {
gBS->Stall (TIMEOUT_STALL_INTERVAL);
TimeOut++;
if (TimeOut > 5) {
@@ -881,28 +894,22 @@ IsaSerialReceiveTransmit (
Msr.Data = READ_MSR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
}
- if (Msr.Bits.Cts == 1) {
+ if (Msr.Bits.Dcd== 0 || (Msr.Bits.Cts ^ SerialDevice->UseHalfHandshake)) {
IsaSerialFifoRemove (&SerialDevice->Transmit, &Data);
WRITE_THR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Data);
}
- }
- //
- // write the data out
- //
- if (!SerialDevice->HardwareFlowControl) {
- IsaSerialFifoRemove (&SerialDevice->Transmit, &Data);
- WRITE_THR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Data);
- }
- //
- // Make sure the transmit data will not be missed
- //
- if (SerialDevice->HardwareFlowControl) {
+
//
- // Assert RTS
+ // For half handshake flow control, tell DCE we are done.
//
- Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
- Mcr.Bits.Rts &= 0;
- WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);
+ if (SerialDevice->UseHalfHandshake) {
+ Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
+ Mcr.Bits.Rts = 1;
+ WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);
+ }
+ } else {
+ IsaSerialFifoRemove (&SerialDevice->Transmit, &Data);
+ WRITE_THR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Data);
}
}
} while (Lsr.Bits.Thre == 1 && !IsaSerialFifoEmpty (&SerialDevice->Transmit));
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.h b/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.h
index c7f2105f62..8d985a408f 100644
--- a/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.h
+++ b/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.h
@@ -109,6 +109,7 @@ typedef struct {
BOOLEAN HardwareFlowControl;
EFI_UART_TYPE Type;
EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+ BOOLEAN UseHalfHandshake;
} SERIAL_DEV;
#define SERIAL_DEV_FROM_THIS(a) CR (a, SERIAL_DEV, SerialIo, SERIAL_DEV_SIGNATURE)
diff --git a/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec b/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
index da4459022c..9e6a9bf1ca 100644
--- a/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+++ b/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
@@ -143,6 +143,9 @@
# The default value in DxePhase is 128 KBytes.
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1|UINT16|0x00010025
+ ## This PCD specifies whether Serial device use half hand shake.
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdIsaBusSerialUseHalfHandshake|FALSE|BOOLEAN|0x00010043
+
[PcdsDynamic]
## PCD is used to mark if the machine has complete one boot cycle before.
# After the complete boot, the variable BootState will be set to TRUE.
diff --git a/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc b/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc
index edd151a492..a910344504 100644
--- a/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc
+++ b/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc
@@ -153,7 +153,8 @@
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1
gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|0
-
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdIsaBusSerialUseHalfHandshake|FALSE
+
[PcdsDynamicDefault.PEIM.DEFAULT]
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1