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