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