iPXE
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.
#define NS16550_TEMT_TIMEOUT_MS   1000
 Timeout for transmitter to become empty.

Functions

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

Variables

struct uart_operations ns16550_operations
 16550 UART operations

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.

Referenced by ns16550_transmit().

◆ NS16550_TEMT_TIMEOUT_MS

#define NS16550_TEMT_TIMEOUT_MS   1000

Timeout for transmitter to become empty.

Definition at line 41 of file ns16550.c.

Referenced by ns16550_flush().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ ns16550_transmit()

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}
unsigned char uint8_t
Definition stdint.h:10
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define NS16550_THR
Transmitter holding register.
Definition ns16550.h:18
#define NS16550_LSR
Line status register.
Definition ns16550.h:65
uint8_t ns16550_read(struct ns16550_uart *ns16550, unsigned int address)
void ns16550_write(struct ns16550_uart *ns16550, unsigned int address, uint8_t data)
Dummy COM1 UART for non-x86 platforms.
#define NS16550_LSR_THRE
Transmitter holding reg.
Definition ns16550.h:67
#define NS16550_THRE_TIMEOUT_MS
Timeout for transmit holding register to become empty.
Definition ns16550.c:38
A 16550-compatible UART.
Definition ns16550.h:80
A generic UART.
Definition uart.h:17
void * priv
Driver-private data.
Definition uart.h:31
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition timer.c:79

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

◆ ns16550_data_ready()

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}
#define NS16550_LSR_DR
Data ready.
Definition ns16550.h:66

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

Referenced by ns16550_init().

◆ ns16550_receive()

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}
#define NS16550_RBR
Receiver buffer register.
Definition ns16550.h:21

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

Referenced by ns16550_init().

◆ ns16550_flush()

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}
#define NS16550_LSR_TEMT
Transmitter empty.
Definition ns16550.h:68
#define NS16550_TEMT_TIMEOUT_MS
Timeout for transmitter to become empty.
Definition ns16550.c:41

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

Referenced by ns16550_init().

◆ ns16550_init()

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 */
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 ) /
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 ) )
166
167 return 0;
168}
#define ENODEV
No such device.
Definition errno.h:510
#define NS16550_DLL
Divisor latch (least significant byte)
Definition ns16550.h:74
#define NS16550_CLK_BIT
Post-division clock cycles per data bit.
Definition ns16550.h:92
#define NS16550_FCR_FE
FIFO enable.
Definition ns16550.h:28
#define NS16550_SCR
Scratch register.
Definition ns16550.h:71
#define NS16550_MCR
Modem control register.
Definition ns16550.h:60
#define NS16550_DLM
Divisor latch (most significant byte)
Definition ns16550.h:77
#define NS16550_MCR_DTR
Data terminal ready.
Definition ns16550.h:61
#define NS16550_LCR
Line control register.
Definition ns16550.h:31
#define NS16550_MCR_RTS
Request to send.
Definition ns16550.h:62
#define NS16550_LCR_DLAB
Divisor latch access bit.
Definition ns16550.h:37
#define NS16550_IER
Interrupt enable register.
Definition ns16550.h:24
#define NS16550_FCR
FIFO control register.
Definition ns16550.h:27
#define NS16550_LCR_8N1
Default LCR value: 8 data bits, no parity, one stop bit.
Definition ns16550.h:57
static uint8_t ns16550_receive(struct uart *uart)
Receive data.
Definition ns16550.c:87
static int ns16550_data_ready(struct uart *uart)
Check if data is ready.
Definition ns16550.c:72
static void ns16550_flush(struct uart *uart)
Flush transmitted data.
Definition ns16550.c:101
unsigned int clock
Input clock frequency.
Definition ns16550.h:86
uint16_t divisor
Baud rate divisor.
Definition ns16550.h:88
unsigned int baud
Baud rate (if specified)
Definition uart.h:26

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 int ns16550_init(struct uart *uart)
Initialise UART.
Definition ns16550.c:120
static void ns16550_transmit(struct uart *uart, uint8_t data)
Transmit data.
Definition ns16550.c:49

16550 UART operations

Definition at line 171 of file ns16550.c.

171 {
172 .transmit = ns16550_transmit,
173 .data_ready = ns16550_data_ready,
174 .receive = ns16550_receive,
175 .init = ns16550_init,
176 .flush = ns16550_flush,
177};

Referenced by dwuart_probe(), ns16550_read(), and spcr_16550().