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