xref: /openbmc/qemu/hw/char/pl011.c (revision f33af61dbab3b6fe0923bd829461584eaa41039e)
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/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"
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);
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         qemu_log_mask(LOG_GUEST_ERROR,
231                       "PL011 data written to disabled UART\n");
232     }
233     if (!(s->cr & CR_TXE)) {
234         qemu_log_mask(LOG_GUEST_ERROR,
235                       "PL011 data written to disabled TX UART\n");
236     }
237 
238     /*
239      * XXX this blocks entire thread. Rewrite to use
240      * qemu_chr_fe_write and background I/O callbacks
241      */
242     qemu_chr_fe_write_all(&s->chr, &data, 1);
243     pl011_loopback_tx(s, data);
244     s->int_level |= INT_TX;
245     pl011_update(s);
246 }
247 
248 static uint32_t pl011_read_rxdata(PL011State *s)
249 {
250     uint32_t c;
251 
252     s->flags &= ~PL011_FLAG_RXFF;
253     c = s->read_fifo[s->read_pos];
254     if (s->read_count > 0) {
255         s->read_count--;
256         s->read_pos = (s->read_pos + 1) & (pl011_get_fifo_depth(s) - 1);
257     }
258     if (s->read_count == 0) {
259         s->flags |= PL011_FLAG_RXFE;
260     }
261     if (s->read_count == s->read_trigger - 1) {
262         s->int_level &= ~INT_RX;
263     }
264     trace_pl011_read_fifo(s->read_count);
265     s->rsr = c >> 8;
266     pl011_update(s);
267     qemu_chr_fe_accept_input(&s->chr);
268     return c;
269 }
270 
271 static uint64_t pl011_read(void *opaque, hwaddr offset,
272                            unsigned size)
273 {
274     PL011State *s = (PL011State *)opaque;
275     uint64_t r;
276 
277     switch (offset >> 2) {
278     case 0: /* UARTDR */
279         r = pl011_read_rxdata(s);
280         break;
281     case 1: /* UARTRSR */
282         r = s->rsr;
283         break;
284     case 6: /* UARTFR */
285         r = s->flags;
286         break;
287     case 8: /* UARTILPR */
288         r = s->ilpr;
289         break;
290     case 9: /* UARTIBRD */
291         r = s->ibrd;
292         break;
293     case 10: /* UARTFBRD */
294         r = s->fbrd;
295         break;
296     case 11: /* UARTLCR_H */
297         r = s->lcr;
298         break;
299     case 12: /* UARTCR */
300         r = s->cr;
301         break;
302     case 13: /* UARTIFLS */
303         r = s->ifl;
304         break;
305     case 14: /* UARTIMSC */
306         r = s->int_enabled;
307         break;
308     case 15: /* UARTRIS */
309         r = s->int_level;
310         break;
311     case 16: /* UARTMIS */
312         r = s->int_level & s->int_enabled;
313         break;
314     case 18: /* UARTDMACR */
315         r = s->dmacr;
316         break;
317     case 0x3f8 ... 0x400:
318         r = s->id[(offset - 0xfe0) >> 2];
319         break;
320     default:
321         qemu_log_mask(LOG_GUEST_ERROR,
322                       "pl011_read: Bad offset 0x%x\n", (int)offset);
323         r = 0;
324         break;
325     }
326 
327     trace_pl011_read(offset, r, pl011_regname(offset));
328     return r;
329 }
330 
331 static void pl011_set_read_trigger(PL011State *s)
332 {
333 #if 0
334     /* The docs say the RX interrupt is triggered when the FIFO exceeds
335        the threshold.  However linux only reads the FIFO in response to an
336        interrupt.  Triggering the interrupt when the FIFO is non-empty seems
337        to make things work.  */
338     if (s->lcr & LCR_FEN)
339         s->read_trigger = (s->ifl >> 1) & 0x1c;
340     else
341 #endif
342         s->read_trigger = 1;
343 }
344 
345 static unsigned int pl011_get_baudrate(const PL011State *s)
346 {
347     uint64_t clk;
348 
349     if (s->ibrd == 0) {
350         return 0;
351     }
352 
353     clk = clock_get_hz(s->clk);
354     return (clk / ((s->ibrd << 6) + s->fbrd)) << 2;
355 }
356 
357 static void pl011_trace_baudrate_change(const PL011State *s)
358 {
359     trace_pl011_baudrate_change(pl011_get_baudrate(s),
360                                 clock_get_hz(s->clk),
361                                 s->ibrd, s->fbrd);
362 }
363 
364 static void pl011_loopback_mdmctrl(PL011State *s)
365 {
366     uint32_t cr, fr, il;
367 
368     if (!pl011_loopback_enabled(s)) {
369         return;
370     }
371 
372     /*
373      * Loopback software-driven modem control outputs to modem status inputs:
374      *   FR.RI  <= CR.Out2
375      *   FR.DCD <= CR.Out1
376      *   FR.CTS <= CR.RTS
377      *   FR.DSR <= CR.DTR
378      *
379      * The loopback happens immediately even if this call is triggered
380      * by setting only CR.LBE.
381      *
382      * CTS/RTS updates due to enabled hardware flow controls are not
383      * dealt with here.
384      */
385     cr = s->cr;
386     fr = s->flags & ~(PL011_FLAG_RI | PL011_FLAG_DCD |
387                       PL011_FLAG_DSR | PL011_FLAG_CTS);
388     fr |= (cr & CR_OUT2) ? PL011_FLAG_RI  : 0;
389     fr |= (cr & CR_OUT1) ? PL011_FLAG_DCD : 0;
390     fr |= (cr & CR_RTS)  ? PL011_FLAG_CTS : 0;
391     fr |= (cr & CR_DTR)  ? PL011_FLAG_DSR : 0;
392 
393     /* Change interrupts based on updated FR */
394     il = s->int_level & ~(INT_DSR | INT_DCD | INT_CTS | INT_RI);
395     il |= (fr & PL011_FLAG_DSR) ? INT_DSR : 0;
396     il |= (fr & PL011_FLAG_DCD) ? INT_DCD : 0;
397     il |= (fr & PL011_FLAG_CTS) ? INT_CTS : 0;
398     il |= (fr & PL011_FLAG_RI)  ? INT_RI  : 0;
399 
400     s->flags = fr;
401     s->int_level = il;
402     pl011_update(s);
403 }
404 
405 static void pl011_loopback_break(PL011State *s, int brk_enable)
406 {
407     if (brk_enable) {
408         pl011_loopback_tx(s, DR_BE);
409     }
410 }
411 
412 static void pl011_write(void *opaque, hwaddr offset,
413                         uint64_t value, unsigned size)
414 {
415     PL011State *s = (PL011State *)opaque;
416     unsigned char ch;
417 
418     trace_pl011_write(offset, value, pl011_regname(offset));
419 
420     switch (offset >> 2) {
421     case 0: /* UARTDR */
422         ch = value;
423         pl011_write_txdata(s, ch);
424         break;
425     case 1: /* UARTRSR/UARTECR */
426         s->rsr = 0;
427         break;
428     case 6: /* UARTFR */
429         /* Writes to Flag register are ignored.  */
430         break;
431     case 8: /* UARTILPR */
432         s->ilpr = value;
433         break;
434     case 9: /* UARTIBRD */
435         s->ibrd = value & IBRD_MASK;
436         pl011_trace_baudrate_change(s);
437         break;
438     case 10: /* UARTFBRD */
439         s->fbrd = value & FBRD_MASK;
440         pl011_trace_baudrate_change(s);
441         break;
442     case 11: /* UARTLCR_H */
443         /* Reset the FIFO state on FIFO enable or disable */
444         if ((s->lcr ^ value) & LCR_FEN) {
445             pl011_reset_rx_fifo(s);
446             pl011_reset_tx_fifo(s);
447         }
448         if ((s->lcr ^ value) & LCR_BRK) {
449             int break_enable = value & LCR_BRK;
450             qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
451                               &break_enable);
452             pl011_loopback_break(s, break_enable);
453         }
454         s->lcr = value;
455         pl011_set_read_trigger(s);
456         break;
457     case 12: /* UARTCR */
458         /* ??? Need to implement the enable bit.  */
459         s->cr = value;
460         pl011_loopback_mdmctrl(s);
461         break;
462     case 13: /* UARTIFS */
463         s->ifl = value;
464         pl011_set_read_trigger(s);
465         break;
466     case 14: /* UARTIMSC */
467         s->int_enabled = value;
468         pl011_update(s);
469         break;
470     case 17: /* UARTICR */
471         s->int_level &= ~value;
472         pl011_update(s);
473         break;
474     case 18: /* UARTDMACR */
475         s->dmacr = value;
476         if (value & 3) {
477             qemu_log_mask(LOG_UNIMP, "pl011: DMA not implemented\n");
478         }
479         break;
480     default:
481         qemu_log_mask(LOG_GUEST_ERROR,
482                       "pl011_write: Bad offset 0x%x\n", (int)offset);
483     }
484 }
485 
486 static int pl011_can_receive(void *opaque)
487 {
488     PL011State *s = (PL011State *)opaque;
489     unsigned fifo_depth = pl011_get_fifo_depth(s);
490     unsigned fifo_available = fifo_depth - s->read_count;
491     int r = fifo_available ? 1 : 0;
492 
493     if (!(s->cr & CR_UARTEN)) {
494         qemu_log_mask(LOG_GUEST_ERROR,
495                       "PL011 receiving data on disabled UART\n");
496     }
497     if (!(s->cr & CR_RXE)) {
498         qemu_log_mask(LOG_GUEST_ERROR,
499                       "PL011 receiving data on disabled RX UART\n");
500     }
501     trace_pl011_can_receive(s->lcr, s->read_count, r);
502     return r;
503 }
504 
505 static void pl011_receive(void *opaque, const uint8_t *buf, int size)
506 {
507     /*
508      * In loopback mode, the RX input signal is internally disconnected
509      * from the entire receiving logics; thus, all inputs are ignored,
510      * and BREAK detection on RX input signal is also not performed.
511      */
512     if (pl011_loopback_enabled(opaque)) {
513         return;
514     }
515 
516     pl011_fifo_rx_put(opaque, *buf);
517 }
518 
519 static void pl011_event(void *opaque, QEMUChrEvent event)
520 {
521     if (event == CHR_EVENT_BREAK && !pl011_loopback_enabled(opaque)) {
522         pl011_fifo_rx_put(opaque, DR_BE);
523     }
524 }
525 
526 static void pl011_clock_update(void *opaque, ClockEvent event)
527 {
528     PL011State *s = PL011(opaque);
529 
530     pl011_trace_baudrate_change(s);
531 }
532 
533 static const MemoryRegionOps pl011_ops = {
534     .read = pl011_read,
535     .write = pl011_write,
536     .endianness = DEVICE_NATIVE_ENDIAN,
537     .impl.min_access_size = 4,
538     .impl.max_access_size = 4,
539 };
540 
541 static bool pl011_clock_needed(void *opaque)
542 {
543     PL011State *s = PL011(opaque);
544 
545     return s->migrate_clk;
546 }
547 
548 static const VMStateDescription vmstate_pl011_clock = {
549     .name = "pl011/clock",
550     .version_id = 1,
551     .minimum_version_id = 1,
552     .needed = pl011_clock_needed,
553     .fields = (const VMStateField[]) {
554         VMSTATE_CLOCK(clk, PL011State),
555         VMSTATE_END_OF_LIST()
556     }
557 };
558 
559 static int pl011_post_load(void *opaque, int version_id)
560 {
561     PL011State* s = opaque;
562 
563     /* Sanity-check input state */
564     if (s->read_pos >= ARRAY_SIZE(s->read_fifo) ||
565         s->read_count > ARRAY_SIZE(s->read_fifo)) {
566         return -1;
567     }
568 
569     if (!pl011_is_fifo_enabled(s) && s->read_count > 0 && s->read_pos > 0) {
570         /*
571          * Older versions of PL011 didn't ensure that the single
572          * character in the FIFO in FIFO-disabled mode is in
573          * element 0 of the array; convert to follow the current
574          * code's assumptions.
575          */
576         s->read_fifo[0] = s->read_fifo[s->read_pos];
577         s->read_pos = 0;
578     }
579 
580     s->ibrd &= IBRD_MASK;
581     s->fbrd &= FBRD_MASK;
582 
583     return 0;
584 }
585 
586 static const VMStateDescription vmstate_pl011 = {
587     .name = "pl011",
588     .version_id = 2,
589     .minimum_version_id = 2,
590     .post_load = pl011_post_load,
591     .fields = (const VMStateField[]) {
592         VMSTATE_UNUSED(sizeof(uint32_t)),
593         VMSTATE_UINT32(flags, PL011State),
594         VMSTATE_UINT32(lcr, PL011State),
595         VMSTATE_UINT32(rsr, PL011State),
596         VMSTATE_UINT32(cr, PL011State),
597         VMSTATE_UINT32(dmacr, PL011State),
598         VMSTATE_UINT32(int_enabled, PL011State),
599         VMSTATE_UINT32(int_level, PL011State),
600         VMSTATE_UINT32_ARRAY(read_fifo, PL011State, PL011_FIFO_DEPTH),
601         VMSTATE_UINT32(ilpr, PL011State),
602         VMSTATE_UINT32(ibrd, PL011State),
603         VMSTATE_UINT32(fbrd, PL011State),
604         VMSTATE_UINT32(ifl, PL011State),
605         VMSTATE_INT32(read_pos, PL011State),
606         VMSTATE_INT32(read_count, PL011State),
607         VMSTATE_INT32(read_trigger, PL011State),
608         VMSTATE_END_OF_LIST()
609     },
610     .subsections = (const VMStateDescription * const []) {
611         &vmstate_pl011_clock,
612         NULL
613     }
614 };
615 
616 static const Property pl011_properties[] = {
617     DEFINE_PROP_CHR("chardev", PL011State, chr),
618     DEFINE_PROP_BOOL("migrate-clk", PL011State, migrate_clk, true),
619 };
620 
621 static void pl011_init(Object *obj)
622 {
623     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
624     PL011State *s = PL011(obj);
625     int i;
626 
627     memory_region_init_io(&s->iomem, OBJECT(s), &pl011_ops, s, "pl011", 0x1000);
628     sysbus_init_mmio(sbd, &s->iomem);
629     for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
630         sysbus_init_irq(sbd, &s->irq[i]);
631     }
632 
633     s->clk = qdev_init_clock_in(DEVICE(obj), "clk", pl011_clock_update, s,
634                                 ClockUpdate);
635 
636     s->id = pl011_id_arm;
637 }
638 
639 static void pl011_realize(DeviceState *dev, Error **errp)
640 {
641     PL011State *s = PL011(dev);
642 
643     qemu_chr_fe_set_handlers(&s->chr, pl011_can_receive, pl011_receive,
644                              pl011_event, NULL, s, NULL, true);
645 }
646 
647 static void pl011_reset(DeviceState *dev)
648 {
649     PL011State *s = PL011(dev);
650 
651     s->lcr = 0;
652     s->rsr = 0;
653     s->dmacr = 0;
654     s->int_enabled = 0;
655     s->int_level = 0;
656     s->ilpr = 0;
657     s->ibrd = 0;
658     s->fbrd = 0;
659     s->read_trigger = 1;
660     s->ifl = 0x12;
661     s->cr = 0x300;
662     s->flags = 0;
663     pl011_reset_rx_fifo(s);
664     pl011_reset_tx_fifo(s);
665 }
666 
667 static void pl011_class_init(ObjectClass *oc, void *data)
668 {
669     DeviceClass *dc = DEVICE_CLASS(oc);
670 
671     dc->realize = pl011_realize;
672     device_class_set_legacy_reset(dc, pl011_reset);
673     dc->vmsd = &vmstate_pl011;
674     device_class_set_props(dc, pl011_properties);
675 }
676 
677 static const TypeInfo pl011_arm_info = {
678     .name          = TYPE_PL011,
679     .parent        = TYPE_SYS_BUS_DEVICE,
680     .instance_size = sizeof(PL011State),
681     .instance_init = pl011_init,
682     .class_init    = pl011_class_init,
683 };
684 
685 static void pl011_luminary_init(Object *obj)
686 {
687     PL011State *s = PL011(obj);
688 
689     s->id = pl011_id_luminary;
690 }
691 
692 static const TypeInfo pl011_luminary_info = {
693     .name          = TYPE_PL011_LUMINARY,
694     .parent        = TYPE_PL011,
695     .instance_init = pl011_luminary_init,
696 };
697 
698 static void pl011_register_types(void)
699 {
700     type_register_static(&pl011_arm_info);
701     type_register_static(&pl011_luminary_info);
702 }
703 
704 type_init(pl011_register_types)
705