1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
#ifndef _IPXE_NS16550_H
#define _IPXE_NS16550_H
/** @file
*
* 16550-compatible UART
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/uart.h>
/** Length of register region */
#define NS16550_LEN 8
/** Transmitter holding register */
#define NS16550_THR 0x00
/** Receiver buffer register */
#define NS16550_RBR 0x00
/** Interrupt enable register */
#define NS16550_IER 0x01
/** FIFO control register */
#define NS16550_FCR 0x02
#define NS16550_FCR_FE 0x01 /**< FIFO enable */
/** Line control register */
#define NS16550_LCR 0x03
#define NS16550_LCR_WLS0 0x01 /**< Word length select bit 0 */
#define NS16550_LCR_WLS1 0x02 /**< Word length select bit 1 */
#define NS16550_LCR_STB 0x04 /**< Number of stop bits */
#define NS16550_LCR_PEN 0x08 /**< Parity enable */
#define NS16550_LCR_EPS 0x10 /**< Even parity select */
#define NS16550_LCR_DLAB 0x80 /**< Divisor latch access bit */
#define NS16550_LCR_WORD_LEN(x) ( ( (x) - 5 ) << 0 ) /**< Word length */
#define NS16550_LCR_STOP_BITS(x) ( ( (x) - 1 ) << 2 ) /**< Stop bits */
#define NS16550_LCR_PARITY(x) ( ( (x) - 0 ) << 3 ) /**< Parity */
/**
* Calculate line control register value
*
* @v word_len Word length (5-8)
* @v parity Parity (0=none, 1=odd, 3=even)
* @v stop_bits Stop bits (1-2)
* @ret lcr Line control register value
*/
#define NS16550_LCR_WPS( word_len, parity, stop_bits ) \
( NS16550_LCR_WORD_LEN ( (word_len) ) | \
NS16550_LCR_PARITY ( (parity) ) | \
NS16550_LCR_STOP_BITS ( (stop_bits) ) )
/** Default LCR value: 8 data bits, no parity, one stop bit */
#define NS16550_LCR_8N1 NS16550_LCR_WPS ( 8, 0, 1 )
/** Modem control register */
#define NS16550_MCR 0x04
#define NS16550_MCR_DTR 0x01 /**< Data terminal ready */
#define NS16550_MCR_RTS 0x02 /**< Request to send */
/** Line status register */
#define NS16550_LSR 0x05
#define NS16550_LSR_DR 0x01 /**< Data ready */
#define NS16550_LSR_THRE 0x20 /**< Transmitter holding reg. empty */
#define NS16550_LSR_TEMT 0x40 /**< Transmitter empty */
/** Scratch register */
#define NS16550_SCR 0x07
/** Divisor latch (least significant byte) */
#define NS16550_DLL 0x00
/** Divisor latch (most significant byte) */
#define NS16550_DLM 0x01
/** A 16550-compatible UART */
struct ns16550_uart {
/** Register base address */
void *base;
/** Register shift */
unsigned int shift;
/** Input clock frequency */
unsigned int clock;
/** Baud rate divisor */
uint16_t divisor;
};
/** Post-division clock cycles per data bit */
#define NS16550_CLK_BIT 16
/** Default input clock rate (1.8432 MHz) */
#define NS16550_CLK_DEFAULT 1843200
#include <bits/ns16550.h>
/** Dummy COM1 UART for non-x86 platforms
*
* The architecture-independent config/serial.h header has long
* included the line
*
* #define COMCONSOLE COM1
*
* which is meaningless on non-x86 platforms where there is no COM1
* port. Allow COM1 to be treated as equivalent to "no UART" on
* non-x86 platforms, to avoid breaking existing build configurations.
*/
#ifndef COM1
#define COM1 NULL
#endif
void ns16550_write ( struct ns16550_uart *ns16550, unsigned int address,
uint8_t data );
uint8_t ns16550_read ( struct ns16550_uart *ns16550, unsigned int address );
extern struct uart_operations ns16550_operations;
#endif /* _IPXE_NS16550_H */
|