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