mirror of https://github.com/acidanthera/audk.git
Enhanced module to handle half handshake flow control.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8816 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
5b3ea840c4
commit
fa70a2c4cc
|
@ -65,3 +65,4 @@
|
||||||
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|8
|
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|8
|
||||||
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1
|
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1
|
||||||
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1
|
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1
|
||||||
|
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdIsaBusSerialUseHalfHandshake|FALSE
|
||||||
|
|
|
@ -83,7 +83,8 @@ SERIAL_DEV gSerialDevTempate = {
|
||||||
FALSE,
|
FALSE,
|
||||||
FALSE,
|
FALSE,
|
||||||
Uart16550A,
|
Uart16550A,
|
||||||
NULL
|
NULL,
|
||||||
|
FixedPcdGetBool (PcdIsaBusSerialUseHalfHandshake) //UseHalfHandshake
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -801,6 +802,18 @@ IsaSerialReceiveTransmit (
|
||||||
} while (!IsaSerialFifoEmpty (&SerialDevice->Transmit));
|
} while (!IsaSerialFifoEmpty (&SerialDevice->Transmit));
|
||||||
} else {
|
} else {
|
||||||
ReceiveFifoFull = IsaSerialFifoFull (&SerialDevice->Receive);
|
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 {
|
do {
|
||||||
Lsr.Data = READ_LSR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
|
Lsr.Data = READ_LSR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
|
||||||
|
|
||||||
|
@ -821,23 +834,21 @@ IsaSerialReceiveTransmit (
|
||||||
continue;
|
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);
|
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) {
|
if (SerialDevice->HardwareFlowControl &&
|
||||||
Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
|
!SerialDevice->UseHalfHandshake &&
|
||||||
Mcr.Bits.DtrC |= 1;
|
IsaSerialFifoFull (&SerialDevice->Receive)
|
||||||
|
) {
|
||||||
|
Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
|
||||||
|
Mcr.Bits.Rts = 0;
|
||||||
WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);
|
WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -861,17 +872,19 @@ IsaSerialReceiveTransmit (
|
||||||
//
|
//
|
||||||
if (SerialDevice->HardwareFlowControl) {
|
if (SerialDevice->HardwareFlowControl) {
|
||||||
//
|
//
|
||||||
// Send RTS
|
// For half handshake flow control assert RTS before sending.
|
||||||
//
|
//
|
||||||
Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
|
if (SerialDevice->UseHalfHandshake) {
|
||||||
Mcr.Bits.Rts |= 1;
|
Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
|
||||||
WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);
|
Mcr.Bits.Rts= 0;
|
||||||
|
WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// Wait for CTS
|
// Wait for CTS
|
||||||
//
|
//
|
||||||
TimeOut = 0;
|
TimeOut = 0;
|
||||||
Msr.Data = READ_MSR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
|
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);
|
gBS->Stall (TIMEOUT_STALL_INTERVAL);
|
||||||
TimeOut++;
|
TimeOut++;
|
||||||
if (TimeOut > 5) {
|
if (TimeOut > 5) {
|
||||||
|
@ -881,29 +894,23 @@ IsaSerialReceiveTransmit (
|
||||||
Msr.Data = READ_MSR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
|
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);
|
IsaSerialFifoRemove (&SerialDevice->Transmit, &Data);
|
||||||
WRITE_THR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Data);
|
WRITE_THR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Data);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
//
|
//
|
||||||
// write the data out
|
// For half handshake flow control, tell DCE we are done.
|
||||||
//
|
//
|
||||||
if (!SerialDevice->HardwareFlowControl) {
|
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);
|
IsaSerialFifoRemove (&SerialDevice->Transmit, &Data);
|
||||||
WRITE_THR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Data);
|
WRITE_THR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Data);
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// Make sure the transmit data will not be missed
|
|
||||||
//
|
|
||||||
if (SerialDevice->HardwareFlowControl) {
|
|
||||||
//
|
|
||||||
// Assert RTS
|
|
||||||
//
|
|
||||||
Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
|
|
||||||
Mcr.Bits.Rts &= 0;
|
|
||||||
WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} while (Lsr.Bits.Thre == 1 && !IsaSerialFifoEmpty (&SerialDevice->Transmit));
|
} while (Lsr.Bits.Thre == 1 && !IsaSerialFifoEmpty (&SerialDevice->Transmit));
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,6 +109,7 @@ typedef struct {
|
||||||
BOOLEAN HardwareFlowControl;
|
BOOLEAN HardwareFlowControl;
|
||||||
EFI_UART_TYPE Type;
|
EFI_UART_TYPE Type;
|
||||||
EFI_UNICODE_STRING_TABLE *ControllerNameTable;
|
EFI_UNICODE_STRING_TABLE *ControllerNameTable;
|
||||||
|
BOOLEAN UseHalfHandshake;
|
||||||
} SERIAL_DEV;
|
} SERIAL_DEV;
|
||||||
|
|
||||||
#define SERIAL_DEV_FROM_THIS(a) CR (a, SERIAL_DEV, SerialIo, SERIAL_DEV_SIGNATURE)
|
#define SERIAL_DEV_FROM_THIS(a) CR (a, SERIAL_DEV, SerialIo, SERIAL_DEV_SIGNATURE)
|
||||||
|
|
|
@ -143,6 +143,9 @@
|
||||||
# The default value in DxePhase is 128 KBytes.
|
# The default value in DxePhase is 128 KBytes.
|
||||||
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1|UINT16|0x00010025
|
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1|UINT16|0x00010025
|
||||||
|
|
||||||
|
## This PCD specifies whether Serial device use half hand shake.
|
||||||
|
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdIsaBusSerialUseHalfHandshake|FALSE|BOOLEAN|0x00010043
|
||||||
|
|
||||||
[PcdsDynamic]
|
[PcdsDynamic]
|
||||||
## PCD is used to mark if the machine has complete one boot cycle before.
|
## 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.
|
# After the complete boot, the variable BootState will be set to TRUE.
|
||||||
|
|
|
@ -153,7 +153,8 @@
|
||||||
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1
|
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1
|
||||||
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1
|
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1
|
||||||
gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|0
|
gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|0
|
||||||
|
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdIsaBusSerialUseHalfHandshake|FALSE
|
||||||
|
|
||||||
[PcdsDynamicDefault.PEIM.DEFAULT]
|
[PcdsDynamicDefault.PEIM.DEFAULT]
|
||||||
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
|
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue