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