]>
Commit | Line | Data |
---|---|---|
50486d63 PMD |
1 | /* |
2 | * QEMU Arduino boards | |
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 | /* TODO: Implement the use of EXTRAM */ | |
12 | ||
13 | #include "qemu/osdep.h" | |
14 | #include "qapi/error.h" | |
50486d63 PMD |
15 | #include "atmega.h" |
16 | #include "boot.h" | |
db1015e9 | 17 | #include "qom/object.h" |
50486d63 | 18 | |
db1015e9 | 19 | struct ArduinoMachineState { |
50486d63 PMD |
20 | /*< private >*/ |
21 | MachineState parent_obj; | |
22 | /*< public >*/ | |
23 | AtmegaMcuState mcu; | |
db1015e9 EH |
24 | }; |
25 | typedef struct ArduinoMachineState ArduinoMachineState; | |
50486d63 | 26 | |
db1015e9 | 27 | struct ArduinoMachineClass { |
50486d63 PMD |
28 | /*< private >*/ |
29 | MachineClass parent_class; | |
30 | /*< public >*/ | |
31 | const char *mcu_type; | |
32 | uint64_t xtal_hz; | |
db1015e9 EH |
33 | }; |
34 | typedef struct ArduinoMachineClass ArduinoMachineClass; | |
50486d63 PMD |
35 | |
36 | #define TYPE_ARDUINO_MACHINE \ | |
37 | MACHINE_TYPE_NAME("arduino") | |
8110fa1d EH |
38 | DECLARE_OBJ_CHECKERS(ArduinoMachineState, ArduinoMachineClass, |
39 | ARDUINO_MACHINE, TYPE_ARDUINO_MACHINE) | |
50486d63 PMD |
40 | |
41 | static void arduino_machine_init(MachineState *machine) | |
42 | { | |
43 | ArduinoMachineClass *amc = ARDUINO_MACHINE_GET_CLASS(machine); | |
44 | ArduinoMachineState *ams = ARDUINO_MACHINE(machine); | |
45 | ||
46 | object_initialize_child(OBJECT(machine), "mcu", &ams->mcu, amc->mcu_type); | |
47 | object_property_set_uint(OBJECT(&ams->mcu), "xtal-frequency-hz", | |
48 | amc->xtal_hz, &error_abort); | |
49 | sysbus_realize(SYS_BUS_DEVICE(&ams->mcu), &error_abort); | |
50 | ||
51 | if (machine->firmware) { | |
52 | if (!avr_load_firmware(&ams->mcu.cpu, machine, | |
53 | &ams->mcu.flash, machine->firmware)) { | |
54 | exit(1); | |
55 | } | |
56 | } | |
57 | } | |
58 | ||
59 | static void arduino_machine_class_init(ObjectClass *oc, void *data) | |
60 | { | |
61 | MachineClass *mc = MACHINE_CLASS(oc); | |
62 | ||
63 | mc->init = arduino_machine_init; | |
64 | mc->default_cpus = 1; | |
65 | mc->min_cpus = mc->default_cpus; | |
66 | mc->max_cpus = mc->default_cpus; | |
67 | mc->no_floppy = 1; | |
68 | mc->no_cdrom = 1; | |
69 | mc->no_parallel = 1; | |
70 | } | |
71 | ||
72 | static void arduino_duemilanove_class_init(ObjectClass *oc, void *data) | |
73 | { | |
74 | MachineClass *mc = MACHINE_CLASS(oc); | |
75 | ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc); | |
76 | ||
15991968 PMD |
77 | /* |
78 | * https://www.arduino.cc/en/Main/ArduinoBoardDuemilanove | |
79 | * https://www.arduino.cc/en/uploads/Main/arduino-duemilanove-schematic.pdf | |
80 | */ | |
50486d63 PMD |
81 | mc->desc = "Arduino Duemilanove (ATmega168)", |
82 | mc->alias = "2009"; | |
83 | amc->mcu_type = TYPE_ATMEGA168_MCU; | |
84 | amc->xtal_hz = 16 * 1000 * 1000; | |
85 | }; | |
86 | ||
87 | static void arduino_uno_class_init(ObjectClass *oc, void *data) | |
88 | { | |
89 | MachineClass *mc = MACHINE_CLASS(oc); | |
90 | ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc); | |
91 | ||
15991968 PMD |
92 | /* |
93 | * https://store.arduino.cc/arduino-uno-rev3 | |
94 | * https://www.arduino.cc/en/uploads/Main/arduino-uno-schematic.pdf | |
95 | */ | |
50486d63 PMD |
96 | mc->desc = "Arduino UNO (ATmega328P)"; |
97 | mc->alias = "uno"; | |
98 | amc->mcu_type = TYPE_ATMEGA328_MCU; | |
99 | amc->xtal_hz = 16 * 1000 * 1000; | |
100 | }; | |
101 | ||
102 | static void arduino_mega_class_init(ObjectClass *oc, void *data) | |
103 | { | |
104 | MachineClass *mc = MACHINE_CLASS(oc); | |
105 | ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc); | |
106 | ||
15991968 PMD |
107 | /* |
108 | * https://www.arduino.cc/en/Main/ArduinoBoardMega | |
109 | * https://www.arduino.cc/en/uploads/Main/arduino-mega2560-schematic.pdf | |
110 | */ | |
50486d63 PMD |
111 | mc->desc = "Arduino Mega (ATmega1280)"; |
112 | mc->alias = "mega"; | |
113 | amc->mcu_type = TYPE_ATMEGA1280_MCU; | |
114 | amc->xtal_hz = 16 * 1000 * 1000; | |
115 | }; | |
116 | ||
117 | static void arduino_mega2560_class_init(ObjectClass *oc, void *data) | |
118 | { | |
119 | MachineClass *mc = MACHINE_CLASS(oc); | |
120 | ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc); | |
121 | ||
15991968 PMD |
122 | /* |
123 | * https://store.arduino.cc/arduino-mega-2560-rev3 | |
124 | * https://www.arduino.cc/en/uploads/Main/arduino-mega2560_R3-sch.pdf | |
125 | */ | |
50486d63 PMD |
126 | mc->desc = "Arduino Mega 2560 (ATmega2560)"; |
127 | mc->alias = "mega2560"; | |
128 | amc->mcu_type = TYPE_ATMEGA2560_MCU; | |
129 | amc->xtal_hz = 16 * 1000 * 1000; /* CSTCE16M0V53-R0 */ | |
130 | }; | |
131 | ||
132 | static const TypeInfo arduino_machine_types[] = { | |
133 | { | |
134 | .name = MACHINE_TYPE_NAME("arduino-duemilanove"), | |
135 | .parent = TYPE_ARDUINO_MACHINE, | |
136 | .class_init = arduino_duemilanove_class_init, | |
137 | }, { | |
138 | .name = MACHINE_TYPE_NAME("arduino-uno"), | |
139 | .parent = TYPE_ARDUINO_MACHINE, | |
140 | .class_init = arduino_uno_class_init, | |
141 | }, { | |
142 | .name = MACHINE_TYPE_NAME("arduino-mega"), | |
143 | .parent = TYPE_ARDUINO_MACHINE, | |
144 | .class_init = arduino_mega_class_init, | |
145 | }, { | |
146 | .name = MACHINE_TYPE_NAME("arduino-mega-2560-v3"), | |
147 | .parent = TYPE_ARDUINO_MACHINE, | |
148 | .class_init = arduino_mega2560_class_init, | |
149 | }, { | |
150 | .name = TYPE_ARDUINO_MACHINE, | |
151 | .parent = TYPE_MACHINE, | |
152 | .instance_size = sizeof(ArduinoMachineState), | |
153 | .class_size = sizeof(ArduinoMachineClass), | |
154 | .class_init = arduino_machine_class_init, | |
155 | .abstract = true, | |
156 | } | |
157 | }; | |
158 | ||
159 | DEFINE_TYPES(arduino_machine_types) |