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