~ubuntu-branches/ubuntu/trusty/qemu/trusty

« back to all changes in this revision

Viewing changes to .pc/linaro-patches/0041-serial-omap_uart-Add-support-for-fifo-level-regs.patch/hw/char/serial.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2013-10-22 22:47:07 UTC
  • mfrom: (1.8.3) (10.1.42 sid)
  • Revision ID: package-import@ubuntu.com-20131022224707-1lya34fw3k3f24tv
Tags: 1.6.0+dfsg-2ubuntu1
* Merge 1.6.0~rc0+dfsg-2exp from debian experimental.  Remaining changes:
  - debian/control
    * update maintainer
    * remove libiscsi, usb-redir, vde, vnc-jpeg, and libssh2-1-dev
      from build-deps
    * enable rbd
    * add qemu-system and qemu-common B/R to qemu-keymaps
    * add D:udev, R:qemu, R:qemu-common and B:qemu-common to
      qemu-system-common
    * qemu-system-arm, qemu-system-ppc, qemu-system-sparc:
      - add qemu-kvm to Provides
      - add qemu-common, qemu-kvm, kvm to B/R
      - remove openbios-sparc from qemu-system-sparc D
      - drop openbios-ppc and openhackware Depends to Suggests (for now)
    * qemu-system-x86:
      - add qemu-common to Breaks/Replaces.
      - add cpu-checker to Recommends.
    * qemu-user: add B/R:qemu-kvm
    * qemu-kvm:
      - add armhf armel powerpc sparc to Architecture
      - C/R/P: qemu-kvm-spice
    * add qemu-common package
    * drop qemu-slof which is not packaged in ubuntu
  - add qemu-system-common.links for tap ifup/down scripts and OVMF link.
  - qemu-system-x86.links:
    * remove pxe rom links which are in kvm-ipxe
    * add symlink for kvm.1 manpage
  - debian/rules
    * add kvm-spice symlink to qemu-kvm
    * call dh_installmodules for qemu-system-x86
    * update dh_installinit to install upstart script
    * run dh_installman (Closes: #709241) (cherrypicked from 1.5.0+dfsg-2)
  - Add qemu-utils.links for kvm-* symlinks.
  - Add qemu-system-x86.qemu-kvm.upstart and .default
  - Add qemu-system-x86.modprobe to set nesting=1
  - Add qemu-system-common.preinst to add kvm group
  - qemu-system-common.postinst: remove bad group acl if there, then have
    udev relabel /dev/kvm.
  - New linaro patches from qemu-linaro rebasing branch
  - Dropped patches:
    * xen-simplify-xen_enabled.patch
    * sparc-linux-user-fix-missing-symbols-in-.rel-.rela.plt-sections.patch
    * main_loop-do-not-set-nonblocking-if-xen_enabled.patch
    * xen_machine_pv-do-not-create-a-dummy-CPU-in-machine-.patch
    * virtio-rng-fix-crash
  - Kept patches:
    * expose_vms_qemu64cpu.patch - updated
    * linaro arm patches from qemu-linaro rebasing branch
  - New patches:
    * fix-pci-add: change CONFIG variable in ifdef to make sure that
      pci_add is defined.
* Add linaro patches
* Add experimental mach-virt patches for arm virtualization.
* qemu-system-common.install: add debian/tmp/usr/lib to install the
  qemu-bridge-helper

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * QEMU 16550A UART emulation
 
3
 *
 
4
 * Copyright (c) 2003-2004 Fabrice Bellard
 
5
 * Copyright (c) 2008 Citrix Systems, Inc.
 
6
 *
 
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 
8
 * of this software and associated documentation files (the "Software"), to deal
 
9
 * in the Software without restriction, including without limitation the rights
 
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
11
 * copies of the Software, and to permit persons to whom the Software is
 
12
 * furnished to do so, subject to the following conditions:
 
13
 *
 
14
 * The above copyright notice and this permission notice shall be included in
 
15
 * all copies or substantial portions of the Software.
 
16
 *
 
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 
20
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
23
 * THE SOFTWARE.
 
24
 */
 
25
 
 
26
#include "hw/char/serial.h"
 
27
#include "sysemu/char.h"
 
28
#include "qemu/timer.h"
 
29
#include "exec/address-spaces.h"
 
30
 
 
31
//#define DEBUG_SERIAL
 
32
 
 
33
#define UART_LCR_DLAB   0x80    /* Divisor latch access bit */
 
34
 
 
35
#define UART_IER_MSI    0x08    /* Enable Modem status interrupt */
 
36
#define UART_IER_RLSI   0x04    /* Enable receiver line status interrupt */
 
37
#define UART_IER_THRI   0x02    /* Enable Transmitter holding register int. */
 
38
#define UART_IER_RDI    0x01    /* Enable receiver data interrupt */
 
39
 
 
40
#define UART_IIR_NO_INT 0x01    /* No interrupts pending */
 
41
#define UART_IIR_ID     0x06    /* Mask for the interrupt ID */
 
42
 
 
43
#define UART_IIR_MSI    0x00    /* Modem status interrupt */
 
44
#define UART_IIR_THRI   0x02    /* Transmitter holding register empty */
 
45
#define UART_IIR_RDI    0x04    /* Receiver data interrupt */
 
46
#define UART_IIR_RLSI   0x06    /* Receiver line status interrupt */
 
47
#define UART_IIR_CTI    0x0C    /* Character Timeout Indication */
 
48
 
 
49
#define UART_IIR_FENF   0x80    /* Fifo enabled, but not functionning */
 
50
#define UART_IIR_FE     0xC0    /* Fifo enabled */
 
51
 
 
52
/*
 
53
 * These are the definitions for the Modem Control Register
 
54
 */
 
55
#define UART_MCR_LOOP   0x10    /* Enable loopback test mode */
 
56
#define UART_MCR_OUT2   0x08    /* Out2 complement */
 
57
#define UART_MCR_OUT1   0x04    /* Out1 complement */
 
58
#define UART_MCR_RTS    0x02    /* RTS complement */
 
59
#define UART_MCR_DTR    0x01    /* DTR complement */
 
60
 
 
61
/*
 
62
 * These are the definitions for the Modem Status Register
 
63
 */
 
64
#define UART_MSR_DCD    0x80    /* Data Carrier Detect */
 
65
#define UART_MSR_RI     0x40    /* Ring Indicator */
 
66
#define UART_MSR_DSR    0x20    /* Data Set Ready */
 
67
#define UART_MSR_CTS    0x10    /* Clear to Send */
 
68
#define UART_MSR_DDCD   0x08    /* Delta DCD */
 
69
#define UART_MSR_TERI   0x04    /* Trailing edge ring indicator */
 
70
#define UART_MSR_DDSR   0x02    /* Delta DSR */
 
71
#define UART_MSR_DCTS   0x01    /* Delta CTS */
 
72
#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */
 
73
 
 
74
#define UART_LSR_TEMT   0x40    /* Transmitter empty */
 
75
#define UART_LSR_THRE   0x20    /* Transmit-hold-register empty */
 
76
#define UART_LSR_BI     0x10    /* Break interrupt indicator */
 
77
#define UART_LSR_FE     0x08    /* Frame error indicator */
 
78
#define UART_LSR_PE     0x04    /* Parity error indicator */
 
79
#define UART_LSR_OE     0x02    /* Overrun error indicator */
 
80
#define UART_LSR_DR     0x01    /* Receiver data ready */
 
81
#define UART_LSR_INT_ANY 0x1E   /* Any of the lsr-interrupt-triggering status bits */
 
82
 
 
83
/* Interrupt trigger levels. The byte-counts are for 16550A - in newer UARTs the byte-count for each ITL is higher. */
 
84
 
 
85
#define UART_FCR_ITL_1      0x00 /* 1 byte ITL */
 
86
#define UART_FCR_ITL_2      0x40 /* 4 bytes ITL */
 
87
#define UART_FCR_ITL_3      0x80 /* 8 bytes ITL */
 
88
#define UART_FCR_ITL_4      0xC0 /* 14 bytes ITL */
 
89
 
 
90
#define UART_FCR_DMS        0x08    /* DMA Mode Select */
 
91
#define UART_FCR_XFR        0x04    /* XMIT Fifo Reset */
 
92
#define UART_FCR_RFR        0x02    /* RCVR Fifo Reset */
 
93
#define UART_FCR_FE         0x01    /* FIFO Enable */
 
94
 
 
95
#define MAX_XMIT_RETRY      4
 
96
 
 
97
#ifdef DEBUG_SERIAL
 
98
#define DPRINTF(fmt, ...) \
 
99
do { fprintf(stderr, "serial: " fmt , ## __VA_ARGS__); } while (0)
 
100
#else
 
101
#define DPRINTF(fmt, ...) \
 
102
do {} while (0)
 
103
#endif
 
104
 
 
105
static void serial_receive1(void *opaque, const uint8_t *buf, int size);
 
106
 
 
107
static inline void recv_fifo_put(SerialState *s, uint8_t chr)
 
108
{
 
109
    /* Receive overruns do not overwrite FIFO contents. */
 
110
    if (!fifo8_is_full(&s->recv_fifo)) {
 
111
        fifo8_push(&s->recv_fifo, chr);
 
112
    } else {
 
113
        s->lsr |= UART_LSR_OE;
 
114
    }
 
115
}
 
116
 
 
117
static void serial_update_irq(SerialState *s)
 
118
{
 
119
    uint8_t tmp_iir = UART_IIR_NO_INT;
 
120
 
 
121
    if ((s->ier & UART_IER_RLSI) && (s->lsr & UART_LSR_INT_ANY)) {
 
122
        tmp_iir = UART_IIR_RLSI;
 
123
    } else if ((s->ier & UART_IER_RDI) && s->timeout_ipending) {
 
124
        /* Note that(s->ier & UART_IER_RDI) can mask this interrupt,
 
125
         * this is not in the specification but is observed on existing
 
126
         * hardware.  */
 
127
        tmp_iir = UART_IIR_CTI;
 
128
    } else if ((s->ier & UART_IER_RDI) && (s->lsr & UART_LSR_DR) &&
 
129
               (!(s->fcr & UART_FCR_FE) ||
 
130
                s->recv_fifo.num >= s->recv_fifo_itl)) {
 
131
        tmp_iir = UART_IIR_RDI;
 
132
    } else if ((s->ier & UART_IER_THRI) && s->thr_ipending) {
 
133
        tmp_iir = UART_IIR_THRI;
 
134
    } else if ((s->ier & UART_IER_MSI) && (s->msr & UART_MSR_ANY_DELTA)) {
 
135
        tmp_iir = UART_IIR_MSI;
 
136
    }
 
137
 
 
138
    s->iir = tmp_iir | (s->iir & 0xF0);
 
139
 
 
140
    if (tmp_iir != UART_IIR_NO_INT) {
 
141
        qemu_irq_raise(s->irq);
 
142
    } else {
 
143
        qemu_irq_lower(s->irq);
 
144
    }
 
145
}
 
146
 
 
147
static void serial_update_parameters(SerialState *s)
 
148
{
 
149
    int speed, parity, data_bits, stop_bits, frame_size;
 
150
    QEMUSerialSetParams ssp;
 
151
 
 
152
    if (s->divider == 0)
 
153
        return;
 
154
 
 
155
    /* Start bit. */
 
156
    frame_size = 1;
 
157
    if (s->lcr & 0x08) {
 
158
        /* Parity bit. */
 
159
        frame_size++;
 
160
        if (s->lcr & 0x10)
 
161
            parity = 'E';
 
162
        else
 
163
            parity = 'O';
 
164
    } else {
 
165
            parity = 'N';
 
166
    }
 
167
    if (s->lcr & 0x04)
 
168
        stop_bits = 2;
 
169
    else
 
170
        stop_bits = 1;
 
171
 
 
172
    data_bits = (s->lcr & 0x03) + 5;
 
173
    frame_size += data_bits + stop_bits;
 
174
    speed = s->baudbase / s->divider;
 
175
    ssp.speed = speed;
 
176
    ssp.parity = parity;
 
177
    ssp.data_bits = data_bits;
 
178
    ssp.stop_bits = stop_bits;
 
179
    s->char_transmit_time =  (get_ticks_per_sec() / speed) * frame_size;
 
180
    qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
 
181
 
 
182
    DPRINTF("speed=%d parity=%c data=%d stop=%d\n",
 
183
           speed, parity, data_bits, stop_bits);
 
184
}
 
185
 
 
186
static void serial_update_msl(SerialState *s)
 
187
{
 
188
    uint8_t omsr;
 
189
    int flags;
 
190
 
 
191
    qemu_del_timer(s->modem_status_poll);
 
192
 
 
193
    if (qemu_chr_fe_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) {
 
194
        s->poll_msl = -1;
 
195
        return;
 
196
    }
 
197
 
 
198
    omsr = s->msr;
 
199
 
 
200
    s->msr = (flags & CHR_TIOCM_CTS) ? s->msr | UART_MSR_CTS : s->msr & ~UART_MSR_CTS;
 
201
    s->msr = (flags & CHR_TIOCM_DSR) ? s->msr | UART_MSR_DSR : s->msr & ~UART_MSR_DSR;
 
202
    s->msr = (flags & CHR_TIOCM_CAR) ? s->msr | UART_MSR_DCD : s->msr & ~UART_MSR_DCD;
 
203
    s->msr = (flags & CHR_TIOCM_RI) ? s->msr | UART_MSR_RI : s->msr & ~UART_MSR_RI;
 
204
 
 
205
    if (s->msr != omsr) {
 
206
         /* Set delta bits */
 
207
         s->msr = s->msr | ((s->msr >> 4) ^ (omsr >> 4));
 
208
         /* UART_MSR_TERI only if change was from 1 -> 0 */
 
209
         if ((s->msr & UART_MSR_TERI) && !(omsr & UART_MSR_RI))
 
210
             s->msr &= ~UART_MSR_TERI;
 
211
         serial_update_irq(s);
 
212
    }
 
213
 
 
214
    /* The real 16550A apparently has a 250ns response latency to line status changes.
 
215
       We'll be lazy and poll only every 10ms, and only poll it at all if MSI interrupts are turned on */
 
216
 
 
217
    if (s->poll_msl)
 
218
        qemu_mod_timer(s->modem_status_poll, qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 100);
 
219
}
 
220
 
 
221
static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque)
 
222
{
 
223
    SerialState *s = opaque;
 
224
 
 
225
    if (s->tsr_retry <= 0) {
 
226
        if (s->fcr & UART_FCR_FE) {
 
227
            s->tsr = fifo8_is_full(&s->xmit_fifo) ?
 
228
                        0 : fifo8_pop(&s->xmit_fifo);
 
229
            if (!s->xmit_fifo.num) {
 
230
                s->lsr |= UART_LSR_THRE;
 
231
            }
 
232
        } else if ((s->lsr & UART_LSR_THRE)) {
 
233
            return FALSE;
 
234
        } else {
 
235
            s->tsr = s->thr;
 
236
            s->lsr |= UART_LSR_THRE;
 
237
            s->lsr &= ~UART_LSR_TEMT;
 
238
        }
 
239
    }
 
240
 
 
241
    if (s->mcr & UART_MCR_LOOP) {
 
242
        /* in loopback mode, say that we just received a char */
 
243
        serial_receive1(s, &s->tsr, 1);
 
244
    } else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1) {
 
245
        if (s->tsr_retry >= 0 && s->tsr_retry < MAX_XMIT_RETRY &&
 
246
            qemu_chr_fe_add_watch(s->chr, G_IO_OUT, serial_xmit, s) > 0) {
 
247
            s->tsr_retry++;
 
248
            return FALSE;
 
249
        }
 
250
        s->tsr_retry = 0;
 
251
    } else {
 
252
        s->tsr_retry = 0;
 
253
    }
 
254
 
 
255
    s->last_xmit_ts = qemu_get_clock_ns(vm_clock);
 
256
 
 
257
    if (s->lsr & UART_LSR_THRE) {
 
258
        s->lsr |= UART_LSR_TEMT;
 
259
        s->thr_ipending = 1;
 
260
        serial_update_irq(s);
 
261
    }
 
262
 
 
263
    return FALSE;
 
264
}
 
265
 
 
266
 
 
267
static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
 
268
                                unsigned size)
 
269
{
 
270
    SerialState *s = opaque;
 
271
 
 
272
    addr &= 7;
 
273
    DPRINTF("write addr=0x%" HWADDR_PRIx " val=0x%" PRIx64 "\n", addr, val);
 
274
    switch(addr) {
 
275
    default:
 
276
    case 0:
 
277
        if (s->lcr & UART_LCR_DLAB) {
 
278
            s->divider = (s->divider & 0xff00) | val;
 
279
            serial_update_parameters(s);
 
280
        } else {
 
281
            s->thr = (uint8_t) val;
 
282
            if(s->fcr & UART_FCR_FE) {
 
283
                /* xmit overruns overwrite data, so make space if needed */
 
284
                if (fifo8_is_full(&s->xmit_fifo)) {
 
285
                    fifo8_pop(&s->xmit_fifo);
 
286
                }
 
287
                fifo8_push(&s->xmit_fifo, s->thr);
 
288
                s->lsr &= ~UART_LSR_TEMT;
 
289
            }
 
290
            s->thr_ipending = 0;
 
291
            s->lsr &= ~UART_LSR_THRE;
 
292
            serial_update_irq(s);
 
293
            serial_xmit(NULL, G_IO_OUT, s);
 
294
        }
 
295
        break;
 
296
    case 1:
 
297
        if (s->lcr & UART_LCR_DLAB) {
 
298
            s->divider = (s->divider & 0x00ff) | (val << 8);
 
299
            serial_update_parameters(s);
 
300
        } else {
 
301
            s->ier = val & 0x0f;
 
302
            /* If the backend device is a real serial port, turn polling of the modem
 
303
               status lines on physical port on or off depending on UART_IER_MSI state */
 
304
            if (s->poll_msl >= 0) {
 
305
                if (s->ier & UART_IER_MSI) {
 
306
                     s->poll_msl = 1;
 
307
                     serial_update_msl(s);
 
308
                } else {
 
309
                     qemu_del_timer(s->modem_status_poll);
 
310
                     s->poll_msl = 0;
 
311
                }
 
312
            }
 
313
            if (s->lsr & UART_LSR_THRE) {
 
314
                s->thr_ipending = 1;
 
315
                serial_update_irq(s);
 
316
            }
 
317
        }
 
318
        break;
 
319
    case 2:
 
320
        val = val & 0xFF;
 
321
 
 
322
        if (s->fcr == val)
 
323
            break;
 
324
 
 
325
        /* Did the enable/disable flag change? If so, make sure FIFOs get flushed */
 
326
        if ((val ^ s->fcr) & UART_FCR_FE)
 
327
            val |= UART_FCR_XFR | UART_FCR_RFR;
 
328
 
 
329
        /* FIFO clear */
 
330
 
 
331
        if (val & UART_FCR_RFR) {
 
332
            qemu_del_timer(s->fifo_timeout_timer);
 
333
            s->timeout_ipending=0;
 
334
            fifo8_reset(&s->recv_fifo);
 
335
            if ((s->lsr & UART_LSR_DR)) {
 
336
                s->lsr &= ~(UART_LSR_DR | UART_LSR_BI | UART_LSR_OE);
 
337
                if (!(s->mcr & UART_MCR_LOOP)) {
 
338
                    qemu_chr_accept_input(s->chr);
 
339
                }
 
340
            }
 
341
        }
 
342
 
 
343
        if (val & UART_FCR_XFR) {
 
344
            fifo8_reset(&s->xmit_fifo);
 
345
            s->lsr |= UART_LSR_THRE;
 
346
        }
 
347
 
 
348
        if (val & UART_FCR_FE) {
 
349
            s->iir |= UART_IIR_FE;
 
350
            /* Set recv_fifo trigger Level */
 
351
            switch (val & 0xC0) {
 
352
            case UART_FCR_ITL_1:
 
353
                s->recv_fifo_itl = 1;
 
354
                break;
 
355
            case UART_FCR_ITL_2:
 
356
                s->recv_fifo_itl = 4;
 
357
                break;
 
358
            case UART_FCR_ITL_3:
 
359
                s->recv_fifo_itl = 8;
 
360
                break;
 
361
            case UART_FCR_ITL_4:
 
362
                s->recv_fifo_itl = 14;
 
363
                break;
 
364
            }
 
365
        } else
 
366
            s->iir &= ~UART_IIR_FE;
 
367
 
 
368
        /* Set fcr - or at least the bits in it that are supposed to "stick" */
 
369
        s->fcr = val & 0xC9;
 
370
        serial_update_irq(s);
 
371
        break;
 
372
    case 3:
 
373
        {
 
374
            int break_enable;
 
375
            s->lcr = val;
 
376
            serial_update_parameters(s);
 
377
            break_enable = (val >> 6) & 1;
 
378
            if (break_enable != s->last_break_enable) {
 
379
                s->last_break_enable = break_enable;
 
380
                qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
 
381
                               &break_enable);
 
382
            }
 
383
        }
 
384
        break;
 
385
    case 4:
 
386
        {
 
387
            int flags;
 
388
            int old_mcr = s->mcr;
 
389
            s->mcr = val & 0x1f;
 
390
            if (val & UART_MCR_LOOP)
 
391
                break;
 
392
 
 
393
            if (s->poll_msl >= 0 && old_mcr != s->mcr) {
 
394
 
 
395
                qemu_chr_fe_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
 
396
 
 
397
                flags &= ~(CHR_TIOCM_RTS | CHR_TIOCM_DTR);
 
398
 
 
399
                if (val & UART_MCR_RTS)
 
400
                    flags |= CHR_TIOCM_RTS;
 
401
                if (val & UART_MCR_DTR)
 
402
                    flags |= CHR_TIOCM_DTR;
 
403
 
 
404
                qemu_chr_fe_ioctl(s->chr,CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
 
405
                /* Update the modem status after a one-character-send wait-time, since there may be a response
 
406
                   from the device/computer at the other end of the serial line */
 
407
                qemu_mod_timer(s->modem_status_poll, qemu_get_clock_ns(vm_clock) + s->char_transmit_time);
 
408
            }
 
409
        }
 
410
        break;
 
411
    case 5:
 
412
        break;
 
413
    case 6:
 
414
        break;
 
415
    case 7:
 
416
        s->scr = val;
 
417
        break;
 
418
    }
 
419
}
 
420
 
 
421
static uint64_t serial_ioport_read(void *opaque, hwaddr addr, unsigned size)
 
422
{
 
423
    SerialState *s = opaque;
 
424
    uint32_t ret;
 
425
 
 
426
    addr &= 7;
 
427
    switch(addr) {
 
428
    default:
 
429
    case 0:
 
430
        if (s->lcr & UART_LCR_DLAB) {
 
431
            ret = s->divider & 0xff;
 
432
        } else {
 
433
            if(s->fcr & UART_FCR_FE) {
 
434
                ret = fifo8_is_empty(&s->recv_fifo) ?
 
435
                            0 : fifo8_pop(&s->recv_fifo);
 
436
                if (s->recv_fifo.num == 0) {
 
437
                    s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
 
438
                } else {
 
439
                    qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock_ns (vm_clock) + s->char_transmit_time * 4);
 
440
                }
 
441
                s->timeout_ipending = 0;
 
442
            } else {
 
443
                ret = s->rbr;
 
444
                s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
 
445
            }
 
446
            serial_update_irq(s);
 
447
            if (!(s->mcr & UART_MCR_LOOP)) {
 
448
                /* in loopback mode, don't receive any data */
 
449
                qemu_chr_accept_input(s->chr);
 
450
            }
 
451
        }
 
452
        break;
 
453
    case 1:
 
454
        if (s->lcr & UART_LCR_DLAB) {
 
455
            ret = (s->divider >> 8) & 0xff;
 
456
        } else {
 
457
            ret = s->ier;
 
458
        }
 
459
        break;
 
460
    case 2:
 
461
        ret = s->iir;
 
462
        if ((ret & UART_IIR_ID) == UART_IIR_THRI) {
 
463
            s->thr_ipending = 0;
 
464
            serial_update_irq(s);
 
465
        }
 
466
        break;
 
467
    case 3:
 
468
        ret = s->lcr;
 
469
        break;
 
470
    case 4:
 
471
        ret = s->mcr;
 
472
        break;
 
473
    case 5:
 
474
        ret = s->lsr;
 
475
        /* Clear break and overrun interrupts */
 
476
        if (s->lsr & (UART_LSR_BI|UART_LSR_OE)) {
 
477
            s->lsr &= ~(UART_LSR_BI|UART_LSR_OE);
 
478
            serial_update_irq(s);
 
479
        }
 
480
        break;
 
481
    case 6:
 
482
        if (s->mcr & UART_MCR_LOOP) {
 
483
            /* in loopback, the modem output pins are connected to the
 
484
               inputs */
 
485
            ret = (s->mcr & 0x0c) << 4;
 
486
            ret |= (s->mcr & 0x02) << 3;
 
487
            ret |= (s->mcr & 0x01) << 5;
 
488
        } else {
 
489
            if (s->poll_msl >= 0)
 
490
                serial_update_msl(s);
 
491
            ret = s->msr;
 
492
            /* Clear delta bits & msr int after read, if they were set */
 
493
            if (s->msr & UART_MSR_ANY_DELTA) {
 
494
                s->msr &= 0xF0;
 
495
                serial_update_irq(s);
 
496
            }
 
497
        }
 
498
        break;
 
499
    case 7:
 
500
        ret = s->scr;
 
501
        break;
 
502
    }
 
503
    DPRINTF("read addr=0x%" HWADDR_PRIx " val=0x%02x\n", addr, ret);
 
504
    return ret;
 
505
}
 
506
 
 
507
static int serial_can_receive(SerialState *s)
 
508
{
 
509
    if(s->fcr & UART_FCR_FE) {
 
510
        if (s->recv_fifo.num < UART_FIFO_LENGTH) {
 
511
            /*
 
512
             * Advertise (fifo.itl - fifo.count) bytes when count < ITL, and 1
 
513
             * if above. If UART_FIFO_LENGTH - fifo.count is advertised the
 
514
             * effect will be to almost always fill the fifo completely before
 
515
             * the guest has a chance to respond, effectively overriding the ITL
 
516
             * that the guest has set.
 
517
             */
 
518
            return (s->recv_fifo.num <= s->recv_fifo_itl) ?
 
519
                        s->recv_fifo_itl - s->recv_fifo.num : 1;
 
520
        } else {
 
521
            return 0;
 
522
        }
 
523
    } else {
 
524
        return !(s->lsr & UART_LSR_DR);
 
525
    }
 
526
}
 
527
 
 
528
static void serial_receive_break(SerialState *s)
 
529
{
 
530
    s->rbr = 0;
 
531
    /* When the LSR_DR is set a null byte is pushed into the fifo */
 
532
    recv_fifo_put(s, '\0');
 
533
    s->lsr |= UART_LSR_BI | UART_LSR_DR;
 
534
    serial_update_irq(s);
 
535
}
 
536
 
 
537
/* There's data in recv_fifo and s->rbr has not been read for 4 char transmit times */
 
538
static void fifo_timeout_int (void *opaque) {
 
539
    SerialState *s = opaque;
 
540
    if (s->recv_fifo.num) {
 
541
        s->timeout_ipending = 1;
 
542
        serial_update_irq(s);
 
543
    }
 
544
}
 
545
 
 
546
static int serial_can_receive1(void *opaque)
 
547
{
 
548
    SerialState *s = opaque;
 
549
    return serial_can_receive(s);
 
550
}
 
551
 
 
552
static void serial_receive1(void *opaque, const uint8_t *buf, int size)
 
553
{
 
554
    SerialState *s = opaque;
 
555
 
 
556
    if (s->wakeup) {
 
557
        qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
 
558
    }
 
559
    if(s->fcr & UART_FCR_FE) {
 
560
        int i;
 
561
        for (i = 0; i < size; i++) {
 
562
            recv_fifo_put(s, buf[i]);
 
563
        }
 
564
        s->lsr |= UART_LSR_DR;
 
565
        /* call the timeout receive callback in 4 char transmit time */
 
566
        qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock_ns (vm_clock) + s->char_transmit_time * 4);
 
567
    } else {
 
568
        if (s->lsr & UART_LSR_DR)
 
569
            s->lsr |= UART_LSR_OE;
 
570
        s->rbr = buf[0];
 
571
        s->lsr |= UART_LSR_DR;
 
572
    }
 
573
    serial_update_irq(s);
 
574
}
 
575
 
 
576
static void serial_event(void *opaque, int event)
 
577
{
 
578
    SerialState *s = opaque;
 
579
    DPRINTF("event %x\n", event);
 
580
    if (event == CHR_EVENT_BREAK)
 
581
        serial_receive_break(s);
 
582
}
 
583
 
 
584
static void serial_pre_save(void *opaque)
 
585
{
 
586
    SerialState *s = opaque;
 
587
    s->fcr_vmstate = s->fcr;
 
588
}
 
589
 
 
590
static int serial_post_load(void *opaque, int version_id)
 
591
{
 
592
    SerialState *s = opaque;
 
593
 
 
594
    if (version_id < 3) {
 
595
        s->fcr_vmstate = 0;
 
596
    }
 
597
    /* Initialize fcr via setter to perform essential side-effects */
 
598
    serial_ioport_write(s, 0x02, s->fcr_vmstate, 1);
 
599
    serial_update_parameters(s);
 
600
    return 0;
 
601
}
 
602
 
 
603
const VMStateDescription vmstate_serial = {
 
604
    .name = "serial",
 
605
    .version_id = 3,
 
606
    .minimum_version_id = 2,
 
607
    .pre_save = serial_pre_save,
 
608
    .post_load = serial_post_load,
 
609
    .fields      = (VMStateField []) {
 
610
        VMSTATE_UINT16_V(divider, SerialState, 2),
 
611
        VMSTATE_UINT8(rbr, SerialState),
 
612
        VMSTATE_UINT8(ier, SerialState),
 
613
        VMSTATE_UINT8(iir, SerialState),
 
614
        VMSTATE_UINT8(lcr, SerialState),
 
615
        VMSTATE_UINT8(mcr, SerialState),
 
616
        VMSTATE_UINT8(lsr, SerialState),
 
617
        VMSTATE_UINT8(msr, SerialState),
 
618
        VMSTATE_UINT8(scr, SerialState),
 
619
        VMSTATE_UINT8_V(fcr_vmstate, SerialState, 3),
 
620
        VMSTATE_END_OF_LIST()
 
621
    }
 
622
};
 
623
 
 
624
static void serial_reset(void *opaque)
 
625
{
 
626
    SerialState *s = opaque;
 
627
 
 
628
    s->rbr = 0;
 
629
    s->ier = 0;
 
630
    s->iir = UART_IIR_NO_INT;
 
631
    s->lcr = 0;
 
632
    s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
 
633
    s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
 
634
    /* Default to 9600 baud, 1 start bit, 8 data bits, 1 stop bit, no parity. */
 
635
    s->divider = 0x0C;
 
636
    s->mcr = UART_MCR_OUT2;
 
637
    s->scr = 0;
 
638
    s->tsr_retry = 0;
 
639
    s->char_transmit_time = (get_ticks_per_sec() / 9600) * 10;
 
640
    s->poll_msl = 0;
 
641
 
 
642
    fifo8_reset(&s->recv_fifo);
 
643
    fifo8_reset(&s->xmit_fifo);
 
644
 
 
645
    s->last_xmit_ts = qemu_get_clock_ns(vm_clock);
 
646
 
 
647
    s->thr_ipending = 0;
 
648
    s->last_break_enable = 0;
 
649
    qemu_irq_lower(s->irq);
 
650
}
 
651
 
 
652
void serial_realize_core(SerialState *s, Error **errp)
 
653
{
 
654
    if (!s->chr) {
 
655
        error_setg(errp, "Can't create serial device, empty char device");
 
656
        return;
 
657
    }
 
658
 
 
659
    s->modem_status_poll = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) serial_update_msl, s);
 
660
 
 
661
    s->fifo_timeout_timer = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) fifo_timeout_int, s);
 
662
    qemu_register_reset(serial_reset, s);
 
663
 
 
664
    qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1,
 
665
                          serial_event, s);
 
666
    fifo8_create(&s->recv_fifo, UART_FIFO_LENGTH);
 
667
    fifo8_create(&s->xmit_fifo, UART_FIFO_LENGTH);
 
668
}
 
669
 
 
670
void serial_exit_core(SerialState *s)
 
671
{
 
672
    qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
 
673
    qemu_unregister_reset(serial_reset, s);
 
674
}
 
675
 
 
676
/* Change the main reference oscillator frequency. */
 
677
void serial_set_frequency(SerialState *s, uint32_t frequency)
 
678
{
 
679
    s->baudbase = frequency;
 
680
    serial_update_parameters(s);
 
681
}
 
682
 
 
683
const MemoryRegionOps serial_io_ops = {
 
684
    .read = serial_ioport_read,
 
685
    .write = serial_ioport_write,
 
686
    .impl = {
 
687
        .min_access_size = 1,
 
688
        .max_access_size = 1,
 
689
    },
 
690
    .endianness = DEVICE_LITTLE_ENDIAN,
 
691
};
 
692
 
 
693
SerialState *serial_init(int base, qemu_irq irq, int baudbase,
 
694
                         CharDriverState *chr, MemoryRegion *system_io)
 
695
{
 
696
    SerialState *s;
 
697
    Error *err = NULL;
 
698
 
 
699
    s = g_malloc0(sizeof(SerialState));
 
700
 
 
701
    s->irq = irq;
 
702
    s->baudbase = baudbase;
 
703
    s->chr = chr;
 
704
    serial_realize_core(s, &err);
 
705
    if (err != NULL) {
 
706
        fprintf(stderr, "%s\n", error_get_pretty(err));
 
707
        error_free(err);
 
708
        exit(1);
 
709
    }
 
710
 
 
711
    vmstate_register(NULL, base, &vmstate_serial, s);
 
712
 
 
713
    memory_region_init_io(&s->io, NULL, &serial_io_ops, s, "serial", 8);
 
714
    memory_region_add_subregion(system_io, base, &s->io);
 
715
 
 
716
    return s;
 
717
}
 
718
 
 
719
/* Memory mapped interface */
 
720
static uint64_t serial_mm_read(void *opaque, hwaddr addr,
 
721
                               unsigned size)
 
722
{
 
723
    SerialState *s = opaque;
 
724
    return serial_ioport_read(s, addr >> s->it_shift, 1);
 
725
}
 
726
 
 
727
static void serial_mm_write(void *opaque, hwaddr addr,
 
728
                            uint64_t value, unsigned size)
 
729
{
 
730
    SerialState *s = opaque;
 
731
    value &= ~0u >> (32 - (size * 8));
 
732
    serial_ioport_write(s, addr >> s->it_shift, value, 1);
 
733
}
 
734
 
 
735
static const MemoryRegionOps serial_mm_ops[3] = {
 
736
    [DEVICE_NATIVE_ENDIAN] = {
 
737
        .read = serial_mm_read,
 
738
        .write = serial_mm_write,
 
739
        .endianness = DEVICE_NATIVE_ENDIAN,
 
740
    },
 
741
    [DEVICE_LITTLE_ENDIAN] = {
 
742
        .read = serial_mm_read,
 
743
        .write = serial_mm_write,
 
744
        .endianness = DEVICE_LITTLE_ENDIAN,
 
745
    },
 
746
    [DEVICE_BIG_ENDIAN] = {
 
747
        .read = serial_mm_read,
 
748
        .write = serial_mm_write,
 
749
        .endianness = DEVICE_BIG_ENDIAN,
 
750
    },
 
751
};
 
752
 
 
753
SerialState *serial_mm_init(MemoryRegion *address_space,
 
754
                            hwaddr base, int it_shift,
 
755
                            qemu_irq irq, int baudbase,
 
756
                            CharDriverState *chr, enum device_endian end)
 
757
{
 
758
    SerialState *s;
 
759
    Error *err = NULL;
 
760
 
 
761
    s = g_malloc0(sizeof(SerialState));
 
762
 
 
763
    s->it_shift = it_shift;
 
764
    s->irq = irq;
 
765
    s->baudbase = baudbase;
 
766
    s->chr = chr;
 
767
 
 
768
    serial_realize_core(s, &err);
 
769
    if (err != NULL) {
 
770
        fprintf(stderr, "%s\n", error_get_pretty(err));
 
771
        error_free(err);
 
772
        exit(1);
 
773
    }
 
774
    vmstate_register(NULL, base, &vmstate_serial, s);
 
775
 
 
776
    if (address_space) {
 
777
        memory_region_init_io(&s->io, NULL, &serial_mm_ops[end], s,
 
778
                              "serial", 8 << it_shift);
 
779
        memory_region_add_subregion(address_space, base, &s->io);
 
780
    }
 
781
 
 
782
    serial_update_msl(s);
 
783
    return s;
 
784
}
 
785
 
 
786
void serial_change_char_driver(SerialState *s, CharDriverState *chr)
 
787
{
 
788
    /* TODO this is somewhat guesswork, and pretty ugly anyhow */
 
789
    qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
 
790
    s->chr = chr;
 
791
    qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1,
 
792
                          serial_event, s);
 
793
    serial_update_msl(s);
 
794
}
 
795
 
 
796
const MemoryRegionOps *serial_get_memops(enum device_endian end)
 
797
{
 
798
    return &serial_mm_ops[end];
 
799
}
 
800
 
 
801
qemu_irq *serial_get_irq(SerialState *s)
 
802
{
 
803
    return &s->irq;
 
804
}