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