iPXE
Macros | Functions | Variables
ns16550.c File Reference

16550-compatible UART More...

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

Go to the source code of this file.

Macros

#define NS16550_THRE_TIMEOUT_MS   100
 Timeout for transmit holding register to become empty. More...
 
#define NS16550_TEMT_TIMEOUT_MS   1000
 Timeout for transmitter to become empty. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static void ns16550_transmit (struct uart *uart, uint8_t data)
 Transmit data. More...
 
static int ns16550_data_ready (struct uart *uart)
 Check if data is ready. More...
 
static uint8_t ns16550_receive (struct uart *uart)
 Receive data. More...
 
static void ns16550_flush (struct uart *uart)
 Flush transmitted data. More...
 
static int ns16550_init (struct uart *uart)
 Initialise UART. More...
 

Variables

struct uart_operations ns16550_operations
 16550 UART operations More...
 

Detailed Description

16550-compatible UART

Definition in file ns16550.c.

Macro Definition Documentation

◆ NS16550_THRE_TIMEOUT_MS

#define NS16550_THRE_TIMEOUT_MS   100

Timeout for transmit holding register to become empty.

Definition at line 38 of file ns16550.c.

◆ NS16550_TEMT_TIMEOUT_MS

#define NS16550_TEMT_TIMEOUT_MS   1000

Timeout for transmitter to become empty.

Definition at line 41 of file ns16550.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ ns16550_transmit()

static void ns16550_transmit ( struct uart uart,
uint8_t  data 
)
static

Transmit data.

Parameters
uartUART
dataData

Definition at line 49 of file ns16550.c.

49  {
50  struct ns16550_uart *ns16550 = uart->priv;
51  unsigned int i;
52  uint8_t lsr;
53 
54  /* Wait for transmitter holding register to become empty */
55  for ( i = 0 ; i < NS16550_THRE_TIMEOUT_MS ; i++ ) {
56  lsr = ns16550_read ( ns16550, NS16550_LSR );
57  if ( lsr & NS16550_LSR_THRE )
58  break;
59  mdelay ( 1 );
60  }
61 
62  /* Transmit data (even if we timed out) */
63  ns16550_write ( ns16550, NS16550_THR, data );
64 }
A generic UART.
Definition: uart.h:17
void * priv
Driver-private data.
Definition: uart.h:31
A 16550-compatible UART.
Definition: ns16550.h:80
unsigned char uint8_t
Definition: stdint.h:10
uint8_t ns16550_read(struct ns16550_uart *ns16550, unsigned int address)
#define NS16550_THR
Transmitter holding register.
Definition: ns16550.h:18
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:78
#define NS16550_LSR
Line status register.
Definition: ns16550.h:65
#define NS16550_LSR_THRE
Transmitter holding reg.
Definition: ns16550.h:67
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define NS16550_THRE_TIMEOUT_MS
Timeout for transmit holding register to become empty.
Definition: ns16550.c:38
void ns16550_write(struct ns16550_uart *ns16550, unsigned int address, uint8_t data)
Dummy COM1 UART for non-x86 platforms.

References data, mdelay(), NS16550_LSR, NS16550_LSR_THRE, ns16550_read(), NS16550_THR, NS16550_THRE_TIMEOUT_MS, ns16550_write(), and uart::priv.

◆ ns16550_data_ready()

static int ns16550_data_ready ( struct uart uart)
static

Check if data is ready.

Parameters
uartUART
Return values
readyData is ready

Definition at line 72 of file ns16550.c.

72  {
73  struct ns16550_uart *ns16550 = uart->priv;
74  uint8_t lsr;
75 
76  /* Check for receive data ready */
77  lsr = ns16550_read ( ns16550, NS16550_LSR );
78  return ( lsr & NS16550_LSR_DR );
79 }
A generic UART.
Definition: uart.h:17
void * priv
Driver-private data.
Definition: uart.h:31
A 16550-compatible UART.
Definition: ns16550.h:80
unsigned char uint8_t
Definition: stdint.h:10
uint8_t ns16550_read(struct ns16550_uart *ns16550, unsigned int address)
#define NS16550_LSR_DR
Data ready.
Definition: ns16550.h:66
#define NS16550_LSR
Line status register.
Definition: ns16550.h:65

References NS16550_LSR, NS16550_LSR_DR, ns16550_read(), and uart::priv.

Referenced by ns16550_init().

◆ ns16550_receive()

static uint8_t ns16550_receive ( struct uart uart)
static

Receive data.

Parameters
uartUART
Return values
dataData

Definition at line 87 of file ns16550.c.

87  {
88  struct ns16550_uart *ns16550 = uart->priv;
89  uint8_t rbr;
90 
91  /* Receive byte */
92  rbr = ns16550_read ( ns16550, NS16550_RBR );
93  return rbr;
94 }
A generic UART.
Definition: uart.h:17
void * priv
Driver-private data.
Definition: uart.h:31
A 16550-compatible UART.
Definition: ns16550.h:80
unsigned char uint8_t
Definition: stdint.h:10
uint8_t ns16550_read(struct ns16550_uart *ns16550, unsigned int address)
#define NS16550_RBR
Receiver buffer register.
Definition: ns16550.h:21

References NS16550_RBR, ns16550_read(), and uart::priv.

Referenced by ns16550_init().

◆ ns16550_flush()

static void ns16550_flush ( struct uart uart)
static

Flush transmitted data.

Parameters
uartUART

Definition at line 101 of file ns16550.c.

101  {
102  struct ns16550_uart *ns16550 = uart->priv;
103  unsigned int i;
104  uint8_t lsr;
105 
106  /* Wait for transmitter to become empty */
107  for ( i = 0 ; i < NS16550_TEMT_TIMEOUT_MS ; i++ ) {
108  lsr = ns16550_read ( ns16550, NS16550_LSR );
109  if ( lsr & NS16550_LSR_TEMT )
110  break;
111  }
112 }
A generic UART.
Definition: uart.h:17
#define NS16550_TEMT_TIMEOUT_MS
Timeout for transmitter to become empty.
Definition: ns16550.c:41
#define NS16550_LSR_TEMT
Transmitter empty.
Definition: ns16550.h:68
void * priv
Driver-private data.
Definition: uart.h:31
A 16550-compatible UART.
Definition: ns16550.h:80
unsigned char uint8_t
Definition: stdint.h:10
uint8_t ns16550_read(struct ns16550_uart *ns16550, unsigned int address)
#define NS16550_LSR
Line status register.
Definition: ns16550.h:65

References NS16550_LSR, NS16550_LSR_TEMT, ns16550_read(), NS16550_TEMT_TIMEOUT_MS, and uart::priv.

Referenced by ns16550_init().

◆ ns16550_init()

static int ns16550_init ( struct uart uart)
static

Initialise UART.

Parameters
uartUART
Return values
rcReturn status code

Definition at line 120 of file ns16550.c.

120  {
121  struct ns16550_uart *ns16550 = uart->priv;
122  uint8_t dlm;
123  uint8_t dll;
124 
125  /* Fail if UART scratch register seems not to be present */
126  ns16550_write ( ns16550, NS16550_SCR, 0x18 );
127  if ( ns16550_read ( ns16550, NS16550_SCR ) != 0x18 )
128  return -ENODEV;
129  ns16550_write ( ns16550, NS16550_SCR, 0xae );
130  if ( ns16550_read ( ns16550, NS16550_SCR ) != 0xae )
131  return -ENODEV;
132 
133  /* Wait for UART to become idle before modifying LCR */
134  ns16550_flush ( uart );
135 
136  /* Configure divisor and line control register, if applicable */
137  ns16550_write ( ns16550, NS16550_LCR,
139  if ( uart->baud ) {
140  ns16550->divisor = ( ( ns16550->clock / uart->baud ) /
141  NS16550_CLK_BIT );
142  dlm = ( ( ns16550->divisor >> 8 ) & 0xff );
143  dll = ( ( ns16550->divisor >> 0 ) & 0xff );
144  ns16550_write ( ns16550, NS16550_DLM, dlm );
145  ns16550_write ( ns16550, NS16550_DLL, dll );
146  } else {
147  dlm = ns16550_read ( ns16550, NS16550_DLM );
148  dll = ns16550_read ( ns16550, NS16550_DLL );
149  ns16550->divisor = ( ( dlm << 8 ) | dll );
150  }
152 
153  /* Disable interrupts */
154  ns16550_write ( ns16550, NS16550_IER, 0 );
155 
156  /* Enable FIFOs */
158 
159  /* Assert DTR and RTS */
160  ns16550_write ( ns16550, NS16550_MCR,
162 
163  /* Flush any stale received data */
164  while ( ns16550_data_ready ( uart ) )
165  ns16550_receive ( uart );
166 
167  return 0;
168 }
#define NS16550_LCR
Line control register.
Definition: ns16550.h:31
A generic UART.
Definition: uart.h:17
static uint8_t ns16550_receive(struct uart *uart)
Receive data.
Definition: ns16550.c:87
#define NS16550_SCR
Scratch register.
Definition: ns16550.h:71
#define NS16550_DLM
Divisor latch (most significant byte)
Definition: ns16550.h:77
static void ns16550_flush(struct uart *uart)
Flush transmitted data.
Definition: ns16550.c:101
#define NS16550_FCR_FE
FIFO enable.
Definition: ns16550.h:28
#define NS16550_LCR_DLAB
Divisor latch access bit.
Definition: ns16550.h:37
unsigned int baud
Baud rate (if specified)
Definition: uart.h:26
#define NS16550_MCR_DTR
Data terminal ready.
Definition: ns16550.h:61
uint16_t divisor
Baud rate divisor.
Definition: ns16550.h:88
#define NS16550_IER
Interrupt enable register.
Definition: ns16550.h:24
unsigned int clock
Input clock frequency.
Definition: ns16550.h:86
void * priv
Driver-private data.
Definition: uart.h:31
A 16550-compatible UART.
Definition: ns16550.h:80
#define ENODEV
No such device.
Definition: errno.h:509
unsigned char uint8_t
Definition: stdint.h:10
#define NS16550_MCR
Modem control register.
Definition: ns16550.h:60
uint8_t ns16550_read(struct ns16550_uart *ns16550, unsigned int address)
#define NS16550_MCR_RTS
Request to send.
Definition: ns16550.h:62
#define NS16550_FCR
FIFO control register.
Definition: ns16550.h:27
#define NS16550_CLK_BIT
Post-division clock cycles per data bit.
Definition: ns16550.h:92
#define NS16550_DLL
Divisor latch (least significant byte)
Definition: ns16550.h:74
void ns16550_write(struct ns16550_uart *ns16550, unsigned int address, uint8_t data)
Dummy COM1 UART for non-x86 platforms.
#define NS16550_LCR_8N1
Default LCR value: 8 data bits, no parity, one stop bit.
Definition: ns16550.h:57
static int ns16550_data_ready(struct uart *uart)
Check if data is ready.
Definition: ns16550.c:72

References uart::baud, ns16550_uart::clock, ns16550_uart::divisor, ENODEV, NS16550_CLK_BIT, ns16550_data_ready(), NS16550_DLL, NS16550_DLM, NS16550_FCR, NS16550_FCR_FE, ns16550_flush(), NS16550_IER, NS16550_LCR, NS16550_LCR_8N1, NS16550_LCR_DLAB, NS16550_MCR, NS16550_MCR_DTR, NS16550_MCR_RTS, ns16550_read(), ns16550_receive(), NS16550_SCR, ns16550_write(), and uart::priv.

Variable Documentation

◆ ns16550_operations

struct uart_operations ns16550_operations
Initial value:
= {
.transmit = ns16550_transmit,
.data_ready = ns16550_data_ready,
.receive = ns16550_receive,
.init = ns16550_init,
.flush = ns16550_flush,
}
static uint8_t ns16550_receive(struct uart *uart)
Receive data.
Definition: ns16550.c:87
static int ns16550_init(struct uart *uart)
Initialise UART.
Definition: ns16550.c:120
static void ns16550_flush(struct uart *uart)
Flush transmitted data.
Definition: ns16550.c:101
static void ns16550_transmit(struct uart *uart, uint8_t data)
Transmit data.
Definition: ns16550.c:49
static int ns16550_data_ready(struct uart *uart)
Check if data is ready.
Definition: ns16550.c:72

16550 UART operations

Definition at line 171 of file ns16550.c.

Referenced by dwuart_probe(), and spcr_16550().