qapi: Call QAPIDoc.check() always
[qemu/kevin.git] / hw / char / pl011.c
blob855cb82d08de18750ece0a00c85f92a8c087e5df
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_TXFE 0x80
53 #define PL011_FLAG_RXFF 0x40
54 #define PL011_FLAG_TXFF 0x20
55 #define PL011_FLAG_RXFE 0x10
57 /* Data Register, UARTDR */
58 #define DR_BE (1 << 10)
60 /* Interrupt status bits in UARTRIS, UARTMIS, UARTIMSC */
61 #define INT_OE (1 << 10)
62 #define INT_BE (1 << 9)
63 #define INT_PE (1 << 8)
64 #define INT_FE (1 << 7)
65 #define INT_RT (1 << 6)
66 #define INT_TX (1 << 5)
67 #define INT_RX (1 << 4)
68 #define INT_DSR (1 << 3)
69 #define INT_DCD (1 << 2)
70 #define INT_CTS (1 << 1)
71 #define INT_RI (1 << 0)
72 #define INT_E (INT_OE | INT_BE | INT_PE | INT_FE)
73 #define INT_MS (INT_RI | INT_DSR | INT_DCD | INT_CTS)
75 /* Line Control Register, UARTLCR_H */
76 #define LCR_FEN (1 << 4)
77 #define LCR_BRK (1 << 0)
79 static const unsigned char pl011_id_arm[8] =
80 { 0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
81 static const unsigned char pl011_id_luminary[8] =
82 { 0x11, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1 };
84 static const char *pl011_regname(hwaddr offset)
86 static const char *const rname[] = {
87 [0] = "DR", [1] = "RSR", [6] = "FR", [8] = "ILPR", [9] = "IBRD",
88 [10] = "FBRD", [11] = "LCRH", [12] = "CR", [13] = "IFLS", [14] = "IMSC",
89 [15] = "RIS", [16] = "MIS", [17] = "ICR", [18] = "DMACR",
91 unsigned idx = offset >> 2;
93 if (idx < ARRAY_SIZE(rname) && rname[idx]) {
94 return rname[idx];
96 if (idx >= 0x3f8 && idx <= 0x400) {
97 return "ID";
99 return "UNKN";
102 /* Which bits in the interrupt status matter for each outbound IRQ line ? */
103 static const uint32_t irqmask[] = {
104 INT_E | INT_MS | INT_RT | INT_TX | INT_RX, /* combined IRQ */
105 INT_RX,
106 INT_TX,
107 INT_RT,
108 INT_MS,
109 INT_E,
112 static void pl011_update(PL011State *s)
114 uint32_t flags;
115 int i;
117 flags = s->int_level & s->int_enabled;
118 trace_pl011_irq_state(flags != 0);
119 for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
120 qemu_set_irq(s->irq[i], (flags & irqmask[i]) != 0);
124 static bool pl011_is_fifo_enabled(PL011State *s)
126 return (s->lcr & LCR_FEN) != 0;
129 static inline unsigned pl011_get_fifo_depth(PL011State *s)
131 /* Note: FIFO depth is expected to be power-of-2 */
132 return pl011_is_fifo_enabled(s) ? PL011_FIFO_DEPTH : 1;
135 static inline void pl011_reset_fifo(PL011State *s)
137 s->read_count = 0;
138 s->read_pos = 0;
140 /* Reset FIFO flags */
141 s->flags &= ~(PL011_FLAG_RXFF | PL011_FLAG_TXFF);
142 s->flags |= PL011_FLAG_RXFE | PL011_FLAG_TXFE;
145 static uint64_t pl011_read(void *opaque, hwaddr offset,
146 unsigned size)
148 PL011State *s = (PL011State *)opaque;
149 uint32_t c;
150 uint64_t r;
152 switch (offset >> 2) {
153 case 0: /* UARTDR */
154 s->flags &= ~PL011_FLAG_RXFF;
155 c = s->read_fifo[s->read_pos];
156 if (s->read_count > 0) {
157 s->read_count--;
158 s->read_pos = (s->read_pos + 1) & (pl011_get_fifo_depth(s) - 1);
160 if (s->read_count == 0) {
161 s->flags |= PL011_FLAG_RXFE;
163 if (s->read_count == s->read_trigger - 1)
164 s->int_level &= ~ INT_RX;
165 trace_pl011_read_fifo(s->read_count);
166 s->rsr = c >> 8;
167 pl011_update(s);
168 qemu_chr_fe_accept_input(&s->chr);
169 r = c;
170 break;
171 case 1: /* UARTRSR */
172 r = s->rsr;
173 break;
174 case 6: /* UARTFR */
175 r = s->flags;
176 break;
177 case 8: /* UARTILPR */
178 r = s->ilpr;
179 break;
180 case 9: /* UARTIBRD */
181 r = s->ibrd;
182 break;
183 case 10: /* UARTFBRD */
184 r = s->fbrd;
185 break;
186 case 11: /* UARTLCR_H */
187 r = s->lcr;
188 break;
189 case 12: /* UARTCR */
190 r = s->cr;
191 break;
192 case 13: /* UARTIFLS */
193 r = s->ifl;
194 break;
195 case 14: /* UARTIMSC */
196 r = s->int_enabled;
197 break;
198 case 15: /* UARTRIS */
199 r = s->int_level;
200 break;
201 case 16: /* UARTMIS */
202 r = s->int_level & s->int_enabled;
203 break;
204 case 18: /* UARTDMACR */
205 r = s->dmacr;
206 break;
207 case 0x3f8 ... 0x400:
208 r = s->id[(offset - 0xfe0) >> 2];
209 break;
210 default:
211 qemu_log_mask(LOG_GUEST_ERROR,
212 "pl011_read: Bad offset 0x%x\n", (int)offset);
213 r = 0;
214 break;
217 trace_pl011_read(offset, r, pl011_regname(offset));
218 return r;
221 static void pl011_set_read_trigger(PL011State *s)
223 #if 0
224 /* The docs say the RX interrupt is triggered when the FIFO exceeds
225 the threshold. However linux only reads the FIFO in response to an
226 interrupt. Triggering the interrupt when the FIFO is non-empty seems
227 to make things work. */
228 if (s->lcr & LCR_FEN)
229 s->read_trigger = (s->ifl >> 1) & 0x1c;
230 else
231 #endif
232 s->read_trigger = 1;
235 static unsigned int pl011_get_baudrate(const PL011State *s)
237 uint64_t clk;
239 if (s->ibrd == 0) {
240 return 0;
243 clk = clock_get_hz(s->clk);
244 return (clk / ((s->ibrd << 6) + s->fbrd)) << 2;
247 static void pl011_trace_baudrate_change(const PL011State *s)
249 trace_pl011_baudrate_change(pl011_get_baudrate(s),
250 clock_get_hz(s->clk),
251 s->ibrd, s->fbrd);
254 static void pl011_write(void *opaque, hwaddr offset,
255 uint64_t value, unsigned size)
257 PL011State *s = (PL011State *)opaque;
258 unsigned char ch;
260 trace_pl011_write(offset, value, pl011_regname(offset));
262 switch (offset >> 2) {
263 case 0: /* UARTDR */
264 /* ??? Check if transmitter is enabled. */
265 ch = value;
266 /* XXX this blocks entire thread. Rewrite to use
267 * qemu_chr_fe_write and background I/O callbacks */
268 qemu_chr_fe_write_all(&s->chr, &ch, 1);
269 s->int_level |= INT_TX;
270 pl011_update(s);
271 break;
272 case 1: /* UARTRSR/UARTECR */
273 s->rsr = 0;
274 break;
275 case 6: /* UARTFR */
276 /* Writes to Flag register are ignored. */
277 break;
278 case 8: /* UARTILPR */
279 s->ilpr = value;
280 break;
281 case 9: /* UARTIBRD */
282 s->ibrd = value;
283 pl011_trace_baudrate_change(s);
284 break;
285 case 10: /* UARTFBRD */
286 s->fbrd = value;
287 pl011_trace_baudrate_change(s);
288 break;
289 case 11: /* UARTLCR_H */
290 /* Reset the FIFO state on FIFO enable or disable */
291 if ((s->lcr ^ value) & LCR_FEN) {
292 pl011_reset_fifo(s);
294 if ((s->lcr ^ value) & LCR_BRK) {
295 int break_enable = value & LCR_BRK;
296 qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
297 &break_enable);
299 s->lcr = value;
300 pl011_set_read_trigger(s);
301 break;
302 case 12: /* UARTCR */
303 /* ??? Need to implement the enable and loopback bits. */
304 s->cr = value;
305 break;
306 case 13: /* UARTIFS */
307 s->ifl = value;
308 pl011_set_read_trigger(s);
309 break;
310 case 14: /* UARTIMSC */
311 s->int_enabled = value;
312 pl011_update(s);
313 break;
314 case 17: /* UARTICR */
315 s->int_level &= ~value;
316 pl011_update(s);
317 break;
318 case 18: /* UARTDMACR */
319 s->dmacr = value;
320 if (value & 3) {
321 qemu_log_mask(LOG_UNIMP, "pl011: DMA not implemented\n");
323 break;
324 default:
325 qemu_log_mask(LOG_GUEST_ERROR,
326 "pl011_write: Bad offset 0x%x\n", (int)offset);
330 static int pl011_can_receive(void *opaque)
332 PL011State *s = (PL011State *)opaque;
333 int r;
335 r = s->read_count < pl011_get_fifo_depth(s);
336 trace_pl011_can_receive(s->lcr, s->read_count, r);
337 return r;
340 static void pl011_put_fifo(void *opaque, uint32_t value)
342 PL011State *s = (PL011State *)opaque;
343 int slot;
344 unsigned pipe_depth;
346 pipe_depth = pl011_get_fifo_depth(s);
347 slot = (s->read_pos + s->read_count) & (pipe_depth - 1);
348 s->read_fifo[slot] = value;
349 s->read_count++;
350 s->flags &= ~PL011_FLAG_RXFE;
351 trace_pl011_put_fifo(value, s->read_count);
352 if (s->read_count == pipe_depth) {
353 trace_pl011_put_fifo_full();
354 s->flags |= PL011_FLAG_RXFF;
356 if (s->read_count == s->read_trigger) {
357 s->int_level |= INT_RX;
358 pl011_update(s);
362 static void pl011_receive(void *opaque, const uint8_t *buf, int size)
364 pl011_put_fifo(opaque, *buf);
367 static void pl011_event(void *opaque, QEMUChrEvent event)
369 if (event == CHR_EVENT_BREAK) {
370 pl011_put_fifo(opaque, DR_BE);
374 static void pl011_clock_update(void *opaque, ClockEvent event)
376 PL011State *s = PL011(opaque);
378 pl011_trace_baudrate_change(s);
381 static const MemoryRegionOps pl011_ops = {
382 .read = pl011_read,
383 .write = pl011_write,
384 .endianness = DEVICE_NATIVE_ENDIAN,
385 .impl.min_access_size = 4,
386 .impl.max_access_size = 4,
389 static bool pl011_clock_needed(void *opaque)
391 PL011State *s = PL011(opaque);
393 return s->migrate_clk;
396 static const VMStateDescription vmstate_pl011_clock = {
397 .name = "pl011/clock",
398 .version_id = 1,
399 .minimum_version_id = 1,
400 .needed = pl011_clock_needed,
401 .fields = (const VMStateField[]) {
402 VMSTATE_CLOCK(clk, PL011State),
403 VMSTATE_END_OF_LIST()
407 static int pl011_post_load(void *opaque, int version_id)
409 PL011State* s = opaque;
411 /* Sanity-check input state */
412 if (s->read_pos >= ARRAY_SIZE(s->read_fifo) ||
413 s->read_count > ARRAY_SIZE(s->read_fifo)) {
414 return -1;
417 if (!pl011_is_fifo_enabled(s) && s->read_count > 0 && s->read_pos > 0) {
419 * Older versions of PL011 didn't ensure that the single
420 * character in the FIFO in FIFO-disabled mode is in
421 * element 0 of the array; convert to follow the current
422 * code's assumptions.
424 s->read_fifo[0] = s->read_fifo[s->read_pos];
425 s->read_pos = 0;
428 return 0;
431 static const VMStateDescription vmstate_pl011 = {
432 .name = "pl011",
433 .version_id = 2,
434 .minimum_version_id = 2,
435 .post_load = pl011_post_load,
436 .fields = (const VMStateField[]) {
437 VMSTATE_UINT32(readbuff, PL011State),
438 VMSTATE_UINT32(flags, PL011State),
439 VMSTATE_UINT32(lcr, PL011State),
440 VMSTATE_UINT32(rsr, PL011State),
441 VMSTATE_UINT32(cr, PL011State),
442 VMSTATE_UINT32(dmacr, PL011State),
443 VMSTATE_UINT32(int_enabled, PL011State),
444 VMSTATE_UINT32(int_level, PL011State),
445 VMSTATE_UINT32_ARRAY(read_fifo, PL011State, PL011_FIFO_DEPTH),
446 VMSTATE_UINT32(ilpr, PL011State),
447 VMSTATE_UINT32(ibrd, PL011State),
448 VMSTATE_UINT32(fbrd, PL011State),
449 VMSTATE_UINT32(ifl, PL011State),
450 VMSTATE_INT32(read_pos, PL011State),
451 VMSTATE_INT32(read_count, PL011State),
452 VMSTATE_INT32(read_trigger, PL011State),
453 VMSTATE_END_OF_LIST()
455 .subsections = (const VMStateDescription * const []) {
456 &vmstate_pl011_clock,
457 NULL
461 static Property pl011_properties[] = {
462 DEFINE_PROP_CHR("chardev", PL011State, chr),
463 DEFINE_PROP_BOOL("migrate-clk", PL011State, migrate_clk, true),
464 DEFINE_PROP_END_OF_LIST(),
467 static void pl011_init(Object *obj)
469 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
470 PL011State *s = PL011(obj);
471 int i;
473 memory_region_init_io(&s->iomem, OBJECT(s), &pl011_ops, s, "pl011", 0x1000);
474 sysbus_init_mmio(sbd, &s->iomem);
475 for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
476 sysbus_init_irq(sbd, &s->irq[i]);
479 s->clk = qdev_init_clock_in(DEVICE(obj), "clk", pl011_clock_update, s,
480 ClockUpdate);
482 s->id = pl011_id_arm;
485 static void pl011_realize(DeviceState *dev, Error **errp)
487 PL011State *s = PL011(dev);
489 qemu_chr_fe_set_handlers(&s->chr, pl011_can_receive, pl011_receive,
490 pl011_event, NULL, s, NULL, true);
493 static void pl011_reset(DeviceState *dev)
495 PL011State *s = PL011(dev);
497 s->lcr = 0;
498 s->rsr = 0;
499 s->dmacr = 0;
500 s->int_enabled = 0;
501 s->int_level = 0;
502 s->ilpr = 0;
503 s->ibrd = 0;
504 s->fbrd = 0;
505 s->read_trigger = 1;
506 s->ifl = 0x12;
507 s->cr = 0x300;
508 s->flags = 0;
509 pl011_reset_fifo(s);
512 static void pl011_class_init(ObjectClass *oc, void *data)
514 DeviceClass *dc = DEVICE_CLASS(oc);
516 dc->realize = pl011_realize;
517 dc->reset = pl011_reset;
518 dc->vmsd = &vmstate_pl011;
519 device_class_set_props(dc, pl011_properties);
522 static const TypeInfo pl011_arm_info = {
523 .name = TYPE_PL011,
524 .parent = TYPE_SYS_BUS_DEVICE,
525 .instance_size = sizeof(PL011State),
526 .instance_init = pl011_init,
527 .class_init = pl011_class_init,
530 static void pl011_luminary_init(Object *obj)
532 PL011State *s = PL011(obj);
534 s->id = pl011_id_luminary;
537 static const TypeInfo pl011_luminary_info = {
538 .name = TYPE_PL011_LUMINARY,
539 .parent = TYPE_PL011,
540 .instance_init = pl011_luminary_init,
543 static void pl011_register_types(void)
545 type_register_static(&pl011_arm_info);
546 type_register_static(&pl011_luminary_info);
549 type_init(pl011_register_types)