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

« back to all changes in this revision

Viewing changes to .pc/ubuntu/linaro/0035-hw-omap_uart.c-Unconditionally-enable-non-16550-exte.patch/hw/char/omap_uart.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2014-02-04 12:13:08 UTC
  • mfrom: (10.1.45 sid)
  • Revision ID: package-import@ubuntu.com-20140204121308-1xq92lrfs75agw2g
Tags: 1.7.0+dfsg-3ubuntu1~ppa1
* Merge 1.7.0+dfsg-3 from debian.  Remaining changes:
  - debian/patches/ubuntu:
    * expose-vmx_qemu64cpu.patch
    * linaro (omap3) and arm64 patches
    * ubuntu/target-ppc-add-stubs-for-kvm-breakpoints: fix FTBFS
      on ppc
    * ubuntu/CVE-2013-4377.patch: fix denial of service via virtio
  - debian/qemu-system-x86.modprobe: set kvm_intel nested=1 options
  - debian/control:
    * add arm64 to Architectures
    * add qemu-common and qemu-system-aarch64 packages
  - debian/qemu-system-common.install: add debian/tmp/usr/lib
  - debian/qemu-system-common.preinst: add kvm group
  - debian/qemu-system-common.postinst: remove acl placed by udev,
    and add udevadm trigger.
  - qemu-system-x86.links: add eepro100.rom, remove pxe-virtio,
    pxe-e1000 and pxe-rtl8139.
  - add qemu-system-x86.qemu-kvm.upstart and .default
  - qemu-user-static.postinst-in: remove arm64 binfmt
  - debian/rules:
    * allow parallel build
    * add aarch64 to system_targets and sys_systems
    * add qemu-kvm-spice links
    * install qemu-system-x86.modprobe
  - add debian/qemu-system-common.links for OVMF.fd link
* Remove kvm-img, kvm-nbd, kvm-ifup and kvm-ifdown symlinks.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * TI OMAP processors UART emulation.
 
3
 *
 
4
 * Copyright (C) 2006-2008 Andrzej Zaborowski  <balrog@zabor.org>
 
5
 * Copyright (C) 2007-2009 Nokia Corporation
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU General Public License as
 
9
 * published by the Free Software Foundation; either version 2 or
 
10
 * (at your option) version 3 of the License.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License along
 
18
 * with this program; if not, see <http://www.gnu.org/licenses/>.
 
19
 */
 
20
#include "sysemu/char.h"
 
21
#include "hw/hw.h"
 
22
#include "hw/arm/omap.h"
 
23
#include "hw/char/serial.h"
 
24
#include "exec/address-spaces.h"
 
25
#include "hw/sysbus.h"
 
26
 
 
27
#define TYPE_OMAP_UART "omap_uart"
 
28
#define OMAP_UART(obj) OBJECT_CHECK(omap_uart_s, (obj), TYPE_OMAP_UART)
 
29
 
 
30
/* The OMAP UART functionality is similar to the TI16C752 rather than
 
31
 * the 16550A. When the flag below is enabled, the code will however
 
32
 * offer 'only' the basic 16550A emulation. */
 
33
/* TODO: real functionality for the TI16C752 enhanced features. Note
 
34
 * QEMU's SerialState emulation internally always uses a 16-byte FIFO
 
35
 * whereas we would need a 64-byte FIFO for OMAP. */
 
36
#define OMAP_UART_16550A
 
37
 
 
38
typedef struct omap_uart_s {
 
39
    SysBusDevice busdev;
 
40
    MemoryRegion iomem;
 
41
    CharDriverState *chr;
 
42
    SerialState *serial; /* TODO */
 
43
    const MemoryRegionOps *serial_ops;
 
44
    uint32_t mmio_size;
 
45
    uint32_t baudrate;
 
46
    qemu_irq tx_drq;
 
47
    qemu_irq rx_drq;
 
48
 
 
49
    uint8_t lcr_cache;
 
50
    uint8_t eblr;
 
51
    uint8_t syscontrol;
 
52
    uint8_t wkup;
 
53
    uint8_t cfps;
 
54
    uint8_t mdr[2];
 
55
    uint8_t scr;
 
56
    uint8_t clksel;
 
57
    uint8_t blr;
 
58
    uint8_t acreg;
 
59
 
 
60
#ifndef OMAP_UART_16550A
 
61
    uint8_t mcr_cache;
 
62
    uint8_t efr;
 
63
    uint8_t tcr;
 
64
    uint8_t tlr;
 
65
    uint8_t xon[2], xoff[2];
 
66
#endif
 
67
} omap_uart_s;
 
68
 
 
69
static void omap_uart_reset(DeviceState *qdev)
 
70
{
 
71
    struct omap_uart_s *s = OMAP_UART(qdev);
 
72
 
 
73
    s->eblr = 0x00;
 
74
    s->syscontrol = 0;
 
75
    s->wkup = 0x3f;
 
76
    s->cfps = 0x69;
 
77
    s->clksel = 0;
 
78
    s->blr = 0x40;
 
79
    s->acreg = 0;
 
80
    s->lcr_cache = 0;
 
81
 
 
82
#ifndef OMAP_UART_16550A
 
83
    s->mcr_cache = 0;
 
84
    s->tcr = 0x0f;
 
85
    s->tlr = 0;
 
86
    s->efr = 0;
 
87
    s->xon[0] = s->xon[1] = 0;
 
88
    s->xoff[0] = s->xoff[1] = 0;
 
89
#endif
 
90
}
 
91
 
 
92
static uint64_t omap_uart_read(void *opaque, hwaddr addr,
 
93
                               unsigned size)
 
94
{
 
95
    struct omap_uart_s *s = (struct omap_uart_s *) opaque;
 
96
 
 
97
    switch (addr) {
 
98
    case 0x00:
 
99
    case 0x04:
 
100
    case 0x0c:
 
101
        return s->serial_ops->read(s->serial, addr, size);
 
102
    case 0x08:
 
103
#ifndef OMAP_UART_16550A
 
104
        if (s->lcr_cache == 0xbf) {
 
105
            return s->efr;
 
106
        }
 
107
#endif
 
108
        return s->serial_ops->read(s->serial, addr, size);
 
109
    case 0x10:
 
110
    case 0x14:
 
111
#ifndef OMAP_UART_16550A
 
112
        if (s->lcr_cache == 0xbf) {
 
113
            return s->xon[(addr & 7) >> 2];
 
114
        } else if (addr == 0x10) {
 
115
            return s->serial_ops->read(s->serial, addr, size)
 
116
                   | (s->mcr_cache & 0xe0);
 
117
        }
 
118
#endif
 
119
        return s->serial_ops->read(s->serial, addr, size);
 
120
    case 0x18:
 
121
    case 0x1c:
 
122
#ifndef OMAP_UART_16550A
 
123
        if ((s->efr & 0x10) && (s->mcr_cache & 0x40)) {
 
124
            return (addr == 0x18) ? s->tcr : s->tlr;
 
125
        }
 
126
        if (s->lcr_cache == 0xbf) {
 
127
            return s->xoff[(addr & 7) >> 2];
 
128
        }
 
129
#endif
 
130
        return s->serial_ops->read(s->serial, addr, size);
 
131
    case 0x20:  /* MDR1 */
 
132
        return s->mdr[0];
 
133
    case 0x24:  /* MDR2 */
 
134
        return s->mdr[1];
 
135
    case 0x28: /* SFLSR */
 
136
        return 0;
 
137
    case 0x2c: /* RESUME */
 
138
        return 0;
 
139
    case 0x30: /* SFREGL */
 
140
        return 0;
 
141
    case 0x34: /* SFREGH */
 
142
        return 0;
 
143
    case 0x38: /* UASR/BLR */
 
144
        if ((s->lcr_cache & 0x80)) {
 
145
            return 0; /* FIXME: return correct autodetect value */
 
146
        }
 
147
        return s->blr;
 
148
    case 0x3c: /* ACREG */
 
149
        return (s->lcr_cache & 0x80) ? 0 : s->acreg;
 
150
    case 0x40:  /* SCR */
 
151
        return s->scr;
 
152
    case 0x44:  /* SSR */
 
153
        return 0x0;
 
154
    case 0x48:  /* EBLR (OMAP2) */
 
155
        return s->eblr;
 
156
    case 0x4C:  /* OSC_12M_SEL (OMAP1) */
 
157
        return s->clksel;
 
158
    case 0x50:  /* MVR */
 
159
        return 0x30;
 
160
    case 0x54:  /* SYSC (OMAP2) */
 
161
        return s->syscontrol;
 
162
    case 0x58:  /* SYSS (OMAP2) */
 
163
        return 1;
 
164
    case 0x5c:  /* WER (OMAP2) */
 
165
        return s->wkup;
 
166
    case 0x60:  /* CFPS (OMAP2) */
 
167
        return s->cfps;
 
168
    }
 
169
 
 
170
    OMAP_BAD_REG(addr);
 
171
    return 0;
 
172
}
 
173
 
 
174
static void omap_uart_write(void *opaque, hwaddr addr,
 
175
                            uint64_t value, unsigned size)
 
176
{
 
177
    struct omap_uart_s *s = (struct omap_uart_s *) opaque;
 
178
 
 
179
    switch (addr) {
 
180
    case 0x00:
 
181
    case 0x04:
 
182
        s->serial_ops->write(s->serial, addr, value, size);
 
183
        break;
 
184
    case 0x08:
 
185
#ifndef OMAP_UART_16550A
 
186
        if (s->lcr_cache == 0xbf) {
 
187
            s->efr = value;
 
188
        } else
 
189
#endif
 
190
        s->serial_ops->write(s->serial, addr, value, size);
 
191
        break;
 
192
    case 0x0c:
 
193
        s->lcr_cache = value;
 
194
        s->serial_ops->write(s->serial, addr, value, size);
 
195
        break;
 
196
    case 0x10:
 
197
    case 0x14:
 
198
#ifndef OMAP_UART_16550A
 
199
        if (s->lcr_cache == 0xbf) {
 
200
            s->xon[(addr & 7) >> 2] = value;
 
201
        } else {
 
202
            if (addr == 0x10) {
 
203
                s->mcr_cache = value & 0x7f;
 
204
            }
 
205
#endif
 
206
        s->serial_ops->write(s->serial, addr, value, size);
 
207
#ifndef OMAP_UART_16550A
 
208
        }
 
209
#endif
 
210
        break;
 
211
    case 0x18:
 
212
    case 0x1c:
 
213
#ifndef OMAP_UART_16550A
 
214
        if ((s->efr & 0x10) && (s->mcr_cache & 0x40)) {
 
215
            if (addr == 0x18) {
 
216
                s->tcr = value & 0xff;
 
217
            } else {
 
218
                s->tlr = value & 0xff;
 
219
            }
 
220
        } else if (s->lcr_cache == 0xbf) {
 
221
            s->xoff[(addr & 7) >> 2] = value;
 
222
        } else
 
223
#endif
 
224
        s->serial_ops->write(s->serial, addr, value, size);
 
225
        break;
 
226
    case 0x20:  /* MDR1 */
 
227
        s->mdr[0] = value & 0x7f;
 
228
        break;
 
229
    case 0x24:  /* MDR2 */
 
230
        s->mdr[1] = value & 0xff;
 
231
        break;
 
232
    case 0x28: /* TXFLL */
 
233
    case 0x2c: /* TXFLH */
 
234
    case 0x30: /* RXFLL */
 
235
    case 0x34: /* RXFLH */
 
236
        /* ignored */
 
237
        break;
 
238
    case 0x38: /* BLR */
 
239
        if (!(s->lcr_cache & 0x80)) {
 
240
            s->blr = value & 0xc0;
 
241
        }
 
242
        break;
 
243
    case 0x3c: /* ACREG */
 
244
        if (!(s->lcr_cache & 0x80)) {
 
245
            s->acreg = value & 0xff;
 
246
        }
 
247
        break;
 
248
    case 0x40:  /* SCR */
 
249
        s->scr = value & 0xff;
 
250
        break;
 
251
    case 0x44:  /* SSR */
 
252
        OMAP_RO_REG(addr);
 
253
        break;
 
254
    case 0x48:  /* EBLR (OMAP2) */
 
255
        s->eblr = value & 0xff;
 
256
        break;
 
257
    case 0x4C:  /* OSC_12M_SEL (OMAP1) */
 
258
        s->clksel = value & 1;
 
259
        break;
 
260
    case 0x50:  /* MVR */
 
261
        OMAP_RO_REG(addr);
 
262
        break;
 
263
    case 0x54:  /* SYSC (OMAP2) */
 
264
        s->syscontrol = value & 0x1d;
 
265
        if (value & 2) {
 
266
            /* TODO: reset s->serial also. */
 
267
            omap_uart_reset(DEVICE(s));
 
268
        }
 
269
        break;
 
270
    case 0x58:  /* SYSS (OMAP2) */
 
271
        OMAP_RO_REG(addr);
 
272
        break;
 
273
    case 0x5c:  /* WER (OMAP2) */
 
274
        s->wkup = value & 0x7f;
 
275
        break;
 
276
    case 0x60:  /* CFPS (OMAP2) */
 
277
        s->cfps = value & 0xff;
 
278
        break;
 
279
    default:
 
280
        OMAP_BAD_REG(addr);
 
281
    }
 
282
}
 
283
 
 
284
static const MemoryRegionOps omap_uart_ops = {
 
285
    .read = omap_uart_read,
 
286
    .write = omap_uart_write,
 
287
    .endianness = DEVICE_NATIVE_ENDIAN,
 
288
};
 
289
 
 
290
static int omap_uart_init(SysBusDevice *busdev)
 
291
{
 
292
    struct omap_uart_s *s = OMAP_UART(busdev);
 
293
 
 
294
    if (!s->chr) {
 
295
        // XXX looks a bit dubious to grab id like this
 
296
        s->chr = qemu_chr_new(DEVICE(busdev)->id, "null", NULL);
 
297
    }
 
298
    /* TODO: DMA support. Current 16550A emulation does not emulate DMA mode
 
299
     * transfers via TXRDY/RXRDY pins. We create DMA irq lines here for
 
300
     * future use nevertheless. */
 
301
    /* Nasty hackery because trying to extend an existing device is
 
302
     * not really supported, and the serial driver isn't even qdev.
 
303
     */
 
304
    s->serial = serial_mm_init(NULL, 0, 2, NULL, s->baudrate, s->chr,
 
305
                               DEVICE_NATIVE_ENDIAN);
 
306
    s->serial_ops = serial_get_memops(DEVICE_NATIVE_ENDIAN);
 
307
    sysbus_init_irq(busdev, serial_get_irq(s->serial));
 
308
    sysbus_init_irq(busdev, &s->tx_drq);
 
309
    sysbus_init_irq(busdev, &s->rx_drq);
 
310
    memory_region_init_io(&s->iomem, NULL, &omap_uart_ops, s, "omap_uart",
 
311
                          s->mmio_size);
 
312
    sysbus_init_mmio(busdev, &s->iomem);
 
313
    return 0;
 
314
}
 
315
 
 
316
static Property omap_uart_properties[] = {
 
317
    DEFINE_PROP_UINT32("mmio_size", struct omap_uart_s, mmio_size, 0x400),
 
318
    DEFINE_PROP_UINT32("baudrate", struct omap_uart_s, baudrate, 0),
 
319
    DEFINE_PROP_CHR("chardev", struct omap_uart_s, chr),
 
320
    DEFINE_PROP_END_OF_LIST()
 
321
};
 
322
 
 
323
static void omap_uart_class_init(ObjectClass *klass, void *data)
 
324
{
 
325
    DeviceClass *dc = DEVICE_CLASS(klass);
 
326
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
327
    k->init = omap_uart_init;
 
328
    dc->props = omap_uart_properties;
 
329
    dc->reset = omap_uart_reset;
 
330
}
 
331
 
 
332
static TypeInfo omap_uart_info = {
 
333
    .name = "omap_uart",
 
334
    .parent = TYPE_SYS_BUS_DEVICE,
 
335
    .instance_size = sizeof(struct omap_uart_s),
 
336
    .class_init = omap_uart_class_init,
 
337
};
 
338
 
 
339
static void omap_uart_register_types(void)
 
340
{
 
341
    type_register_static(&omap_uart_info);
 
342
}
 
343
 
 
344
void omap_uart_attach(DeviceState *qdev, CharDriverState *chr,
 
345
                      const char *label)
 
346
{
 
347
    struct omap_uart_s *s = OMAP_UART(qdev);
 
348
 
 
349
    s->chr = chr ?: qemu_chr_new(label, "null", NULL);
 
350
    serial_change_char_driver(s->serial, s->chr);
 
351
}
 
352
 
 
353
type_init(omap_uart_register_types)