master
c 750 lines 20 KB
Raw
1 /*
2 * Arm PrimeCell PL011 UART
3 *
4 * Copyright (c) 2006 CodeSourcery.
5 * Written by Paul Brook
6 *
7 * This code is licensed under the GPL.
8 */
9
10 /*
11 * QEMU interface:
12 * + sysbus MMIO region 0: device registers
13 * + sysbus IRQ 0: UARTINTR (combined interrupt line)
14 * + sysbus IRQ 1: UARTRXINTR (receive FIFO interrupt line)
15 * + sysbus IRQ 2: UARTTXINTR (transmit FIFO interrupt line)
16 * + sysbus IRQ 3: UARTRTINTR (receive timeout interrupt line)
17 * + sysbus IRQ 4: UARTMSINTR (momem status interrupt line)
18 * + sysbus IRQ 5: UARTEINTR (error interrupt line)
19 */
20
21 #include "qemu/osdep.h"
22 #include "qapi/error.h"
23 #include "hw/char/pl011.h"
24 #include "hw/core/irq.h"
25 #include "hw/core/sysbus.h"
26 #include "hw/core/qdev-clock.h"
27 #include "hw/core/qdev-properties.h"
28 #include "hw/core/qdev-properties-system.h"
29 #include "migration/vmstate.h"
30 #include "chardev/char-fe.h"
31 #include "chardev/char-serial.h"
32 #include "qemu/log.h"
33 #include "qemu/module.h"
34 #include "trace.h"
35
36 DeviceState *pl011_create(hwaddr addr, qemu_irq irq, Chardev *chr)
37 {
38 DeviceState *dev;
39 SysBusDevice *s;
40
41 dev = qdev_new("pl011");
42 s = SYS_BUS_DEVICE(dev);
43 qdev_prop_set_chr(dev, "chardev", chr);
44 sysbus_realize_and_unref(s, &error_fatal);
45 sysbus_mmio_map(s, 0, addr);
46 sysbus_connect_irq(s, 0, irq);
47
48 return dev;
49 }
50
51 /* Flag Register, UARTFR */
52 #define PL011_FLAG_RI 0x100
53 #define PL011_FLAG_TXFE 0x80
54 #define PL011_FLAG_RXFF 0x40
55 #define PL011_FLAG_TXFF 0x20
56 #define PL011_FLAG_RXFE 0x10
57 #define PL011_FLAG_DCD 0x04
58 #define PL011_FLAG_DSR 0x02
59 #define PL011_FLAG_CTS 0x01
60
61 /* Data Register, UARTDR */
62 #define DR_BE (1 << 10)
63
64 /* Interrupt status bits in UARTRIS, UARTMIS, UARTIMSC */
65 #define INT_OE (1 << 10)
66 #define INT_BE (1 << 9)
67 #define INT_PE (1 << 8)
68 #define INT_FE (1 << 7)
69 #define INT_RT (1 << 6)
70 #define INT_TX (1 << 5)
71 #define INT_RX (1 << 4)
72 #define INT_DSR (1 << 3)
73 #define INT_DCD (1 << 2)
74 #define INT_CTS (1 << 1)
75 #define INT_RI (1 << 0)
76 #define INT_E (INT_OE | INT_BE | INT_PE | INT_FE)
77 #define INT_MS (INT_RI | INT_DSR | INT_DCD | INT_CTS)
78
79 /* Line Control Register, UARTLCR_H */
80 #define LCR_FEN (1 << 4)
81 #define LCR_BRK (1 << 0)
82
83 /* Control Register, UARTCR */
84 #define CR_OUT2 (1 << 13)
85 #define CR_OUT1 (1 << 12)
86 #define CR_RTS (1 << 11)
87 #define CR_DTR (1 << 10)
88 #define CR_RXE (1 << 9)
89 #define CR_TXE (1 << 8)
90 #define CR_LBE (1 << 7)
91 #define CR_UARTEN (1 << 0)
92
93 /* Integer Baud Rate Divider, UARTIBRD */
94 #define IBRD_MASK 0xffff
95
96 /* Fractional Baud Rate Divider, UARTFBRD */
97 #define FBRD_MASK 0x3f
98
99 static const unsigned char pl011_id_arm[8] =
100 { 0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
101 static const unsigned char pl011_id_luminary[8] =
102 { 0x11, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1 };
103
104 static const char *pl011_regname(hwaddr offset)
105 {
106 static const char *const rname[] = {
107 [0] = "DR", [1] = "RSR", [6] = "FR", [8] = "ILPR", [9] = "IBRD",
108 [10] = "FBRD", [11] = "LCRH", [12] = "CR", [13] = "IFLS", [14] = "IMSC",
109 [15] = "RIS", [16] = "MIS", [17] = "ICR", [18] = "DMACR",
110 };
111 unsigned idx = offset >> 2;
112
113 if (idx < ARRAY_SIZE(rname) && rname[idx]) {
114 return rname[idx];
115 }
116 if (idx >= 0x3f8 && idx <= 0x400) {
117 return "ID";
118 }
119 return "UNKN";
120 }
121
122 /* Which bits in the interrupt status matter for each outbound IRQ line ? */
123 static const uint32_t irqmask[] = {
124 INT_E | INT_MS | INT_RT | INT_TX | INT_RX, /* combined IRQ */
125 INT_RX,
126 INT_TX,
127 INT_RT,
128 INT_MS,
129 INT_E,
130 };
131
132 static void pl011_update(PL011State *s)
133 {
134 uint32_t flags;
135 int i;
136
137 flags = s->int_level & s->int_enabled;
138 trace_pl011_irq_state(flags != 0);
139 for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
140 qemu_set_irq(s->irq[i], (flags & irqmask[i]) != 0);
141 }
142 }
143
144 static bool pl011_loopback_enabled(PL011State *s)
145 {
146 return !!(s->cr & CR_LBE);
147 }
148
149 static bool pl011_is_fifo_enabled(PL011State *s)
150 {
151 return (s->lcr & LCR_FEN) != 0;
152 }
153
154 static inline unsigned pl011_get_fifo_depth(PL011State *s)
155 {
156 /* Note: FIFO depth is expected to be power-of-2 */
157 return pl011_is_fifo_enabled(s) ? PL011_FIFO_DEPTH : 1;
158 }
159
160 static inline void pl011_reset_rx_fifo(PL011State *s)
161 {
162 s->read_count = 0;
163 s->read_pos = 0;
164
165 /* Reset FIFO flags */
166 s->flags &= ~PL011_FLAG_RXFF;
167 s->flags |= PL011_FLAG_RXFE;
168 }
169
170 static inline void pl011_reset_tx_fifo(PL011State *s)
171 {
172 /* Reset FIFO flags */
173 s->flags &= ~PL011_FLAG_TXFF;
174 s->flags |= PL011_FLAG_TXFE;
175 }
176
177 static void pl011_fifo_rx_put(void *opaque, uint32_t value)
178 {
179 PL011State *s = (PL011State *)opaque;
180 int slot;
181 unsigned pipe_depth;
182
183 pipe_depth = pl011_get_fifo_depth(s);
184 slot = (s->read_pos + s->read_count) & (pipe_depth - 1);
185 s->read_fifo[slot] = value;
186 s->read_count++;
187 s->flags &= ~PL011_FLAG_RXFE;
188 trace_pl011_fifo_rx_put(value, s->read_count, pipe_depth);
189 if (s->read_count == pipe_depth) {
190 trace_pl011_fifo_rx_full();
191 s->flags |= PL011_FLAG_RXFF;
192 }
193 if (s->read_count == s->read_trigger) {
194 s->int_level |= INT_RX;
195 pl011_update(s);
196 }
197 }
198
199 static void pl011_loopback_tx(PL011State *s, uint32_t value)
200 {
201 if (!pl011_loopback_enabled(s)) {
202 return;
203 }
204
205 /*
206 * Caveat:
207 *
208 * In real hardware, TX loopback happens at the serial-bit level
209 * and then reassembled by the RX logics back into bytes and placed
210 * into the RX fifo. That is, loopback happens after TX fifo.
211 *
212 * Because the real hardware TX fifo is time-drained at the frame
213 * rate governed by the configured serial format, some loopback
214 * bytes in TX fifo may still be able to get into the RX fifo
215 * that could be full at times while being drained at software
216 * pace.
217 *
218 * In such scenario, the RX draining pace is the major factor
219 * deciding which loopback bytes get into the RX fifo, unless
220 * hardware flow-control is enabled.
221 *
222 * For simplicity, the above described is not emulated.
223 */
224 pl011_fifo_rx_put(s, value);
225 }
226
227 static void pl011_write_txdata(PL011State *s, uint8_t data)
228 {
229 if (!(s->cr & CR_UARTEN)) {
230 /*
231 * Only log this message once, not every time the guest outputs:
232 * otherwise we would flood the logs with this message, making
233 * harder to debug guests. (Some very popular guests like Linux
234 * don't actively enable the UART.)
235 */
236 if (!s->logged_disabled_uart) {
237 qemu_log_mask(LOG_GUEST_ERROR,
238 "PL011 data written to disabled UART\n");
239 s->logged_disabled_uart = true;
240 }
241 }
242 if (!(s->cr & CR_TXE)) {
243 /*
244 * We don't bother with the only-log-once machinery for this check
245 * because TXE is enabled by default from PL011 reset, so there
246 * isn't likely to be existing in-the-wild guest code that trips
247 * over this one.
248 */
249 qemu_log_mask(LOG_GUEST_ERROR,
250 "PL011 data written to disabled TX UART\n");
251 }
252
253 /*
254 * XXX this blocks entire thread. Rewrite to use
255 * qemu_chr_fe_write and background I/O callbacks
256 */
257 qemu_chr_fe_write_all(&s->chr, &data, 1);
258 pl011_loopback_tx(s, data);
259 s->int_level |= INT_TX;
260 pl011_update(s);
261 }
262
263 static uint32_t pl011_read_rxdata(PL011State *s)
264 {
265 uint32_t c;
266 unsigned fifo_depth = pl011_get_fifo_depth(s);
267
268 s->flags &= ~PL011_FLAG_RXFF;
269 c = s->read_fifo[s->read_pos];
270 if (s->read_count > 0) {
271 s->read_count--;
272 s->read_pos = (s->read_pos + 1) & (fifo_depth - 1);
273 }
274 if (s->read_count == 0) {
275 s->flags |= PL011_FLAG_RXFE;
276 }
277 if (s->read_count == s->read_trigger - 1) {
278 s->int_level &= ~INT_RX;
279 }
280 trace_pl011_read_fifo(s->read_count, fifo_depth);
281 s->rsr = c >> 8;
282 pl011_update(s);
283 qemu_chr_fe_accept_input(&s->chr);
284 return c;
285 }
286
287 static uint64_t pl011_read(void *opaque, hwaddr offset,
288 unsigned size)
289 {
290 PL011State *s = (PL011State *)opaque;
291 uint64_t r;
292
293 switch (offset >> 2) {
294 case 0: /* UARTDR */
295 r = pl011_read_rxdata(s);
296 break;
297 case 1: /* UARTRSR */
298 r = s->rsr;
299 break;
300 case 6: /* UARTFR */
301 r = s->flags;
302 break;
303 case 8: /* UARTILPR */
304 r = s->ilpr;
305 break;
306 case 9: /* UARTIBRD */
307 r = s->ibrd;
308 break;
309 case 10: /* UARTFBRD */
310 r = s->fbrd;
311 break;
312 case 11: /* UARTLCR_H */
313 r = s->lcr;
314 break;
315 case 12: /* UARTCR */
316 r = s->cr;
317 break;
318 case 13: /* UARTIFLS */
319 r = s->ifl;
320 break;
321 case 14: /* UARTIMSC */
322 r = s->int_enabled;
323 break;
324 case 15: /* UARTRIS */
325 r = s->int_level;
326 break;
327 case 16: /* UARTMIS */
328 r = s->int_level & s->int_enabled;
329 break;
330 case 18: /* UARTDMACR */
331 r = s->dmacr;
332 break;
333 case 0x3f8 ... 0x400:
334 r = s->id[(offset - 0xfe0) >> 2];
335 break;
336 default:
337 qemu_log_mask(LOG_GUEST_ERROR,
338 "pl011_read: Bad offset 0x%x\n", (int)offset);
339 r = 0;
340 break;
341 }
342
343 trace_pl011_read(offset, r, pl011_regname(offset));
344 return r;
345 }
346
347 static void pl011_set_read_trigger(PL011State *s)
348 {
349 #if 0
350 /* The docs say the RX interrupt is triggered when the FIFO exceeds
351 the threshold. However linux only reads the FIFO in response to an
352 interrupt. Triggering the interrupt when the FIFO is non-empty seems
353 to make things work. */
354 if (s->lcr & LCR_FEN)
355 s->read_trigger = (s->ifl >> 1) & 0x1c;
356 else
357 #endif
358 s->read_trigger = 1;
359 }
360
361 static unsigned int pl011_get_baudrate(const PL011State *s)
362 {
363 uint64_t clk;
364
365 if (s->ibrd == 0) {
366 return 0;
367 }
368
369 clk = clock_get_hz(s->clk);
370 return (clk / ((s->ibrd << 6) + s->fbrd)) << 2;
371 }
372
373 static void pl011_trace_baudrate_change(const PL011State *s)
374 {
375 trace_pl011_baudrate_change(pl011_get_baudrate(s),
376 clock_get_hz(s->clk),
377 s->ibrd, s->fbrd);
378 }
379
380 static void pl011_loopback_mdmctrl(PL011State *s)
381 {
382 uint32_t cr, fr, il;
383
384 if (!pl011_loopback_enabled(s)) {
385 return;
386 }
387
388 /*
389 * Loopback software-driven modem control outputs to modem status inputs:
390 * FR.RI <= CR.Out2
391 * FR.DCD <= CR.Out1
392 * FR.CTS <= CR.RTS
393 * FR.DSR <= CR.DTR
394 *
395 * The loopback happens immediately even if this call is triggered
396 * by setting only CR.LBE.
397 *
398 * CTS/RTS updates due to enabled hardware flow controls are not
399 * dealt with here.
400 */
401 cr = s->cr;
402 fr = s->flags & ~(PL011_FLAG_RI | PL011_FLAG_DCD |
403 PL011_FLAG_DSR | PL011_FLAG_CTS);
404 fr |= (cr & CR_OUT2) ? PL011_FLAG_RI : 0;
405 fr |= (cr & CR_OUT1) ? PL011_FLAG_DCD : 0;
406 fr |= (cr & CR_RTS) ? PL011_FLAG_CTS : 0;
407 fr |= (cr & CR_DTR) ? PL011_FLAG_DSR : 0;
408
409 /* Change interrupts based on updated FR */
410 il = s->int_level & ~(INT_DSR | INT_DCD | INT_CTS | INT_RI);
411 il |= (fr & PL011_FLAG_DSR) ? INT_DSR : 0;
412 il |= (fr & PL011_FLAG_DCD) ? INT_DCD : 0;
413 il |= (fr & PL011_FLAG_CTS) ? INT_CTS : 0;
414 il |= (fr & PL011_FLAG_RI) ? INT_RI : 0;
415
416 s->flags = fr;
417 s->int_level = il;
418 pl011_update(s);
419 }
420
421 static void pl011_loopback_break(PL011State *s, int brk_enable)
422 {
423 if (brk_enable) {
424 pl011_loopback_tx(s, DR_BE);
425 }
426 }
427
428 static inline void pl011_set_break(PL011State *s, int brk_enable)
429 {
430 qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_BREAK, &brk_enable);
431 }
432
433 static void pl011_write(void *opaque, hwaddr offset,
434 uint64_t value, unsigned size)
435 {
436 PL011State *s = (PL011State *)opaque;
437 unsigned char ch;
438
439 trace_pl011_write(offset, value, pl011_regname(offset));
440
441 switch (offset >> 2) {
442 case 0: /* UARTDR */
443 ch = value;
444 pl011_write_txdata(s, ch);
445 break;
446 case 1: /* UARTRSR/UARTECR */
447 s->rsr = 0;
448 break;
449 case 6: /* UARTFR */
450 /* Writes to Flag register are ignored. */
451 break;
452 case 8: /* UARTILPR */
453 s->ilpr = value;
454 break;
455 case 9: /* UARTIBRD */
456 s->ibrd = value & IBRD_MASK;
457 pl011_trace_baudrate_change(s);
458 break;
459 case 10: /* UARTFBRD */
460 s->fbrd = value & FBRD_MASK;
461 pl011_trace_baudrate_change(s);
462 break;
463 case 11: /* UARTLCR_H */
464 /* Reset the FIFO state on FIFO enable or disable */
465 if ((s->lcr ^ value) & LCR_FEN) {
466 pl011_reset_rx_fifo(s);
467 pl011_reset_tx_fifo(s);
468 }
469 if ((s->lcr ^ value) & LCR_BRK) {
470 bool break_enable = value & LCR_BRK;
471 pl011_set_break(s, break_enable);
472 pl011_loopback_break(s, break_enable);
473 }
474 s->lcr = value;
475 pl011_set_read_trigger(s);
476 break;
477 case 12: /* UARTCR */
478 /* ??? Need to implement the enable bit. */
479 if ((s->cr ^ value) & CR_UARTEN) {
480 /* Re-arm the log warning when the guest toggles UARTEN */
481 s->logged_disabled_uart = false;
482 }
483 s->cr = value;
484 pl011_loopback_mdmctrl(s);
485 break;
486 case 13: /* UARTIFS */
487 s->ifl = value;
488 pl011_set_read_trigger(s);
489 break;
490 case 14: /* UARTIMSC */
491 s->int_enabled = value;
492 pl011_update(s);
493 break;
494 case 17: /* UARTICR */
495 s->int_level &= ~value;
496 pl011_update(s);
497 break;
498 case 18: /* UARTDMACR */
499 s->dmacr = value;
500 if (value & 3) {
501 qemu_log_mask(LOG_UNIMP, "pl011: DMA not implemented\n");
502 }
503 break;
504 default:
505 qemu_log_mask(LOG_GUEST_ERROR,
506 "pl011_write: Bad offset 0x%x\n", (int)offset);
507 }
508 }
509
510 static int pl011_can_receive(void *opaque)
511 {
512 PL011State *s = (PL011State *)opaque;
513 unsigned fifo_depth = pl011_get_fifo_depth(s);
514 unsigned fifo_available = fifo_depth - s->read_count;
515
516 /*
517 * In theory we should check the UART and RX enable bits here and
518 * return 0 if they are not set (so the guest can't receive data
519 * until you have enabled the UART). In practice we suspect there
520 * is at least some guest code out there which has been tested only
521 * on QEMU and which never bothers to enable the UART because we
522 * historically never enforced that. So we effectively keep the
523 * UART continuously enabled regardless of the enable bits.
524 */
525
526 trace_pl011_can_receive(s->lcr, s->read_count, fifo_depth, fifo_available);
527 return fifo_available;
528 }
529
530 static void pl011_receive(void *opaque, const uint8_t *buf, int size)
531 {
532 trace_pl011_receive(size);
533 /*
534 * In loopback mode, the RX input signal is internally disconnected
535 * from the entire receiving logics; thus, all inputs are ignored,
536 * and BREAK detection on RX input signal is also not performed.
537 */
538 if (pl011_loopback_enabled(opaque)) {
539 return;
540 }
541
542 for (int i = 0; i < size; i++) {
543 pl011_fifo_rx_put(opaque, buf[i]);
544 }
545 }
546
547 static void pl011_event(void *opaque, QEMUChrEvent event)
548 {
549 if (event == CHR_EVENT_BREAK && !pl011_loopback_enabled(opaque)) {
550 pl011_fifo_rx_put(opaque, DR_BE);
551 }
552 }
553
554 static void pl011_clock_update(void *opaque, ClockEvent event)
555 {
556 PL011State *s = PL011(opaque);
557
558 pl011_trace_baudrate_change(s);
559 }
560
561 static const MemoryRegionOps pl011_ops = {
562 .read = pl011_read,
563 .write = pl011_write,
564 .endianness = DEVICE_LITTLE_ENDIAN,
565 .impl.min_access_size = 4,
566 .impl.max_access_size = 4,
567 };
568
569 static bool pl011_clock_needed(void *opaque)
570 {
571 PL011State *s = PL011(opaque);
572
573 return s->migrate_clk;
574 }
575
576 static const VMStateDescription vmstate_pl011_clock = {
577 .name = "pl011/clock",
578 .version_id = 1,
579 .minimum_version_id = 1,
580 .needed = pl011_clock_needed,
581 .fields = (const VMStateField[]) {
582 VMSTATE_CLOCK(clk, PL011State),
583 VMSTATE_END_OF_LIST()
584 }
585 };
586
587 static int pl011_post_load(void *opaque, int version_id)
588 {
589 PL011State* s = opaque;
590
591 /* Sanity-check input state */
592 if (s->read_pos >= ARRAY_SIZE(s->read_fifo) ||
593 s->read_count > ARRAY_SIZE(s->read_fifo)) {
594 return -1;
595 }
596
597 if (!pl011_is_fifo_enabled(s) && s->read_count > 0 && s->read_pos > 0) {
598 /*
599 * Older versions of PL011 didn't ensure that the single
600 * character in the FIFO in FIFO-disabled mode is in
601 * element 0 of the array; convert to follow the current
602 * code's assumptions.
603 */
604 s->read_fifo[0] = s->read_fifo[s->read_pos];
605 s->read_pos = 0;
606 }
607
608 s->ibrd &= IBRD_MASK;
609 s->fbrd &= FBRD_MASK;
610
611 return 0;
612 }
613
614 static const VMStateDescription vmstate_pl011 = {
615 .name = "pl011",
616 .version_id = 2,
617 .minimum_version_id = 2,
618 .post_load = pl011_post_load,
619 .fields = (const VMStateField[]) {
620 VMSTATE_UNUSED(sizeof(uint32_t)),
621 VMSTATE_UINT32(flags, PL011State),
622 VMSTATE_UINT32(lcr, PL011State),
623 VMSTATE_UINT32(rsr, PL011State),
624 VMSTATE_UINT32(cr, PL011State),
625 VMSTATE_UINT32(dmacr, PL011State),
626 VMSTATE_UINT32(int_enabled, PL011State),
627 VMSTATE_UINT32(int_level, PL011State),
628 VMSTATE_UINT32_ARRAY(read_fifo, PL011State, PL011_FIFO_DEPTH),
629 VMSTATE_UINT32(ilpr, PL011State),
630 VMSTATE_UINT32(ibrd, PL011State),
631 VMSTATE_UINT32(fbrd, PL011State),
632 VMSTATE_UINT32(ifl, PL011State),
633 VMSTATE_INT32(read_pos, PL011State),
634 VMSTATE_INT32(read_count, PL011State),
635 VMSTATE_INT32(read_trigger, PL011State),
636 VMSTATE_END_OF_LIST()
637 },
638 .subsections = (const VMStateDescription * const []) {
639 &vmstate_pl011_clock,
640 NULL
641 }
642 };
643
644 static const Property pl011_properties[] = {
645 DEFINE_PROP_CHR("chardev", PL011State, chr),
646 DEFINE_PROP_BOOL("migrate-clk", PL011State, migrate_clk, true),
647 };
648
649 static void pl011_init(Object *obj)
650 {
651 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
652 PL011State *s = PL011(obj);
653 int i;
654
655 memory_region_init_io(&s->iomem, OBJECT(s), &pl011_ops, s, "pl011", 0x1000);
656 sysbus_init_mmio(sbd, &s->iomem);
657 for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
658 sysbus_init_irq(sbd, &s->irq[i]);
659 }
660
661 s->clk = qdev_init_clock_in(DEVICE(obj), "clk", pl011_clock_update, s,
662 ClockUpdate);
663
664 s->id = pl011_id_arm;
665 }
666
667 static int pl011_be_change(void *opaque);
668
669 static inline void pl011_set_handlers(PL011State *s)
670 {
671 qemu_chr_fe_set_handlers(&s->chr, pl011_can_receive, pl011_receive,
672 pl011_event, pl011_be_change, s, NULL, true);
673 }
674
675 static int pl011_be_change(void *opaque)
676 {
677 PL011State *s = opaque;
678
679 pl011_set_handlers(s);
680 pl011_set_break(s, s->lcr & LCR_BRK);
681
682 return 0;
683 }
684
685 static void pl011_realize(DeviceState *dev, Error **errp)
686 {
687 PL011State *s = PL011(dev);
688
689 pl011_set_handlers(s);
690 }
691
692 static void pl011_reset(DeviceState *dev)
693 {
694 PL011State *s = PL011(dev);
695
696 s->lcr = 0;
697 s->rsr = 0;
698 s->dmacr = 0;
699 s->int_enabled = 0;
700 s->int_level = 0;
701 s->ilpr = 0;
702 s->ibrd = 0;
703 s->fbrd = 0;
704 s->read_trigger = 1;
705 s->ifl = 0x12;
706 s->cr = 0x300;
707 s->flags = 0;
708 s->logged_disabled_uart = false;
709 pl011_reset_rx_fifo(s);
710 pl011_reset_tx_fifo(s);
711 }
712
713 static void pl011_class_init(ObjectClass *oc, const void *data)
714 {
715 DeviceClass *dc = DEVICE_CLASS(oc);
716
717 dc->realize = pl011_realize;
718 device_class_set_legacy_reset(dc, pl011_reset);
719 dc->vmsd = &vmstate_pl011;
720 device_class_set_props(dc, pl011_properties);
721 }
722
723 static const TypeInfo pl011_arm_info = {
724 .name = TYPE_PL011,
725 .parent = TYPE_SYS_BUS_DEVICE,
726 .instance_size = sizeof(PL011State),
727 .instance_init = pl011_init,
728 .class_init = pl011_class_init,
729 };
730
731 static void pl011_luminary_init(Object *obj)
732 {
733 PL011State *s = PL011(obj);
734
735 s->id = pl011_id_luminary;
736 }
737
738 static const TypeInfo pl011_luminary_info = {
739 .name = TYPE_PL011_LUMINARY,
740 .parent = TYPE_PL011,
741 .instance_init = pl011_luminary_init,
742 };
743
744 static void pl011_register_types(void)
745 {
746 type_register_static(&pl011_arm_info);
747 type_register_static(&pl011_luminary_info);
748 }
749
750 type_init(pl011_register_types)