]> git.karo-electronics.de Git - karo-tx-linux.git/blob - tools/kvm/hw/serial.c
Merge remote-tracking branch 'signal/for-next'
[karo-tx-linux.git] / tools / kvm / hw / serial.c
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 /*
16  * This fakes a U6_16550A. The fifo len needs to be 64 as the kernel
17  * expects that for autodetection.
18  */
19 #define FIFO_LEN                64
20 #define FIFO_MASK               (FIFO_LEN - 1)
21
22 #define UART_IIR_TYPE_BITS      0xc0
23
24 struct serial8250_device {
25         pthread_mutex_t         mutex;
26         u8                      id;
27
28         u16                     iobase;
29         u8                      irq;
30         u8                      irq_state;
31         int                     txcnt;
32         int                     rxcnt;
33         int                     rxdone;
34         char                    txbuf[FIFO_LEN];
35         char                    rxbuf[FIFO_LEN];
36
37         u8                      dll;
38         u8                      dlm;
39         u8                      iir;
40         u8                      ier;
41         u8                      fcr;
42         u8                      lcr;
43         u8                      mcr;
44         u8                      lsr;
45         u8                      msr;
46         u8                      scr;
47 };
48
49 #define SERIAL_REGS_SETTING \
50         .iir                    = UART_IIR_NO_INT, \
51         .lsr                    = UART_LSR_TEMT | UART_LSR_THRE, \
52         .msr                    = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS, \
53         .mcr                    = UART_MCR_OUT2,
54
55 static struct serial8250_device devices[] = {
56         /* ttyS0 */
57         [0]     = {
58                 .mutex                  = PTHREAD_MUTEX_INITIALIZER,
59
60                 .id                     = 0,
61                 .iobase                 = 0x3f8,
62                 .irq                    = 4,
63
64                 SERIAL_REGS_SETTING
65         },
66         /* ttyS1 */
67         [1]     = {
68                 .mutex                  = PTHREAD_MUTEX_INITIALIZER,
69
70                 .id                     = 1,
71                 .iobase                 = 0x2f8,
72                 .irq                    = 3,
73
74                 SERIAL_REGS_SETTING
75         },
76         /* ttyS2 */
77         [2]     = {
78                 .mutex                  = PTHREAD_MUTEX_INITIALIZER,
79
80                 .id                     = 2,
81                 .iobase                 = 0x3e8,
82                 .irq                    = 4,
83
84                 SERIAL_REGS_SETTING
85         },
86         /* ttyS3 */
87         [3]     = {
88                 .mutex                  = PTHREAD_MUTEX_INITIALIZER,
89
90                 .id                     = 3,
91                 .iobase                 = 0x2e8,
92                 .irq                    = 3,
93
94                 SERIAL_REGS_SETTING
95         },
96 };
97
98 static void serial8250_flush_tx(struct kvm *kvm, struct serial8250_device *dev)
99 {
100         dev->lsr |= UART_LSR_TEMT | UART_LSR_THRE;
101
102         if (dev->txcnt) {
103                 if (kvm->cfg.active_console == CONSOLE_8250)
104                         term_putc(dev->txbuf, dev->txcnt, dev->id);
105                 dev->txcnt = 0;
106         }
107 }
108
109 static void serial8250_update_irq(struct kvm *kvm, struct serial8250_device *dev)
110 {
111         u8 iir = 0;
112
113         /* Handle clear rx */
114         if (dev->lcr & UART_FCR_CLEAR_RCVR) {
115                 dev->lcr &= ~UART_FCR_CLEAR_RCVR;
116                 dev->rxcnt = dev->rxdone = 0;
117                 dev->lsr &= ~UART_LSR_DR;
118         }
119
120         /* Handle clear tx */
121         if (dev->lcr & UART_FCR_CLEAR_XMIT) {
122                 dev->lcr &= ~UART_FCR_CLEAR_XMIT;
123                 dev->txcnt = 0;
124                 dev->lsr |= UART_LSR_TEMT | UART_LSR_THRE;
125         }
126
127         /* Data ready and rcv interrupt enabled ? */
128         if ((dev->ier & UART_IER_RDI) && (dev->lsr & UART_LSR_DR))
129                 iir |= UART_IIR_RDI;
130
131         /* Transmitter empty and interrupt enabled ? */
132         if ((dev->ier & UART_IER_THRI) && (dev->lsr & UART_LSR_TEMT))
133                 iir |= UART_IIR_THRI;
134
135         /* Now update the irq line, if necessary */
136         if (!iir) {
137                 dev->iir = UART_IIR_NO_INT;
138                 if (dev->irq_state)
139                         kvm__irq_line(kvm, dev->irq, 0);
140         } else {
141                 dev->iir = iir;
142                 if (!dev->irq_state)
143                         kvm__irq_line(kvm, dev->irq, 1);
144         }
145         dev->irq_state = iir;
146
147         /*
148          * If the kernel disabled the tx interrupt, we know that there
149          * is nothing more to transmit, so we can reset our tx logic
150          * here.
151          */
152         if (!(dev->ier & UART_IER_THRI))
153                 serial8250_flush_tx(kvm, dev);
154 }
155
156 #define SYSRQ_PENDING_NONE              0
157
158 static int sysrq_pending;
159
160 static void serial8250__sysrq(struct kvm *kvm, struct serial8250_device *dev)
161 {
162         dev->lsr |= UART_LSR_DR | UART_LSR_BI;
163         dev->rxbuf[dev->rxcnt++] = sysrq_pending;
164         sysrq_pending   = SYSRQ_PENDING_NONE;
165 }
166
167 static void serial8250__receive(struct kvm *kvm, struct serial8250_device *dev,
168                                 bool handle_sysrq)
169 {
170         int c;
171
172         /*
173          * If the guest transmitted a full fifo, we clear the
174          * TEMT/THRE bits to let the kernel escape from the 8250
175          * interrupt handler. We come here only once a ms, so that
176          * should give the kernel the desired pause. That also flushes
177          * the tx fifo to the terminal.
178          */
179         serial8250_flush_tx(kvm, dev);
180
181         if (dev->mcr & UART_MCR_LOOP)
182                 return;
183
184         if ((dev->lsr & UART_LSR_DR) || dev->rxcnt)
185                 return;
186
187         if (handle_sysrq && sysrq_pending) {
188                 serial8250__sysrq(kvm, dev);
189                 return;
190         }
191
192         if (kvm->cfg.active_console != CONSOLE_8250)
193                 return;
194
195         while (term_readable(dev->id) &&
196                dev->rxcnt < FIFO_LEN) {
197
198                 c = term_getc(kvm, dev->id);
199
200                 if (c < 0)
201                         break;
202                 dev->rxbuf[dev->rxcnt++] = c;
203                 dev->lsr |= UART_LSR_DR;
204         }
205 }
206
207 void serial8250__update_consoles(struct kvm *kvm)
208 {
209         unsigned int i;
210
211         for (i = 0; i < ARRAY_SIZE(devices); i++) {
212                 struct serial8250_device *dev = &devices[i];
213
214                 mutex_lock(&dev->mutex);
215
216                 /* Restrict sysrq injection to the first port */
217                 serial8250__receive(kvm, dev, i == 0);
218
219                 serial8250_update_irq(kvm, dev);
220
221                 mutex_unlock(&dev->mutex);
222         }
223 }
224
225 void serial8250__inject_sysrq(struct kvm *kvm, char sysrq)
226 {
227         sysrq_pending = sysrq;
228 }
229
230 static struct serial8250_device *find_device(u16 port)
231 {
232         unsigned int i;
233
234         for (i = 0; i < ARRAY_SIZE(devices); i++) {
235                 struct serial8250_device *dev = &devices[i];
236
237                 if (dev->iobase == (port & ~0x7))
238                         return dev;
239         }
240         return NULL;
241 }
242
243 static bool serial8250_out(struct ioport *ioport, struct kvm *kvm, u16 port,
244                            void *data, int size)
245 {
246         struct serial8250_device *dev;
247         u16 offset;
248         bool ret = true;
249         char *addr = data;
250
251         dev = find_device(port);
252         if (!dev)
253                 return false;
254
255         mutex_lock(&dev->mutex);
256
257         offset = port - dev->iobase;
258
259         switch (offset) {
260         case UART_TX:
261                 if (dev->lcr & UART_LCR_DLAB) {
262                         dev->dll = ioport__read8(data);
263                         break;
264                 }
265
266                 /* Loopback mode */
267                 if (dev->mcr & UART_MCR_LOOP) {
268                         if (dev->rxcnt < FIFO_LEN) {
269                                 dev->rxbuf[dev->rxcnt++] = *addr;
270                                 dev->lsr |= UART_LSR_DR;
271                         }
272                         break;
273                 }
274
275                 if (dev->txcnt < FIFO_LEN) {
276                         dev->txbuf[dev->txcnt++] = *addr;
277                         dev->lsr &= ~UART_LSR_TEMT;
278                         if (dev->txcnt == FIFO_LEN / 2)
279                                 dev->lsr &= ~UART_LSR_THRE;
280                 } else {
281                         /* Should never happpen */
282                         dev->lsr &= ~(UART_LSR_TEMT | UART_LSR_THRE);
283                 }
284                 break;
285         case UART_IER:
286                 if (!(dev->lcr & UART_LCR_DLAB))
287                         dev->ier = ioport__read8(data) & 0x0f;
288                 else
289                         dev->dlm = ioport__read8(data);
290                 break;
291         case UART_FCR:
292                 dev->fcr = ioport__read8(data);
293                 break;
294         case UART_LCR:
295                 dev->lcr = ioport__read8(data);
296                 break;
297         case UART_MCR:
298                 dev->mcr = ioport__read8(data);
299                 break;
300         case UART_LSR:
301                 /* Factory test */
302                 break;
303         case UART_MSR:
304                 /* Not used */
305                 break;
306         case UART_SCR:
307                 dev->scr = ioport__read8(data);
308                 break;
309         default:
310                 ret = false;
311                 break;
312         }
313
314         serial8250_update_irq(kvm, dev);
315
316         mutex_unlock(&dev->mutex);
317
318         return ret;
319 }
320
321 static void serial8250_rx(struct serial8250_device *dev, void *data)
322 {
323         if (dev->rxdone == dev->rxcnt)
324                 return;
325
326         /* Break issued ? */
327         if (dev->lsr & UART_LSR_BI) {
328                 dev->lsr &= ~UART_LSR_BI;
329                 ioport__write8(data, 0);
330                 return;
331         }
332
333         ioport__write8(data, dev->rxbuf[dev->rxdone++]);
334         if (dev->rxcnt == dev->rxdone) {
335                 dev->lsr &= ~UART_LSR_DR;
336                 dev->rxcnt = dev->rxdone = 0;
337         }
338 }
339
340 static bool serial8250_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
341 {
342         struct serial8250_device *dev;
343         u16 offset;
344         bool ret = true;
345
346         dev = find_device(port);
347         if (!dev)
348                 return false;
349
350         mutex_lock(&dev->mutex);
351
352         offset = port - dev->iobase;
353
354         switch (offset) {
355         case UART_RX:
356                 if (dev->lcr & UART_LCR_DLAB)
357                         ioport__write8(data, dev->dll);
358                 else
359                         serial8250_rx(dev, data);
360                 break;
361         case UART_IER:
362                 if (dev->lcr & UART_LCR_DLAB)
363                         ioport__write8(data, dev->dlm);
364                 else
365                         ioport__write8(data, dev->ier);
366                 break;
367         case UART_IIR:
368                 ioport__write8(data, dev->iir | UART_IIR_TYPE_BITS);
369                 break;
370         case UART_LCR:
371                 ioport__write8(data, dev->lcr);
372                 break;
373         case UART_MCR:
374                 ioport__write8(data, dev->mcr);
375                 break;
376         case UART_LSR:
377                 ioport__write8(data, dev->lsr);
378                 break;
379         case UART_MSR:
380                 ioport__write8(data, dev->msr);
381                 break;
382         case UART_SCR:
383                 ioport__write8(data, dev->scr);
384                 break;
385         default:
386                 ret = false;
387                 break;
388         }
389
390         serial8250_update_irq(kvm, dev);
391
392         mutex_unlock(&dev->mutex);
393
394         return ret;
395 }
396
397 static struct ioport_operations serial8250_ops = {
398         .io_in          = serial8250_in,
399         .io_out         = serial8250_out,
400 };
401
402 static int serial8250__device_init(struct kvm *kvm, struct serial8250_device *dev)
403 {
404         int r;
405
406         r = ioport__register(kvm, dev->iobase, &serial8250_ops, 8, NULL);
407         kvm__irq_line(kvm, dev->irq, 0);
408
409         return r;
410 }
411
412 int serial8250__init(struct kvm *kvm)
413 {
414         unsigned int i, j;
415         int r = 0;
416
417         for (i = 0; i < ARRAY_SIZE(devices); i++) {
418                 struct serial8250_device *dev = &devices[i];
419
420                 r = serial8250__device_init(kvm, dev);
421                 if (r < 0)
422                         goto cleanup;
423         }
424
425         return r;
426 cleanup:
427         for (j = 0; j <= i; j++) {
428                 struct serial8250_device *dev = &devices[j];
429
430                 ioport__unregister(kvm, dev->iobase);
431         }
432
433         return r;
434 }
435 dev_init(serial8250__init);
436
437 int serial8250__exit(struct kvm *kvm)
438 {
439         unsigned int i;
440         int r;
441
442         for (i = 0; i < ARRAY_SIZE(devices); i++) {
443                 struct serial8250_device *dev = &devices[i];
444
445                 r = ioport__unregister(kvm, dev->iobase);
446                 if (r < 0)
447                         return r;
448         }
449
450         return 0;
451 }
452 dev_exit(serial8250__exit);