24#define R_UART_BAUD_LOW 0
25#define R_UART_BAUD_HIGH 1
28#define B_UART_FCR_FIFOE BIT0
29#define B_UART_FCR_FIFO64 BIT5
31#define B_UART_LCR_DLAB BIT7
33#define B_UART_MCR_DTRC BIT0
34#define B_UART_MCR_RTS BIT1
36#define B_UART_LSR_RXRDY BIT0
37#define B_UART_LSR_TXRDY BIT5
38#define B_UART_LSR_TEMT BIT6
40#define B_UART_MSR_CTS BIT4
41#define B_UART_MSR_DSR BIT5
42#define B_UART_MSR_RI BIT6
43#define B_UART_MSR_DCD BIT7
56BOOLEAN mBaseSerialPortLibHobAtRuntime =
FALSE;
80 return MmioRead8 (Base + Offset * RegisterStride);
82 return IoRead8 (Base + Offset * RegisterStride);
110 return MmioWrite8 (Base + Offset * RegisterStride, Value);
112 return IoWrite8 (Base + Offset * RegisterStride, Value);
133 UINTN SerialRegisterBase;
134 UINT8 RegisterStride;
136 UINT32 CurrentDivisor;
142 if (mUartCount > 0) {
148 SerialRegisterBase =
PcdGet64 (PcdSerialRegisterBase);
150 BaudRate =
PcdGet32 (PcdSerialBaudRate);
151 RegisterStride = (UINT8)
PcdGet32 (PcdSerialRegisterStride);
153 mUartInfo[mUartCount].BaseAddress = SerialRegisterBase;
154 mUartInfo[mUartCount].UseMmio = MmioEnable;
155 mUartInfo[mUartCount].BaudRate = BaudRate;
156 mUartInfo[mUartCount].RegisterStride = RegisterStride;
159 Divisor =
PcdGet32 (PcdSerialClockRate) / (BaudRate * 16);
160 if ((
PcdGet32 (PcdSerialClockRate) % (BaudRate * 16)) >= BaudRate * 8) {
168 if ((
SerialPortReadRegister (SerialRegisterBase, R_UART_LCR, MmioEnable, RegisterStride) & 0x3F) != (
PcdGet8 (PcdSerialLineControl) & 0x3F)) {
172 Value = (UINT8)(
SerialPortReadRegister (SerialRegisterBase, R_UART_LCR, MmioEnable, RegisterStride) | B_UART_LCR_DLAB);
174 CurrentDivisor =
SerialPortReadRegister (SerialRegisterBase, R_UART_BAUD_HIGH, MmioEnable, RegisterStride) << 8;
175 CurrentDivisor |= (UINT32)
SerialPortReadRegister (SerialRegisterBase, R_UART_BAUD_LOW, MmioEnable, RegisterStride);
176 Value = (UINT8)(
SerialPortReadRegister (SerialRegisterBase, R_UART_LCR, MmioEnable, RegisterStride) & ~B_UART_LCR_DLAB);
178 if (CurrentDivisor != Divisor) {
186 SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8)(Divisor >> 8), MmioEnable, RegisterStride);
187 SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8)(Divisor & 0xff), MmioEnable, RegisterStride);
200 SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, (UINT8)(
PcdGet8 (PcdSerialFifoControl) & (B_UART_FCR_FIFOE | B_UART_FCR_FIFO64)), MmioEnable, RegisterStride);
216 while (GuidHob !=
NULL) {
218 SerialRegisterBase = SerialPortInfo->RegisterBase;
219 MmioEnable = SerialPortInfo->UseMmio;
220 BaudRate = SerialPortInfo->BaudRate;
221 RegisterStride = SerialPortInfo->RegisterStride;
223 if (SerialRegisterBase == 0) {
224 GuidHob = GET_NEXT_HOB (GuidHob);
225 GuidHob =
GetNextGuidHob (&gUniversalPayloadSerialPortInfoGuid, GuidHob);
229 mUartInfo[mUartCount].BaseAddress = SerialRegisterBase;
230 mUartInfo[mUartCount].UseMmio = MmioEnable;
231 mUartInfo[mUartCount].BaudRate = BaudRate;
232 mUartInfo[mUartCount].RegisterStride = RegisterStride;
235 Divisor =
PcdGet32 (PcdSerialClockRate) / (BaudRate * 16);
236 if ((
PcdGet32 (PcdSerialClockRate) % (BaudRate * 16)) >= BaudRate * 8) {
244 if ((
SerialPortReadRegister (SerialRegisterBase, R_UART_LCR, MmioEnable, RegisterStride) & 0x3F) != (
PcdGet8 (PcdSerialLineControl) & 0x3F)) {
248 Value = (UINT8)(
SerialPortReadRegister (SerialRegisterBase, R_UART_LCR, MmioEnable, RegisterStride) | B_UART_LCR_DLAB);
250 CurrentDivisor =
SerialPortReadRegister (SerialRegisterBase, R_UART_BAUD_HIGH, MmioEnable, RegisterStride) << 8;
251 CurrentDivisor |= (UINT32)
SerialPortReadRegister (SerialRegisterBase, R_UART_BAUD_LOW, MmioEnable, RegisterStride);
252 Value = (UINT8)(
SerialPortReadRegister (SerialRegisterBase, R_UART_LCR, MmioEnable, RegisterStride) & ~B_UART_LCR_DLAB);
254 if (CurrentDivisor != Divisor) {
259 GuidHob = GET_NEXT_HOB (GuidHob);
260 GuidHob =
GetNextGuidHob (&gUniversalPayloadSerialPortInfoGuid, GuidHob);
268 SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8)(Divisor >> 8), MmioEnable, RegisterStride);
269 SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8)(Divisor & 0xff), MmioEnable, RegisterStride);
282 SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, (UINT8)(
PcdGet8 (PcdSerialFifoControl) & (B_UART_FCR_FIFOE | B_UART_FCR_FIFO64)), MmioEnable, RegisterStride);
294 GuidHob = GET_NEXT_HOB (GuidHob);
295 GuidHob =
GetNextGuidHob (&gUniversalPayloadSerialPortInfoGuid, GuidHob);
336 if ((Buffer ==
NULL) || (NumberOfBytes == 0) || (mUartCount == 0)) {
344 if ((
PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFOE) != 0) {
345 if ((
PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFO64) == 0) {
348 FifoSize =
PcdGet32 (PcdSerialExtendedTxFifoSize);
353 while (Count < mUartCount) {
354 BaseAddress = mUartInfo[Count].BaseAddress;
355 UseMmio = mUartInfo[Count].UseMmio;
356 Stride = mUartInfo[Count].RegisterStride;
358 if (UseMmio && mBaseSerialPortLibHobAtRuntime) {
363 if (BaseAddress == 0) {
369 BytesLeft = NumberOfBytes;
371 while (BytesLeft != 0) {
382 for (Index = 0; Index < FifoSize && BytesLeft != 0; Index++, BytesLeft--, DataBuffer++) {
395 return NumberOfBytes;
426 if (Buffer ==
NULL) {
431 while (Count < mUartCount) {
432 BaseAddress = mUartInfo[Count].BaseAddress;
433 UseMmio = mUartInfo[Count].UseMmio;
434 Stride = mUartInfo[Count].RegisterStride;
436 if (BaseAddress == 0) {
442 BytesLeft = NumberOfBytes;
447 for (Result = 0; BytesLeft-- != 0; Result++, DataBuffer++) {
452 if (
PcdGetBool (PcdSerialUseHardwareFlowControl)) {
467 if (
PcdGetBool (PcdSerialUseHardwareFlowControl)) {
480 if ((!IsNextPort) && (*(--DataBuffer) !=
'\0')) {
514 while (Count < mUartCount) {
515 BaseAddress = mUartInfo[Count].BaseAddress;
516 UseMmio = mUartInfo[Count].UseMmio;
517 Stride = mUartInfo[Count].RegisterStride;
519 if (BaseAddress == 0) {
530 if (
PcdGetBool (PcdSerialUseHardwareFlowControl)) {
540 if (
PcdGetBool (PcdSerialUseHardwareFlowControl)) {
578 while (Count < mUartCount) {
579 BaseAddress = mUartInfo[Count].BaseAddress;
580 UseMmio = mUartInfo[Count].UseMmio;
581 Stride = mUartInfo[Count].RegisterStride;
583 if (BaseAddress == 0) {
591 if ((Control & (~(EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY |
592 EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) != 0)
602 Mcr &= (~(B_UART_MCR_DTRC | B_UART_MCR_RTS));
604 if ((Control & EFI_SERIAL_DATA_TERMINAL_READY) == EFI_SERIAL_DATA_TERMINAL_READY) {
605 Mcr |= B_UART_MCR_DTRC;
608 if ((Control & EFI_SERIAL_REQUEST_TO_SEND) == EFI_SERIAL_REQUEST_TO_SEND) {
609 Mcr |= B_UART_MCR_RTS;
645 while (Count < mUartCount) {
646 BaseAddress = mUartInfo[Count].BaseAddress;
647 UseMmio = mUartInfo[Count].UseMmio;
648 Stride = mUartInfo[Count].RegisterStride;
650 if (BaseAddress == 0) {
662 if ((Msr & B_UART_MSR_CTS) == B_UART_MSR_CTS) {
663 *Control |= EFI_SERIAL_CLEAR_TO_SEND;
666 if ((Msr & B_UART_MSR_DSR) == B_UART_MSR_DSR) {
667 *Control |= EFI_SERIAL_DATA_SET_READY;
670 if ((Msr & B_UART_MSR_RI) == B_UART_MSR_RI) {
671 *Control |= EFI_SERIAL_RING_INDICATE;
674 if ((Msr & B_UART_MSR_DCD) == B_UART_MSR_DCD) {
675 *Control |= EFI_SERIAL_CARRIER_DETECT;
683 if ((Mcr & B_UART_MCR_DTRC) == B_UART_MCR_DTRC) {
684 *Control |= EFI_SERIAL_DATA_TERMINAL_READY;
687 if ((Mcr & B_UART_MCR_RTS) == B_UART_MCR_RTS) {
688 *Control |= EFI_SERIAL_REQUEST_TO_SEND;
691 if (
PcdGetBool (PcdSerialUseHardwareFlowControl)) {
692 *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
700 if ((Lsr & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) == (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) {
701 *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY;
704 if ((Lsr & B_UART_LSR_RXRDY) == 0) {
705 *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
708 if ((((*Control & EFI_SERIAL_OUTPUT_BUFFER_EMPTY) == EFI_SERIAL_OUTPUT_BUFFER_EMPTY) &&
709 ((*Control & EFI_SERIAL_INPUT_BUFFER_EMPTY) != EFI_SERIAL_INPUT_BUFFER_EMPTY)) ||
710 ((*Control & (EFI_SERIAL_DATA_SET_READY | EFI_SERIAL_CLEAR_TO_SEND |
711 EFI_SERIAL_CARRIER_DETECT)) == (EFI_SERIAL_DATA_SET_READY | EFI_SERIAL_CLEAR_TO_SEND |
712 EFI_SERIAL_CARRIER_DETECT)))
756 IN OUT UINT64 *BaudRate,
757 IN OUT UINT32 *ReceiveFifoDepth,
758 IN OUT UINT32 *Timeout,
760 IN OUT UINT8 *DataBits,
766 UINT32 SerialBaudRate;
776 while (Count < mUartCount) {
777 BaseAddress = mUartInfo[Count].BaseAddress;
778 UseMmio = mUartInfo[Count].UseMmio;
779 Stride = mUartInfo[Count].RegisterStride;
781 if (BaseAddress == 0) {
789 if (*BaudRate == 0) {
790 *BaudRate = mUartInfo[Count].BaudRate;
793 SerialBaudRate = (UINT32)*BaudRate;
795 if (*DataBits == 0) {
796 LcrData = (UINT8)(
PcdGet8 (PcdSerialLineControl) & 0x3);
797 *DataBits = LcrData + 5;
799 if ((*DataBits < 5) || (*DataBits > 8)) {
807 LcrData = (UINT8)(*DataBits - (UINT8)5);
810 if (*Parity == DefaultParity) {
811 LcrParity = (UINT8)((
PcdGet8 (PcdSerialLineControl) >> 3) & 0x7);
818 *Parity = EvenParity;
826 *Parity = SpaceParity;
830 *Parity = MarkParity;
864 if (*StopBits == DefaultStopBits) {
865 LcrStop = (UINT8)((
PcdGet8 (PcdSerialLineControl) >> 2) & 0x1);
868 *StopBits = OneStopBit;
872 if (*DataBits == 5) {
873 *StopBits = OneFiveStopBits;
875 *StopBits = TwoStopBits;
889 case OneFiveStopBits:
904 Divisor =
PcdGet32 (PcdSerialClockRate) / (SerialBaudRate * 16);
905 if ((
PcdGet32 (PcdSerialClockRate) % (SerialBaudRate * 16)) >= SerialBaudRate * 8) {
920 Lcr = (UINT8)((LcrParity << 3) | (LcrStop << 2) | LcrData);
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
VOID *EFIAPI GetNextGuidHob(IN CONST EFI_GUID *Guid, IN CONST VOID *HobStart)
VOID *EFIAPI GetHobList(VOID)
UINT8 SerialPortReadRegister(UINTN Base, UINTN Offset, BOOLEAN UseMmio, UINT8 RegisterStride)
BOOLEAN EFIAPI SerialPortPoll(VOID)
RETURN_STATUS EFIAPI SerialPortSetAttributes(IN OUT UINT64 *BaudRate, IN OUT UINT32 *ReceiveFifoDepth, IN OUT UINT32 *Timeout, IN OUT EFI_PARITY_TYPE *Parity, IN OUT UINT8 *DataBits, IN OUT EFI_STOP_BITS_TYPE *StopBits)
UINTN EFIAPI SerialPortRead(OUT UINT8 *Buffer, IN UINTN NumberOfBytes)
RETURN_STATUS EFIAPI SerialPortInitialize(VOID)
RETURN_STATUS EFIAPI SerialPortSetControl(IN UINT32 Control)
UINT8 SerialPortWriteRegister(UINTN Base, UINTN Offset, UINT8 Value, BOOLEAN UseMmio, UINT8 RegisterStride)
RETURN_STATUS EFIAPI SerialPortGetControl(OUT UINT32 *Control)
UINTN EFIAPI SerialPortWrite(IN UINT8 *Buffer, IN UINTN NumberOfBytes)
UINT8 EFIAPI IoWrite8(IN UINTN Port, IN UINT8 Value)
UINT8 EFIAPI MmioRead8(IN UINTN Address)
UINT8 EFIAPI MmioWrite8(IN UINTN Address, IN UINT8 Value)
UINT8 EFIAPI IoRead8(IN UINTN Port)
#define PcdGet64(TokenName)
#define PcdGet8(TokenName)
#define PcdGet32(TokenName)
#define PcdGetBool(TokenName)