iPXE
Defines | Functions
uart.c File Reference

16550-compatible UART More...

#include <unistd.h>
#include <errno.h>
#include <ipxe/uart.h>

Go to the source code of this file.

Defines

#define UART_THRE_TIMEOUT_MS   100
 Timeout for transmit holding register to become empty.
#define UART_TEMT_TIMEOUT_MS   1000
 Timeout for transmitter to become empty.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
void uart_transmit (struct uart *uart, uint8_t data)
 Transmit data.
void uart_flush (struct uart *uart)
 Flush data.
int uart_exists (struct uart *uart)
 Check for existence of UART.
int uart_init (struct uart *uart, unsigned int baud, uint8_t lcr)
 Initialise UART.

Detailed Description

16550-compatible UART

Definition in file uart.c.


Define Documentation

#define UART_THRE_TIMEOUT_MS   100

Timeout for transmit holding register to become empty.

Definition at line 37 of file uart.c.

Referenced by uart_transmit().

#define UART_TEMT_TIMEOUT_MS   1000

Timeout for transmitter to become empty.

Definition at line 40 of file uart.c.

Referenced by uart_flush().


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
void uart_transmit ( struct uart uart,
uint8_t  data 
)

Transmit data.

Parameters:
uartUART
dataData

Definition at line 48 of file uart.c.

References mdelay(), UART_LSR, UART_LSR_THRE, uart_read(), UART_THR, UART_THRE_TIMEOUT_MS, and uart_write().

Referenced by gdbserial_send(), int21(), and serial_putchar().

                                                       {
        unsigned int i;
        uint8_t lsr;

        /* Wait for transmitter holding register to become empty */
        for ( i = 0 ; i < UART_THRE_TIMEOUT_MS ; i++ ) {
                lsr = uart_read ( uart, UART_LSR );
                if ( lsr & UART_LSR_THRE )
                        break;
                mdelay ( 1 );
        }

        /* Transmit data (even if we timed out) */
        uart_write ( uart, UART_THR, data );
}
void uart_flush ( struct uart uart)

Flush data.

Parameters:
uartUART

Definition at line 69 of file uart.c.

References UART_LSR, UART_LSR_DR, UART_LSR_TEMT, UART_RBR, uart_read(), and UART_TEMT_TIMEOUT_MS.

Referenced by serial_shutdown(), and uart_init().

                                      {
        unsigned int i;
        uint8_t lsr;

        /* Wait for transmitter and receiver to become empty */
        for ( i = 0 ; i < UART_TEMT_TIMEOUT_MS ; i++ ) {
                uart_read ( uart, UART_RBR );
                lsr = uart_read ( uart, UART_LSR );
                if ( ( lsr & UART_LSR_TEMT ) && ! ( lsr & UART_LSR_DR ) )
                        break;
        }
}
int uart_exists ( struct uart uart)

Check for existence of UART.

Parameters:
uartUART
Return values:
rcReturn status code

Definition at line 88 of file uart.c.

References uart::base, ENODEV, uart_read(), UART_SCR, and uart_write().

Referenced by uart_init(), and uart_select().

                                      {

        /* Fail if no UART port is defined */
        if ( ! uart->base )
                return -ENODEV;

        /* Fail if UART scratch register seems not to be present */
        uart_write ( uart, UART_SCR, 0x18 );
        if ( uart_read ( uart, UART_SCR ) != 0x18 )
                return -ENODEV;
        uart_write ( uart, UART_SCR, 0xae );
        if ( uart_read ( uart, UART_SCR ) != 0xae )
                return -ENODEV;

        return 0;
}
int uart_init ( struct uart uart,
unsigned int  baud,
uint8_t  lcr 
)

Initialise UART.

Parameters:
uartUART
baudBaud rate, or zero to leave unchanged
lcrLine control register value, or zero to leave unchanged
Return values:
rcReturn status code

Definition at line 113 of file uart.c.

References uart::divisor, uart::lcr, rc, UART_DLL, UART_DLM, uart_exists(), UART_FCR, UART_FCR_FE, uart_flush(), UART_IER, UART_LCR, UART_LCR_DLAB, UART_MAX_BAUD, UART_MCR, UART_MCR_DTR, UART_MCR_RTS, uart_read(), and uart_write().

Referenced by gdbserial_configure(), and serial_init().

                                                                    {
        uint8_t dlm;
        uint8_t dll;
        int rc;

        /* Check for existence of UART */
        if ( ( rc = uart_exists ( uart ) ) != 0 )
                return rc;

        /* Configure divisor and line control register, if applicable */
        if ( ! lcr )
                lcr = uart_read ( uart, UART_LCR );
        uart->lcr = lcr;
        uart_write ( uart, UART_LCR, ( lcr | UART_LCR_DLAB ) );
        if ( baud ) {
                uart->divisor = ( UART_MAX_BAUD / baud );
                dlm = ( ( uart->divisor >> 8 ) & 0xff );
                dll = ( ( uart->divisor >> 0 ) & 0xff );
                uart_write ( uart, UART_DLM, dlm );
                uart_write ( uart, UART_DLL, dll );
        } else {
                dlm = uart_read ( uart, UART_DLM );
                dll = uart_read ( uart, UART_DLL );
                uart->divisor = ( ( dlm << 8 ) | dll );
        }
        uart_write ( uart, UART_LCR, ( lcr & ~UART_LCR_DLAB ) );

        /* Disable interrupts */
        uart_write ( uart, UART_IER, 0 );

        /* Enable FIFOs */
        uart_write ( uart, UART_FCR, UART_FCR_FE );

        /* Assert DTR and RTS */
        uart_write ( uart, UART_MCR, ( UART_MCR_DTR | UART_MCR_RTS ) );

        /* Flush any stale data */
        uart_flush ( uart );

        return 0;
}