xref: /kvmtool/hw/serial.c (revision 1add4b76d64864e9b43f0057a21d9b80cd1f6ac1)
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 	int i;
134 
135 	for (i = 0; i < 4; 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 			break;
237 		case UART_LCR:
238 			dev->lcr	= ioport__read8(data);
239 			break;
240 		case UART_MCR:
241 			dev->mcr	= ioport__read8(data);
242 			break;
243 		case UART_LSR:
244 			/* Factory test */
245 			break;
246 		case UART_MSR:
247 			/* Not used */
248 			break;
249 		case UART_SCR:
250 			dev->scr	= ioport__read8(data);
251 			break;
252 		default:
253 			ret		= false;
254 			goto out_unlock;
255 		}
256 	}
257 
258 out_unlock:
259 	mutex_unlock(&dev->mutex);
260 
261 	return ret;
262 }
263 
264 static bool serial8250_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
265 {
266 	struct serial8250_device *dev;
267 	u16 offset;
268 	bool ret = true;
269 
270 	dev		= find_device(port);
271 	if (!dev)
272 		return false;
273 
274 	mutex_lock(&dev->mutex);
275 
276 	offset		= port - dev->iobase;
277 
278 	if (dev->lcr & UART_LCR_DLAB) {
279 		switch (offset) {
280 		case UART_DLL:
281 			ioport__write8(data, dev->dll);
282 			goto out_unlock;
283 
284 		case UART_DLM:
285 			ioport__write8(data, dev->dlm);
286 			goto out_unlock;
287 
288 		default:
289 			break;
290 		}
291 	} else {
292 		switch (offset) {
293 		case UART_RX:
294 			ioport__write8(data, dev->rbr);
295 			dev->lsr		&= ~UART_LSR_DR;
296 			dev->iir		= UART_IIR_NO_INT;
297 			goto out_unlock;
298 
299 		case UART_IER:
300 			ioport__write8(data, dev->ier);
301 			goto out_unlock;
302 
303 		default:
304 			break;
305 		}
306 	}
307 
308 	switch (offset) {
309 	case UART_IIR: {
310 		u8 iir = dev->iir;
311 
312 		if (dev->fcr & UART_FCR_ENABLE_FIFO)
313 			iir		|= 0xc0;
314 
315 		ioport__write8(data, iir);
316 		break;
317 	}
318 	case UART_LCR:
319 		ioport__write8(data, dev->lcr);
320 		break;
321 	case UART_MCR:
322 		ioport__write8(data, dev->mcr);
323 		break;
324 	case UART_LSR:
325 		ioport__write8(data, dev->lsr);
326 		dev->lsr		&= ~(UART_LSR_OE|UART_LSR_PE|UART_LSR_FE|UART_LSR_BI);
327 		break;
328 	case UART_MSR:
329 		ioport__write8(data, dev->msr);
330 		break;
331 	case UART_SCR:
332 		ioport__write8(data, dev->scr);
333 		break;
334 	default:
335 		ret		= false;
336 		goto out_unlock;
337 	}
338 out_unlock:
339 	mutex_unlock(&dev->mutex);
340 
341 	return ret;
342 }
343 
344 static struct ioport_operations serial8250_ops = {
345 	.io_in		= serial8250_in,
346 	.io_out		= serial8250_out,
347 };
348 
349 static void serial8250__device_init(struct kvm *kvm, struct serial8250_device *dev)
350 {
351 	ioport__register(dev->iobase, &serial8250_ops, 8, NULL);
352 	kvm__irq_line(kvm, dev->irq, 0);
353 }
354 
355 void serial8250__init(struct kvm *kvm)
356 {
357 	unsigned int i;
358 
359 	for (i = 0; i < ARRAY_SIZE(devices); i++) {
360 		struct serial8250_device *dev = &devices[i];
361 
362 		serial8250__device_init(kvm, dev);
363 	}
364 }
365