1 /* 2 * ColdFire UART emulation. 3 * 4 * Copyright (c) 2007 CodeSourcery. 5 * 6 * This code is licensed under the GPL 7 */ 8 9 #include "qemu/osdep.h" 10 #include "hw/irq.h" 11 #include "hw/sysbus.h" 12 #include "qemu/module.h" 13 #include "qapi/error.h" 14 #include "hw/m68k/mcf.h" 15 #include "hw/qdev-properties.h" 16 #include "chardev/char-fe.h" 17 18 typedef struct { 19 SysBusDevice parent_obj; 20 21 MemoryRegion iomem; 22 uint8_t mr[2]; 23 uint8_t sr; 24 uint8_t isr; 25 uint8_t imr; 26 uint8_t bg1; 27 uint8_t bg2; 28 uint8_t fifo[4]; 29 uint8_t tb; 30 int current_mr; 31 int fifo_len; 32 int tx_enabled; 33 int rx_enabled; 34 qemu_irq irq; 35 CharBackend chr; 36 } mcf_uart_state; 37 38 #define TYPE_MCF_UART "mcf-uart" 39 #define MCF_UART(obj) OBJECT_CHECK(mcf_uart_state, (obj), TYPE_MCF_UART) 40 41 /* UART Status Register bits. */ 42 #define MCF_UART_RxRDY 0x01 43 #define MCF_UART_FFULL 0x02 44 #define MCF_UART_TxRDY 0x04 45 #define MCF_UART_TxEMP 0x08 46 #define MCF_UART_OE 0x10 47 #define MCF_UART_PE 0x20 48 #define MCF_UART_FE 0x40 49 #define MCF_UART_RB 0x80 50 51 /* Interrupt flags. */ 52 #define MCF_UART_TxINT 0x01 53 #define MCF_UART_RxINT 0x02 54 #define MCF_UART_DBINT 0x04 55 #define MCF_UART_COSINT 0x80 56 57 /* UMR1 flags. */ 58 #define MCF_UART_BC0 0x01 59 #define MCF_UART_BC1 0x02 60 #define MCF_UART_PT 0x04 61 #define MCF_UART_PM0 0x08 62 #define MCF_UART_PM1 0x10 63 #define MCF_UART_ERR 0x20 64 #define MCF_UART_RxIRQ 0x40 65 #define MCF_UART_RxRTS 0x80 66 67 static void mcf_uart_update(mcf_uart_state *s) 68 { 69 s->isr &= ~(MCF_UART_TxINT | MCF_UART_RxINT); 70 if (s->sr & MCF_UART_TxRDY) 71 s->isr |= MCF_UART_TxINT; 72 if ((s->sr & ((s->mr[0] & MCF_UART_RxIRQ) 73 ? MCF_UART_FFULL : MCF_UART_RxRDY)) != 0) 74 s->isr |= MCF_UART_RxINT; 75 76 qemu_set_irq(s->irq, (s->isr & s->imr) != 0); 77 } 78 79 uint64_t mcf_uart_read(void *opaque, hwaddr addr, 80 unsigned size) 81 { 82 mcf_uart_state *s = (mcf_uart_state *)opaque; 83 switch (addr & 0x3f) { 84 case 0x00: 85 return s->mr[s->current_mr]; 86 case 0x04: 87 return s->sr; 88 case 0x0c: 89 { 90 uint8_t val; 91 int i; 92 93 if (s->fifo_len == 0) 94 return 0; 95 96 val = s->fifo[0]; 97 s->fifo_len--; 98 for (i = 0; i < s->fifo_len; i++) 99 s->fifo[i] = s->fifo[i + 1]; 100 s->sr &= ~MCF_UART_FFULL; 101 if (s->fifo_len == 0) 102 s->sr &= ~MCF_UART_RxRDY; 103 mcf_uart_update(s); 104 qemu_chr_fe_accept_input(&s->chr); 105 return val; 106 } 107 case 0x10: 108 /* TODO: Implement IPCR. */ 109 return 0; 110 case 0x14: 111 return s->isr; 112 case 0x18: 113 return s->bg1; 114 case 0x1c: 115 return s->bg2; 116 default: 117 return 0; 118 } 119 } 120 121 /* Update TxRDY flag and set data if present and enabled. */ 122 static void mcf_uart_do_tx(mcf_uart_state *s) 123 { 124 if (s->tx_enabled && (s->sr & MCF_UART_TxEMP) == 0) { 125 /* XXX this blocks entire thread. Rewrite to use 126 * qemu_chr_fe_write and background I/O callbacks */ 127 qemu_chr_fe_write_all(&s->chr, (unsigned char *)&s->tb, 1); 128 s->sr |= MCF_UART_TxEMP; 129 } 130 if (s->tx_enabled) { 131 s->sr |= MCF_UART_TxRDY; 132 } else { 133 s->sr &= ~MCF_UART_TxRDY; 134 } 135 } 136 137 static void mcf_do_command(mcf_uart_state *s, uint8_t cmd) 138 { 139 /* Misc command. */ 140 switch ((cmd >> 4) & 7) { 141 case 0: /* No-op. */ 142 break; 143 case 1: /* Reset mode register pointer. */ 144 s->current_mr = 0; 145 break; 146 case 2: /* Reset receiver. */ 147 s->rx_enabled = 0; 148 s->fifo_len = 0; 149 s->sr &= ~(MCF_UART_RxRDY | MCF_UART_FFULL); 150 break; 151 case 3: /* Reset transmitter. */ 152 s->tx_enabled = 0; 153 s->sr |= MCF_UART_TxEMP; 154 s->sr &= ~MCF_UART_TxRDY; 155 break; 156 case 4: /* Reset error status. */ 157 break; 158 case 5: /* Reset break-change interrupt. */ 159 s->isr &= ~MCF_UART_DBINT; 160 break; 161 case 6: /* Start break. */ 162 case 7: /* Stop break. */ 163 break; 164 } 165 166 /* Transmitter command. */ 167 switch ((cmd >> 2) & 3) { 168 case 0: /* No-op. */ 169 break; 170 case 1: /* Enable. */ 171 s->tx_enabled = 1; 172 mcf_uart_do_tx(s); 173 break; 174 case 2: /* Disable. */ 175 s->tx_enabled = 0; 176 mcf_uart_do_tx(s); 177 break; 178 case 3: /* Reserved. */ 179 fprintf(stderr, "mcf_uart: Bad TX command\n"); 180 break; 181 } 182 183 /* Receiver command. */ 184 switch (cmd & 3) { 185 case 0: /* No-op. */ 186 break; 187 case 1: /* Enable. */ 188 s->rx_enabled = 1; 189 break; 190 case 2: 191 s->rx_enabled = 0; 192 break; 193 case 3: /* Reserved. */ 194 fprintf(stderr, "mcf_uart: Bad RX command\n"); 195 break; 196 } 197 } 198 199 void mcf_uart_write(void *opaque, hwaddr addr, 200 uint64_t val, unsigned size) 201 { 202 mcf_uart_state *s = (mcf_uart_state *)opaque; 203 switch (addr & 0x3f) { 204 case 0x00: 205 s->mr[s->current_mr] = val; 206 s->current_mr = 1; 207 break; 208 case 0x04: 209 /* CSR is ignored. */ 210 break; 211 case 0x08: /* Command Register. */ 212 mcf_do_command(s, val); 213 break; 214 case 0x0c: /* Transmit Buffer. */ 215 s->sr &= ~MCF_UART_TxEMP; 216 s->tb = val; 217 mcf_uart_do_tx(s); 218 break; 219 case 0x10: 220 /* ACR is ignored. */ 221 break; 222 case 0x14: 223 s->imr = val; 224 break; 225 default: 226 break; 227 } 228 mcf_uart_update(s); 229 } 230 231 static void mcf_uart_reset(DeviceState *dev) 232 { 233 mcf_uart_state *s = MCF_UART(dev); 234 235 s->fifo_len = 0; 236 s->mr[0] = 0; 237 s->mr[1] = 0; 238 s->sr = MCF_UART_TxEMP; 239 s->tx_enabled = 0; 240 s->rx_enabled = 0; 241 s->isr = 0; 242 s->imr = 0; 243 } 244 245 static void mcf_uart_push_byte(mcf_uart_state *s, uint8_t data) 246 { 247 /* Break events overwrite the last byte if the fifo is full. */ 248 if (s->fifo_len == 4) 249 s->fifo_len--; 250 251 s->fifo[s->fifo_len] = data; 252 s->fifo_len++; 253 s->sr |= MCF_UART_RxRDY; 254 if (s->fifo_len == 4) 255 s->sr |= MCF_UART_FFULL; 256 257 mcf_uart_update(s); 258 } 259 260 static void mcf_uart_event(void *opaque, QEMUChrEvent event) 261 { 262 mcf_uart_state *s = (mcf_uart_state *)opaque; 263 264 switch (event) { 265 case CHR_EVENT_BREAK: 266 s->isr |= MCF_UART_DBINT; 267 mcf_uart_push_byte(s, 0); 268 break; 269 default: 270 break; 271 } 272 } 273 274 static int mcf_uart_can_receive(void *opaque) 275 { 276 mcf_uart_state *s = (mcf_uart_state *)opaque; 277 278 return s->rx_enabled && (s->sr & MCF_UART_FFULL) == 0; 279 } 280 281 static void mcf_uart_receive(void *opaque, const uint8_t *buf, int size) 282 { 283 mcf_uart_state *s = (mcf_uart_state *)opaque; 284 285 mcf_uart_push_byte(s, buf[0]); 286 } 287 288 static const MemoryRegionOps mcf_uart_ops = { 289 .read = mcf_uart_read, 290 .write = mcf_uart_write, 291 .endianness = DEVICE_NATIVE_ENDIAN, 292 }; 293 294 static void mcf_uart_instance_init(Object *obj) 295 { 296 SysBusDevice *dev = SYS_BUS_DEVICE(obj); 297 mcf_uart_state *s = MCF_UART(dev); 298 299 memory_region_init_io(&s->iomem, obj, &mcf_uart_ops, s, "uart", 0x40); 300 sysbus_init_mmio(dev, &s->iomem); 301 302 sysbus_init_irq(dev, &s->irq); 303 } 304 305 static void mcf_uart_realize(DeviceState *dev, Error **errp) 306 { 307 mcf_uart_state *s = MCF_UART(dev); 308 309 qemu_chr_fe_set_handlers(&s->chr, mcf_uart_can_receive, mcf_uart_receive, 310 mcf_uart_event, NULL, s, NULL, true); 311 } 312 313 static Property mcf_uart_properties[] = { 314 DEFINE_PROP_CHR("chardev", mcf_uart_state, chr), 315 DEFINE_PROP_END_OF_LIST(), 316 }; 317 318 static void mcf_uart_class_init(ObjectClass *oc, void *data) 319 { 320 DeviceClass *dc = DEVICE_CLASS(oc); 321 322 dc->realize = mcf_uart_realize; 323 dc->reset = mcf_uart_reset; 324 device_class_set_props(dc, mcf_uart_properties); 325 set_bit(DEVICE_CATEGORY_INPUT, dc->categories); 326 } 327 328 static const TypeInfo mcf_uart_info = { 329 .name = TYPE_MCF_UART, 330 .parent = TYPE_SYS_BUS_DEVICE, 331 .instance_size = sizeof(mcf_uart_state), 332 .instance_init = mcf_uart_instance_init, 333 .class_init = mcf_uart_class_init, 334 }; 335 336 static void mcf_uart_register(void) 337 { 338 type_register_static(&mcf_uart_info); 339 } 340 341 type_init(mcf_uart_register) 342 343 void *mcf_uart_init(qemu_irq irq, Chardev *chrdrv) 344 { 345 DeviceState *dev; 346 347 dev = qdev_new(TYPE_MCF_UART); 348 if (chrdrv) { 349 qdev_prop_set_chr(dev, "chardev", chrdrv); 350 } 351 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 352 353 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq); 354 355 return dev; 356 } 357 358 void mcf_uart_mm_init(hwaddr base, qemu_irq irq, Chardev *chrdrv) 359 { 360 DeviceState *dev; 361 362 dev = mcf_uart_init(irq, chrdrv); 363 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); 364 } 365