hw/avr: Add limited support for some Arduino boards
[qemu/ar7.git] / hw / avr / arduino.c
blob65093ab6fd91484a32ea52a950ea86f270d71dc3
1 /*
2 * QEMU Arduino boards
4 * Copyright (c) 2019-2020 Philippe Mathieu-Daudé
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 */
11 /* TODO: Implement the use of EXTRAM */
13 #include "qemu/osdep.h"
14 #include "qapi/error.h"
15 #include "hw/boards.h"
16 #include "atmega.h"
17 #include "boot.h"
19 typedef struct ArduinoMachineState {
20 /*< private >*/
21 MachineState parent_obj;
22 /*< public >*/
23 AtmegaMcuState mcu;
24 } ArduinoMachineState;
26 typedef struct ArduinoMachineClass {
27 /*< private >*/
28 MachineClass parent_class;
29 /*< public >*/
30 const char *mcu_type;
31 uint64_t xtal_hz;
32 } ArduinoMachineClass;
34 #define TYPE_ARDUINO_MACHINE \
35 MACHINE_TYPE_NAME("arduino")
36 #define ARDUINO_MACHINE(obj) \
37 OBJECT_CHECK(ArduinoMachineState, (obj), TYPE_ARDUINO_MACHINE)
38 #define ARDUINO_MACHINE_CLASS(klass) \
39 OBJECT_CLASS_CHECK(ArduinoMachineClass, (klass), TYPE_ARDUINO_MACHINE)
40 #define ARDUINO_MACHINE_GET_CLASS(obj) \
41 OBJECT_GET_CLASS(ArduinoMachineClass, (obj), TYPE_ARDUINO_MACHINE)
43 static void arduino_machine_init(MachineState *machine)
45 ArduinoMachineClass *amc = ARDUINO_MACHINE_GET_CLASS(machine);
46 ArduinoMachineState *ams = ARDUINO_MACHINE(machine);
48 object_initialize_child(OBJECT(machine), "mcu", &ams->mcu, amc->mcu_type);
49 object_property_set_uint(OBJECT(&ams->mcu), "xtal-frequency-hz",
50 amc->xtal_hz, &error_abort);
51 sysbus_realize(SYS_BUS_DEVICE(&ams->mcu), &error_abort);
53 if (machine->firmware) {
54 if (!avr_load_firmware(&ams->mcu.cpu, machine,
55 &ams->mcu.flash, machine->firmware)) {
56 exit(1);
61 static void arduino_machine_class_init(ObjectClass *oc, void *data)
63 MachineClass *mc = MACHINE_CLASS(oc);
65 mc->init = arduino_machine_init;
66 mc->default_cpus = 1;
67 mc->min_cpus = mc->default_cpus;
68 mc->max_cpus = mc->default_cpus;
69 mc->no_floppy = 1;
70 mc->no_cdrom = 1;
71 mc->no_parallel = 1;
74 static void arduino_duemilanove_class_init(ObjectClass *oc, void *data)
76 MachineClass *mc = MACHINE_CLASS(oc);
77 ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);
79 /* https://www.arduino.cc/en/Main/ArduinoBoardDuemilanove */
80 mc->desc = "Arduino Duemilanove (ATmega168)",
81 mc->alias = "2009";
82 amc->mcu_type = TYPE_ATMEGA168_MCU;
83 amc->xtal_hz = 16 * 1000 * 1000;
86 static void arduino_uno_class_init(ObjectClass *oc, void *data)
88 MachineClass *mc = MACHINE_CLASS(oc);
89 ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);
91 /* https://store.arduino.cc/arduino-uno-rev3 */
92 mc->desc = "Arduino UNO (ATmega328P)";
93 mc->alias = "uno";
94 amc->mcu_type = TYPE_ATMEGA328_MCU;
95 amc->xtal_hz = 16 * 1000 * 1000;
98 static void arduino_mega_class_init(ObjectClass *oc, void *data)
100 MachineClass *mc = MACHINE_CLASS(oc);
101 ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);
103 /* https://www.arduino.cc/en/Main/ArduinoBoardMega */
104 mc->desc = "Arduino Mega (ATmega1280)";
105 mc->alias = "mega";
106 amc->mcu_type = TYPE_ATMEGA1280_MCU;
107 amc->xtal_hz = 16 * 1000 * 1000;
110 static void arduino_mega2560_class_init(ObjectClass *oc, void *data)
112 MachineClass *mc = MACHINE_CLASS(oc);
113 ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);
115 /* https://store.arduino.cc/arduino-mega-2560-rev3 */
116 mc->desc = "Arduino Mega 2560 (ATmega2560)";
117 mc->alias = "mega2560";
118 amc->mcu_type = TYPE_ATMEGA2560_MCU;
119 amc->xtal_hz = 16 * 1000 * 1000; /* CSTCE16M0V53-R0 */
122 static const TypeInfo arduino_machine_types[] = {
124 .name = MACHINE_TYPE_NAME("arduino-duemilanove"),
125 .parent = TYPE_ARDUINO_MACHINE,
126 .class_init = arduino_duemilanove_class_init,
127 }, {
128 .name = MACHINE_TYPE_NAME("arduino-uno"),
129 .parent = TYPE_ARDUINO_MACHINE,
130 .class_init = arduino_uno_class_init,
131 }, {
132 .name = MACHINE_TYPE_NAME("arduino-mega"),
133 .parent = TYPE_ARDUINO_MACHINE,
134 .class_init = arduino_mega_class_init,
135 }, {
136 .name = MACHINE_TYPE_NAME("arduino-mega-2560-v3"),
137 .parent = TYPE_ARDUINO_MACHINE,
138 .class_init = arduino_mega2560_class_init,
139 }, {
140 .name = TYPE_ARDUINO_MACHINE,
141 .parent = TYPE_MACHINE,
142 .instance_size = sizeof(ArduinoMachineState),
143 .class_size = sizeof(ArduinoMachineClass),
144 .class_init = arduino_machine_class_init,
145 .abstract = true,
149 DEFINE_TYPES(arduino_machine_types)