Update version for v9.0.0-rc0 release
[qemu/kevin.git] / hw / char / pl011.c
blob8753b84a84278fecba0f0e2eb5b0073cfc67fc2e
1 /*
2 * Arm PrimeCell PL011 UART
4 * Copyright (c) 2006 CodeSourcery.
5 * Written by Paul Brook
7 * This code is licensed under the GPL.
8 */
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)
21 #include "qemu/osdep.h"
22 #include "qapi/error.h"
23 #include "hw/char/pl011.h"
24 #include "hw/irq.h"
25 #include "hw/sysbus.h"
26 #include "hw/qdev-clock.h"
27 #include "hw/qdev-properties.h"
28 #include "hw/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"
36 DeviceState *pl011_create(hwaddr addr, qemu_irq irq, Chardev *chr)
38 DeviceState *dev;
39 SysBusDevice *s;
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);
48 return dev;
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
61 /* Data Register, UARTDR */
62 #define DR_BE (1 << 10)
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)
79 /* Line Control Register, UARTLCR_H */
80 #define LCR_FEN (1 << 4)
81 #define LCR_BRK (1 << 0)
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_LBE (1 << 7)
90 static const unsigned char pl011_id_arm[8] =
91 { 0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
92 static const unsigned char pl011_id_luminary[8] =
93 { 0x11, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1 };
95 static const char *pl011_regname(hwaddr offset)
97 static const char *const rname[] = {
98 [0] = "DR", [1] = "RSR", [6] = "FR", [8] = "ILPR", [9] = "IBRD",
99 [10] = "FBRD", [11] = "LCRH", [12] = "CR", [13] = "IFLS", [14] = "IMSC",
100 [15] = "RIS", [16] = "MIS", [17] = "ICR", [18] = "DMACR",
102 unsigned idx = offset >> 2;
104 if (idx < ARRAY_SIZE(rname) && rname[idx]) {
105 return rname[idx];
107 if (idx >= 0x3f8 && idx <= 0x400) {
108 return "ID";
110 return "UNKN";
113 /* Which bits in the interrupt status matter for each outbound IRQ line ? */
114 static const uint32_t irqmask[] = {
115 INT_E | INT_MS | INT_RT | INT_TX | INT_RX, /* combined IRQ */
116 INT_RX,
117 INT_TX,
118 INT_RT,
119 INT_MS,
120 INT_E,
123 static void pl011_update(PL011State *s)
125 uint32_t flags;
126 int i;
128 flags = s->int_level & s->int_enabled;
129 trace_pl011_irq_state(flags != 0);
130 for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
131 qemu_set_irq(s->irq[i], (flags & irqmask[i]) != 0);
135 static bool pl011_is_fifo_enabled(PL011State *s)
137 return (s->lcr & LCR_FEN) != 0;
140 static inline unsigned pl011_get_fifo_depth(PL011State *s)
142 /* Note: FIFO depth is expected to be power-of-2 */
143 return pl011_is_fifo_enabled(s) ? PL011_FIFO_DEPTH : 1;
146 static inline void pl011_reset_fifo(PL011State *s)
148 s->read_count = 0;
149 s->read_pos = 0;
151 /* Reset FIFO flags */
152 s->flags &= ~(PL011_FLAG_RXFF | PL011_FLAG_TXFF);
153 s->flags |= PL011_FLAG_RXFE | PL011_FLAG_TXFE;
156 static uint64_t pl011_read(void *opaque, hwaddr offset,
157 unsigned size)
159 PL011State *s = (PL011State *)opaque;
160 uint32_t c;
161 uint64_t r;
163 switch (offset >> 2) {
164 case 0: /* UARTDR */
165 s->flags &= ~PL011_FLAG_RXFF;
166 c = s->read_fifo[s->read_pos];
167 if (s->read_count > 0) {
168 s->read_count--;
169 s->read_pos = (s->read_pos + 1) & (pl011_get_fifo_depth(s) - 1);
171 if (s->read_count == 0) {
172 s->flags |= PL011_FLAG_RXFE;
174 if (s->read_count == s->read_trigger - 1)
175 s->int_level &= ~ INT_RX;
176 trace_pl011_read_fifo(s->read_count);
177 s->rsr = c >> 8;
178 pl011_update(s);
179 qemu_chr_fe_accept_input(&s->chr);
180 r = c;
181 break;
182 case 1: /* UARTRSR */
183 r = s->rsr;
184 break;
185 case 6: /* UARTFR */
186 r = s->flags;
187 break;
188 case 8: /* UARTILPR */
189 r = s->ilpr;
190 break;
191 case 9: /* UARTIBRD */
192 r = s->ibrd;
193 break;
194 case 10: /* UARTFBRD */
195 r = s->fbrd;
196 break;
197 case 11: /* UARTLCR_H */
198 r = s->lcr;
199 break;
200 case 12: /* UARTCR */
201 r = s->cr;
202 break;
203 case 13: /* UARTIFLS */
204 r = s->ifl;
205 break;
206 case 14: /* UARTIMSC */
207 r = s->int_enabled;
208 break;
209 case 15: /* UARTRIS */
210 r = s->int_level;
211 break;
212 case 16: /* UARTMIS */
213 r = s->int_level & s->int_enabled;
214 break;
215 case 18: /* UARTDMACR */
216 r = s->dmacr;
217 break;
218 case 0x3f8 ... 0x400:
219 r = s->id[(offset - 0xfe0) >> 2];
220 break;
221 default:
222 qemu_log_mask(LOG_GUEST_ERROR,
223 "pl011_read: Bad offset 0x%x\n", (int)offset);
224 r = 0;
225 break;
228 trace_pl011_read(offset, r, pl011_regname(offset));
229 return r;
232 static void pl011_set_read_trigger(PL011State *s)
234 #if 0
235 /* The docs say the RX interrupt is triggered when the FIFO exceeds
236 the threshold. However linux only reads the FIFO in response to an
237 interrupt. Triggering the interrupt when the FIFO is non-empty seems
238 to make things work. */
239 if (s->lcr & LCR_FEN)
240 s->read_trigger = (s->ifl >> 1) & 0x1c;
241 else
242 #endif
243 s->read_trigger = 1;
246 static unsigned int pl011_get_baudrate(const PL011State *s)
248 uint64_t clk;
250 if (s->ibrd == 0) {
251 return 0;
254 clk = clock_get_hz(s->clk);
255 return (clk / ((s->ibrd << 6) + s->fbrd)) << 2;
258 static void pl011_trace_baudrate_change(const PL011State *s)
260 trace_pl011_baudrate_change(pl011_get_baudrate(s),
261 clock_get_hz(s->clk),
262 s->ibrd, s->fbrd);
265 static bool pl011_loopback_enabled(PL011State *s)
267 return !!(s->cr & CR_LBE);
270 static void pl011_loopback_mdmctrl(PL011State *s)
272 uint32_t cr, fr, il;
274 if (!pl011_loopback_enabled(s)) {
275 return;
279 * Loopback software-driven modem control outputs to modem status inputs:
280 * FR.RI <= CR.Out2
281 * FR.DCD <= CR.Out1
282 * FR.CTS <= CR.RTS
283 * FR.DSR <= CR.DTR
285 * The loopback happens immediately even if this call is triggered
286 * by setting only CR.LBE.
288 * CTS/RTS updates due to enabled hardware flow controls are not
289 * dealt with here.
291 cr = s->cr;
292 fr = s->flags & ~(PL011_FLAG_RI | PL011_FLAG_DCD |
293 PL011_FLAG_DSR | PL011_FLAG_CTS);
294 fr |= (cr & CR_OUT2) ? PL011_FLAG_RI : 0;
295 fr |= (cr & CR_OUT1) ? PL011_FLAG_DCD : 0;
296 fr |= (cr & CR_RTS) ? PL011_FLAG_CTS : 0;
297 fr |= (cr & CR_DTR) ? PL011_FLAG_DSR : 0;
299 /* Change interrupts based on updated FR */
300 il = s->int_level & ~(INT_DSR | INT_DCD | INT_CTS | INT_RI);
301 il |= (fr & PL011_FLAG_DSR) ? INT_DSR : 0;
302 il |= (fr & PL011_FLAG_DCD) ? INT_DCD : 0;
303 il |= (fr & PL011_FLAG_CTS) ? INT_CTS : 0;
304 il |= (fr & PL011_FLAG_RI) ? INT_RI : 0;
306 s->flags = fr;
307 s->int_level = il;
308 pl011_update(s);
311 static void pl011_put_fifo(void *opaque, uint32_t value);
313 static void pl011_loopback_tx(PL011State *s, uint32_t value)
315 if (!pl011_loopback_enabled(s)) {
316 return;
320 * Caveat:
322 * In real hardware, TX loopback happens at the serial-bit level
323 * and then reassembled by the RX logics back into bytes and placed
324 * into the RX fifo. That is, loopback happens after TX fifo.
326 * Because the real hardware TX fifo is time-drained at the frame
327 * rate governed by the configured serial format, some loopback
328 * bytes in TX fifo may still be able to get into the RX fifo
329 * that could be full at times while being drained at software
330 * pace.
332 * In such scenario, the RX draining pace is the major factor
333 * deciding which loopback bytes get into the RX fifo, unless
334 * hardware flow-control is enabled.
336 * For simplicity, the above described is not emulated.
338 pl011_put_fifo(s, value);
341 static void pl011_loopback_break(PL011State *s, int brk_enable)
343 if (brk_enable) {
344 pl011_loopback_tx(s, DR_BE);
348 static void pl011_write(void *opaque, hwaddr offset,
349 uint64_t value, unsigned size)
351 PL011State *s = (PL011State *)opaque;
352 unsigned char ch;
354 trace_pl011_write(offset, value, pl011_regname(offset));
356 switch (offset >> 2) {
357 case 0: /* UARTDR */
358 /* ??? Check if transmitter is enabled. */
359 ch = value;
360 /* XXX this blocks entire thread. Rewrite to use
361 * qemu_chr_fe_write and background I/O callbacks */
362 qemu_chr_fe_write_all(&s->chr, &ch, 1);
363 pl011_loopback_tx(s, ch);
364 s->int_level |= INT_TX;
365 pl011_update(s);
366 break;
367 case 1: /* UARTRSR/UARTECR */
368 s->rsr = 0;
369 break;
370 case 6: /* UARTFR */
371 /* Writes to Flag register are ignored. */
372 break;
373 case 8: /* UARTILPR */
374 s->ilpr = value;
375 break;
376 case 9: /* UARTIBRD */
377 s->ibrd = value;
378 pl011_trace_baudrate_change(s);
379 break;
380 case 10: /* UARTFBRD */
381 s->fbrd = value;
382 pl011_trace_baudrate_change(s);
383 break;
384 case 11: /* UARTLCR_H */
385 /* Reset the FIFO state on FIFO enable or disable */
386 if ((s->lcr ^ value) & LCR_FEN) {
387 pl011_reset_fifo(s);
389 if ((s->lcr ^ value) & LCR_BRK) {
390 int break_enable = value & LCR_BRK;
391 qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
392 &break_enable);
393 pl011_loopback_break(s, break_enable);
395 s->lcr = value;
396 pl011_set_read_trigger(s);
397 break;
398 case 12: /* UARTCR */
399 /* ??? Need to implement the enable bit. */
400 s->cr = value;
401 pl011_loopback_mdmctrl(s);
402 break;
403 case 13: /* UARTIFS */
404 s->ifl = value;
405 pl011_set_read_trigger(s);
406 break;
407 case 14: /* UARTIMSC */
408 s->int_enabled = value;
409 pl011_update(s);
410 break;
411 case 17: /* UARTICR */
412 s->int_level &= ~value;
413 pl011_update(s);
414 break;
415 case 18: /* UARTDMACR */
416 s->dmacr = value;
417 if (value & 3) {
418 qemu_log_mask(LOG_UNIMP, "pl011: DMA not implemented\n");
420 break;
421 default:
422 qemu_log_mask(LOG_GUEST_ERROR,
423 "pl011_write: Bad offset 0x%x\n", (int)offset);
427 static int pl011_can_receive(void *opaque)
429 PL011State *s = (PL011State *)opaque;
430 int r;
432 r = s->read_count < pl011_get_fifo_depth(s);
433 trace_pl011_can_receive(s->lcr, s->read_count, r);
434 return r;
437 static void pl011_put_fifo(void *opaque, uint32_t value)
439 PL011State *s = (PL011State *)opaque;
440 int slot;
441 unsigned pipe_depth;
443 pipe_depth = pl011_get_fifo_depth(s);
444 slot = (s->read_pos + s->read_count) & (pipe_depth - 1);
445 s->read_fifo[slot] = value;
446 s->read_count++;
447 s->flags &= ~PL011_FLAG_RXFE;
448 trace_pl011_put_fifo(value, s->read_count);
449 if (s->read_count == pipe_depth) {
450 trace_pl011_put_fifo_full();
451 s->flags |= PL011_FLAG_RXFF;
453 if (s->read_count == s->read_trigger) {
454 s->int_level |= INT_RX;
455 pl011_update(s);
459 static void pl011_receive(void *opaque, const uint8_t *buf, int size)
462 * In loopback mode, the RX input signal is internally disconnected
463 * from the entire receiving logics; thus, all inputs are ignored,
464 * and BREAK detection on RX input signal is also not performed.
466 if (pl011_loopback_enabled(opaque)) {
467 return;
470 pl011_put_fifo(opaque, *buf);
473 static void pl011_event(void *opaque, QEMUChrEvent event)
475 if (event == CHR_EVENT_BREAK && !pl011_loopback_enabled(opaque)) {
476 pl011_put_fifo(opaque, DR_BE);
480 static void pl011_clock_update(void *opaque, ClockEvent event)
482 PL011State *s = PL011(opaque);
484 pl011_trace_baudrate_change(s);
487 static const MemoryRegionOps pl011_ops = {
488 .read = pl011_read,
489 .write = pl011_write,
490 .endianness = DEVICE_NATIVE_ENDIAN,
491 .impl.min_access_size = 4,
492 .impl.max_access_size = 4,
495 static bool pl011_clock_needed(void *opaque)
497 PL011State *s = PL011(opaque);
499 return s->migrate_clk;
502 static const VMStateDescription vmstate_pl011_clock = {
503 .name = "pl011/clock",
504 .version_id = 1,
505 .minimum_version_id = 1,
506 .needed = pl011_clock_needed,
507 .fields = (const VMStateField[]) {
508 VMSTATE_CLOCK(clk, PL011State),
509 VMSTATE_END_OF_LIST()
513 static int pl011_post_load(void *opaque, int version_id)
515 PL011State* s = opaque;
517 /* Sanity-check input state */
518 if (s->read_pos >= ARRAY_SIZE(s->read_fifo) ||
519 s->read_count > ARRAY_SIZE(s->read_fifo)) {
520 return -1;
523 if (!pl011_is_fifo_enabled(s) && s->read_count > 0 && s->read_pos > 0) {
525 * Older versions of PL011 didn't ensure that the single
526 * character in the FIFO in FIFO-disabled mode is in
527 * element 0 of the array; convert to follow the current
528 * code's assumptions.
530 s->read_fifo[0] = s->read_fifo[s->read_pos];
531 s->read_pos = 0;
534 return 0;
537 static const VMStateDescription vmstate_pl011 = {
538 .name = "pl011",
539 .version_id = 2,
540 .minimum_version_id = 2,
541 .post_load = pl011_post_load,
542 .fields = (const VMStateField[]) {
543 VMSTATE_UINT32(readbuff, PL011State),
544 VMSTATE_UINT32(flags, PL011State),
545 VMSTATE_UINT32(lcr, PL011State),
546 VMSTATE_UINT32(rsr, PL011State),
547 VMSTATE_UINT32(cr, PL011State),
548 VMSTATE_UINT32(dmacr, PL011State),
549 VMSTATE_UINT32(int_enabled, PL011State),
550 VMSTATE_UINT32(int_level, PL011State),
551 VMSTATE_UINT32_ARRAY(read_fifo, PL011State, PL011_FIFO_DEPTH),
552 VMSTATE_UINT32(ilpr, PL011State),
553 VMSTATE_UINT32(ibrd, PL011State),
554 VMSTATE_UINT32(fbrd, PL011State),
555 VMSTATE_UINT32(ifl, PL011State),
556 VMSTATE_INT32(read_pos, PL011State),
557 VMSTATE_INT32(read_count, PL011State),
558 VMSTATE_INT32(read_trigger, PL011State),
559 VMSTATE_END_OF_LIST()
561 .subsections = (const VMStateDescription * const []) {
562 &vmstate_pl011_clock,
563 NULL
567 static Property pl011_properties[] = {
568 DEFINE_PROP_CHR("chardev", PL011State, chr),
569 DEFINE_PROP_BOOL("migrate-clk", PL011State, migrate_clk, true),
570 DEFINE_PROP_END_OF_LIST(),
573 static void pl011_init(Object *obj)
575 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
576 PL011State *s = PL011(obj);
577 int i;
579 memory_region_init_io(&s->iomem, OBJECT(s), &pl011_ops, s, "pl011", 0x1000);
580 sysbus_init_mmio(sbd, &s->iomem);
581 for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
582 sysbus_init_irq(sbd, &s->irq[i]);
585 s->clk = qdev_init_clock_in(DEVICE(obj), "clk", pl011_clock_update, s,
586 ClockUpdate);
588 s->id = pl011_id_arm;
591 static void pl011_realize(DeviceState *dev, Error **errp)
593 PL011State *s = PL011(dev);
595 qemu_chr_fe_set_handlers(&s->chr, pl011_can_receive, pl011_receive,
596 pl011_event, NULL, s, NULL, true);
599 static void pl011_reset(DeviceState *dev)
601 PL011State *s = PL011(dev);
603 s->lcr = 0;
604 s->rsr = 0;
605 s->dmacr = 0;
606 s->int_enabled = 0;
607 s->int_level = 0;
608 s->ilpr = 0;
609 s->ibrd = 0;
610 s->fbrd = 0;
611 s->read_trigger = 1;
612 s->ifl = 0x12;
613 s->cr = 0x300;
614 s->flags = 0;
615 pl011_reset_fifo(s);
618 static void pl011_class_init(ObjectClass *oc, void *data)
620 DeviceClass *dc = DEVICE_CLASS(oc);
622 dc->realize = pl011_realize;
623 dc->reset = pl011_reset;
624 dc->vmsd = &vmstate_pl011;
625 device_class_set_props(dc, pl011_properties);
628 static const TypeInfo pl011_arm_info = {
629 .name = TYPE_PL011,
630 .parent = TYPE_SYS_BUS_DEVICE,
631 .instance_size = sizeof(PL011State),
632 .instance_init = pl011_init,
633 .class_init = pl011_class_init,
636 static void pl011_luminary_init(Object *obj)
638 PL011State *s = PL011(obj);
640 s->id = pl011_id_luminary;
643 static const TypeInfo pl011_luminary_info = {
644 .name = TYPE_PL011_LUMINARY,
645 .parent = TYPE_PL011,
646 .instance_init = pl011_luminary_init,
649 static void pl011_register_types(void)
651 type_register_static(&pl011_arm_info);
652 type_register_static(&pl011_luminary_info);
655 type_init(pl011_register_types)