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