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