xref: /kvmtool/hw/serial.c (revision 0ea58e5bbc3775506d99a8d9e1c78c371426a6ac)
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 
188 			if (!(dev->mcr & UART_MCR_LOOP))
189 				term_putc(CONSOLE_8250, addr, size * count);
190 
191 			dev->iir		= UART_IIR_NO_INT;
192 			break;
193 		}
194 		case UART_FCR:
195 			dev->fcr	= ioport__read8(data);
196 			break;
197 		case UART_IER:
198 			dev->ier	= ioport__read8(data) & 0x3f;
199 			break;
200 		case UART_LCR:
201 			dev->lcr	= ioport__read8(data);
202 			break;
203 		case UART_MCR:
204 			dev->mcr	= ioport__read8(data);
205 			break;
206 		case UART_LSR:
207 			/* Factory test */
208 			break;
209 		case UART_MSR:
210 			/* Not used */
211 			break;
212 		case UART_SCR:
213 			dev->scr	= ioport__read8(data);
214 			break;
215 		default:
216 			return false;
217 		}
218 	}
219 	return true;
220 }
221 
222 static bool serial8250_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count)
223 {
224 	struct serial8250_device *dev;
225 	uint16_t offset;
226 
227 	dev		= find_device(port);
228 	if (!dev)
229 		return false;
230 
231 	offset		= port - dev->iobase;
232 
233 	if (dev->lcr & UART_LCR_DLAB) {
234 		switch (offset) {
235 		case UART_DLL:
236 			ioport__write8(data, dev->dll);
237 			return true;
238 		case UART_DLM:
239 			ioport__write8(data, dev->dlm);
240 			return true;
241 		default:
242 			break;
243 		}
244 	} else {
245 		switch (offset) {
246 		case UART_RX:
247 			ioport__write8(data, dev->rbr);
248 			dev->lsr		&= ~UART_LSR_DR;
249 			dev->iir		= UART_IIR_NO_INT;
250 			return true;
251 		case UART_IER:
252 			ioport__write8(data, dev->ier);
253 			return true;
254 		default:
255 			break;
256 		}
257 	}
258 
259 	switch (offset) {
260 	case UART_IIR: {
261 		uint8_t iir = dev->iir;
262 
263 		if (dev->fcr & UART_FCR_ENABLE_FIFO)
264 			iir		|= 0xc0;
265 
266 		ioport__write8(data, iir);
267 		break;
268 	}
269 	case UART_LCR:
270 		ioport__write8(data, dev->lcr);
271 		break;
272 	case UART_MCR:
273 		ioport__write8(data, dev->mcr);
274 		break;
275 	case UART_LSR:
276 		ioport__write8(data, dev->lsr);
277 		dev->lsr		&= ~(UART_LSR_OE|UART_LSR_PE|UART_LSR_FE|UART_LSR_BI);
278 		break;
279 	case UART_MSR:
280 		ioport__write8(data, dev->msr);
281 		break;
282 	case UART_SCR:
283 		ioport__write8(data, dev->scr);
284 		break;
285 	default:
286 		return false;
287 	}
288 	return true;
289 }
290 
291 static struct ioport_operations serial8250_ops = {
292 	.io_in		= serial8250_in,
293 	.io_out		= serial8250_out,
294 };
295 
296 static void serial8250__device_init(struct kvm *kvm, struct serial8250_device *dev)
297 {
298 	ioport__register(dev->iobase, &serial8250_ops, 8);
299 	kvm__irq_line(kvm, dev->irq, 0);
300 }
301 
302 void serial8250__init(struct kvm *kvm)
303 {
304 	unsigned int i;
305 
306 	for (i = 0; i < ARRAY_SIZE(devices); i++) {
307 		struct serial8250_device *dev = &devices[i];
308 
309 		serial8250__device_init(kvm, dev);
310 	}
311 }
312