1 /* 2 * AVR USART 3 * 4 * Copyright (c) 2018 University of Kent 5 * Author: Sarah Harris 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, see 19 * <http://www.gnu.org/licenses/lgpl-2.1.html> 20 */ 21 22 #include "qemu/osdep.h" 23 #include "hw/char/avr_usart.h" 24 #include "qemu/log.h" 25 #include "hw/irq.h" 26 #include "hw/qdev-properties.h" 27 28 static int avr_usart_can_receive(void *opaque) 29 { 30 AVRUsartState *usart = opaque; 31 32 if (usart->data_valid || !(usart->csrb & USART_CSRB_RXEN)) { 33 return 0; 34 } 35 return 1; 36 } 37 38 static void avr_usart_receive(void *opaque, const uint8_t *buffer, int size) 39 { 40 AVRUsartState *usart = opaque; 41 assert(size == 1); 42 assert(!usart->data_valid); 43 usart->data = buffer[0]; 44 usart->data_valid = true; 45 usart->csra |= USART_CSRA_RXC; 46 if (usart->csrb & USART_CSRB_RXCIE) { 47 qemu_set_irq(usart->rxc_irq, 1); 48 } 49 } 50 51 static void update_char_mask(AVRUsartState *usart) 52 { 53 uint8_t mode = ((usart->csrc & USART_CSRC_CSZ0) ? 1 : 0) | 54 ((usart->csrc & USART_CSRC_CSZ1) ? 2 : 0) | 55 ((usart->csrb & USART_CSRB_CSZ2) ? 4 : 0); 56 switch (mode) { 57 case 0: 58 usart->char_mask = 0b11111; 59 break; 60 case 1: 61 usart->char_mask = 0b111111; 62 break; 63 case 2: 64 usart->char_mask = 0b1111111; 65 break; 66 case 3: 67 usart->char_mask = 0b11111111; 68 break; 69 case 4: 70 /* Fallthrough. */ 71 case 5: 72 /* Fallthrough. */ 73 case 6: 74 qemu_log_mask( 75 LOG_GUEST_ERROR, 76 "%s: Reserved character size 0x%x\n", 77 __func__, 78 mode); 79 break; 80 case 7: 81 qemu_log_mask( 82 LOG_GUEST_ERROR, 83 "%s: Nine bit character size not supported (forcing eight)\n", 84 __func__); 85 usart->char_mask = 0b11111111; 86 break; 87 default: 88 assert(0); 89 } 90 } 91 92 static void avr_usart_reset(DeviceState *dev) 93 { 94 AVRUsartState *usart = AVR_USART(dev); 95 usart->data_valid = false; 96 usart->csra = 0b00100000; 97 usart->csrb = 0b00000000; 98 usart->csrc = 0b00000110; 99 usart->brrl = 0; 100 usart->brrh = 0; 101 update_char_mask(usart); 102 qemu_set_irq(usart->rxc_irq, 0); 103 qemu_set_irq(usart->txc_irq, 0); 104 qemu_set_irq(usart->dre_irq, 0); 105 } 106 107 static uint64_t avr_usart_read(void *opaque, hwaddr addr, unsigned int size) 108 { 109 AVRUsartState *usart = opaque; 110 uint8_t data; 111 assert(size == 1); 112 113 if (!usart->enabled) { 114 return 0; 115 } 116 117 switch (addr) { 118 case USART_DR: 119 if (!(usart->csrb & USART_CSRB_RXEN)) { 120 /* Receiver disabled, ignore. */ 121 return 0; 122 } 123 if (usart->data_valid) { 124 data = usart->data & usart->char_mask; 125 usart->data_valid = false; 126 } else { 127 data = 0; 128 } 129 usart->csra &= 0xff ^ USART_CSRA_RXC; 130 qemu_set_irq(usart->rxc_irq, 0); 131 qemu_chr_fe_accept_input(&usart->chr); 132 return data; 133 case USART_CSRA: 134 return usart->csra; 135 case USART_CSRB: 136 return usart->csrb; 137 case USART_CSRC: 138 return usart->csrc; 139 case USART_BRRL: 140 return usart->brrl; 141 case USART_BRRH: 142 return usart->brrh; 143 default: 144 qemu_log_mask( 145 LOG_GUEST_ERROR, 146 "%s: Bad offset 0x%"HWADDR_PRIx"\n", 147 __func__, 148 addr); 149 } 150 return 0; 151 } 152 153 static void avr_usart_write(void *opaque, hwaddr addr, uint64_t value, 154 unsigned int size) 155 { 156 AVRUsartState *usart = opaque; 157 uint8_t mask; 158 uint8_t data; 159 assert((value & 0xff) == value); 160 assert(size == 1); 161 162 if (!usart->enabled) { 163 return; 164 } 165 166 switch (addr) { 167 case USART_DR: 168 if (!(usart->csrb & USART_CSRB_TXEN)) { 169 /* Transmitter disabled, ignore. */ 170 return; 171 } 172 usart->csra |= USART_CSRA_TXC; 173 usart->csra |= USART_CSRA_DRE; 174 if (usart->csrb & USART_CSRB_TXCIE) { 175 qemu_set_irq(usart->txc_irq, 1); 176 usart->csra &= 0xff ^ USART_CSRA_TXC; 177 } 178 if (usart->csrb & USART_CSRB_DREIE) { 179 qemu_set_irq(usart->dre_irq, 1); 180 } 181 data = value; 182 qemu_chr_fe_write_all(&usart->chr, &data, 1); 183 break; 184 case USART_CSRA: 185 mask = 0b01000011; 186 /* Mask read-only bits. */ 187 value = (value & mask) | (usart->csra & (0xff ^ mask)); 188 usart->csra = value; 189 if (value & USART_CSRA_TXC) { 190 usart->csra ^= USART_CSRA_TXC; 191 qemu_set_irq(usart->txc_irq, 0); 192 } 193 if (value & USART_CSRA_MPCM) { 194 qemu_log_mask( 195 LOG_GUEST_ERROR, 196 "%s: MPCM not supported by USART\n", 197 __func__); 198 } 199 break; 200 case USART_CSRB: 201 mask = 0b11111101; 202 /* Mask read-only bits. */ 203 value = (value & mask) | (usart->csrb & (0xff ^ mask)); 204 usart->csrb = value; 205 if (!(value & USART_CSRB_RXEN)) { 206 /* Receiver disabled, flush input buffer. */ 207 usart->data_valid = false; 208 } 209 qemu_set_irq(usart->rxc_irq, 210 ((value & USART_CSRB_RXCIE) && 211 (usart->csra & USART_CSRA_RXC)) ? 1 : 0); 212 qemu_set_irq(usart->txc_irq, 213 ((value & USART_CSRB_TXCIE) && 214 (usart->csra & USART_CSRA_TXC)) ? 1 : 0); 215 qemu_set_irq(usart->dre_irq, 216 ((value & USART_CSRB_DREIE) && 217 (usart->csra & USART_CSRA_DRE)) ? 1 : 0); 218 update_char_mask(usart); 219 break; 220 case USART_CSRC: 221 usart->csrc = value; 222 if ((value & USART_CSRC_MSEL1) && (value & USART_CSRC_MSEL0)) { 223 qemu_log_mask( 224 LOG_GUEST_ERROR, 225 "%s: SPI mode not supported by USART\n", 226 __func__); 227 } 228 if ((value & USART_CSRC_MSEL1) && !(value & USART_CSRC_MSEL0)) { 229 qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad USART mode\n", __func__); 230 } 231 if (!(value & USART_CSRC_PM1) && (value & USART_CSRC_PM0)) { 232 qemu_log_mask( 233 LOG_GUEST_ERROR, 234 "%s: Bad USART parity mode\n", 235 __func__); 236 } 237 update_char_mask(usart); 238 break; 239 case USART_BRRL: 240 usart->brrl = value; 241 break; 242 case USART_BRRH: 243 usart->brrh = value & 0b00001111; 244 break; 245 default: 246 qemu_log_mask( 247 LOG_GUEST_ERROR, 248 "%s: Bad offset 0x%"HWADDR_PRIx"\n", 249 __func__, 250 addr); 251 } 252 } 253 254 static const MemoryRegionOps avr_usart_ops = { 255 .read = avr_usart_read, 256 .write = avr_usart_write, 257 .endianness = DEVICE_NATIVE_ENDIAN, 258 .impl = {.min_access_size = 1, .max_access_size = 1} 259 }; 260 261 static Property avr_usart_properties[] = { 262 DEFINE_PROP_CHR("chardev", AVRUsartState, chr), 263 DEFINE_PROP_END_OF_LIST(), 264 }; 265 266 static void avr_usart_pr(void *opaque, int irq, int level) 267 { 268 AVRUsartState *s = AVR_USART(opaque); 269 270 s->enabled = !level; 271 272 if (!s->enabled) { 273 avr_usart_reset(DEVICE(s)); 274 } 275 } 276 277 static void avr_usart_init(Object *obj) 278 { 279 AVRUsartState *s = AVR_USART(obj); 280 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->rxc_irq); 281 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->dre_irq); 282 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->txc_irq); 283 memory_region_init_io(&s->mmio, obj, &avr_usart_ops, s, TYPE_AVR_USART, 7); 284 sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); 285 qdev_init_gpio_in(DEVICE(s), avr_usart_pr, 1); 286 s->enabled = true; 287 } 288 289 static void avr_usart_realize(DeviceState *dev, Error **errp) 290 { 291 AVRUsartState *s = AVR_USART(dev); 292 qemu_chr_fe_set_handlers(&s->chr, avr_usart_can_receive, 293 avr_usart_receive, NULL, NULL, 294 s, NULL, true); 295 avr_usart_reset(dev); 296 } 297 298 static void avr_usart_class_init(ObjectClass *klass, void *data) 299 { 300 DeviceClass *dc = DEVICE_CLASS(klass); 301 302 dc->reset = avr_usart_reset; 303 device_class_set_props(dc, avr_usart_properties); 304 dc->realize = avr_usart_realize; 305 } 306 307 static const TypeInfo avr_usart_info = { 308 .name = TYPE_AVR_USART, 309 .parent = TYPE_SYS_BUS_DEVICE, 310 .instance_size = sizeof(AVRUsartState), 311 .instance_init = avr_usart_init, 312 .class_init = avr_usart_class_init, 313 }; 314 315 static void avr_usart_register_types(void) 316 { 317 type_register_static(&avr_usart_info); 318 } 319 320 type_init(avr_usart_register_types) 321