From fa70a2c4cc9607f38e49a389f64ac32c600d47d2 Mon Sep 17 00:00:00 2001 From: gikidy Date: Wed, 8 Jul 2009 09:29:08 +0000 Subject: 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 --- .../Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf | 1 + .../Bus/Isa/IsaSerialDxe/Serial.c | 77 ++++++++++++---------- .../Bus/Isa/IsaSerialDxe/Serial.h | 1 + .../IntelFrameworkModulePkg.dec | 3 + .../IntelFrameworkModulePkg.dsc | 3 +- 5 files changed, 49 insertions(+), 36 deletions(-) (limited to 'IntelFrameworkModulePkg') diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf b/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf index aa7c315..4c8c08f 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 f9d08ce..65f0723 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 c7f2105..8d985a4 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 da44590..9e6a9bf 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 edd151a..a910344 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 -- cgit v1.1