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_TXFE 0x80 53 #define PL011_FLAG_RXFF 0x40 54 #define PL011_FLAG_TXFF 0x20 55 #define PL011_FLAG_RXFE 0x10 56 57 /* Data Register, UARTDR */ 58 #define DR_BE (1 << 10) 59 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) 74 75 /* Line Control Register, UARTLCR_H */ 76 #define LCR_FEN (1 << 4) 77 #define LCR_BRK (1 << 0) 78 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 }; 83 84 static const char *pl011_regname(hwaddr offset) 85 { 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", 90 }; 91 unsigned idx = offset >> 2; 92 93 if (idx < ARRAY_SIZE(rname) && rname[idx]) { 94 return rname[idx]; 95 } 96 if (idx >= 0x3f8 && idx <= 0x400) { 97 return "ID"; 98 } 99 return "UNKN"; 100 } 101 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, 110 }; 111 112 static void pl011_update(PL011State *s) 113 { 114 uint32_t flags; 115 int i; 116 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); 121 } 122 } 123 124 static bool pl011_is_fifo_enabled(PL011State *s) 125 { 126 return (s->lcr & LCR_FEN) != 0; 127 } 128 129 static inline unsigned pl011_get_fifo_depth(PL011State *s) 130 { 131 /* Note: FIFO depth is expected to be power-of-2 */ 132 return pl011_is_fifo_enabled(s) ? PL011_FIFO_DEPTH : 1; 133 } 134 135 static inline void pl011_reset_fifo(PL011State *s) 136 { 137 s->read_count = 0; 138 s->read_pos = 0; 139 140 /* Reset FIFO flags */ 141 s->flags &= ~(PL011_FLAG_RXFF | PL011_FLAG_TXFF); 142 s->flags |= PL011_FLAG_RXFE | PL011_FLAG_TXFE; 143 } 144 145 static uint64_t pl011_read(void *opaque, hwaddr offset, 146 unsigned size) 147 { 148 PL011State *s = (PL011State *)opaque; 149 uint32_t c; 150 uint64_t r; 151 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); 159 } 160 if (s->read_count == 0) { 161 s->flags |= PL011_FLAG_RXFE; 162 } 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; 215 } 216 217 trace_pl011_read(offset, r, pl011_regname(offset)); 218 return r; 219 } 220 221 static void pl011_set_read_trigger(PL011State *s) 222 { 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; 233 } 234 235 static unsigned int pl011_get_baudrate(const PL011State *s) 236 { 237 uint64_t clk; 238 239 if (s->ibrd == 0) { 240 return 0; 241 } 242 243 clk = clock_get_hz(s->clk); 244 return (clk / ((s->ibrd << 6) + s->fbrd)) << 2; 245 } 246 247 static void pl011_trace_baudrate_change(const PL011State *s) 248 { 249 trace_pl011_baudrate_change(pl011_get_baudrate(s), 250 clock_get_hz(s->clk), 251 s->ibrd, s->fbrd); 252 } 253 254 static void pl011_write(void *opaque, hwaddr offset, 255 uint64_t value, unsigned size) 256 { 257 PL011State *s = (PL011State *)opaque; 258 unsigned char ch; 259 260 trace_pl011_write(offset, value, pl011_regname(offset)); 261 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); 293 } 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); 298 } 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"); 322 } 323 break; 324 default: 325 qemu_log_mask(LOG_GUEST_ERROR, 326 "pl011_write: Bad offset 0x%x\n", (int)offset); 327 } 328 } 329 330 static int pl011_can_receive(void *opaque) 331 { 332 PL011State *s = (PL011State *)opaque; 333 int r; 334 335 r = s->read_count < pl011_get_fifo_depth(s); 336 trace_pl011_can_receive(s->lcr, s->read_count, r); 337 return r; 338 } 339 340 static void pl011_put_fifo(void *opaque, uint32_t value) 341 { 342 PL011State *s = (PL011State *)opaque; 343 int slot; 344 unsigned pipe_depth; 345 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; 355 } 356 if (s->read_count == s->read_trigger) { 357 s->int_level |= INT_RX; 358 pl011_update(s); 359 } 360 } 361 362 static void pl011_receive(void *opaque, const uint8_t *buf, int size) 363 { 364 pl011_put_fifo(opaque, *buf); 365 } 366 367 static void pl011_event(void *opaque, QEMUChrEvent event) 368 { 369 if (event == CHR_EVENT_BREAK) { 370 pl011_put_fifo(opaque, DR_BE); 371 } 372 } 373 374 static void pl011_clock_update(void *opaque, ClockEvent event) 375 { 376 PL011State *s = PL011(opaque); 377 378 pl011_trace_baudrate_change(s); 379 } 380 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, 387 }; 388 389 static bool pl011_clock_needed(void *opaque) 390 { 391 PL011State *s = PL011(opaque); 392 393 return s->migrate_clk; 394 } 395 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 = (VMStateField[]) { 402 VMSTATE_CLOCK(clk, PL011State), 403 VMSTATE_END_OF_LIST() 404 } 405 }; 406 407 static int pl011_post_load(void *opaque, int version_id) 408 { 409 PL011State* s = opaque; 410 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; 415 } 416 417 if (!pl011_is_fifo_enabled(s) && s->read_count > 0 && s->read_pos > 0) { 418 /* 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. 423 */ 424 s->read_fifo[0] = s->read_fifo[s->read_pos]; 425 s->read_pos = 0; 426 } 427 428 return 0; 429 } 430 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 = (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() 454 }, 455 .subsections = (const VMStateDescription * []) { 456 &vmstate_pl011_clock, 457 NULL 458 } 459 }; 460 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(), 465 }; 466 467 static void pl011_init(Object *obj) 468 { 469 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 470 PL011State *s = PL011(obj); 471 int i; 472 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]); 477 } 478 479 s->clk = qdev_init_clock_in(DEVICE(obj), "clk", pl011_clock_update, s, 480 ClockUpdate); 481 482 s->id = pl011_id_arm; 483 } 484 485 static void pl011_realize(DeviceState *dev, Error **errp) 486 { 487 PL011State *s = PL011(dev); 488 489 qemu_chr_fe_set_handlers(&s->chr, pl011_can_receive, pl011_receive, 490 pl011_event, NULL, s, NULL, true); 491 } 492 493 static void pl011_reset(DeviceState *dev) 494 { 495 PL011State *s = PL011(dev); 496 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); 510 } 511 512 static void pl011_class_init(ObjectClass *oc, void *data) 513 { 514 DeviceClass *dc = DEVICE_CLASS(oc); 515 516 dc->realize = pl011_realize; 517 dc->reset = pl011_reset; 518 dc->vmsd = &vmstate_pl011; 519 device_class_set_props(dc, pl011_properties); 520 } 521 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, 528 }; 529 530 static void pl011_luminary_init(Object *obj) 531 { 532 PL011State *s = PL011(obj); 533 534 s->id = pl011_id_luminary; 535 } 536 537 static const TypeInfo pl011_luminary_info = { 538 .name = TYPE_PL011_LUMINARY, 539 .parent = TYPE_PL011, 540 .instance_init = pl011_luminary_init, 541 }; 542 543 static void pl011_register_types(void) 544 { 545 type_register_static(&pl011_arm_info); 546 type_register_static(&pl011_luminary_info); 547 } 548 549 type_init(pl011_register_types) 550