1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include "hw/sysbus.h"
23#include "hw/arm/arm.h"
24#include "hw/arm/primecell.h"
25#include "hw/devices.h"
26#include "net/net.h"
27#include "sysemu/sysemu.h"
28#include "hw/boards.h"
29#include "exec/address-spaces.h"
30#include "sysemu/blockdev.h"
31#include "hw/block/flash.h"
32#include "sysemu/device_tree.h"
33#include "qemu/error-report.h"
34#include "sysemu/kvm.h"
35#include <libfdt.h>
36
37#define FOUNDATION_BOARD_ID 0x8e0
38#define FOUNDATION_FLASH_SIZE (64 * 1024 * 1024)
39#define FOUNDATION_FLASH_SECT_SIZE (256 * 1024)
40
41
42
43
44#define NUM_VIRTIO_TRANSPORTS 4
45
46
47
48
49
50
51
52
53
54enum {
55 VE_TROM,
56 VE_TSRAM,
57 VE_TDRAM,
58 VE_SYSREGS,
59 VE_SP810,
60 VE_SERIALPCI,
61 VE_PL041,
62 VE_MMCI,
63 VE_KMI0,
64 VE_KMI1,
65 VE_UART0,
66 VE_UART1,
67 VE_UART2,
68 VE_UART3,
69 VE_WDT,
70 VE_TIMER01,
71 VE_TIMER23,
72 VE_SERIALDVI,
73 VE_RTC,
74 VE_COMPACTFLASH,
75 VE_CLCD,
76 VE_NORFLASH0,
77 VE_NORFLASH1,
78 VE_NORFLASHALIAS,
79 VE_SRAM,
80 VE_VIDEORAM,
81 VE_ETHERNET,
82 VE_USB,
83 VE_DAPROM,
84 VE_VIRTIO,
85};
86
87static hwaddr motherboard_aseries_map[] = {
88 [VE_NORFLASHALIAS] = -1,
89 [VE_TROM] = 0,
90 [VE_TSRAM] = 0x04000000,
91 [VE_TDRAM] = 0x06000000,
92
93 [VE_NORFLASH0] = 0x08000000,
94
95 [VE_NORFLASH1] = 0x0c000000,
96
97
98 [VE_SRAM] = 0x14000000,
99
100 [VE_VIDEORAM] = 0x18000000,
101 [VE_ETHERNET] = 0x1a000000,
102 [VE_USB] = 0x1b000000,
103
104 [VE_DAPROM] = 0x1c000000,
105 [VE_SYSREGS] = 0x1c010000,
106 [VE_SP810] = 0x1c020000,
107 [VE_SERIALPCI] = 0x1c030000,
108 [VE_PL041] = 0x1c040000,
109 [VE_MMCI] = 0x1c050000,
110 [VE_KMI0] = 0x1c060000,
111 [VE_KMI1] = 0x1c070000,
112 [VE_UART0] = 0x1c090000,
113 [VE_UART1] = 0x1c0a0000,
114 [VE_UART2] = 0x1c0b0000,
115 [VE_UART3] = 0x1c0c0000,
116 [VE_WDT] = 0x1c0f0000,
117 [VE_TIMER01] = 0x1c110000,
118 [VE_TIMER23] = 0x1c120000,
119 [VE_VIRTIO] = 0x1c130000,
120 [VE_SERIALDVI] = 0x1c160000,
121 [VE_RTC] = 0x1c170000,
122 [VE_COMPACTFLASH] = 0x1c1a0000,
123 [VE_CLCD] = 0x1c1f0000,
124};
125
126
127
128typedef struct VEDBoardInfo VEDBoardInfo;
129
130typedef void DBoardInitFn(const VEDBoardInfo *daughterboard,
131 ram_addr_t ram_size,
132 const char *cpu_model,
133 qemu_irq *pic);
134
135struct VEDBoardInfo {
136 struct arm_boot_info bootinfo;
137 const hwaddr *motherboard_map;
138 hwaddr loader_start;
139 const hwaddr gic_cpu_if_addr;
140 uint32_t proc_id;
141 uint32_t num_voltage_sensors;
142 const uint32_t *voltages;
143 uint32_t num_clocks;
144 const uint32_t *clocks;
145 DBoardInitFn *init;
146};
147
148static void init_cpus(const char *cpu_model, const char *privdev,
149 hwaddr periphbase, qemu_irq *pic)
150{
151 ObjectClass *cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
152 DeviceState *dev;
153 SysBusDevice *busdev;
154 int n;
155
156 if (!cpu_oc) {
157 fprintf(stderr, "Unable to find CPU definition\n");
158 exit(1);
159 }
160
161
162 for (n = 0; n < smp_cpus; n++) {
163 Object *cpuobj = object_new(object_class_get_name(cpu_oc));
164 Error *err = NULL;
165
166 object_property_set_int(cpuobj, 0x411fd000, "midr", &error_abort);
167 object_property_set_int(cpuobj, periphbase, "reset-cbar", &err);
168 err = NULL;
169 if (err) {
170 error_report("%s", error_get_pretty(err));
171 exit(1);
172 }
173 object_property_set_bool(cpuobj, true, "realized", &err);
174 if (err) {
175 error_report("%s", error_get_pretty(err));
176 exit(1);
177 }
178 }
179
180
181
182
183
184 dev = qdev_create(NULL, privdev);
185 qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
186 qdev_init_nofail(dev);
187 busdev = SYS_BUS_DEVICE(dev);
188 sysbus_mmio_map(busdev, 0, periphbase);
189
190
191
192
193
194
195
196 for (n = 0; n < 64; n++) {
197 pic[n] = qdev_get_gpio_in(dev, n);
198 }
199
200
201 for (n = 0; n < smp_cpus; n++) {
202 DeviceState *cpudev = DEVICE(qemu_get_cpu(n));
203
204 sysbus_connect_irq(busdev, n, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
205 if (!kvm_enabled()) {
206 sysbus_connect_irq(busdev, smp_cpus + n,
207 qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
208 }
209 }
210}
211
212static void a15_daughterboard_init(const VEDBoardInfo *daughterboard,
213 ram_addr_t ram_size,
214 const char *cpu_model,
215 qemu_irq *pic)
216{
217 MemoryRegion *sysmem = get_system_memory();
218 MemoryRegion *ram = g_new(MemoryRegion, 1);
219 MemoryRegion *ram2 = g_new(MemoryRegion, 1);
220 MemoryRegion *sram = g_new(MemoryRegion, 1);
221
222 if (!cpu_model) {
223 cpu_model = "cortex-a15";
224 }
225
226 {
227
228
229
230
231 uint64_t rsz = ram_size;
232 if (rsz > (30ULL * 1024 * 1024 * 1024)) {
233 fprintf(stderr, "vexpress-a15: cannot model more than 30GB RAM\n");
234 exit(1);
235 }
236 }
237
238 memory_region_init_ram(ram, NULL, "vexpress.highmem", ram_size,
239 &error_abort);
240 vmstate_register_ram_global(ram);
241
242 memory_region_add_subregion(sysmem, 0x80000000, ram);
243
244 memory_region_init_ram(ram2, NULL, "vexpress.highmem2", 32 * 1024 * 1024,
245 &error_abort);
246 vmstate_register_ram_global(ram2);
247
248 memory_region_add_subregion(sysmem, 0x88000000, ram2);
249
250
251
252 init_cpus(cpu_model, "a15mpcore_priv", 0x2c000000, pic);
253
254
255
256
257
258
259
260
261
262
263
264 memory_region_init_ram(sram, NULL, "vexpress.a15sram", 0x10000,
265 &error_abort);
266 vmstate_register_ram_global(sram);
267 memory_region_add_subregion(sysmem, 0x2e000000, sram);
268
269
270
271}
272
273static const uint32_t a15_voltages[] = {
274 900000,
275};
276
277static const uint32_t a15_clocks[] = {
278 60000000,
279 0,
280 0,
281 0,
282 40000000,
283 23750000,
284 50000000,
285 60000000,
286 40000000,
287};
288
289static VEDBoardInfo a15_daughterboard = {
290 .motherboard_map = motherboard_aseries_map,
291 .loader_start = 0x80000000,
292 .gic_cpu_if_addr = 0x2c002000,
293 .proc_id = 0x14000237,
294 .num_voltage_sensors = ARRAY_SIZE(a15_voltages),
295 .voltages = a15_voltages,
296 .num_clocks = ARRAY_SIZE(a15_clocks),
297 .clocks = a15_clocks,
298 .init = a15_daughterboard_init,
299};
300
301static int add_virtio_mmio_node(void *fdt, uint32_t acells, uint32_t scells,
302 hwaddr addr, hwaddr size, uint32_t intc,
303 int irq)
304{
305
306
307
308
309
310
311
312
313
314
315
316 int rc;
317 char *nodename = g_strdup_printf("/virtio_mmio@%" PRIx64, addr);
318
319 rc = qemu_fdt_add_subnode(fdt, nodename);
320 rc |= qemu_fdt_setprop_string(fdt, nodename,
321 "compatible", "virtio,mmio");
322 rc |= qemu_fdt_setprop_sized_cells(fdt, nodename, "reg",
323 acells, addr, scells, size);
324 qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", intc);
325 qemu_fdt_setprop_cells(fdt, nodename, "interrupts", 0, irq, 1);
326 g_free(nodename);
327 if (rc) {
328 return -1;
329 }
330 return 0;
331}
332
333static uint32_t find_int_controller(void *fdt)
334{
335
336
337
338
339
340
341 const char *compat = "arm,cortex-a9-gic";
342 int offset;
343
344 offset = fdt_node_offset_by_compatible(fdt, -1, compat);
345 if (offset >= 0) {
346 return fdt_get_phandle(fdt, offset);
347 }
348 return 0;
349}
350
351static void vexpress_modify_dtb(const struct arm_boot_info *info, void *fdt)
352{
353 uint32_t acells, scells, intc;
354 const VEDBoardInfo *daughterboard = (const VEDBoardInfo *)info;
355
356 acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells", 0, false, NULL);
357 scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells", 0, false, NULL);
358 intc = find_int_controller(fdt);
359 if (!intc) {
360
361
362
363 fprintf(stderr, "QEMU: warning: couldn't find interrupt controller in "
364 "dtb; will not include virtio-mmio devices in the dtb.\n");
365 } else {
366 int i;
367 const hwaddr *map = daughterboard->motherboard_map;
368
369
370
371
372 for (i = NUM_VIRTIO_TRANSPORTS - 1; i >= 0; i--) {
373 add_virtio_mmio_node(fdt, acells, scells,
374 map[VE_VIRTIO] + 0x200 * i,
375 0x200, intc, 40 + i);
376 }
377 }
378}
379
380
381
382
383
384static pflash_t *ve_pflash_cfi01_register(hwaddr base, const char *name,
385 DriveInfo *di)
386{
387 DeviceState *dev = qdev_create(NULL, "cfi.pflash01");
388
389 if (di && qdev_prop_set_drive(dev, "drive",
390 di ? blk_by_legacy_dinfo(di) : NULL)) {
391 abort();
392 }
393
394 qdev_prop_set_uint32(dev, "num-blocks",
395 FOUNDATION_FLASH_SIZE / FOUNDATION_FLASH_SECT_SIZE);
396 qdev_prop_set_uint64(dev, "sector-length", FOUNDATION_FLASH_SECT_SIZE);
397 qdev_prop_set_uint8(dev, "width", 4);
398 qdev_prop_set_uint8(dev, "device-width", 2);
399 qdev_prop_set_uint8(dev, "big-endian", 0);
400 qdev_prop_set_uint16(dev, "id0", 0x89);
401 qdev_prop_set_uint16(dev, "id1", 0x18);
402 qdev_prop_set_uint16(dev, "id2", 0x00);
403 qdev_prop_set_uint16(dev, "id3", 0x00);
404 qdev_prop_set_string(dev, "name", name);
405 qdev_init_nofail(dev);
406
407 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
408 return OBJECT_CHECK(pflash_t, (dev), "cfi.pflash01");
409}
410
411static void foundation_common_init(VEDBoardInfo *daughterboard,
412 MachineState *machine)
413{
414 DeviceState *dev, *sysctl, *pl041;
415 qemu_irq pic[64];
416 uint32_t sys_id;
417 DriveInfo *dinfo;
418 pflash_t *pflash0;
419 ram_addr_t vram_size, sram_size;
420 MemoryRegion *sysmem = get_system_memory();
421 MemoryRegion *vram = g_new(MemoryRegion, 1);
422 MemoryRegion *sram = g_new(MemoryRegion, 1);
423 MemoryRegion *trom = g_new(MemoryRegion, 1);
424 MemoryRegion *tsram = g_new(MemoryRegion, 1);
425 MemoryRegion *tdram = g_new(MemoryRegion, 1);
426 MemoryRegion *flashalias = g_new(MemoryRegion, 1);
427 MemoryRegion *flash0mem;
428 const hwaddr *map = daughterboard->motherboard_map;
429 int i;
430
431 daughterboard->init(daughterboard, machine->ram_size, machine->cpu_model, pic);
432
433
434
435
436
437 sys_id = 0x00100100;
438
439 sysctl = qdev_create(NULL, "realview_sysctl");
440 qdev_prop_set_uint32(sysctl, "sys_id", sys_id);
441 qdev_prop_set_uint32(sysctl, "proc_id", daughterboard->proc_id);
442 qdev_prop_set_uint32(sysctl, "len-db-voltage",
443 daughterboard->num_voltage_sensors);
444 for (i = 0; i < daughterboard->num_voltage_sensors; i++) {
445 char *propname = g_strdup_printf("db-voltage[%d]", i);
446 qdev_prop_set_uint32(sysctl, propname, daughterboard->voltages[i]);
447 g_free(propname);
448 }
449 qdev_prop_set_uint32(sysctl, "len-db-clock",
450 daughterboard->num_clocks);
451 for (i = 0; i < daughterboard->num_clocks; i++) {
452 char *propname = g_strdup_printf("db-clock[%d]", i);
453 qdev_prop_set_uint32(sysctl, propname, daughterboard->clocks[i]);
454 g_free(propname);
455 }
456 qdev_init_nofail(sysctl);
457 sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, map[VE_SYSREGS]);
458
459
460
461
462 pl041 = qdev_create(NULL, "pl041");
463 qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512);
464 qdev_init_nofail(pl041);
465 sysbus_mmio_map(SYS_BUS_DEVICE(pl041), 0, map[VE_PL041]);
466 sysbus_connect_irq(SYS_BUS_DEVICE(pl041), 0, pic[11]);
467
468 dev = sysbus_create_varargs("pl181", map[VE_MMCI], pic[9], pic[10], NULL);
469
470 qdev_connect_gpio_out(dev, 0,
471 qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT));
472 qdev_connect_gpio_out(dev, 1,
473 qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN));
474
475 sysbus_create_simple("pl050_keyboard", map[VE_KMI0], pic[12]);
476 sysbus_create_simple("pl050_mouse", map[VE_KMI1], pic[13]);
477
478 sysbus_create_simple("pl011", map[VE_UART0], pic[5]);
479 sysbus_create_simple("pl011", map[VE_UART1], pic[6]);
480 sysbus_create_simple("pl011", map[VE_UART2], pic[7]);
481 sysbus_create_simple("pl011", map[VE_UART3], pic[8]);
482
483 sysbus_create_simple("sp804", map[VE_TIMER01], pic[2]);
484 sysbus_create_simple("sp804", map[VE_TIMER23], pic[3]);
485
486
487
488 sysbus_create_simple("pl031", map[VE_RTC], pic[4]);
489
490
491
492 sysbus_create_simple("pl111", map[VE_CLCD], pic[14]);
493
494 dinfo = drive_get_next(IF_PFLASH);
495 pflash0 = ve_pflash_cfi01_register(map[VE_NORFLASH0], "vexpress.flash0",
496 dinfo);
497 if (!pflash0) {
498 fprintf(stderr, "vexpress: error registering flash 0.\n");
499 exit(1);
500 }
501
502 if (map[VE_NORFLASHALIAS] != -1) {
503
504 flash0mem = sysbus_mmio_get_region(SYS_BUS_DEVICE(pflash0), 0);
505 memory_region_init_alias(flashalias, NULL, "vexpress.flashalias",
506 flash0mem, 0, FOUNDATION_FLASH_SIZE);
507 memory_region_add_subregion(sysmem, map[VE_NORFLASHALIAS], flashalias);
508 }
509
510 dinfo = drive_get_next(IF_PFLASH);
511 if (!ve_pflash_cfi01_register(map[VE_NORFLASH1], "vexpress.flash1",
512 dinfo)) {
513 fprintf(stderr, "vexpress: error registering flash 1.\n");
514 exit(1);
515 }
516
517 memory_region_init_ram(trom, NULL, "vexpress.trom", 32 * 1024 * 1024,
518 &error_abort);
519 vmstate_register_ram_global(trom);
520 memory_region_add_subregion(sysmem, map[VE_TROM], trom);
521
522 memory_region_init_ram(tsram, NULL, "vexpress.tsram", 256 * 1024,
523 &error_abort);
524 vmstate_register_ram_global(tsram);
525 memory_region_add_subregion(sysmem, map[VE_TSRAM], tsram);
526
527 memory_region_init_ram(tdram, NULL, "vexpress.tdram", 32 * 1024 * 1024,
528 &error_abort);
529 vmstate_register_ram_global(tdram);
530 memory_region_add_subregion(sysmem, map[VE_TDRAM], tdram);
531
532 sram_size = 0x2000000;
533 memory_region_init_ram(sram, NULL, "vexpress.sram", sram_size,
534 &error_abort);
535 vmstate_register_ram_global(sram);
536 memory_region_add_subregion(sysmem, map[VE_SRAM], sram);
537
538 vram_size = 0x800000;
539 memory_region_init_ram(vram, NULL, "vexpress.vram", vram_size,
540 &error_abort);
541 vmstate_register_ram_global(vram);
542 memory_region_add_subregion(sysmem, map[VE_VIDEORAM], vram);
543
544
545 if (nd_table[0].used) {
546 lan9118_init(&nd_table[0], map[VE_ETHERNET], pic[15]);
547 }
548
549
550
551
552
553
554
555
556
557 for (i = 0; i < NUM_VIRTIO_TRANSPORTS; i++) {
558 sysbus_create_simple("virtio-mmio", map[VE_VIRTIO] + 0x200 * i,
559 pic[40 + i]);
560 }
561
562 daughterboard->bootinfo.ram_size = machine->ram_size;
563 daughterboard->bootinfo.kernel_filename = machine->kernel_filename;
564 daughterboard->bootinfo.kernel_cmdline = machine->kernel_cmdline;
565 daughterboard->bootinfo.initrd_filename = machine->initrd_filename;
566 daughterboard->bootinfo.nb_cpus = smp_cpus;
567 daughterboard->bootinfo.board_id = FOUNDATION_BOARD_ID;
568 daughterboard->bootinfo.loader_start = daughterboard->loader_start;
569 daughterboard->bootinfo.smp_loader_start = map[VE_SRAM];
570 daughterboard->bootinfo.smp_bootreg_addr = map[VE_SYSREGS] + 0x30;
571 daughterboard->bootinfo.gic_cpu_if_addr = daughterboard->gic_cpu_if_addr;
572 daughterboard->bootinfo.modify_dtb = vexpress_modify_dtb;
573 arm_load_kernel(ARM_CPU(first_cpu), &daughterboard->bootinfo);
574}
575
576static void foundation_init(MachineState *machine)
577{
578 foundation_common_init(&a15_daughterboard, machine);
579}
580
581static QEMUMachine foundation_machine = {
582 .name = "foundation",
583 .desc = "ARM Foundation model",
584 .init = foundation_init,
585 .block_default_type = IF_SCSI,
586 .max_cpus = 4,
587};
588
589static void vexpress_machine_init(void)
590{
591 qemu_register_machine(&foundation_machine);
592}
593
594machine_init(vexpress_machine_init);
595