xref: /kvmtool/hw/serial.c (revision 3d62dea656058a6bc9248124521c6fc81efc6474)
1 #include "kvm/8250-serial.h"
2 
3 #include "kvm/read-write.h"
4 #include "kvm/ioport.h"
5 #include "kvm/mutex.h"
6 #include "kvm/util.h"
7 #include "kvm/term.h"
8 #include "kvm/kvm.h"
9 
10 #include <linux/types.h>
11 #include <linux/serial_reg.h>
12 
13 #include <pthread.h>
14 
15 struct serial8250_device {
16 	pthread_mutex_t		mutex;
17 
18 	u16			iobase;
19 	u8			irq;
20 
21 	u8			rbr;		/* receive buffer */
22 	u8			dll;
23 	u8			dlm;
24 	u8			iir;
25 	u8			ier;
26 	u8			fcr;
27 	u8			lcr;
28 	u8			mcr;
29 	u8			lsr;
30 	u8			msr;
31 	u8			scr;
32 };
33 
34 static struct serial8250_device devices[] = {
35 	/* ttyS0 */
36 	[0]	= {
37 		.mutex			= PTHREAD_MUTEX_INITIALIZER,
38 
39 		.iobase			= 0x3f8,
40 		.irq			= 4,
41 
42 		.iir			= UART_IIR_NO_INT,
43 		.lsr			= UART_LSR_TEMT | UART_LSR_THRE,
44 		.msr			= UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS,
45 		.mcr			= UART_MCR_OUT2,
46 	},
47 	/* ttyS1 */
48 	[1]	= {
49 		.mutex			= PTHREAD_MUTEX_INITIALIZER,
50 
51 		.iobase			= 0x2f8,
52 		.irq			= 3,
53 
54 		.iir			= UART_IIR_NO_INT,
55 	},
56 	/* ttyS2 */
57 	[2]	= {
58 		.mutex			= PTHREAD_MUTEX_INITIALIZER,
59 
60 		.iobase			= 0x3e8,
61 		.irq			= 4,
62 
63 		.iir			= UART_IIR_NO_INT,
64 	},
65 	/* ttyS3 */
66 	[3]	= {
67 		.mutex			= PTHREAD_MUTEX_INITIALIZER,
68 
69 		.iobase			= 0x2e8,
70 		.irq			= 3,
71 
72 		.iir			= UART_IIR_NO_INT,
73 	},
74 };
75 
76 #define SYSRQ_PENDING_NONE		0
77 #define SYSRQ_PENDING_BREAK		1
78 #define SYSRQ_PENDING_CMD		2
79 
80 static int sysrq_pending;
81 
82 static void serial8250__sysrq(struct kvm *kvm, struct serial8250_device *dev)
83 {
84 	switch (sysrq_pending) {
85 	case SYSRQ_PENDING_BREAK:
86 		dev->lsr	|= UART_LSR_DR | UART_LSR_BI;
87 
88 		sysrq_pending	= SYSRQ_PENDING_CMD;
89 		break;
90 	case SYSRQ_PENDING_CMD:
91 		dev->rbr	= 'p';
92 		dev->lsr	|= UART_LSR_DR;
93 
94 		sysrq_pending	= SYSRQ_PENDING_NONE;
95 		break;
96 	}
97 }
98 
99 static void serial8250__receive(struct kvm *kvm, struct serial8250_device *dev)
100 {
101 	int c;
102 
103 	if (dev->lsr & UART_LSR_DR)
104 		return;
105 
106 	if (sysrq_pending) {
107 		serial8250__sysrq(kvm, dev);
108 		return;
109 	}
110 
111 	if (!term_readable(CONSOLE_8250))
112 		return;
113 
114 	c		= term_getc(CONSOLE_8250);
115 
116 	if (c < 0)
117 		return;
118 
119 	dev->rbr	= c;
120 	dev->lsr	|= UART_LSR_DR;
121 }
122 
123 /*
124  * Interrupts are injected for ttyS0 only.
125  */
126 void serial8250__inject_interrupt(struct kvm *kvm)
127 {
128 	struct serial8250_device *dev = &devices[0];
129 
130 	mutex_lock(&dev->mutex);
131 
132 	serial8250__receive(kvm, dev);
133 
134 	if (dev->ier & UART_IER_RDI && dev->lsr & UART_LSR_DR)
135 		dev->iir		= UART_IIR_RDI;
136 	else if (dev->ier & UART_IER_THRI)
137 		dev->iir		= UART_IIR_THRI;
138 	else
139 		dev->iir		= UART_IIR_NO_INT;
140 
141 	if (dev->iir != UART_IIR_NO_INT) {
142 		kvm__irq_line(kvm, dev->irq, 0);
143 		kvm__irq_line(kvm, dev->irq, 1);
144 	}
145 
146 	mutex_unlock(&dev->mutex);
147 }
148 
149 void serial8250__inject_sysrq(struct kvm *kvm)
150 {
151 	sysrq_pending	= SYSRQ_PENDING_BREAK;
152 }
153 
154 static struct serial8250_device *find_device(u16 port)
155 {
156 	unsigned int i;
157 
158 	for (i = 0; i < ARRAY_SIZE(devices); i++) {
159 		struct serial8250_device *dev = &devices[i];
160 
161 		if (dev->iobase == (port & ~0x7))
162 			return dev;
163 	}
164 	return NULL;
165 }
166 
167 static bool serial8250_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
168 {
169 	struct serial8250_device *dev;
170 	u16 offset;
171 	bool ret = true;
172 
173 	dev		= find_device(port);
174 	if (!dev)
175 		return false;
176 
177 	mutex_lock(&dev->mutex);
178 
179 	offset		= port - dev->iobase;
180 
181 	if (dev->lcr & UART_LCR_DLAB) {
182 		switch (offset) {
183 		case UART_DLL:
184 			dev->dll	= ioport__read8(data);
185 			break;
186 		case UART_DLM:
187 			dev->dlm	= ioport__read8(data);
188 			break;
189 		case UART_FCR:
190 			dev->fcr	= ioport__read8(data);
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 			ret		= false;
209 			goto out_unlock;
210 		}
211 	} else {
212 		switch (offset) {
213 		case UART_TX: {
214 			char *addr = data;
215 
216 			if (!(dev->mcr & UART_MCR_LOOP))
217 				term_putc(CONSOLE_8250, addr, size * count);
218 
219 			dev->iir		= UART_IIR_NO_INT;
220 			break;
221 		}
222 		case UART_FCR:
223 			dev->fcr	= ioport__read8(data);
224 			break;
225 		case UART_IER:
226 			dev->ier	= ioport__read8(data) & 0x3f;
227 			break;
228 		case UART_LCR:
229 			dev->lcr	= ioport__read8(data);
230 			break;
231 		case UART_MCR:
232 			dev->mcr	= ioport__read8(data);
233 			break;
234 		case UART_LSR:
235 			/* Factory test */
236 			break;
237 		case UART_MSR:
238 			/* Not used */
239 			break;
240 		case UART_SCR:
241 			dev->scr	= ioport__read8(data);
242 			break;
243 		default:
244 			ret		= false;
245 			goto out_unlock;
246 		}
247 	}
248 
249 out_unlock:
250 	mutex_unlock(&dev->mutex);
251 
252 	return ret;
253 }
254 
255 static bool serial8250_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count)
256 {
257 	struct serial8250_device *dev;
258 	u16 offset;
259 	bool ret = true;
260 
261 	dev		= find_device(port);
262 	if (!dev)
263 		return false;
264 
265 	mutex_lock(&dev->mutex);
266 
267 	offset		= port - dev->iobase;
268 
269 	if (dev->lcr & UART_LCR_DLAB) {
270 		switch (offset) {
271 		case UART_DLL:
272 			ioport__write8(data, dev->dll);
273 			goto out_unlock;
274 
275 		case UART_DLM:
276 			ioport__write8(data, dev->dlm);
277 			goto out_unlock;
278 
279 		default:
280 			break;
281 		}
282 	} else {
283 		switch (offset) {
284 		case UART_RX:
285 			ioport__write8(data, dev->rbr);
286 			dev->lsr		&= ~UART_LSR_DR;
287 			dev->iir		= UART_IIR_NO_INT;
288 			goto out_unlock;
289 
290 		case UART_IER:
291 			ioport__write8(data, dev->ier);
292 			goto out_unlock;
293 
294 		default:
295 			break;
296 		}
297 	}
298 
299 	switch (offset) {
300 	case UART_IIR: {
301 		u8 iir = dev->iir;
302 
303 		if (dev->fcr & UART_FCR_ENABLE_FIFO)
304 			iir		|= 0xc0;
305 
306 		ioport__write8(data, iir);
307 		break;
308 	}
309 	case UART_LCR:
310 		ioport__write8(data, dev->lcr);
311 		break;
312 	case UART_MCR:
313 		ioport__write8(data, dev->mcr);
314 		break;
315 	case UART_LSR:
316 		ioport__write8(data, dev->lsr);
317 		dev->lsr		&= ~(UART_LSR_OE|UART_LSR_PE|UART_LSR_FE|UART_LSR_BI);
318 		break;
319 	case UART_MSR:
320 		ioport__write8(data, dev->msr);
321 		break;
322 	case UART_SCR:
323 		ioport__write8(data, dev->scr);
324 		break;
325 	default:
326 		ret		= false;
327 		goto out_unlock;
328 	}
329 out_unlock:
330 	mutex_unlock(&dev->mutex);
331 
332 	return ret;
333 }
334 
335 static struct ioport_operations serial8250_ops = {
336 	.io_in		= serial8250_in,
337 	.io_out		= serial8250_out,
338 };
339 
340 static void serial8250__device_init(struct kvm *kvm, struct serial8250_device *dev)
341 {
342 	ioport__register(dev->iobase, &serial8250_ops, 8, NULL);
343 	kvm__irq_line(kvm, dev->irq, 0);
344 }
345 
346 void serial8250__init(struct kvm *kvm)
347 {
348 	unsigned int i;
349 
350 	for (i = 0; i < ARRAY_SIZE(devices); i++) {
351 		struct serial8250_device *dev = &devices[i];
352 
353 		serial8250__device_init(kvm, dev);
354 	}
355 }
356