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
26
27#include "qemu/osdep.h"
28#include "qemu/units.h"
29#include "qemu/cutils.h"
30#include "qapi/error.h"
31#include "qemu/error-report.h"
32#include "hw/arm/boot.h"
33#include "hw/arm/armv7m.h"
34#include "hw/or-irq.h"
35#include "hw/boards.h"
36#include "exec/address-spaces.h"
37#include "sysemu/sysemu.h"
38#include "hw/misc/unimp.h"
39#include "hw/char/cmsdk-apb-uart.h"
40#include "hw/timer/cmsdk-apb-timer.h"
41#include "hw/timer/cmsdk-apb-dualtimer.h"
42#include "hw/misc/mps2-scc.h"
43#include "hw/misc/mps2-fpgaio.h"
44#include "hw/ssi/pl022.h"
45#include "hw/i2c/arm_sbcon_i2c.h"
46#include "hw/net/lan9118.h"
47#include "net/net.h"
48#include "hw/watchdog/cmsdk-apb-watchdog.h"
49#include "qom/object.h"
50
51typedef enum MPS2FPGAType {
52 FPGA_AN385,
53 FPGA_AN386,
54 FPGA_AN500,
55 FPGA_AN511,
56} MPS2FPGAType;
57
58struct MPS2MachineClass {
59 MachineClass parent;
60 MPS2FPGAType fpga_type;
61 uint32_t scc_id;
62 bool has_block_ram;
63 hwaddr ethernet_base;
64 hwaddr psram_base;
65};
66
67struct MPS2MachineState {
68 MachineState parent;
69
70 ARMv7MState armv7m;
71 MemoryRegion ssram1;
72 MemoryRegion ssram1_m;
73 MemoryRegion ssram23;
74 MemoryRegion ssram23_m;
75 MemoryRegion blockram;
76 MemoryRegion blockram_m1;
77 MemoryRegion blockram_m2;
78 MemoryRegion blockram_m3;
79 MemoryRegion sram;
80
81 MPS2SCC scc;
82 MPS2FPGAIO fpgaio;
83
84 CMSDKAPBDualTimer dualtimer;
85 CMSDKAPBWatchdog watchdog;
86};
87
88#define TYPE_MPS2_MACHINE "mps2"
89#define TYPE_MPS2_AN385_MACHINE MACHINE_TYPE_NAME("mps2-an385")
90#define TYPE_MPS2_AN386_MACHINE MACHINE_TYPE_NAME("mps2-an386")
91#define TYPE_MPS2_AN500_MACHINE MACHINE_TYPE_NAME("mps2-an500")
92#define TYPE_MPS2_AN511_MACHINE MACHINE_TYPE_NAME("mps2-an511")
93
94OBJECT_DECLARE_TYPE(MPS2MachineState, MPS2MachineClass, MPS2_MACHINE)
95
96
97#define SYSCLK_FRQ 25000000
98
99
100
101
102static void make_ram(MemoryRegion *mr, const char *name,
103 hwaddr base, hwaddr size)
104{
105 memory_region_init_ram(mr, NULL, name, size, &error_fatal);
106 memory_region_add_subregion(get_system_memory(), base, mr);
107}
108
109
110
111
112static void make_ram_alias(MemoryRegion *mr, const char *name,
113 MemoryRegion *orig, hwaddr base)
114{
115 memory_region_init_alias(mr, NULL, name, orig, 0,
116 memory_region_size(orig));
117 memory_region_add_subregion(get_system_memory(), base, mr);
118}
119
120static void mps2_common_init(MachineState *machine)
121{
122 MPS2MachineState *mms = MPS2_MACHINE(machine);
123 MPS2MachineClass *mmc = MPS2_MACHINE_GET_CLASS(machine);
124 MemoryRegion *system_memory = get_system_memory();
125 MachineClass *mc = MACHINE_GET_CLASS(machine);
126 DeviceState *armv7m, *sccdev;
127 int i;
128
129 if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
130 error_report("This board can only be used with CPU %s",
131 mc->default_cpu_type);
132 exit(1);
133 }
134
135 if (machine->ram_size != mc->default_ram_size) {
136 char *sz = size_to_str(mc->default_ram_size);
137 error_report("Invalid RAM size, should be %s", sz);
138 g_free(sz);
139 exit(EXIT_FAILURE);
140 }
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173 memory_region_add_subregion(system_memory, mmc->psram_base, machine->ram);
174
175 if (mmc->has_block_ram) {
176 make_ram(&mms->blockram, "mps.blockram", 0x01000000, 0x4000);
177 make_ram_alias(&mms->blockram_m1, "mps.blockram_m1",
178 &mms->blockram, 0x01004000);
179 make_ram_alias(&mms->blockram_m2, "mps.blockram_m2",
180 &mms->blockram, 0x01008000);
181 make_ram_alias(&mms->blockram_m3, "mps.blockram_m3",
182 &mms->blockram, 0x0100c000);
183 }
184
185 switch (mmc->fpga_type) {
186 case FPGA_AN385:
187 case FPGA_AN386:
188 case FPGA_AN500:
189 make_ram(&mms->ssram1, "mps.ssram1", 0x0, 0x400000);
190 make_ram_alias(&mms->ssram1_m, "mps.ssram1_m", &mms->ssram1, 0x400000);
191 make_ram(&mms->ssram23, "mps.ssram23", 0x20000000, 0x400000);
192 make_ram_alias(&mms->ssram23_m, "mps.ssram23_m",
193 &mms->ssram23, 0x20400000);
194 break;
195 case FPGA_AN511:
196 make_ram(&mms->blockram, "mps.blockram", 0x0, 0x40000);
197 make_ram(&mms->ssram1, "mps.ssram1", 0x00400000, 0x00800000);
198 make_ram(&mms->sram, "mps.sram", 0x20000000, 0x20000);
199 make_ram(&mms->ssram23, "mps.ssram23", 0x20400000, 0x400000);
200 break;
201 default:
202 g_assert_not_reached();
203 }
204
205 object_initialize_child(OBJECT(mms), "armv7m", &mms->armv7m, TYPE_ARMV7M);
206 armv7m = DEVICE(&mms->armv7m);
207 switch (mmc->fpga_type) {
208 case FPGA_AN385:
209 case FPGA_AN386:
210 case FPGA_AN500:
211 qdev_prop_set_uint32(armv7m, "num-irq", 32);
212 break;
213 case FPGA_AN511:
214 qdev_prop_set_uint32(armv7m, "num-irq", 64);
215 break;
216 default:
217 g_assert_not_reached();
218 }
219 qdev_prop_set_string(armv7m, "cpu-type", machine->cpu_type);
220 qdev_prop_set_bit(armv7m, "enable-bitband", true);
221 object_property_set_link(OBJECT(&mms->armv7m), "memory",
222 OBJECT(system_memory), &error_abort);
223 sysbus_realize(SYS_BUS_DEVICE(&mms->armv7m), &error_fatal);
224
225 create_unimplemented_device("zbtsmram mirror", 0x00400000, 0x00400000);
226 create_unimplemented_device("RESERVED 1", 0x00800000, 0x00800000);
227 create_unimplemented_device("Block RAM", 0x01000000, 0x00010000);
228 create_unimplemented_device("RESERVED 2", 0x01010000, 0x1EFF0000);
229 create_unimplemented_device("RESERVED 3", 0x20800000, 0x00800000);
230 create_unimplemented_device("PSRAM", 0x21000000, 0x01000000);
231
232
233
234
235 create_unimplemented_device("CMSDK APB peripheral region @0x40000000",
236 0x40000000, 0x00010000);
237 create_unimplemented_device("CMSDK AHB peripheral region @0x40010000",
238 0x40010000, 0x00010000);
239 create_unimplemented_device("Extra peripheral region @0x40020000",
240 0x40020000, 0x00010000);
241
242 create_unimplemented_device("RESERVED 4", 0x40030000, 0x001D0000);
243 create_unimplemented_device("VGA", 0x41000000, 0x0200000);
244
245 switch (mmc->fpga_type) {
246 case FPGA_AN385:
247 case FPGA_AN386:
248 case FPGA_AN500:
249 {
250
251
252
253 Object *orgate;
254 DeviceState *orgate_dev;
255
256 orgate = object_new(TYPE_OR_IRQ);
257 object_property_set_int(orgate, "num-lines", 6, &error_fatal);
258 qdev_realize(DEVICE(orgate), NULL, &error_fatal);
259 orgate_dev = DEVICE(orgate);
260 qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
261
262 for (i = 0; i < 5; i++) {
263 static const hwaddr uartbase[] = {0x40004000, 0x40005000,
264 0x40006000, 0x40007000,
265 0x40009000};
266
267 static const int uartirq[] = {0, 2, 4, 18, 20};
268 qemu_irq txovrint = NULL, rxovrint = NULL;
269
270 if (i < 3) {
271 txovrint = qdev_get_gpio_in(orgate_dev, i * 2);
272 rxovrint = qdev_get_gpio_in(orgate_dev, i * 2 + 1);
273 }
274
275 cmsdk_apb_uart_create(uartbase[i],
276 qdev_get_gpio_in(armv7m, uartirq[i] + 1),
277 qdev_get_gpio_in(armv7m, uartirq[i]),
278 txovrint, rxovrint,
279 NULL,
280 serial_hd(i), SYSCLK_FRQ);
281 }
282 break;
283 }
284 case FPGA_AN511:
285 {
286
287
288
289 Object *orgate;
290 DeviceState *orgate_dev;
291
292 orgate = object_new(TYPE_OR_IRQ);
293 object_property_set_int(orgate, "num-lines", 10, &error_fatal);
294 qdev_realize(DEVICE(orgate), NULL, &error_fatal);
295 orgate_dev = DEVICE(orgate);
296 qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
297
298 for (i = 0; i < 5; i++) {
299
300 static const int uart_txrx_irqno[] = {0, 2, 45, 46, 56};
301 static const hwaddr uartbase[] = {0x40004000, 0x40005000,
302 0x4002c000, 0x4002d000,
303 0x4002e000};
304 Object *txrx_orgate;
305 DeviceState *txrx_orgate_dev;
306
307 txrx_orgate = object_new(TYPE_OR_IRQ);
308 object_property_set_int(txrx_orgate, "num-lines", 2, &error_fatal);
309 qdev_realize(DEVICE(txrx_orgate), NULL, &error_fatal);
310 txrx_orgate_dev = DEVICE(txrx_orgate);
311 qdev_connect_gpio_out(txrx_orgate_dev, 0,
312 qdev_get_gpio_in(armv7m, uart_txrx_irqno[i]));
313 cmsdk_apb_uart_create(uartbase[i],
314 qdev_get_gpio_in(txrx_orgate_dev, 0),
315 qdev_get_gpio_in(txrx_orgate_dev, 1),
316 qdev_get_gpio_in(orgate_dev, i * 2),
317 qdev_get_gpio_in(orgate_dev, i * 2 + 1),
318 NULL,
319 serial_hd(i), SYSCLK_FRQ);
320 }
321 break;
322 }
323 default:
324 g_assert_not_reached();
325 }
326 for (i = 0; i < 4; i++) {
327 static const hwaddr gpiobase[] = {0x40010000, 0x40011000,
328 0x40012000, 0x40013000};
329 create_unimplemented_device("cmsdk-ahb-gpio", gpiobase[i], 0x1000);
330 }
331
332
333 cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
334 cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
335 object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
336 TYPE_CMSDK_APB_DUALTIMER);
337 qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
338 sysbus_realize(SYS_BUS_DEVICE(&mms->dualtimer), &error_fatal);
339 sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
340 qdev_get_gpio_in(armv7m, 10));
341 sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);
342 object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
343 TYPE_CMSDK_APB_WATCHDOG);
344 qdev_prop_set_uint32(DEVICE(&mms->watchdog), "wdogclk-frq", SYSCLK_FRQ);
345 sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
346 sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
347 qdev_get_gpio_in_named(armv7m, "NMI", 0));
348 sysbus_mmio_map(SYS_BUS_DEVICE(&mms->watchdog), 0, 0x40008000);
349
350
351 object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
352 sccdev = DEVICE(&mms->scc);
353 qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
354 qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
355 qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
356 sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
357 sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
358 object_initialize_child(OBJECT(mms), "fpgaio",
359 &mms->fpgaio, TYPE_MPS2_FPGAIO);
360 qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", 25000000);
361 sysbus_realize(SYS_BUS_DEVICE(&mms->fpgaio), &error_fatal);
362 sysbus_mmio_map(SYS_BUS_DEVICE(&mms->fpgaio), 0, 0x40028000);
363 sysbus_create_simple(TYPE_PL022, 0x40025000,
364 qdev_get_gpio_in(armv7m, 22));
365 for (i = 0; i < 2; i++) {
366 static const int spi_irqno[] = {11, 24};
367 static const hwaddr spibase[] = {0x40020000,
368 0x40021000,
369 0x40026000,
370 0x40027000};
371 DeviceState *orgate_dev;
372 Object *orgate;
373 int j;
374
375 orgate = object_new(TYPE_OR_IRQ);
376 object_property_set_int(orgate, "num-lines", 2, &error_fatal);
377 orgate_dev = DEVICE(orgate);
378 qdev_realize(orgate_dev, NULL, &error_fatal);
379 qdev_connect_gpio_out(orgate_dev, 0,
380 qdev_get_gpio_in(armv7m, spi_irqno[i]));
381 for (j = 0; j < 2; j++) {
382 sysbus_create_simple(TYPE_PL022, spibase[2 * i + j],
383 qdev_get_gpio_in(orgate_dev, j));
384 }
385 }
386 for (i = 0; i < 4; i++) {
387 static const hwaddr i2cbase[] = {0x40022000,
388 0x40023000,
389 0x40029000,
390 0x4002a000};
391 sysbus_create_simple(TYPE_ARM_SBCON_I2C, i2cbase[i], NULL);
392 }
393 create_unimplemented_device("i2s", 0x40024000, 0x400);
394
395
396
397
398 lan9118_init(&nd_table[0], mmc->ethernet_base,
399 qdev_get_gpio_in(armv7m,
400 mmc->fpga_type == FPGA_AN511 ? 47 : 13));
401
402 system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
403
404 armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
405 0x400000);
406}
407
408static void mps2_class_init(ObjectClass *oc, void *data)
409{
410 MachineClass *mc = MACHINE_CLASS(oc);
411
412 mc->init = mps2_common_init;
413 mc->max_cpus = 1;
414 mc->default_ram_size = 16 * MiB;
415 mc->default_ram_id = "mps.ram";
416}
417
418static void mps2_an385_class_init(ObjectClass *oc, void *data)
419{
420 MachineClass *mc = MACHINE_CLASS(oc);
421 MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc);
422
423 mc->desc = "ARM MPS2 with AN385 FPGA image for Cortex-M3";
424 mmc->fpga_type = FPGA_AN385;
425 mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3");
426 mmc->scc_id = 0x41043850;
427 mmc->psram_base = 0x21000000;
428 mmc->ethernet_base = 0x40200000;
429 mmc->has_block_ram = true;
430}
431
432static void mps2_an386_class_init(ObjectClass *oc, void *data)
433{
434 MachineClass *mc = MACHINE_CLASS(oc);
435 MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc);
436
437 mc->desc = "ARM MPS2 with AN386 FPGA image for Cortex-M4";
438 mmc->fpga_type = FPGA_AN386;
439 mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m4");
440 mmc->scc_id = 0x41043860;
441 mmc->psram_base = 0x21000000;
442 mmc->ethernet_base = 0x40200000;
443 mmc->has_block_ram = true;
444}
445
446static void mps2_an500_class_init(ObjectClass *oc, void *data)
447{
448 MachineClass *mc = MACHINE_CLASS(oc);
449 MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc);
450
451 mc->desc = "ARM MPS2 with AN500 FPGA image for Cortex-M7";
452 mmc->fpga_type = FPGA_AN500;
453 mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m7");
454 mmc->scc_id = 0x41045000;
455 mmc->psram_base = 0x60000000;
456 mmc->ethernet_base = 0xa0000000;
457 mmc->has_block_ram = false;
458}
459
460static void mps2_an511_class_init(ObjectClass *oc, void *data)
461{
462 MachineClass *mc = MACHINE_CLASS(oc);
463 MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc);
464
465 mc->desc = "ARM MPS2 with AN511 DesignStart FPGA image for Cortex-M3";
466 mmc->fpga_type = FPGA_AN511;
467 mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3");
468 mmc->scc_id = 0x41045110;
469 mmc->psram_base = 0x21000000;
470 mmc->ethernet_base = 0x40200000;
471 mmc->has_block_ram = false;
472}
473
474static const TypeInfo mps2_info = {
475 .name = TYPE_MPS2_MACHINE,
476 .parent = TYPE_MACHINE,
477 .abstract = true,
478 .instance_size = sizeof(MPS2MachineState),
479 .class_size = sizeof(MPS2MachineClass),
480 .class_init = mps2_class_init,
481};
482
483static const TypeInfo mps2_an385_info = {
484 .name = TYPE_MPS2_AN385_MACHINE,
485 .parent = TYPE_MPS2_MACHINE,
486 .class_init = mps2_an385_class_init,
487};
488
489static const TypeInfo mps2_an386_info = {
490 .name = TYPE_MPS2_AN386_MACHINE,
491 .parent = TYPE_MPS2_MACHINE,
492 .class_init = mps2_an386_class_init,
493};
494
495static const TypeInfo mps2_an500_info = {
496 .name = TYPE_MPS2_AN500_MACHINE,
497 .parent = TYPE_MPS2_MACHINE,
498 .class_init = mps2_an500_class_init,
499};
500
501static const TypeInfo mps2_an511_info = {
502 .name = TYPE_MPS2_AN511_MACHINE,
503 .parent = TYPE_MPS2_MACHINE,
504 .class_init = mps2_an511_class_init,
505};
506
507static void mps2_machine_init(void)
508{
509 type_register_static(&mps2_info);
510 type_register_static(&mps2_an385_info);
511 type_register_static(&mps2_an386_info);
512 type_register_static(&mps2_an500_info);
513 type_register_static(&mps2_an511_info);
514}
515
516type_init(mps2_machine_init);
517