xref: /kvmtool/hw/serial.c (revision a428f72ec339b72f6656e1d13773e50b2a546b82)
1 #include "kvm/8250-serial.h"
2 
3 #include "kvm/read-write.h"
4 #include "kvm/ioport.h"
5 #include "kvm/util.h"
6 #include "kvm/term.h"
7 #include "kvm/kvm.h"
8 
9 #include <linux/serial_reg.h>
10 
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 #define SYSRQ_PENDING_NONE		0
57 #define SYSRQ_PENDING_BREAK		1
58 #define SYSRQ_PENDING_CMD		2
59 
60 static int sysrq_pending;
61 
62 static void serial8250__sysrq(struct kvm *self, struct serial8250_device *dev)
63 {
64 	switch (sysrq_pending) {
65 	case SYSRQ_PENDING_BREAK:
66 		dev->lsr	|= UART_LSR_DR | UART_LSR_BI;
67 
68 		sysrq_pending	= SYSRQ_PENDING_CMD;
69 		break;
70 	case SYSRQ_PENDING_CMD:
71 		dev->rbr	= 'p';
72 		dev->lsr	|= UART_LSR_DR;
73 
74 		sysrq_pending	= SYSRQ_PENDING_NONE;
75 		break;
76 	}
77 }
78 
79 static void serial8250__receive(struct kvm *self, struct serial8250_device *dev)
80 {
81 	int c;
82 
83 	if (dev->lsr & UART_LSR_DR)
84 		return;
85 
86 	if (sysrq_pending) {
87 		serial8250__sysrq(self, dev);
88 		return;
89 	}
90 
91 	if (!term_readable(CONSOLE_8250))
92 		return;
93 
94 	c		= term_getc(CONSOLE_8250);
95 
96 	if (c < 0)
97 		return;
98 
99 	dev->rbr	= c;
100 	dev->lsr	|= UART_LSR_DR;
101 }
102 
103 /*
104  * Interrupts are injected for ttyS0 only.
105  */
106 void serial8250__inject_interrupt(struct kvm *self)
107 {
108 	struct serial8250_device *dev = &devices[0];
109 
110 	serial8250__receive(self, dev);
111 
112 	if (dev->ier & UART_IER_RDI && dev->lsr & UART_LSR_DR)
113 		dev->iir		= UART_IIR_RDI;
114 	else if (dev->ier & UART_IER_THRI)
115 		dev->iir		= UART_IIR_THRI;
116 	else
117 		dev->iir		= UART_IIR_NO_INT;
118 
119 	if (dev->iir != UART_IIR_NO_INT) {
120 		kvm__irq_line(self, dev->irq, 0);
121 		kvm__irq_line(self, dev->irq, 1);
122 	}
123 }
124 
125 void serial8250__inject_sysrq(struct kvm *self)
126 {
127 	sysrq_pending	= SYSRQ_PENDING_BREAK;
128 }
129 
130 static struct serial8250_device *find_device(uint16_t port)
131 {
132 	unsigned int i;
133 
134 	for (i = 0; i < ARRAY_SIZE(devices); i++) {
135 		struct serial8250_device *dev = &devices[i];
136 
137 		if (dev->iobase == (port & ~0x7))
138 			return dev;
139 	}
140 	return NULL;
141 }
142 
143 static bool serial8250_out(struct kvm *self, uint16_t port, void *data, int size, uint32_t count)
144 {
145 	struct serial8250_device *dev;
146 	uint16_t offset;
147 
148 	dev		= find_device(port);
149 	if (!dev)
150 		return false;
151 
152 	offset		= port - dev->iobase;
153 
154 	if (dev->lcr & UART_LCR_DLAB) {
155 		switch (offset) {
156 		case UART_DLL:
157 			dev->dll	= ioport__read8(data);
158 			break;
159 		case UART_DLM:
160 			dev->dlm	= ioport__read8(data);
161 			break;
162 		case UART_FCR:
163 			dev->fcr	= ioport__read8(data);
164 			break;
165 		case UART_LCR:
166 			dev->lcr	= ioport__read8(data);
167 			break;
168 		case UART_MCR:
169 			dev->mcr	= ioport__read8(data);
170 			break;
171 		case UART_LSR:
172 			/* Factory test */
173 			break;
174 		case UART_MSR:
175 			/* Not used */
176 			break;
177 		case UART_SCR:
178 			dev->scr	= ioport__read8(data);
179 			break;
180 		default:
181 			return false;
182 		}
183 	} else {
184 		switch (offset) {
185 		case UART_TX: {
186 			char *addr = data;
187 			if (!(dev->mcr & UART_MCR_LOOP)) {
188 				term_putc(CONSOLE_8250, addr, size * count);
189 			}
190 			dev->iir		= UART_IIR_NO_INT;
191 			break;
192 		}
193 		case UART_FCR:
194 			dev->fcr	= ioport__read8(data);
195 			break;
196 		case UART_IER:
197 			dev->ier	= ioport__read8(data) & 0x3f;
198 			break;
199 		case UART_LCR:
200 			dev->lcr	= ioport__read8(data);
201 			break;
202 		case UART_MCR:
203 			dev->mcr	= ioport__read8(data);
204 			break;
205 		case UART_LSR:
206 			/* Factory test */
207 			break;
208 		case UART_MSR:
209 			/* Not used */
210 			break;
211 		case UART_SCR:
212 			dev->scr	= ioport__read8(data);
213 			break;
214 		default:
215 			return false;
216 		}
217 	}
218 	return true;
219 }
220 
221 static bool serial8250_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count)
222 {
223 	struct serial8250_device *dev;
224 	uint16_t offset;
225 
226 	dev		= find_device(port);
227 	if (!dev)
228 		return false;
229 
230 	offset		= port - dev->iobase;
231 
232 	if (dev->lcr & UART_LCR_DLAB) {
233 		switch (offset) {
234 		case UART_DLL:
235 			ioport__write8(data, dev->dll);
236 			return true;
237 		case UART_DLM:
238 			ioport__write8(data, dev->dlm);
239 			return true;
240 		default:
241 			break;
242 		}
243 	} else {
244 		switch (offset) {
245 		case UART_RX:
246 			ioport__write8(data, dev->rbr);
247 			dev->lsr		&= ~UART_LSR_DR;
248 			dev->iir		= UART_IIR_NO_INT;
249 			return true;
250 		case UART_IER:
251 			ioport__write8(data, dev->ier);
252 			return true;
253 		default:
254 			break;
255 		}
256 	}
257 
258 	switch (offset) {
259 	case UART_IIR: {
260 		uint8_t iir = dev->iir;
261 
262 		if (dev->fcr & UART_FCR_ENABLE_FIFO)
263 			iir		|= 0xc0;
264 
265 		ioport__write8(data, iir);
266 		break;
267 	}
268 	case UART_LCR:
269 		ioport__write8(data, dev->lcr);
270 		break;
271 	case UART_MCR:
272 		ioport__write8(data, dev->mcr);
273 		break;
274 	case UART_LSR:
275 		ioport__write8(data, dev->lsr);
276 		dev->lsr		&= ~(UART_LSR_OE|UART_LSR_PE|UART_LSR_FE|UART_LSR_BI);
277 		break;
278 	case UART_MSR:
279 		ioport__write8(data, dev->msr);
280 		break;
281 	case UART_SCR:
282 		ioport__write8(data, dev->scr);
283 		break;
284 	default:
285 		return false;
286 	}
287 	return true;
288 }
289 
290 static struct ioport_operations serial8250_ops = {
291 	.io_in		= serial8250_in,
292 	.io_out		= serial8250_out,
293 };
294 
295 static void serial8250__device_init(struct kvm *kvm, struct serial8250_device *dev)
296 {
297 	ioport__register(dev->iobase, &serial8250_ops, 8);
298 	kvm__irq_line(kvm, dev->irq, 0);
299 }
300 
301 void serial8250__init(struct kvm *kvm)
302 {
303 	unsigned int i;
304 
305 	for (i = 0; i < ARRAY_SIZE(devices); i++) {
306 		struct serial8250_device *dev = &devices[i];
307 
308 		serial8250__device_init(kvm, dev);
309 	}
310 }
311