1 /* 2 * QEMU ATmega MCU 3 * 4 * Copyright (c) 2019-2020 Philippe Mathieu-Daudé 5 * 6 * This work is licensed under the terms of the GNU GPLv2 or later. 7 * See the COPYING file in the top-level directory. 8 * SPDX-License-Identifier: GPL-2.0-or-later 9 */ 10 11 #include "qemu/osdep.h" 12 #include "qemu/module.h" 13 #include "qemu/units.h" 14 #include "qapi/error.h" 15 #include "exec/target_page.h" 16 #include "system/memory.h" 17 #include "system/address-spaces.h" 18 #include "system/system.h" 19 #include "hw/qdev-properties.h" 20 #include "hw/sysbus.h" 21 #include "qom/object.h" 22 #include "hw/misc/unimp.h" 23 #include "migration/vmstate.h" 24 #include "atmega.h" 25 26 enum AtmegaPeripheral { 27 POWER0, POWER1, 28 GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, 29 GPIOG, GPIOH, GPIOI, GPIOJ, GPIOK, GPIOL, 30 USART0, USART1, USART2, USART3, 31 TIMER0, TIMER1, TIMER2, TIMER3, TIMER4, TIMER5, 32 PERIFMAX 33 }; 34 35 #define GPIO(n) (n + GPIOA) 36 #define USART(n) (n + USART0) 37 #define TIMER(n) (n + TIMER0) 38 #define POWER(n) (n + POWER0) 39 40 typedef struct { 41 uint16_t addr; 42 enum AtmegaPeripheral power_index; 43 uint8_t power_bit; 44 /* timer specific */ 45 uint16_t intmask_addr; 46 uint16_t intflag_addr; 47 bool is_timer16; 48 } peripheral_cfg; 49 50 struct AtmegaMcuClass { 51 /*< private >*/ 52 SysBusDeviceClass parent_class; 53 /*< public >*/ 54 const char *uc_name; 55 const char *cpu_type; 56 size_t flash_size; 57 size_t eeprom_size; 58 size_t sram_size; 59 size_t io_size; 60 size_t gpio_count; 61 size_t adc_count; 62 const uint8_t *irq; 63 const peripheral_cfg *dev; 64 }; 65 typedef struct AtmegaMcuClass AtmegaMcuClass; 66 67 DECLARE_CLASS_CHECKERS(AtmegaMcuClass, ATMEGA_MCU, 68 TYPE_ATMEGA_MCU) 69 70 static const peripheral_cfg dev168_328[PERIFMAX] = { 71 [USART0] = { 0xc0, POWER0, 1 }, 72 [TIMER2] = { 0xb0, POWER0, 6, 0x70, 0x37, false }, 73 [TIMER1] = { 0x80, POWER0, 3, 0x6f, 0x36, true }, 74 [POWER0] = { 0x64 }, 75 [TIMER0] = { 0x44, POWER0, 5, 0x6e, 0x35, false }, 76 [GPIOD] = { 0x29 }, 77 [GPIOC] = { 0x26 }, 78 [GPIOB] = { 0x23 }, 79 }, dev1280_2560[PERIFMAX] = { 80 [USART3] = { 0x130, POWER1, 2 }, 81 [TIMER5] = { 0x120, POWER1, 5, 0x73, 0x3a, true }, 82 [GPIOL] = { 0x109 }, 83 [GPIOK] = { 0x106 }, 84 [GPIOJ] = { 0x103 }, 85 [GPIOH] = { 0x100 }, 86 [USART2] = { 0xd0, POWER1, 1 }, 87 [USART1] = { 0xc8, POWER1, 0 }, 88 [USART0] = { 0xc0, POWER0, 1 }, 89 [TIMER2] = { 0xb0, POWER0, 6, 0x70, 0x37, false }, /* TODO async */ 90 [TIMER4] = { 0xa0, POWER1, 4, 0x72, 0x39, true }, 91 [TIMER3] = { 0x90, POWER1, 3, 0x71, 0x38, true }, 92 [TIMER1] = { 0x80, POWER0, 3, 0x6f, 0x36, true }, 93 [POWER1] = { 0x65 }, 94 [POWER0] = { 0x64 }, 95 [TIMER0] = { 0x44, POWER0, 5, 0x6e, 0x35, false }, 96 [GPIOG] = { 0x32 }, 97 [GPIOF] = { 0x2f }, 98 [GPIOE] = { 0x2c }, 99 [GPIOD] = { 0x29 }, 100 [GPIOC] = { 0x26 }, 101 [GPIOB] = { 0x23 }, 102 [GPIOA] = { 0x20 }, 103 }; 104 105 enum AtmegaIrq { 106 USART0_RXC_IRQ, USART0_DRE_IRQ, USART0_TXC_IRQ, 107 USART1_RXC_IRQ, USART1_DRE_IRQ, USART1_TXC_IRQ, 108 USART2_RXC_IRQ, USART2_DRE_IRQ, USART2_TXC_IRQ, 109 USART3_RXC_IRQ, USART3_DRE_IRQ, USART3_TXC_IRQ, 110 TIMER0_CAPT_IRQ, TIMER0_COMPA_IRQ, TIMER0_COMPB_IRQ, 111 TIMER0_COMPC_IRQ, TIMER0_OVF_IRQ, 112 TIMER1_CAPT_IRQ, TIMER1_COMPA_IRQ, TIMER1_COMPB_IRQ, 113 TIMER1_COMPC_IRQ, TIMER1_OVF_IRQ, 114 TIMER2_CAPT_IRQ, TIMER2_COMPA_IRQ, TIMER2_COMPB_IRQ, 115 TIMER2_COMPC_IRQ, TIMER2_OVF_IRQ, 116 TIMER3_CAPT_IRQ, TIMER3_COMPA_IRQ, TIMER3_COMPB_IRQ, 117 TIMER3_COMPC_IRQ, TIMER3_OVF_IRQ, 118 TIMER4_CAPT_IRQ, TIMER4_COMPA_IRQ, TIMER4_COMPB_IRQ, 119 TIMER4_COMPC_IRQ, TIMER4_OVF_IRQ, 120 TIMER5_CAPT_IRQ, TIMER5_COMPA_IRQ, TIMER5_COMPB_IRQ, 121 TIMER5_COMPC_IRQ, TIMER5_OVF_IRQ, 122 IRQ_COUNT 123 }; 124 125 #define USART_IRQ_COUNT 3 126 #define USART_RXC_IRQ(n) (n * USART_IRQ_COUNT + USART0_RXC_IRQ) 127 #define USART_DRE_IRQ(n) (n * USART_IRQ_COUNT + USART0_DRE_IRQ) 128 #define USART_TXC_IRQ(n) (n * USART_IRQ_COUNT + USART0_TXC_IRQ) 129 #define TIMER_IRQ_COUNT 5 130 #define TIMER_CAPT_IRQ(n) (n * TIMER_IRQ_COUNT + TIMER0_CAPT_IRQ) 131 #define TIMER_COMPA_IRQ(n) (n * TIMER_IRQ_COUNT + TIMER0_COMPA_IRQ) 132 #define TIMER_COMPB_IRQ(n) (n * TIMER_IRQ_COUNT + TIMER0_COMPB_IRQ) 133 #define TIMER_COMPC_IRQ(n) (n * TIMER_IRQ_COUNT + TIMER0_COMPC_IRQ) 134 #define TIMER_OVF_IRQ(n) (n * TIMER_IRQ_COUNT + TIMER0_OVF_IRQ) 135 136 static const uint8_t irq168_328[IRQ_COUNT] = { 137 [TIMER2_COMPA_IRQ] = 8, 138 [TIMER2_COMPB_IRQ] = 9, 139 [TIMER2_OVF_IRQ] = 10, 140 [TIMER1_CAPT_IRQ] = 11, 141 [TIMER1_COMPA_IRQ] = 12, 142 [TIMER1_COMPB_IRQ] = 13, 143 [TIMER1_OVF_IRQ] = 14, 144 [TIMER0_COMPA_IRQ] = 15, 145 [TIMER0_COMPB_IRQ] = 16, 146 [TIMER0_OVF_IRQ] = 17, 147 [USART0_RXC_IRQ] = 19, 148 [USART0_DRE_IRQ] = 20, 149 [USART0_TXC_IRQ] = 21, 150 }, irq1280_2560[IRQ_COUNT] = { 151 [TIMER2_COMPA_IRQ] = 14, 152 [TIMER2_COMPB_IRQ] = 15, 153 [TIMER2_OVF_IRQ] = 16, 154 [TIMER1_CAPT_IRQ] = 17, 155 [TIMER1_COMPA_IRQ] = 18, 156 [TIMER1_COMPB_IRQ] = 19, 157 [TIMER1_COMPC_IRQ] = 20, 158 [TIMER1_OVF_IRQ] = 21, 159 [TIMER0_COMPA_IRQ] = 22, 160 [TIMER0_COMPB_IRQ] = 23, 161 [TIMER0_OVF_IRQ] = 24, 162 [USART0_RXC_IRQ] = 26, 163 [USART0_DRE_IRQ] = 27, 164 [USART0_TXC_IRQ] = 28, 165 [TIMER3_CAPT_IRQ] = 32, 166 [TIMER3_COMPA_IRQ] = 33, 167 [TIMER3_COMPB_IRQ] = 34, 168 [TIMER3_COMPC_IRQ] = 35, 169 [TIMER3_OVF_IRQ] = 36, 170 [USART1_RXC_IRQ] = 37, 171 [USART1_DRE_IRQ] = 38, 172 [USART1_TXC_IRQ] = 39, 173 [TIMER4_CAPT_IRQ] = 42, 174 [TIMER4_COMPA_IRQ] = 43, 175 [TIMER4_COMPB_IRQ] = 44, 176 [TIMER4_COMPC_IRQ] = 45, 177 [TIMER4_OVF_IRQ] = 46, 178 [TIMER5_CAPT_IRQ] = 47, 179 [TIMER5_COMPA_IRQ] = 48, 180 [TIMER5_COMPB_IRQ] = 49, 181 [TIMER5_COMPC_IRQ] = 50, 182 [TIMER5_OVF_IRQ] = 51, 183 [USART2_RXC_IRQ] = 52, 184 [USART2_DRE_IRQ] = 53, 185 [USART2_TXC_IRQ] = 54, 186 [USART3_RXC_IRQ] = 55, 187 [USART3_DRE_IRQ] = 56, 188 [USART3_TXC_IRQ] = 57, 189 }; 190 191 static void connect_peripheral_irq(const AtmegaMcuClass *k, 192 SysBusDevice *dev, int dev_irqn, 193 DeviceState *cpu, 194 unsigned peripheral_index) 195 { 196 int cpu_irq = k->irq[peripheral_index]; 197 198 if (!cpu_irq) { 199 return; 200 } 201 /* FIXME move that to avr_cpu_set_int() once 'sample' board is removed */ 202 assert(cpu_irq >= 2); 203 cpu_irq -= 2; 204 205 sysbus_connect_irq(dev, dev_irqn, qdev_get_gpio_in(cpu, cpu_irq)); 206 } 207 208 static void connect_power_reduction_gpio(AtmegaMcuState *s, 209 const AtmegaMcuClass *k, 210 DeviceState *cpu, 211 unsigned peripheral_index) 212 { 213 unsigned power_index = k->dev[peripheral_index].power_index; 214 assert(k->dev[power_index].addr); 215 sysbus_connect_irq(SYS_BUS_DEVICE(&s->pwr[power_index - POWER0]), 216 k->dev[peripheral_index].power_bit, 217 qdev_get_gpio_in(cpu, 0)); 218 } 219 220 static void atmega_realize(DeviceState *dev, Error **errp) 221 { 222 AtmegaMcuState *s = ATMEGA_MCU(dev); 223 const AtmegaMcuClass *mc = ATMEGA_MCU_GET_CLASS(dev); 224 DeviceState *cpudev; 225 SysBusDevice *sbd; 226 char *devname; 227 size_t i; 228 229 if (!s->xtal_freq_hz) { 230 error_setg(errp, "\"xtal-frequency-hz\" property must be provided."); 231 return; 232 } 233 234 /* CPU */ 235 object_initialize_child(OBJECT(dev), "cpu", &s->cpu, mc->cpu_type); 236 237 object_property_set_uint(OBJECT(&s->cpu), "init-sp", 238 mc->io_size + mc->sram_size - 1, &error_abort); 239 240 qdev_realize(DEVICE(&s->cpu), NULL, &error_abort); 241 cpudev = DEVICE(&s->cpu); 242 243 /* 244 * SRAM 245 * 246 * Softmmu is not able mix i/o and ram on the same page. 247 * Therefore in all cases, the first page exclusively contains i/o. 248 * 249 * If the MCU's i/o region matches the page size, then we can simply 250 * allocate all ram starting at the second page. Otherwise, we must 251 * allocate some ram as i/o to complete the first page. 252 */ 253 assert(mc->io_size == 0x100 || mc->io_size == 0x200); 254 if (mc->io_size >= TARGET_PAGE_SIZE) { 255 memory_region_init_ram(&s->sram, OBJECT(dev), "sram", mc->sram_size, 256 &error_abort); 257 memory_region_add_subregion(get_system_memory(), 258 OFFSET_DATA + mc->io_size, &s->sram); 259 } else { 260 int sram_io_size = TARGET_PAGE_SIZE - mc->io_size; 261 void *sram_io_mem = g_malloc0(sram_io_size); 262 263 memory_region_init_ram_device_ptr(&s->sram_io, OBJECT(dev), "sram-as-io", 264 sram_io_size, sram_io_mem); 265 memory_region_add_subregion(get_system_memory(), 266 OFFSET_DATA + mc->io_size, &s->sram_io); 267 vmstate_register_ram(&s->sram_io, dev); 268 269 memory_region_init_ram(&s->sram, OBJECT(dev), "sram", 270 mc->sram_size - sram_io_size, &error_abort); 271 memory_region_add_subregion(get_system_memory(), 272 OFFSET_DATA + TARGET_PAGE_SIZE, &s->sram); 273 } 274 275 /* Flash */ 276 memory_region_init_rom(&s->flash, OBJECT(dev), 277 "flash", mc->flash_size, &error_fatal); 278 memory_region_add_subregion(get_system_memory(), OFFSET_CODE, &s->flash); 279 280 /* 281 * I/O 282 * 283 * 0x00 - 0x1f: Registers 284 * 0x20 - 0x5f: I/O memory 285 * 0x60 - 0xff: Extended I/O 286 */ 287 s->io = qdev_new(TYPE_UNIMPLEMENTED_DEVICE); 288 qdev_prop_set_string(s->io, "name", "I/O"); 289 qdev_prop_set_uint64(s->io, "size", mc->io_size); 290 sysbus_realize_and_unref(SYS_BUS_DEVICE(s->io), &error_fatal); 291 sysbus_mmio_map_overlap(SYS_BUS_DEVICE(s->io), 0, OFFSET_DATA, -1234); 292 293 /* Power Reduction */ 294 for (i = 0; i < POWER_MAX; i++) { 295 int idx = POWER(i); 296 if (!mc->dev[idx].addr) { 297 continue; 298 } 299 devname = g_strdup_printf("power%zu", i); 300 object_initialize_child(OBJECT(dev), devname, &s->pwr[i], 301 TYPE_AVR_MASK); 302 sysbus_realize(SYS_BUS_DEVICE(&s->pwr[i]), &error_abort); 303 sysbus_mmio_map(SYS_BUS_DEVICE(&s->pwr[i]), 0, 304 OFFSET_DATA + mc->dev[idx].addr); 305 g_free(devname); 306 } 307 308 /* GPIO */ 309 for (i = 0; i < GPIO_MAX; i++) { 310 int idx = GPIO(i); 311 if (!mc->dev[idx].addr) { 312 continue; 313 } 314 devname = g_strdup_printf("atmega-gpio-%c", 'a' + (char)i); 315 create_unimplemented_device(devname, 316 OFFSET_DATA + mc->dev[idx].addr, 3); 317 g_free(devname); 318 } 319 320 /* USART */ 321 for (i = 0; i < USART_MAX; i++) { 322 int idx = USART(i); 323 if (!mc->dev[idx].addr) { 324 continue; 325 } 326 devname = g_strdup_printf("usart%zu", i); 327 object_initialize_child(OBJECT(dev), devname, &s->usart[i], 328 TYPE_AVR_USART); 329 qdev_prop_set_chr(DEVICE(&s->usart[i]), "chardev", serial_hd(i)); 330 sbd = SYS_BUS_DEVICE(&s->usart[i]); 331 sysbus_realize(sbd, &error_abort); 332 sysbus_mmio_map(sbd, 0, OFFSET_DATA + mc->dev[USART(i)].addr); 333 connect_peripheral_irq(mc, sbd, 0, cpudev, USART_RXC_IRQ(i)); 334 connect_peripheral_irq(mc, sbd, 1, cpudev, USART_DRE_IRQ(i)); 335 connect_peripheral_irq(mc, sbd, 2, cpudev, USART_TXC_IRQ(i)); 336 connect_power_reduction_gpio(s, mc, DEVICE(&s->usart[i]), idx); 337 g_free(devname); 338 } 339 340 /* Timer */ 341 for (i = 0; i < TIMER_MAX; i++) { 342 int idx = TIMER(i); 343 if (!mc->dev[idx].addr) { 344 continue; 345 } 346 if (!mc->dev[idx].is_timer16) { 347 create_unimplemented_device("avr-timer8", 348 OFFSET_DATA + mc->dev[idx].addr, 5); 349 create_unimplemented_device("avr-timer8-intmask", 350 OFFSET_DATA 351 + mc->dev[idx].intmask_addr, 1); 352 create_unimplemented_device("avr-timer8-intflag", 353 OFFSET_DATA 354 + mc->dev[idx].intflag_addr, 1); 355 continue; 356 } 357 devname = g_strdup_printf("timer%zu", i); 358 object_initialize_child(OBJECT(dev), devname, &s->timer[i], 359 TYPE_AVR_TIMER16); 360 object_property_set_uint(OBJECT(&s->timer[i]), "cpu-frequency-hz", 361 s->xtal_freq_hz, &error_abort); 362 sbd = SYS_BUS_DEVICE(&s->timer[i]); 363 sysbus_realize(sbd, &error_abort); 364 sysbus_mmio_map(sbd, 0, OFFSET_DATA + mc->dev[idx].addr); 365 sysbus_mmio_map(sbd, 1, OFFSET_DATA + mc->dev[idx].intmask_addr); 366 sysbus_mmio_map(sbd, 2, OFFSET_DATA + mc->dev[idx].intflag_addr); 367 connect_peripheral_irq(mc, sbd, 0, cpudev, TIMER_CAPT_IRQ(i)); 368 connect_peripheral_irq(mc, sbd, 1, cpudev, TIMER_COMPA_IRQ(i)); 369 connect_peripheral_irq(mc, sbd, 2, cpudev, TIMER_COMPB_IRQ(i)); 370 connect_peripheral_irq(mc, sbd, 3, cpudev, TIMER_COMPC_IRQ(i)); 371 connect_peripheral_irq(mc, sbd, 4, cpudev, TIMER_OVF_IRQ(i)); 372 connect_power_reduction_gpio(s, mc, DEVICE(&s->timer[i]), idx); 373 g_free(devname); 374 } 375 376 create_unimplemented_device("avr-twi", OFFSET_DATA + 0x0b8, 6); 377 create_unimplemented_device("avr-adc", OFFSET_DATA + 0x078, 8); 378 create_unimplemented_device("avr-ext-mem-ctrl", OFFSET_DATA + 0x074, 2); 379 create_unimplemented_device("avr-watchdog", OFFSET_DATA + 0x060, 1); 380 create_unimplemented_device("avr-spi", OFFSET_DATA + 0x04c, 3); 381 create_unimplemented_device("avr-eeprom", OFFSET_DATA + 0x03f, 3); 382 } 383 384 static const Property atmega_props[] = { 385 DEFINE_PROP_UINT64("xtal-frequency-hz", AtmegaMcuState, 386 xtal_freq_hz, 0), 387 }; 388 389 static void atmega_class_init(ObjectClass *oc, const void *data) 390 { 391 DeviceClass *dc = DEVICE_CLASS(oc); 392 393 dc->realize = atmega_realize; 394 device_class_set_props(dc, atmega_props); 395 /* Reason: Mapped at fixed location on the system bus */ 396 dc->user_creatable = false; 397 } 398 399 static void atmega168_class_init(ObjectClass *oc, const void *data) 400 { 401 AtmegaMcuClass *amc = ATMEGA_MCU_CLASS(oc); 402 403 amc->cpu_type = AVR_CPU_TYPE_NAME("avr5"); 404 amc->flash_size = 16 * KiB; 405 amc->eeprom_size = 512; 406 amc->sram_size = 1 * KiB; 407 amc->io_size = 256; 408 amc->gpio_count = 23; 409 amc->adc_count = 6; 410 amc->irq = irq168_328; 411 amc->dev = dev168_328; 412 }; 413 414 static void atmega328_class_init(ObjectClass *oc, const void *data) 415 { 416 AtmegaMcuClass *amc = ATMEGA_MCU_CLASS(oc); 417 418 amc->cpu_type = AVR_CPU_TYPE_NAME("avr5"); 419 amc->flash_size = 32 * KiB; 420 amc->eeprom_size = 1 * KiB; 421 amc->sram_size = 2 * KiB; 422 amc->io_size = 256; 423 amc->gpio_count = 23; 424 amc->adc_count = 6; 425 amc->irq = irq168_328; 426 amc->dev = dev168_328; 427 }; 428 429 static void atmega1280_class_init(ObjectClass *oc, const void *data) 430 { 431 AtmegaMcuClass *amc = ATMEGA_MCU_CLASS(oc); 432 433 amc->cpu_type = AVR_CPU_TYPE_NAME("avr51"); 434 amc->flash_size = 128 * KiB; 435 amc->eeprom_size = 4 * KiB; 436 amc->sram_size = 8 * KiB; 437 amc->io_size = 512; 438 amc->gpio_count = 86; 439 amc->adc_count = 16; 440 amc->irq = irq1280_2560; 441 amc->dev = dev1280_2560; 442 }; 443 444 static void atmega2560_class_init(ObjectClass *oc, const void *data) 445 { 446 AtmegaMcuClass *amc = ATMEGA_MCU_CLASS(oc); 447 448 amc->cpu_type = AVR_CPU_TYPE_NAME("avr6"); 449 amc->flash_size = 256 * KiB; 450 amc->eeprom_size = 4 * KiB; 451 amc->sram_size = 8 * KiB; 452 amc->io_size = 512; 453 amc->gpio_count = 54; 454 amc->adc_count = 16; 455 amc->irq = irq1280_2560; 456 amc->dev = dev1280_2560; 457 }; 458 459 static const TypeInfo atmega_mcu_types[] = { 460 { 461 .name = TYPE_ATMEGA168_MCU, 462 .parent = TYPE_ATMEGA_MCU, 463 .class_init = atmega168_class_init, 464 }, { 465 .name = TYPE_ATMEGA328_MCU, 466 .parent = TYPE_ATMEGA_MCU, 467 .class_init = atmega328_class_init, 468 }, { 469 .name = TYPE_ATMEGA1280_MCU, 470 .parent = TYPE_ATMEGA_MCU, 471 .class_init = atmega1280_class_init, 472 }, { 473 .name = TYPE_ATMEGA2560_MCU, 474 .parent = TYPE_ATMEGA_MCU, 475 .class_init = atmega2560_class_init, 476 }, { 477 .name = TYPE_ATMEGA_MCU, 478 .parent = TYPE_SYS_BUS_DEVICE, 479 .instance_size = sizeof(AtmegaMcuState), 480 .class_size = sizeof(AtmegaMcuClass), 481 .class_init = atmega_class_init, 482 .abstract = true, 483 } 484 }; 485 486 DEFINE_TYPES(atmega_mcu_types) 487