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