summaryrefslogtreecommitdiffstats
path: root/src/include/ipxe/uart.h
blob: f2ecf3ce9290741afc846c400afc0160b4d2148d (plain) (blame)
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#ifndef _IPXE_UART_H
#define _IPXE_UART_H

/** @file
 *
 * Generic UART
 *
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <stdint.h>
#include <ipxe/refcnt.h>
#include <ipxe/list.h>

/** A generic UART */
struct uart {
	/** Reference count */
	struct refcnt refcnt;
	/** Name */
	const char *name;
	/** List of registered UARTs */
	struct list_head list;

	/** Baud rate (if specified) */
	unsigned int baud;

	/** UART operations */
	struct uart_operations *op;
	/** Driver-private data */
	void *priv;
};

/** UART operations */
struct uart_operations {
	/**
	 * Transmit byte
	 *
	 * @v uart		UART
	 * @v byte		Byte to transmit
	 * @ret rc		Return status code
	 */
	void ( * transmit ) ( struct uart *uart, uint8_t byte );
	/**
	 * Check if data is ready
	 *
	 * @v uart		UART
	 * @ret ready		Data is ready
	 */
	int ( * data_ready ) ( struct uart *uart );
	/**
	 * Receive byte
	 *
	 * @v uart		UART
	 * @ret byte		Received byte
	 */
	uint8_t ( * receive ) ( struct uart *uart );
	/**
	 * Initialise UART
	 *
	 * @v uart		UART
	 * @ret rc		Return status code
	 */
	int ( * init ) ( struct uart *uart );
	/**
	 * Flush transmitted data
	 *
	 * @v uart		UART
	 */
	void ( * flush ) ( struct uart *uart );
};

/**
 * Transmit byte
 *
 * @v uart		UART
 * @v byte		Byte to transmit
 * @ret rc		Return status code
 */
static inline __attribute__ (( always_inline )) void
uart_transmit ( struct uart *uart, uint8_t byte ) {

	uart->op->transmit ( uart, byte );
}

/**
 * Check if data is ready
 *
 * @v uart		UART
 * @ret ready		Data is ready
 */
static inline __attribute__ (( always_inline )) int
uart_data_ready ( struct uart *uart ) {

	return uart->op->data_ready ( uart );
}

/**
 * Receive byte
 *
 * @v uart		UART
 * @ret byte		Received byte
 */
static inline __attribute__ (( always_inline )) uint8_t
uart_receive ( struct uart *uart ) {

	return uart->op->receive ( uart );
}

/**
 * Initialise UART
 *
 * @v uart		UART
 * @ret rc		Return status code
 */
static inline __attribute__ (( always_inline )) int
uart_init ( struct uart *uart ) {

	return uart->op->init ( uart );
}

/**
 * Flush transmitted data
 *
 * @v uart		UART
 */
static inline __attribute__ (( always_inline )) void
uart_flush ( struct uart *uart ) {

	uart->op->flush ( uart );
}

extern struct list_head uarts;
extern struct uart_operations null_uart_operations;

/**
 * Get reference to UART
 *
 * @v uart		UART
 * @ret uart		UART
 */
static inline __attribute__ (( always_inline )) struct uart *
uart_get ( struct uart *uart ) {

	ref_get ( &uart->refcnt );
	return uart;
}

/**
 * Drop reference to UART
 *
 * @v uart		UART
 */
static inline __attribute__ (( always_inline )) void
uart_put ( struct uart *uart ) {

	ref_put ( &uart->refcnt );
}

/**
 * Nullify UART
 *
 * @v uart		UART
 */
static inline __attribute__ (( always_inline )) void
uart_nullify ( struct uart *uart ) {

	uart->op = &null_uart_operations;
}

extern struct uart * alloc_uart ( size_t priv_len );
extern int uart_register ( struct uart *uart );
extern int uart_register_fixed ( void );
extern void uart_unregister ( struct uart *uart );
extern struct uart * uart_find ( const char *name );

#endif /* _IPXE_UART_H */