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

« back to all changes in this revision

Viewing changes to .pc/linaro-patches/0035-serial-reset-lsr-dr-thre-upon-fcr-rfr-xfr.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
        }
 
336
 
 
337
        if (val & UART_FCR_XFR) {
 
338
            fifo8_reset(&s->xmit_fifo);
 
339
        }
 
340
 
 
341
        if (val & UART_FCR_FE) {
 
342
            s->iir |= UART_IIR_FE;
 
343
            /* Set recv_fifo trigger Level */
 
344
            switch (val & 0xC0) {
 
345
            case UART_FCR_ITL_1:
 
346
                s->recv_fifo_itl = 1;
 
347
                break;
 
348
            case UART_FCR_ITL_2:
 
349
                s->recv_fifo_itl = 4;
 
350
                break;
 
351
            case UART_FCR_ITL_3:
 
352
                s->recv_fifo_itl = 8;
 
353
                break;
 
354
            case UART_FCR_ITL_4:
 
355
                s->recv_fifo_itl = 14;
 
356
                break;
 
357
            }
 
358
        } else
 
359
            s->iir &= ~UART_IIR_FE;
 
360
 
 
361
        /* Set fcr - or at least the bits in it that are supposed to "stick" */
 
362
        s->fcr = val & 0xC9;
 
363
        serial_update_irq(s);
 
364
        break;
 
365
    case 3:
 
366
        {
 
367
            int break_enable;
 
368
            s->lcr = val;
 
369
            serial_update_parameters(s);
 
370
            break_enable = (val >> 6) & 1;
 
371
            if (break_enable != s->last_break_enable) {
 
372
                s->last_break_enable = break_enable;
 
373
                qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
 
374
                               &break_enable);
 
375
            }
 
376
        }
 
377
        break;
 
378
    case 4:
 
379
        {
 
380
            int flags;
 
381
            int old_mcr = s->mcr;
 
382
            s->mcr = val & 0x1f;
 
383
            if (val & UART_MCR_LOOP)
 
384
                break;
 
385
 
 
386
            if (s->poll_msl >= 0 && old_mcr != s->mcr) {
 
387
 
 
388
                qemu_chr_fe_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
 
389
 
 
390
                flags &= ~(CHR_TIOCM_RTS | CHR_TIOCM_DTR);
 
391
 
 
392
                if (val & UART_MCR_RTS)
 
393
                    flags |= CHR_TIOCM_RTS;
 
394
                if (val & UART_MCR_DTR)
 
395
                    flags |= CHR_TIOCM_DTR;
 
396
 
 
397
                qemu_chr_fe_ioctl(s->chr,CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
 
398
                /* Update the modem status after a one-character-send wait-time, since there may be a response
 
399
                   from the device/computer at the other end of the serial line */
 
400
                qemu_mod_timer(s->modem_status_poll, qemu_get_clock_ns(vm_clock) + s->char_transmit_time);
 
401
            }
 
402
        }
 
403
        break;
 
404
    case 5:
 
405
        break;
 
406
    case 6:
 
407
        break;
 
408
    case 7:
 
409
        s->scr = val;
 
410
        break;
 
411
    }
 
412
}
 
413
 
 
414
static uint64_t serial_ioport_read(void *opaque, hwaddr addr, unsigned size)
 
415
{
 
416
    SerialState *s = opaque;
 
417
    uint32_t ret;
 
418
 
 
419
    addr &= 7;
 
420
    switch(addr) {
 
421
    default:
 
422
    case 0:
 
423
        if (s->lcr & UART_LCR_DLAB) {
 
424
            ret = s->divider & 0xff;
 
425
        } else {
 
426
            if(s->fcr & UART_FCR_FE) {
 
427
                ret = fifo8_is_empty(&s->recv_fifo) ?
 
428
                            0 : fifo8_pop(&s->recv_fifo);
 
429
                if (s->recv_fifo.num == 0) {
 
430
                    s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
 
431
                } else {
 
432
                    qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock_ns (vm_clock) + s->char_transmit_time * 4);
 
433
                }
 
434
                s->timeout_ipending = 0;
 
435
            } else {
 
436
                ret = s->rbr;
 
437
                s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
 
438
            }
 
439
            serial_update_irq(s);
 
440
            if (!(s->mcr & UART_MCR_LOOP)) {
 
441
                /* in loopback mode, don't receive any data */
 
442
                qemu_chr_accept_input(s->chr);
 
443
            }
 
444
        }
 
445
        break;
 
446
    case 1:
 
447
        if (s->lcr & UART_LCR_DLAB) {
 
448
            ret = (s->divider >> 8) & 0xff;
 
449
        } else {
 
450
            ret = s->ier;
 
451
        }
 
452
        break;
 
453
    case 2:
 
454
        ret = s->iir;
 
455
        if ((ret & UART_IIR_ID) == UART_IIR_THRI) {
 
456
            s->thr_ipending = 0;
 
457
            serial_update_irq(s);
 
458
        }
 
459
        break;
 
460
    case 3:
 
461
        ret = s->lcr;
 
462
        break;
 
463
    case 4:
 
464
        ret = s->mcr;
 
465
        break;
 
466
    case 5:
 
467
        ret = s->lsr;
 
468
        /* Clear break and overrun interrupts */
 
469
        if (s->lsr & (UART_LSR_BI|UART_LSR_OE)) {
 
470
            s->lsr &= ~(UART_LSR_BI|UART_LSR_OE);
 
471
            serial_update_irq(s);
 
472
        }
 
473
        break;
 
474
    case 6:
 
475
        if (s->mcr & UART_MCR_LOOP) {
 
476
            /* in loopback, the modem output pins are connected to the
 
477
               inputs */
 
478
            ret = (s->mcr & 0x0c) << 4;
 
479
            ret |= (s->mcr & 0x02) << 3;
 
480
            ret |= (s->mcr & 0x01) << 5;
 
481
        } else {
 
482
            if (s->poll_msl >= 0)
 
483
                serial_update_msl(s);
 
484
            ret = s->msr;
 
485
            /* Clear delta bits & msr int after read, if they were set */
 
486
            if (s->msr & UART_MSR_ANY_DELTA) {
 
487
                s->msr &= 0xF0;
 
488
                serial_update_irq(s);
 
489
            }
 
490
        }
 
491
        break;
 
492
    case 7:
 
493
        ret = s->scr;
 
494
        break;
 
495
    }
 
496
    DPRINTF("read addr=0x%" HWADDR_PRIx " val=0x%02x\n", addr, ret);
 
497
    return ret;
 
498
}
 
499
 
 
500
static int serial_can_receive(SerialState *s)
 
501
{
 
502
    if(s->fcr & UART_FCR_FE) {
 
503
        if (s->recv_fifo.num < UART_FIFO_LENGTH) {
 
504
            /*
 
505
             * Advertise (fifo.itl - fifo.count) bytes when count < ITL, and 1
 
506
             * if above. If UART_FIFO_LENGTH - fifo.count is advertised the
 
507
             * effect will be to almost always fill the fifo completely before
 
508
             * the guest has a chance to respond, effectively overriding the ITL
 
509
             * that the guest has set.
 
510
             */
 
511
            return (s->recv_fifo.num <= s->recv_fifo_itl) ?
 
512
                        s->recv_fifo_itl - s->recv_fifo.num : 1;
 
513
        } else {
 
514
            return 0;
 
515
        }
 
516
    } else {
 
517
        return !(s->lsr & UART_LSR_DR);
 
518
    }
 
519
}
 
520
 
 
521
static void serial_receive_break(SerialState *s)
 
522
{
 
523
    s->rbr = 0;
 
524
    /* When the LSR_DR is set a null byte is pushed into the fifo */
 
525
    recv_fifo_put(s, '\0');
 
526
    s->lsr |= UART_LSR_BI | UART_LSR_DR;
 
527
    serial_update_irq(s);
 
528
}
 
529
 
 
530
/* There's data in recv_fifo and s->rbr has not been read for 4 char transmit times */
 
531
static void fifo_timeout_int (void *opaque) {
 
532
    SerialState *s = opaque;
 
533
    if (s->recv_fifo.num) {
 
534
        s->timeout_ipending = 1;
 
535
        serial_update_irq(s);
 
536
    }
 
537
}
 
538
 
 
539
static int serial_can_receive1(void *opaque)
 
540
{
 
541
    SerialState *s = opaque;
 
542
    return serial_can_receive(s);
 
543
}
 
544
 
 
545
static void serial_receive1(void *opaque, const uint8_t *buf, int size)
 
546
{
 
547
    SerialState *s = opaque;
 
548
 
 
549
    if (s->wakeup) {
 
550
        qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
 
551
    }
 
552
    if(s->fcr & UART_FCR_FE) {
 
553
        int i;
 
554
        for (i = 0; i < size; i++) {
 
555
            recv_fifo_put(s, buf[i]);
 
556
        }
 
557
        s->lsr |= UART_LSR_DR;
 
558
        /* call the timeout receive callback in 4 char transmit time */
 
559
        qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock_ns (vm_clock) + s->char_transmit_time * 4);
 
560
    } else {
 
561
        if (s->lsr & UART_LSR_DR)
 
562
            s->lsr |= UART_LSR_OE;
 
563
        s->rbr = buf[0];
 
564
        s->lsr |= UART_LSR_DR;
 
565
    }
 
566
    serial_update_irq(s);
 
567
}
 
568
 
 
569
static void serial_event(void *opaque, int event)
 
570
{
 
571
    SerialState *s = opaque;
 
572
    DPRINTF("event %x\n", event);
 
573
    if (event == CHR_EVENT_BREAK)
 
574
        serial_receive_break(s);
 
575
}
 
576
 
 
577
static void serial_pre_save(void *opaque)
 
578
{
 
579
    SerialState *s = opaque;
 
580
    s->fcr_vmstate = s->fcr;
 
581
}
 
582
 
 
583
static int serial_post_load(void *opaque, int version_id)
 
584
{
 
585
    SerialState *s = opaque;
 
586
 
 
587
    if (version_id < 3) {
 
588
        s->fcr_vmstate = 0;
 
589
    }
 
590
    /* Initialize fcr via setter to perform essential side-effects */
 
591
    serial_ioport_write(s, 0x02, s->fcr_vmstate, 1);
 
592
    serial_update_parameters(s);
 
593
    return 0;
 
594
}
 
595
 
 
596
const VMStateDescription vmstate_serial = {
 
597
    .name = "serial",
 
598
    .version_id = 3,
 
599
    .minimum_version_id = 2,
 
600
    .pre_save = serial_pre_save,
 
601
    .post_load = serial_post_load,
 
602
    .fields      = (VMStateField []) {
 
603
        VMSTATE_UINT16_V(divider, SerialState, 2),
 
604
        VMSTATE_UINT8(rbr, SerialState),
 
605
        VMSTATE_UINT8(ier, SerialState),
 
606
        VMSTATE_UINT8(iir, SerialState),
 
607
        VMSTATE_UINT8(lcr, SerialState),
 
608
        VMSTATE_UINT8(mcr, SerialState),
 
609
        VMSTATE_UINT8(lsr, SerialState),
 
610
        VMSTATE_UINT8(msr, SerialState),
 
611
        VMSTATE_UINT8(scr, SerialState),
 
612
        VMSTATE_UINT8_V(fcr_vmstate, SerialState, 3),
 
613
        VMSTATE_END_OF_LIST()
 
614
    }
 
615
};
 
616
 
 
617
static void serial_reset(void *opaque)
 
618
{
 
619
    SerialState *s = opaque;
 
620
 
 
621
    s->rbr = 0;
 
622
    s->ier = 0;
 
623
    s->iir = UART_IIR_NO_INT;
 
624
    s->lcr = 0;
 
625
    s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
 
626
    s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
 
627
    /* Default to 9600 baud, 1 start bit, 8 data bits, 1 stop bit, no parity. */
 
628
    s->divider = 0x0C;
 
629
    s->mcr = UART_MCR_OUT2;
 
630
    s->scr = 0;
 
631
    s->tsr_retry = 0;
 
632
    s->char_transmit_time = (get_ticks_per_sec() / 9600) * 10;
 
633
    s->poll_msl = 0;
 
634
 
 
635
    fifo8_reset(&s->recv_fifo);
 
636
    fifo8_reset(&s->xmit_fifo);
 
637
 
 
638
    s->last_xmit_ts = qemu_get_clock_ns(vm_clock);
 
639
 
 
640
    s->thr_ipending = 0;
 
641
    s->last_break_enable = 0;
 
642
    qemu_irq_lower(s->irq);
 
643
}
 
644
 
 
645
void serial_realize_core(SerialState *s, Error **errp)
 
646
{
 
647
    if (!s->chr) {
 
648
        error_setg(errp, "Can't create serial device, empty char device");
 
649
        return;
 
650
    }
 
651
 
 
652
    s->modem_status_poll = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) serial_update_msl, s);
 
653
 
 
654
    s->fifo_timeout_timer = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) fifo_timeout_int, s);
 
655
    qemu_register_reset(serial_reset, s);
 
656
 
 
657
    qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1,
 
658
                          serial_event, s);
 
659
    fifo8_create(&s->recv_fifo, UART_FIFO_LENGTH);
 
660
    fifo8_create(&s->xmit_fifo, UART_FIFO_LENGTH);
 
661
}
 
662
 
 
663
void serial_exit_core(SerialState *s)
 
664
{
 
665
    qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
 
666
    qemu_unregister_reset(serial_reset, s);
 
667
}
 
668
 
 
669
/* Change the main reference oscillator frequency. */
 
670
void serial_set_frequency(SerialState *s, uint32_t frequency)
 
671
{
 
672
    s->baudbase = frequency;
 
673
    serial_update_parameters(s);
 
674
}
 
675
 
 
676
const MemoryRegionOps serial_io_ops = {
 
677
    .read = serial_ioport_read,
 
678
    .write = serial_ioport_write,
 
679
    .impl = {
 
680
        .min_access_size = 1,
 
681
        .max_access_size = 1,
 
682
    },
 
683
    .endianness = DEVICE_LITTLE_ENDIAN,
 
684
};
 
685
 
 
686
SerialState *serial_init(int base, qemu_irq irq, int baudbase,
 
687
                         CharDriverState *chr, MemoryRegion *system_io)
 
688
{
 
689
    SerialState *s;
 
690
    Error *err = NULL;
 
691
 
 
692
    s = g_malloc0(sizeof(SerialState));
 
693
 
 
694
    s->irq = irq;
 
695
    s->baudbase = baudbase;
 
696
    s->chr = chr;
 
697
    serial_realize_core(s, &err);
 
698
    if (err != NULL) {
 
699
        fprintf(stderr, "%s\n", error_get_pretty(err));
 
700
        error_free(err);
 
701
        exit(1);
 
702
    }
 
703
 
 
704
    vmstate_register(NULL, base, &vmstate_serial, s);
 
705
 
 
706
    memory_region_init_io(&s->io, NULL, &serial_io_ops, s, "serial", 8);
 
707
    memory_region_add_subregion(system_io, base, &s->io);
 
708
 
 
709
    return s;
 
710
}
 
711
 
 
712
/* Memory mapped interface */
 
713
static uint64_t serial_mm_read(void *opaque, hwaddr addr,
 
714
                               unsigned size)
 
715
{
 
716
    SerialState *s = opaque;
 
717
    return serial_ioport_read(s, addr >> s->it_shift, 1);
 
718
}
 
719
 
 
720
static void serial_mm_write(void *opaque, hwaddr addr,
 
721
                            uint64_t value, unsigned size)
 
722
{
 
723
    SerialState *s = opaque;
 
724
    value &= ~0u >> (32 - (size * 8));
 
725
    serial_ioport_write(s, addr >> s->it_shift, value, 1);
 
726
}
 
727
 
 
728
static const MemoryRegionOps serial_mm_ops[3] = {
 
729
    [DEVICE_NATIVE_ENDIAN] = {
 
730
        .read = serial_mm_read,
 
731
        .write = serial_mm_write,
 
732
        .endianness = DEVICE_NATIVE_ENDIAN,
 
733
    },
 
734
    [DEVICE_LITTLE_ENDIAN] = {
 
735
        .read = serial_mm_read,
 
736
        .write = serial_mm_write,
 
737
        .endianness = DEVICE_LITTLE_ENDIAN,
 
738
    },
 
739
    [DEVICE_BIG_ENDIAN] = {
 
740
        .read = serial_mm_read,
 
741
        .write = serial_mm_write,
 
742
        .endianness = DEVICE_BIG_ENDIAN,
 
743
    },
 
744
};
 
745
 
 
746
SerialState *serial_mm_init(MemoryRegion *address_space,
 
747
                            hwaddr base, int it_shift,
 
748
                            qemu_irq irq, int baudbase,
 
749
                            CharDriverState *chr, enum device_endian end)
 
750
{
 
751
    SerialState *s;
 
752
    Error *err = NULL;
 
753
 
 
754
    s = g_malloc0(sizeof(SerialState));
 
755
 
 
756
    s->it_shift = it_shift;
 
757
    s->irq = irq;
 
758
    s->baudbase = baudbase;
 
759
    s->chr = chr;
 
760
 
 
761
    serial_realize_core(s, &err);
 
762
    if (err != NULL) {
 
763
        fprintf(stderr, "%s\n", error_get_pretty(err));
 
764
        error_free(err);
 
765
        exit(1);
 
766
    }
 
767
    vmstate_register(NULL, base, &vmstate_serial, s);
 
768
 
 
769
    if (address_space) {
 
770
        memory_region_init_io(&s->io, NULL, &serial_mm_ops[end], s,
 
771
                              "serial", 8 << it_shift);
 
772
        memory_region_add_subregion(address_space, base, &s->io);
 
773
    }
 
774
 
 
775
    serial_update_msl(s);
 
776
    return s;
 
777
}
 
778
 
 
779
void serial_change_char_driver(SerialState *s, CharDriverState *chr)
 
780
{
 
781
    /* TODO this is somewhat guesswork, and pretty ugly anyhow */
 
782
    qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
 
783
    s->chr = chr;
 
784
    qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1,
 
785
                          serial_event, s);
 
786
    serial_update_msl(s);
 
787
}
 
788
 
 
789
const MemoryRegionOps *serial_get_memops(enum device_endian end)
 
790
{
 
791
    return &serial_mm_ops[end];
 
792
}
 
793
 
 
794
qemu_irq *serial_get_irq(SerialState *s)
 
795
{
 
796
    return &s->irq;
 
797
}