xref: /kvmtool/hw/serial.c (revision 8eb47d298631e727f9747e56faa14a40234b2d22)
1 #include "kvm/8250-serial.h"
2 
3 #include "kvm/read-write.h"
4 #include "kvm/ioport.h"
5 #include "kvm/util.h"
6 #include "kvm/kvm.h"
7 
8 #include <linux/serial_reg.h>
9 
10 #include <stdbool.h>
11 #include <poll.h>
12 
13 struct serial8250_device {
14 	uint16_t		iobase;
15 	uint8_t			irq;
16 
17 	uint8_t			rbr;		/* receive buffer */
18 	uint8_t			dll;
19 	uint8_t			dlm;
20 	uint8_t			iir;
21 	uint8_t			ier;
22 	uint8_t			fcr;
23 	uint8_t			lcr;
24 	uint8_t			mcr;
25 	uint8_t			lsr;
26 	uint8_t			msr;
27 	uint8_t			scr;
28 };
29 
30 static struct serial8250_device devices[] = {
31 	/* ttyS0 */
32 	[0]	= {
33 		.iobase			= 0x3f8,
34 		.irq			= 4,
35 
36 		.iir			= UART_IIR_NO_INT,
37 		.lsr			= UART_LSR_TEMT | UART_LSR_THRE,
38 		.msr			= UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS,
39 		.mcr			= UART_MCR_OUT2,
40 	},
41 	/* ttyS1 */
42 	[1]	= {
43 		.iobase			= 0x2f8,
44 		.irq			= 3,
45 
46 		.iir			= UART_IIR_NO_INT,
47 	},
48 	/* ttyS2 */
49 	[2]	= {
50 		.iobase			= 0x3e8,
51 		.irq			= 4,
52 
53 		.iir			= UART_IIR_NO_INT,
54 	},
55 };
56 
57 static int read_char(int fd)
58 {
59 	char c;
60 
61 	if (read_in_full(fd, &c, 1) == 0)
62 		return -1;
63 
64 	return c;
65 }
66 
67 static bool is_readable(int fd)
68 {
69 	struct pollfd pollfd = (struct pollfd) {
70 		.fd	= fd,
71 		.events	= POLLIN,
72 	};
73 
74 	return poll(&pollfd, 1, 0) > 0;
75 }
76 
77 static void serial8250__receive(struct kvm *self, struct serial8250_device *dev)
78 {
79 	int c;
80 
81 	if (dev->lsr & UART_LSR_DR)
82 		return;
83 
84 	if (!is_readable(STDIN_FILENO))
85 		return;
86 
87 	c		= read_char(STDIN_FILENO);
88 	if (c < 0)
89 		return;
90 
91 	dev->rbr	= c;
92 	dev->lsr	|= UART_LSR_DR;
93 }
94 
95 /*
96  * Interrupts are injected for ttyS0 only.
97  */
98 void serial8250__interrupt(struct kvm *self)
99 {
100 	struct serial8250_device *dev = &devices[0];
101 
102 	serial8250__receive(self, dev);
103 
104 	if (dev->ier & UART_IER_RDI && dev->lsr & UART_LSR_DR)
105 		dev->iir		= UART_IIR_RDI;
106 	else if (dev->ier & UART_IER_THRI)
107 		dev->iir		= UART_IIR_THRI;
108 	else
109 		dev->iir		= UART_IIR_NO_INT;
110 
111 	if (dev->iir != UART_IIR_NO_INT) {
112 		kvm__irq_line(self, dev->irq, 0);
113 		kvm__irq_line(self, dev->irq, 1);
114 	}
115 }
116 
117 static struct serial8250_device *find_device(uint16_t port)
118 {
119 	unsigned int i;
120 
121 	for (i = 0; i < ARRAY_SIZE(devices); i++) {
122 		struct serial8250_device *dev = &devices[i];
123 
124 		if (dev->iobase == (port & ~0x7))
125 			return dev;
126 	}
127 	return NULL;
128 }
129 
130 static bool serial8250_out(struct kvm *self, uint16_t port, void *data, int size, uint32_t count)
131 {
132 	struct serial8250_device *dev;
133 	uint16_t offset;
134 
135 	dev		= find_device(port);
136 	if (!dev)
137 		return false;
138 
139 	offset		= port - dev->iobase;
140 
141 	if (dev->lcr & UART_LCR_DLAB) {
142 		switch (offset) {
143 		case UART_DLL:
144 			dev->dll	= ioport__read8(data);
145 			break;
146 		case UART_DLM:
147 			dev->dlm	= ioport__read8(data);
148 			break;
149 		case UART_FCR:
150 			dev->fcr	= ioport__read8(data);
151 			break;
152 		case UART_LCR:
153 			dev->lcr	= ioport__read8(data);
154 			break;
155 		case UART_MCR:
156 			dev->mcr	= ioport__read8(data);
157 			break;
158 		case UART_LSR:
159 			/* Factory test */
160 			break;
161 		case UART_MSR:
162 			/* Not used */
163 			break;
164 		case UART_SCR:
165 			dev->scr	= ioport__read8(data);
166 			break;
167 		default:
168 			return false;
169 		}
170 	} else {
171 		switch (offset) {
172 		case UART_TX: {
173 			char *p = data;
174 			int i;
175 
176 			if (!(dev->mcr & UART_MCR_LOOP)) {
177 				while (count--) {
178 					for (i = 0; i < size; i++)
179 						fprintf(stdout, "%c", *p++);
180 				}
181 				fflush(stdout);
182 			}
183 			dev->iir		= UART_IIR_NO_INT;
184 			break;
185 		}
186 		case UART_FCR:
187 			dev->fcr	= ioport__read8(data);
188 			break;
189 		case UART_IER:
190 			dev->ier	= ioport__read8(data) & 0x3f;
191 			break;
192 		case UART_LCR:
193 			dev->lcr	= ioport__read8(data);
194 			break;
195 		case UART_MCR:
196 			dev->mcr	= ioport__read8(data);
197 			break;
198 		case UART_LSR:
199 			/* Factory test */
200 			break;
201 		case UART_MSR:
202 			/* Not used */
203 			break;
204 		case UART_SCR:
205 			dev->scr	= ioport__read8(data);
206 			break;
207 		default:
208 			return false;
209 		}
210 	}
211 	return true;
212 }
213 
214 static bool serial8250_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count)
215 {
216 	struct serial8250_device *dev;
217 	uint16_t offset;
218 
219 	dev		= find_device(port);
220 	if (!dev)
221 		return false;
222 
223 	offset		= port - dev->iobase;
224 
225 	if (dev->lcr & UART_LCR_DLAB) {
226 		switch (offset) {
227 		case UART_DLL:
228 			ioport__write8(data, dev->dll);
229 			return true;
230 		case UART_DLM:
231 			ioport__write8(data, dev->dlm);
232 			return true;
233 		default:
234 			break;
235 		}
236 	} else {
237 		switch (offset) {
238 		case UART_RX:
239 			ioport__write8(data, dev->rbr);
240 			dev->lsr		&= ~UART_LSR_DR;
241 			dev->iir		= UART_IIR_NO_INT;
242 			return true;
243 		case UART_IER:
244 			ioport__write8(data, dev->ier);
245 			return true;
246 		default:
247 			break;
248 		}
249 	}
250 
251 	switch (offset) {
252 	case UART_IIR: {
253 		uint8_t iir = dev->iir;
254 
255 		if (dev->fcr & UART_FCR_ENABLE_FIFO)
256 			iir		|= 0xc0;
257 
258 		ioport__write8(data, iir);
259 		break;
260 	}
261 	case UART_LCR:
262 		ioport__write8(data, dev->lcr);
263 		break;
264 	case UART_MCR:
265 		ioport__write8(data, dev->mcr);
266 		break;
267 	case UART_LSR:
268 		ioport__write8(data, dev->lsr);
269 		dev->lsr		&= ~(UART_LSR_OE|UART_LSR_PE|UART_LSR_FE|UART_LSR_BI);
270 		break;
271 	case UART_MSR:
272 		ioport__write8(data, dev->msr);
273 		break;
274 	case UART_SCR:
275 		ioport__write8(data, dev->scr);
276 		break;
277 	default:
278 		return false;
279 	}
280 	return true;
281 }
282 
283 static struct ioport_operations serial8250_ops = {
284 	.io_in		= serial8250_in,
285 	.io_out		= serial8250_out,
286 };
287 
288 static void serial8250__device_init(struct kvm *kvm, struct serial8250_device *dev)
289 {
290 	ioport__register(dev->iobase, &serial8250_ops, 8);
291 	kvm__irq_line(kvm, dev->irq, 0);
292 }
293 
294 void serial8250__init(struct kvm *kvm)
295 {
296 	unsigned int i;
297 
298 	for (i = 0; i < ARRAY_SIZE(devices); i++) {
299 		struct serial8250_device *dev = &devices[i];
300 
301 		serial8250__device_init(kvm, dev);
302 	}
303 }
304