1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "qemu/osdep.h"
26#include "qapi/error.h"
27#include "qemu/error-report.h"
28#include "hw/arm/arm.h"
29#include "hw/arm/armv7m.h"
30#include "hw/or-irq.h"
31#include "hw/boards.h"
32#include "exec/address-spaces.h"
33#include "sysemu/sysemu.h"
34#include "hw/misc/unimp.h"
35#include "hw/char/cmsdk-apb-uart.h"
36#include "hw/timer/cmsdk-apb-timer.h"
37#include "hw/misc/mps2-scc.h"
38#include "hw/devices.h"
39#include "net/net.h"
40
41typedef enum MPS2FPGAType {
42 FPGA_AN385,
43 FPGA_AN511,
44} MPS2FPGAType;
45
46typedef struct {
47 MachineClass parent;
48 MPS2FPGAType fpga_type;
49 const char *cpu_model;
50 uint32_t scc_id;
51} MPS2MachineClass;
52
53typedef struct {
54 MachineState parent;
55
56 ARMv7MState armv7m;
57 MemoryRegion psram;
58 MemoryRegion ssram1;
59 MemoryRegion ssram1_m;
60 MemoryRegion ssram23;
61 MemoryRegion ssram23_m;
62 MemoryRegion blockram;
63 MemoryRegion blockram_m1;
64 MemoryRegion blockram_m2;
65 MemoryRegion blockram_m3;
66 MemoryRegion sram;
67 MPS2SCC scc;
68} MPS2MachineState;
69
70#define TYPE_MPS2_MACHINE "mps2"
71#define TYPE_MPS2_AN385_MACHINE MACHINE_TYPE_NAME("mps2-an385")
72#define TYPE_MPS2_AN511_MACHINE MACHINE_TYPE_NAME("mps2-an511")
73
74#define MPS2_MACHINE(obj) \
75 OBJECT_CHECK(MPS2MachineState, obj, TYPE_MPS2_MACHINE)
76#define MPS2_MACHINE_GET_CLASS(obj) \
77 OBJECT_GET_CLASS(MPS2MachineClass, obj, TYPE_MPS2_MACHINE)
78#define MPS2_MACHINE_CLASS(klass) \
79 OBJECT_CLASS_CHECK(MPS2MachineClass, klass, TYPE_MPS2_MACHINE)
80
81
82#define SYSCLK_FRQ 25000000
83
84
85
86
87static void make_ram(MemoryRegion *mr, const char *name,
88 hwaddr base, hwaddr size)
89{
90 memory_region_init_ram(mr, NULL, name, size, &error_fatal);
91 memory_region_add_subregion(get_system_memory(), base, mr);
92}
93
94
95
96
97static void make_ram_alias(MemoryRegion *mr, const char *name,
98 MemoryRegion *orig, hwaddr base)
99{
100 memory_region_init_alias(mr, NULL, name, orig, 0,
101 memory_region_size(orig));
102 memory_region_add_subregion(get_system_memory(), base, mr);
103}
104
105static void mps2_common_init(MachineState *machine)
106{
107 MPS2MachineState *mms = MPS2_MACHINE(machine);
108 MPS2MachineClass *mmc = MPS2_MACHINE_GET_CLASS(machine);
109 MemoryRegion *system_memory = get_system_memory();
110 DeviceState *armv7m, *sccdev;
111
112 if (!machine->cpu_model) {
113 machine->cpu_model = mmc->cpu_model;
114 }
115
116 if (strcmp(machine->cpu_model, mmc->cpu_model) != 0) {
117 error_report("This board can only be used with CPU %s", mmc->cpu_model);
118 exit(1);
119 }
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 memory_region_allocate_system_memory(&mms->psram,
150 NULL, "mps.ram", 0x1000000);
151 memory_region_add_subregion(system_memory, 0x21000000, &mms->psram);
152
153 switch (mmc->fpga_type) {
154 case FPGA_AN385:
155 make_ram(&mms->ssram1, "mps.ssram1", 0x0, 0x400000);
156 make_ram_alias(&mms->ssram1_m, "mps.ssram1_m", &mms->ssram1, 0x400000);
157 make_ram(&mms->ssram23, "mps.ssram23", 0x20000000, 0x400000);
158 make_ram_alias(&mms->ssram23_m, "mps.ssram23_m",
159 &mms->ssram23, 0x20400000);
160 make_ram(&mms->blockram, "mps.blockram", 0x01000000, 0x4000);
161 make_ram_alias(&mms->blockram_m1, "mps.blockram_m1",
162 &mms->blockram, 0x01004000);
163 make_ram_alias(&mms->blockram_m2, "mps.blockram_m2",
164 &mms->blockram, 0x01008000);
165 make_ram_alias(&mms->blockram_m3, "mps.blockram_m3",
166 &mms->blockram, 0x0100c000);
167 break;
168 case FPGA_AN511:
169 make_ram(&mms->blockram, "mps.blockram", 0x0, 0x40000);
170 make_ram(&mms->ssram1, "mps.ssram1", 0x00400000, 0x00800000);
171 make_ram(&mms->sram, "mps.sram", 0x20000000, 0x20000);
172 make_ram(&mms->ssram23, "mps.ssram23", 0x20400000, 0x400000);
173 break;
174 default:
175 g_assert_not_reached();
176 }
177
178 object_initialize(&mms->armv7m, sizeof(mms->armv7m), TYPE_ARMV7M);
179 armv7m = DEVICE(&mms->armv7m);
180 qdev_set_parent_bus(armv7m, sysbus_get_default());
181 switch (mmc->fpga_type) {
182 case FPGA_AN385:
183 qdev_prop_set_uint32(armv7m, "num-irq", 32);
184 break;
185 case FPGA_AN511:
186 qdev_prop_set_uint32(armv7m, "num-irq", 64);
187 break;
188 default:
189 g_assert_not_reached();
190 }
191 qdev_prop_set_string(armv7m, "cpu-model", machine->cpu_model);
192 object_property_set_link(OBJECT(&mms->armv7m), OBJECT(system_memory),
193 "memory", &error_abort);
194 object_property_set_bool(OBJECT(&mms->armv7m), true, "realized",
195 &error_fatal);
196
197 create_unimplemented_device("zbtsmram mirror", 0x00400000, 0x00400000);
198 create_unimplemented_device("RESERVED 1", 0x00800000, 0x00800000);
199 create_unimplemented_device("Block RAM", 0x01000000, 0x00010000);
200 create_unimplemented_device("RESERVED 2", 0x01010000, 0x1EFF0000);
201 create_unimplemented_device("RESERVED 3", 0x20800000, 0x00800000);
202 create_unimplemented_device("PSRAM", 0x21000000, 0x01000000);
203
204
205
206
207 create_unimplemented_device("CMSDK APB peripheral region @0x40000000",
208 0x40000000, 0x00010000);
209 create_unimplemented_device("CMSDK peripheral region @0x40010000",
210 0x40010000, 0x00010000);
211 create_unimplemented_device("Extra peripheral region @0x40020000",
212 0x40020000, 0x00010000);
213 create_unimplemented_device("RESERVED 4", 0x40030000, 0x001D0000);
214 create_unimplemented_device("VGA", 0x41000000, 0x0200000);
215
216 switch (mmc->fpga_type) {
217 case FPGA_AN385:
218 {
219
220
221
222 Object *orgate;
223 DeviceState *orgate_dev;
224 int i;
225
226 orgate = object_new(TYPE_OR_IRQ);
227 object_property_set_int(orgate, 6, "num-lines", &error_fatal);
228 object_property_set_bool(orgate, true, "realized", &error_fatal);
229 orgate_dev = DEVICE(orgate);
230 qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
231
232 for (i = 0; i < 5; i++) {
233 static const hwaddr uartbase[] = {0x40004000, 0x40005000,
234 0x40006000, 0x40007000,
235 0x40009000};
236 Chardev *uartchr = i < MAX_SERIAL_PORTS ? serial_hds[i] : NULL;
237
238 static const int uartirq[] = {0, 2, 4, 18, 20};
239 qemu_irq txovrint = NULL, rxovrint = NULL;
240
241 if (i < 3) {
242 txovrint = qdev_get_gpio_in(orgate_dev, i * 2);
243 rxovrint = qdev_get_gpio_in(orgate_dev, i * 2 + 1);
244 }
245
246 cmsdk_apb_uart_create(uartbase[i],
247 qdev_get_gpio_in(armv7m, uartirq[i] + 1),
248 qdev_get_gpio_in(armv7m, uartirq[i]),
249 txovrint, rxovrint,
250 NULL,
251 uartchr, SYSCLK_FRQ);
252 }
253 break;
254 }
255 case FPGA_AN511:
256 {
257
258
259
260 Object *orgate;
261 DeviceState *orgate_dev;
262 int i;
263
264 orgate = object_new(TYPE_OR_IRQ);
265 object_property_set_int(orgate, 10, "num-lines", &error_fatal);
266 object_property_set_bool(orgate, true, "realized", &error_fatal);
267 orgate_dev = DEVICE(orgate);
268 qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
269
270 for (i = 0; i < 5; i++) {
271
272 static const int uart_txrx_irqno[] = {0, 2, 45, 46, 56};
273 static const hwaddr uartbase[] = {0x40004000, 0x40005000,
274 0x4002c000, 0x4002d000,
275 0x4002e000};
276 Chardev *uartchr = i < MAX_SERIAL_PORTS ? serial_hds[i] : NULL;
277 Object *txrx_orgate;
278 DeviceState *txrx_orgate_dev;
279
280 txrx_orgate = object_new(TYPE_OR_IRQ);
281 object_property_set_int(txrx_orgate, 2, "num-lines", &error_fatal);
282 object_property_set_bool(txrx_orgate, true, "realized",
283 &error_fatal);
284 txrx_orgate_dev = DEVICE(txrx_orgate);
285 qdev_connect_gpio_out(txrx_orgate_dev, 0,
286 qdev_get_gpio_in(armv7m, uart_txrx_irqno[i]));
287 cmsdk_apb_uart_create(uartbase[i],
288 qdev_get_gpio_in(txrx_orgate_dev, 0),
289 qdev_get_gpio_in(txrx_orgate_dev, 1),
290 qdev_get_gpio_in(orgate_dev, i * 2),
291 qdev_get_gpio_in(orgate_dev, i * 2 + 1),
292 NULL,
293 uartchr, SYSCLK_FRQ);
294 }
295 break;
296 }
297 default:
298 g_assert_not_reached();
299 }
300
301 cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
302 cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
303
304 object_initialize(&mms->scc, sizeof(mms->scc), TYPE_MPS2_SCC);
305 sccdev = DEVICE(&mms->scc);
306 qdev_set_parent_bus(sccdev, sysbus_get_default());
307 qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
308 qdev_prop_set_uint32(sccdev, "scc-aid", 0x02000008);
309 qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
310 object_property_set_bool(OBJECT(&mms->scc), true, "realized",
311 &error_fatal);
312 sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
313
314
315
316
317 lan9118_init(&nd_table[0], 0x40200000,
318 qdev_get_gpio_in(armv7m,
319 mmc->fpga_type == FPGA_AN385 ? 13 : 47));
320
321 system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
322
323 armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
324 0x400000);
325}
326
327static void mps2_class_init(ObjectClass *oc, void *data)
328{
329 MachineClass *mc = MACHINE_CLASS(oc);
330
331 mc->init = mps2_common_init;
332 mc->max_cpus = 1;
333}
334
335static void mps2_an385_class_init(ObjectClass *oc, void *data)
336{
337 MachineClass *mc = MACHINE_CLASS(oc);
338 MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc);
339
340 mc->desc = "ARM MPS2 with AN385 FPGA image for Cortex-M3";
341 mmc->fpga_type = FPGA_AN385;
342 mmc->cpu_model = "cortex-m3";
343 mmc->scc_id = 0x41040000 | (385 << 4);
344}
345
346static void mps2_an511_class_init(ObjectClass *oc, void *data)
347{
348 MachineClass *mc = MACHINE_CLASS(oc);
349 MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc);
350
351 mc->desc = "ARM MPS2 with AN511 DesignStart FPGA image for Cortex-M3";
352 mmc->fpga_type = FPGA_AN511;
353 mmc->cpu_model = "cortex-m3";
354 mmc->scc_id = 0x4104000 | (511 << 4);
355}
356
357static const TypeInfo mps2_info = {
358 .name = TYPE_MPS2_MACHINE,
359 .parent = TYPE_MACHINE,
360 .abstract = true,
361 .instance_size = sizeof(MPS2MachineState),
362 .class_size = sizeof(MPS2MachineClass),
363 .class_init = mps2_class_init,
364};
365
366static const TypeInfo mps2_an385_info = {
367 .name = TYPE_MPS2_AN385_MACHINE,
368 .parent = TYPE_MPS2_MACHINE,
369 .class_init = mps2_an385_class_init,
370};
371
372static const TypeInfo mps2_an511_info = {
373 .name = TYPE_MPS2_AN511_MACHINE,
374 .parent = TYPE_MPS2_MACHINE,
375 .class_init = mps2_an511_class_init,
376};
377
378static void mps2_machine_init(void)
379{
380 type_register_static(&mps2_info);
381 type_register_static(&mps2_an385_info);
382 type_register_static(&mps2_an511_info);
383}
384
385type_init(mps2_machine_init);
386