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