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