1
From a557c2070471841eabdf2f9a4c75068206a0ea68 Mon Sep 17 00:00:00 2001
2
From: =?UTF-8?q?Juha=20Riihim=C3=A4ki?= <juha.riihimaki@nokia.com>
3
Date: Mon, 18 Feb 2013 16:58:29 +0000
4
Subject: [PATCH 33/70] omap_uart updates
6
Content-Type: text/plain; charset=UTF-8
7
Content-Transfer-Encoding: 8bit
10
- add missing registers
12
FIXME this is badly broken due to serial init changing -- PMM
14
Signed-off-by: Juha Riihimäki <juha.riihimaki@nokia.com>
16
hw/arm/omap1.c | 64 ++++++-----
17
hw/arm/omap2.c | 73 +++++++------
18
hw/char/omap_uart.c | 275 +++++++++++++++++++++++++++++++++++++----------
19
hw/char/serial.c | 28 ++++-
20
include/hw/arm/omap.h | 15 +--
21
include/hw/char/serial.h | 3 +
22
6 files changed, 333 insertions(+), 125 deletions(-)
24
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
25
index 47511d2..1500841 100644
28
@@ -3692,9 +3692,6 @@ static void omap1_mpu_reset(void *opaque)
29
omap_dpll_reset(mpu->dpll[0]);
30
omap_dpll_reset(mpu->dpll[1]);
31
omap_dpll_reset(mpu->dpll[2]);
32
- omap_uart_reset(mpu->uart[0]);
33
- omap_uart_reset(mpu->uart[1]);
34
- omap_uart_reset(mpu->uart[2]);
35
omap_mmc_reset(mpu->mmc);
36
omap_mpuio_reset(mpu->mpuio);
37
omap_uwire_reset(mpu->microwire);
38
@@ -3938,27 +3935,46 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
40
omap_tcmi_init(system_memory, 0xfffecc00, s);
42
- s->uart[0] = omap_uart_init(0xfffb0000,
43
- qdev_get_gpio_in(s->ih[1], OMAP_INT_UART1),
44
- omap_findclk(s, "uart1_ck"),
45
- omap_findclk(s, "uart1_ck"),
46
- s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX],
49
- s->uart[1] = omap_uart_init(0xfffb0800,
50
- qdev_get_gpio_in(s->ih[1], OMAP_INT_UART2),
51
- omap_findclk(s, "uart2_ck"),
52
- omap_findclk(s, "uart2_ck"),
53
- s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
55
- serial_hds[0] ? serial_hds[1] : NULL);
56
- s->uart[2] = omap_uart_init(0xfffb9800,
57
- qdev_get_gpio_in(s->ih[0], OMAP_INT_UART3),
58
- omap_findclk(s, "uart3_ck"),
59
- omap_findclk(s, "uart3_ck"),
60
- s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],
62
- serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL);
63
+ s->uart[0] = qdev_create(NULL, "omap_uart");
64
+ s->uart[0]->id = "uart1";
65
+ qdev_prop_set_uint32(s->uart[0], "mmio_size", 0x400);
66
+ qdev_prop_set_uint32(s->uart[0], "baudrate",
67
+ omap_clk_getrate(omap_findclk(s, "uart1_ck")) / 16);
68
+ qdev_prop_set_chr(s->uart[0], "chardev", serial_hds[0]);
69
+ qdev_init_nofail(s->uart[0]);
70
+ busdev = SYS_BUS_DEVICE(s->uart[0]);
71
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(s->ih[1], OMAP_INT_UART1));
72
+ sysbus_connect_irq(busdev, 1, s->drq[OMAP_DMA_UART1_TX]);
73
+ sysbus_connect_irq(busdev, 2, s->drq[OMAP_DMA_UART1_RX]);
74
+ sysbus_mmio_map(busdev, 0, 0xfffb0000);
76
+ s->uart[1] = qdev_create(NULL, "omap_uart");
77
+ s->uart[1]->id = "uart2";
78
+ qdev_prop_set_uint32(s->uart[1], "mmio_size", 0x400);
79
+ qdev_prop_set_uint32(s->uart[1], "baudrate",
80
+ omap_clk_getrate(omap_findclk(s, "uart2_ck")) / 16);
81
+ qdev_prop_set_chr(s->uart[1], "chardev",
82
+ serial_hds[0] ? serial_hds[1] : NULL);
83
+ qdev_init_nofail(s->uart[1]);
84
+ busdev = SYS_BUS_DEVICE(s->uart[1]);
85
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(s->ih[1], OMAP_INT_UART2));
86
+ sysbus_connect_irq(busdev, 1, s->drq[OMAP_DMA_UART2_TX]);
87
+ sysbus_connect_irq(busdev, 2, s->drq[OMAP_DMA_UART2_RX]);
88
+ sysbus_mmio_map(busdev, 0, 0xfffb0800);
90
+ s->uart[2] = qdev_create(NULL, "omap_uart");
91
+ s->uart[2]->id = "uart3";
92
+ qdev_prop_set_uint32(s->uart[2], "mmio_size", 0x400);
93
+ qdev_prop_set_uint32(s->uart[2], "baudrate",
94
+ omap_clk_getrate(omap_findclk(s, "uart3_ck")) / 16);
95
+ qdev_prop_set_chr(s->uart[2], "chardev",
96
+ serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL);
97
+ qdev_init_nofail(s->uart[2]);
98
+ busdev = SYS_BUS_DEVICE(s->uart[2]);
99
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(s->ih[0], OMAP_INT_UART3));
100
+ sysbus_connect_irq(busdev, 1, s->drq[OMAP_DMA_UART3_TX]);
101
+ sysbus_connect_irq(busdev, 2, s->drq[OMAP_DMA_UART3_RX]);
102
+ sysbus_mmio_map(busdev, 0, 0xfffb9800);
104
s->dpll[0] = omap_dpll_init(system_memory, 0xfffecf00,
105
omap_findclk(s, "dpll1"));
106
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
107
index f867ff2..667abb9 100644
110
@@ -2216,9 +2216,6 @@ static void omap2_mpu_reset(void *opaque)
111
omap_sdrc_reset(mpu->sdrc);
112
omap_gpmc_reset(mpu->gpmc);
113
omap_dss_reset(mpu->dss);
114
- omap_uart_reset(mpu->uart[0]);
115
- omap_uart_reset(mpu->uart[1]);
116
- omap_uart_reset(mpu->uart[2]);
117
omap_mmc_reset(mpu->mmc);
118
cpu_reset(CPU(mpu->cpu));
120
@@ -2308,33 +2305,49 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
121
soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->sram),
122
OMAP2_SRAM_BASE, s->sram_size);
124
- s->uart[0] = omap2_uart_init(sysmem, omap_l4ta(s->l4, 19),
125
- qdev_get_gpio_in(s->ih[0],
126
- OMAP_INT_24XX_UART1_IRQ),
127
- omap_findclk(s, "uart1_fclk"),
128
- omap_findclk(s, "uart1_iclk"),
129
- s->drq[OMAP24XX_DMA_UART1_TX],
130
- s->drq[OMAP24XX_DMA_UART1_RX],
133
- s->uart[1] = omap2_uart_init(sysmem, omap_l4ta(s->l4, 20),
134
- qdev_get_gpio_in(s->ih[0],
135
- OMAP_INT_24XX_UART2_IRQ),
136
- omap_findclk(s, "uart2_fclk"),
137
- omap_findclk(s, "uart2_iclk"),
138
- s->drq[OMAP24XX_DMA_UART2_TX],
139
- s->drq[OMAP24XX_DMA_UART2_RX],
141
- serial_hds[0] ? serial_hds[1] : NULL);
142
- s->uart[2] = omap2_uart_init(sysmem, omap_l4ta(s->l4, 21),
143
- qdev_get_gpio_in(s->ih[0],
144
- OMAP_INT_24XX_UART3_IRQ),
145
- omap_findclk(s, "uart3_fclk"),
146
- omap_findclk(s, "uart3_iclk"),
147
- s->drq[OMAP24XX_DMA_UART3_TX],
148
- s->drq[OMAP24XX_DMA_UART3_RX],
150
- serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL);
151
+ s->uart[0] = qdev_create(NULL, "omap_uart");
152
+ s->uart[0]->id = "uart1";
153
+ qdev_prop_set_uint32(s->uart[0], "mmio_size", 0x1000);
154
+ qdev_prop_set_uint32(s->uart[0], "baudrate",
155
+ omap_clk_getrate(omap_findclk(s, "uart1_fclk")) / 16);
156
+ qdev_prop_set_chr(s->uart[0], "chardev", serial_hds[0]);
157
+ qdev_init_nofail(s->uart[0]);
158
+ busdev = SYS_BUS_DEVICE(s->uart[0]);
159
+ sysbus_connect_irq(busdev, 0,
160
+ qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_UART1_IRQ));
161
+ sysbus_connect_irq(busdev, 1, s->drq[OMAP24XX_DMA_UART1_TX]);
162
+ sysbus_connect_irq(busdev, 2, s->drq[OMAP24XX_DMA_UART1_RX]);
163
+ sysbus_mmio_map(busdev, 0, omap_l4_region_base(omap_l4ta(s->l4, 19), 0));
165
+ s->uart[1] = qdev_create(NULL, "omap_uart");
166
+ s->uart[1]->id = "uart2";
167
+ qdev_prop_set_uint32(s->uart[1], "mmio_size", 0x1000);
168
+ qdev_prop_set_uint32(s->uart[1], "baudrate",
169
+ omap_clk_getrate(omap_findclk(s, "uart2_fclk")) / 16);
170
+ qdev_prop_set_chr(s->uart[1], "chardev",
171
+ serial_hds[0] ? serial_hds[1] : NULL);
172
+ qdev_init_nofail(s->uart[1]);
173
+ busdev = SYS_BUS_DEVICE(s->uart[1]);
174
+ sysbus_connect_irq(busdev, 0,
175
+ qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_UART2_IRQ));
176
+ sysbus_connect_irq(busdev, 1, s->drq[OMAP24XX_DMA_UART2_TX]);
177
+ sysbus_connect_irq(busdev, 2, s->drq[OMAP24XX_DMA_UART2_RX]);
178
+ sysbus_mmio_map(busdev, 0, omap_l4_region_base(omap_l4ta(s->l4, 20), 0));
180
+ s->uart[2] = qdev_create(NULL, "omap_uart");
181
+ s->uart[2]->id = "uart3";
182
+ qdev_prop_set_uint32(s->uart[2], "mmio_size", 0x1000);
183
+ qdev_prop_set_uint32(s->uart[2], "baudrate",
184
+ omap_clk_getrate(omap_findclk(s, "uart3_fclk")) / 16);
185
+ qdev_prop_set_chr(s->uart[2], "chardev",
186
+ serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL);
187
+ qdev_init_nofail(s->uart[2]);
188
+ busdev = SYS_BUS_DEVICE(s->uart[2]);
189
+ sysbus_connect_irq(busdev, 0,
190
+ qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_UART3_IRQ));
191
+ sysbus_connect_irq(busdev, 1, s->drq[OMAP24XX_DMA_UART3_TX]);
192
+ sysbus_connect_irq(busdev, 2, s->drq[OMAP24XX_DMA_UART3_RX]);
193
+ sysbus_mmio_map(busdev, 0, omap_l4_region_base(omap_l4ta(s->l4, 21), 0));
195
s->gptimer[0] = omap_gp_timer_init(omap_l4ta(s->l4, 7),
196
qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER1),
197
diff --git a/hw/char/omap_uart.c b/hw/char/omap_uart.c
198
index 61d893b..2bffed4 100644
199
--- a/hw/char/omap_uart.c
200
+++ b/hw/char/omap_uart.c
202
#include "hw/arm/omap.h"
203
#include "hw/char/serial.h"
204
#include "exec/address-spaces.h"
205
+#include "hw/sysbus.h"
208
-struct omap_uart_s {
209
+#define TYPE_OMAP_UART "omap_uart"
210
+#define OMAP_UART(obj) OBJECT_CHECK(omap_uart_s, (obj), TYPE_OMAP_UART)
212
+/* The OMAP UART functionality is similar to the TI16C752 rather than
213
+ * the 16550A. When the flag below is enabled, the code will however
214
+ * offer 'only' the basic 16550A emulation. */
215
+/* TODO: real functionality for the TI16C752 enhanced features. Note
216
+ * QEMU's SerialState emulation internally always uses a 16-byte FIFO
217
+ * whereas we would need a 64-byte FIFO for OMAP. */
218
+#define OMAP_UART_16550A
220
+typedef struct omap_uart_s {
221
+ SysBusDevice busdev;
224
+ CharDriverState *chr;
225
SerialState *serial; /* TODO */
226
- struct omap_target_agent_s *ta;
229
+ const MemoryRegionOps *serial_ops;
230
+ uint32_t mmio_size;
239
@@ -39,33 +54,39 @@ struct omap_uart_s {
247
-void omap_uart_reset(struct omap_uart_s *s)
248
+#ifndef OMAP_UART_16550A
253
+ uint8_t xon[2], xoff[2];
257
+static void omap_uart_reset(DeviceState *qdev)
259
+ struct omap_uart_s *s = OMAP_UART(qdev);
271
-struct omap_uart_s *omap_uart_init(hwaddr base,
272
- qemu_irq irq, omap_clk fclk, omap_clk iclk,
273
- qemu_irq txdma, qemu_irq rxdma,
274
- const char *label, CharDriverState *chr)
276
- struct omap_uart_s *s = (struct omap_uart_s *)
277
- g_malloc0(sizeof(struct omap_uart_s));
282
- s->serial = serial_mm_init(get_system_memory(), base, 2, irq,
283
- omap_clk_getrate(fclk)/16,
284
- chr ?: qemu_chr_new(label, "null", NULL),
285
- DEVICE_NATIVE_ENDIAN);
287
+#ifndef OMAP_UART_16550A
292
+ s->xon[0] = s->xon[1] = 0;
293
+ s->xoff[0] = s->xoff[1] = 0;
297
static uint64_t omap_uart_read(void *opaque, hwaddr addr,
298
@@ -73,15 +94,59 @@ static uint64_t omap_uart_read(void *opaque, hwaddr addr,
300
struct omap_uart_s *s = (struct omap_uart_s *) opaque;
303
- return omap_badwidth_read8(opaque, addr);
310
+ return s->serial_ops->read(s->serial, addr, size);
312
+#ifndef OMAP_UART_16550A
313
+ if (s->lcr_cache == 0xbf) {
317
+ return s->serial_ops->read(s->serial, addr, size);
320
+#ifndef OMAP_UART_16550A
321
+ if (s->lcr_cache == 0xbf) {
322
+ return s->xon[(addr & 7) >> 2];
323
+ } else if (addr == 0x10) {
324
+ return s->serial_ops->read(s->serial, addr, size)
325
+ | (s->mcr_cache & 0xe0);
328
+ return s->serial_ops->read(s->serial, addr, size);
331
+#ifndef OMAP_UART_16550A
332
+ if ((s->efr & 0x10) && (s->mcr_cache & 0x40)) {
333
+ return (addr == 0x18) ? s->tcr : s->tlr;
335
+ if (s->lcr_cache == 0xbf) {
336
+ return s->xoff[(addr & 7) >> 2];
339
+ return s->serial_ops->read(s->serial, addr, size);
340
case 0x20: /* MDR1 */
342
case 0x24: /* MDR2 */
344
+ case 0x28: /* SFLSR */
346
+ case 0x2c: /* RESUME */
348
+ case 0x30: /* SFREGL */
350
+ case 0x34: /* SFREGH */
352
+ case 0x38: /* UASR/BLR */
353
+ if ((s->lcr_cache & 0x80)) {
354
+ return 0; /* FIXME: return correct autodetect value */
357
+ case 0x3c: /* ACREG */
358
+ return (s->lcr_cache & 0x80) ? 0 : s->acreg;
362
@@ -111,35 +176,99 @@ static void omap_uart_write(void *opaque, hwaddr addr,
364
struct omap_uart_s *s = (struct omap_uart_s *) opaque;
367
- return omap_badwidth_write8(opaque, addr, value);
373
+ s->serial_ops->write(s->serial, addr, value, size);
376
+#ifndef OMAP_UART_16550A
377
+ if (s->lcr_cache == 0xbf) {
381
+ s->serial_ops->write(s->serial, addr, value, size);
384
+ s->lcr_cache = value;
385
+ s->serial_ops->write(s->serial, addr, value, size);
389
+#ifndef OMAP_UART_16550A
390
+ if (s->lcr_cache == 0xbf) {
391
+ s->xon[(addr & 7) >> 2] = value;
393
+ if (addr == 0x10) {
394
+ s->mcr_cache = value & 0x7f;
397
+ s->serial_ops->write(s->serial, addr, value, size);
398
+#ifndef OMAP_UART_16550A
404
+#ifndef OMAP_UART_16550A
405
+ if ((s->efr & 0x10) && (s->mcr_cache & 0x40)) {
406
+ if (addr == 0x18) {
407
+ s->tcr = value & 0xff;
409
+ s->tlr = value & 0xff;
411
+ } else if (s->lcr_cache == 0xbf) {
412
+ s->xoff[(addr & 7) >> 2] = value;
415
+ s->serial_ops->write(s->serial, addr, value, size);
417
case 0x20: /* MDR1 */
418
s->mdr[0] = value & 0x7f;
420
case 0x24: /* MDR2 */
421
s->mdr[1] = value & 0xff;
423
+ case 0x28: /* TXFLL */
424
+ case 0x2c: /* TXFLH */
425
+ case 0x30: /* RXFLL */
426
+ case 0x34: /* RXFLH */
429
+ case 0x38: /* BLR */
430
+ if (!(s->lcr_cache & 0x80)) {
431
+ s->blr = value & 0xc0;
434
+ case 0x3c: /* ACREG */
435
+ if (!(s->lcr_cache & 0x80)) {
436
+ s->acreg = value & 0xff;
440
s->scr = value & 0xff;
442
+ case 0x44: /* SSR */
445
case 0x48: /* EBLR (OMAP2) */
446
s->eblr = value & 0xff;
448
case 0x4C: /* OSC_12M_SEL (OMAP1) */
449
s->clksel = value & 1;
451
- case 0x44: /* SSR */
453
- case 0x58: /* SYSS (OMAP2) */
456
case 0x54: /* SYSC (OMAP2) */
457
s->syscontrol = value & 0x1d;
459
- omap_uart_reset(s);
461
+ /* TODO: reset s->serial also. */
462
+ omap_uart_reset(DEVICE(s));
465
+ case 0x58: /* SYSS (OMAP2) */
468
case 0x5c: /* WER (OMAP2) */
469
s->wkup = value & 0x7f;
470
@@ -158,31 +287,67 @@ static const MemoryRegionOps omap_uart_ops = {
471
.endianness = DEVICE_NATIVE_ENDIAN,
474
-struct omap_uart_s *omap2_uart_init(MemoryRegion *sysmem,
475
- struct omap_target_agent_s *ta,
476
- qemu_irq irq, omap_clk fclk, omap_clk iclk,
477
- qemu_irq txdma, qemu_irq rxdma,
478
- const char *label, CharDriverState *chr)
479
+static int omap_uart_init(SysBusDevice *busdev)
481
- hwaddr base = omap_l4_attach(ta, 0, NULL);
482
- struct omap_uart_s *s = omap_uart_init(base, irq,
483
- fclk, iclk, txdma, rxdma, label, chr);
484
+ struct omap_uart_s *s = OMAP_UART(busdev);
487
+ // XXX looks a bit dubious to grab id like this
488
+ s->chr = qemu_chr_new(DEVICE(busdev)->id, "null", NULL);
490
+ /* TODO: DMA support. Current 16550A emulation does not emulate DMA mode
491
+ * transfers via TXRDY/RXRDY pins. We create DMA irq lines here for
492
+ * future use nevertheless. */
493
+ /* Nasty hackery because trying to extend an existing device is
494
+ * not really supported, and the serial driver isn't even qdev.
496
+ s->serial = serial_mm_init(NULL, 0, 2, NULL, s->baudrate, s->chr,
497
+ DEVICE_NATIVE_ENDIAN);
498
+ s->serial_ops = serial_get_memops(DEVICE_NATIVE_ENDIAN);
499
+ sysbus_init_irq(busdev, serial_get_irq(s->serial));
500
+ sysbus_init_irq(busdev, &s->tx_drq);
501
+ sysbus_init_irq(busdev, &s->rx_drq);
502
+ memory_region_init_io(&s->iomem, NULL, &omap_uart_ops, s, "omap_uart",
504
+ sysbus_init_mmio(busdev, &s->iomem);
508
- memory_region_init_io(&s->iomem, NULL, &omap_uart_ops, s, "omap.uart", 0x100);
509
+static Property omap_uart_properties[] = {
510
+ DEFINE_PROP_UINT32("mmio_size", struct omap_uart_s, mmio_size, 0x400),
511
+ DEFINE_PROP_UINT32("baudrate", struct omap_uart_s, baudrate, 0),
512
+ DEFINE_PROP_CHR("chardev", struct omap_uart_s, chr),
513
+ DEFINE_PROP_END_OF_LIST()
517
+static void omap_uart_class_init(ObjectClass *klass, void *data)
519
+ DeviceClass *dc = DEVICE_CLASS(klass);
520
+ SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
521
+ k->init = omap_uart_init;
522
+ dc->props = omap_uart_properties;
523
+ dc->reset = omap_uart_reset;
526
- memory_region_add_subregion(sysmem, base + 0x20, &s->iomem);
527
+static TypeInfo omap_uart_info = {
528
+ .name = "omap_uart",
529
+ .parent = TYPE_SYS_BUS_DEVICE,
530
+ .instance_size = sizeof(struct omap_uart_s),
531
+ .class_init = omap_uart_class_init,
535
+static void omap_uart_register_types(void)
537
+ type_register_static(&omap_uart_info);
540
-void omap_uart_attach(struct omap_uart_s *s, CharDriverState *chr,
541
+void omap_uart_attach(DeviceState *qdev, CharDriverState *chr,
544
- /* TODO: Should reuse or destroy current s->serial */
545
- s->serial = serial_mm_init(get_system_memory(), s->base, 2, s->irq,
546
- omap_clk_getrate(s->fclk) / 16,
547
- chr ?: qemu_chr_new(label, "null", NULL),
548
- DEVICE_NATIVE_ENDIAN);
549
+ struct omap_uart_s *s = OMAP_UART(qdev);
551
+ s->chr = chr ?: qemu_chr_new(label, "null", NULL);
552
+ serial_change_char_driver(s->serial, s->chr);
555
+type_init(omap_uart_register_types)
556
diff --git a/hw/char/serial.c b/hw/char/serial.c
557
index 27dab7d..ab78c1e 100644
558
--- a/hw/char/serial.c
559
+++ b/hw/char/serial.c
560
@@ -767,10 +767,32 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
562
vmstate_register(NULL, base, &vmstate_serial, s);
564
- memory_region_init_io(&s->io, NULL, &serial_mm_ops[end], s,
565
- "serial", 8 << it_shift);
566
- memory_region_add_subregion(address_space, base, &s->io);
567
+ if (address_space) {
568
+ memory_region_init_io(&s->io, NULL, &serial_mm_ops[end], s,
569
+ "serial", 8 << it_shift);
570
+ memory_region_add_subregion(address_space, base, &s->io);
573
serial_update_msl(s);
577
+void serial_change_char_driver(SerialState *s, CharDriverState *chr)
579
+ /* TODO this is somewhat guesswork, and pretty ugly anyhow */
580
+ qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
582
+ qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1,
584
+ serial_update_msl(s);
587
+const MemoryRegionOps *serial_get_memops(enum device_endian end)
589
+ return &serial_mm_ops[end];
592
+qemu_irq *serial_get_irq(SerialState *s)
596
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
597
index e408771..9d0a0b7 100644
598
--- a/include/hw/arm/omap.h
599
+++ b/include/hw/arm/omap.h
600
@@ -871,18 +871,7 @@ struct omap_synctimer_s *omap_synctimer_init(struct omap_target_agent_s *ta,
601
struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk);
602
void omap_synctimer_reset(struct omap_synctimer_s *s);
605
-struct omap_uart_s *omap_uart_init(hwaddr base,
606
- qemu_irq irq, omap_clk fclk, omap_clk iclk,
607
- qemu_irq txdma, qemu_irq rxdma,
608
- const char *label, CharDriverState *chr);
609
-struct omap_uart_s *omap2_uart_init(MemoryRegion *sysmem,
610
- struct omap_target_agent_s *ta,
611
- qemu_irq irq, omap_clk fclk, omap_clk iclk,
612
- qemu_irq txdma, qemu_irq rxdma,
613
- const char *label, CharDriverState *chr);
614
-void omap_uart_reset(struct omap_uart_s *s);
615
-void omap_uart_attach(struct omap_uart_s *s, CharDriverState *chr,
616
+void omap_uart_attach(DeviceState *qdev, CharDriverState *chr,
620
@@ -1048,7 +1037,7 @@ struct omap_mpu_state_s {
621
unsigned long sram_size;
623
/* MPUI-TIPB peripherals */
624
- struct omap_uart_s *uart[3];
625
+ DeviceState *uart[4];
629
diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h
630
index 85f58ac..bc6e493 100644
631
--- a/include/hw/char/serial.h
632
+++ b/include/hw/char/serial.h
633
@@ -81,6 +81,9 @@ extern const MemoryRegionOps serial_io_ops;
634
void serial_realize_core(SerialState *s, Error **errp);
635
void serial_exit_core(SerialState *s);
636
void serial_set_frequency(SerialState *s, uint32_t frequency);
637
+void serial_change_char_driver(SerialState *s, CharDriverState *chr);
638
+const MemoryRegionOps *serial_get_memops(enum device_endian end);
639
+qemu_irq *serial_get_irq(SerialState *s);
642
SerialState *serial_init(int base, qemu_irq irq, int baudbase,