vexpress.c (ef475b5dd12684591e6264e517eaa5b3e90f7ffa) vexpress.c (ba1ba5cca3962a9cc400c713c736b4fb8db1f38e)
1/*
2 * ARM Versatile Express emulation.
3 *
4 * Copyright (c) 2010 - 2011 B Labs Ltd.
5 * Copyright (c) 2011 Linaro Limited
6 * Written by Bahadir Balban, Amit Mahajan, Peter Maydell
7 *
8 * This program is free software; you can redistribute it and/or modify

--- 172 unchanged lines hidden (view full) ---

181 OBJECT_CHECK(VexpressMachineState, (obj), TYPE_VEXPRESS_MACHINE)
182#define VEXPRESS_MACHINE_GET_CLASS(obj) \
183 OBJECT_GET_CLASS(VexpressMachineClass, obj, TYPE_VEXPRESS_MACHINE)
184#define VEXPRESS_MACHINE_CLASS(klass) \
185 OBJECT_CLASS_CHECK(VexpressMachineClass, klass, TYPE_VEXPRESS_MACHINE)
186
187typedef void DBoardInitFn(const VexpressMachineState *machine,
188 ram_addr_t ram_size,
1/*
2 * ARM Versatile Express emulation.
3 *
4 * Copyright (c) 2010 - 2011 B Labs Ltd.
5 * Copyright (c) 2011 Linaro Limited
6 * Written by Bahadir Balban, Amit Mahajan, Peter Maydell
7 *
8 * This program is free software; you can redistribute it and/or modify

--- 172 unchanged lines hidden (view full) ---

181 OBJECT_CHECK(VexpressMachineState, (obj), TYPE_VEXPRESS_MACHINE)
182#define VEXPRESS_MACHINE_GET_CLASS(obj) \
183 OBJECT_GET_CLASS(VexpressMachineClass, obj, TYPE_VEXPRESS_MACHINE)
184#define VEXPRESS_MACHINE_CLASS(klass) \
185 OBJECT_CLASS_CHECK(VexpressMachineClass, klass, TYPE_VEXPRESS_MACHINE)
186
187typedef void DBoardInitFn(const VexpressMachineState *machine,
188 ram_addr_t ram_size,
189 const char *cpu_model,
189 const char *cpu_type,
190 qemu_irq *pic);
191
192struct VEDBoardInfo {
193 struct arm_boot_info bootinfo;
194 const hwaddr *motherboard_map;
195 hwaddr loader_start;
196 const hwaddr gic_cpu_if_addr;
197 uint32_t proc_id;
198 uint32_t num_voltage_sensors;
199 const uint32_t *voltages;
200 uint32_t num_clocks;
201 const uint32_t *clocks;
202 DBoardInitFn *init;
203};
204
190 qemu_irq *pic);
191
192struct VEDBoardInfo {
193 struct arm_boot_info bootinfo;
194 const hwaddr *motherboard_map;
195 hwaddr loader_start;
196 const hwaddr gic_cpu_if_addr;
197 uint32_t proc_id;
198 uint32_t num_voltage_sensors;
199 const uint32_t *voltages;
200 uint32_t num_clocks;
201 const uint32_t *clocks;
202 DBoardInitFn *init;
203};
204
205static void init_cpus(const char *cpu_model, const char *privdev,
205static void init_cpus(const char *cpu_type, const char *privdev,
206 hwaddr periphbase, qemu_irq *pic, bool secure)
207{
206 hwaddr periphbase, qemu_irq *pic, bool secure)
207{
208 ObjectClass *cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
209 DeviceState *dev;
210 SysBusDevice *busdev;
211 int n;
212
208 DeviceState *dev;
209 SysBusDevice *busdev;
210 int n;
211
213 if (!cpu_oc) {
214 fprintf(stderr, "Unable to find CPU definition\n");
215 exit(1);
216 }
217
218 /* Create the actual CPUs */
219 for (n = 0; n < smp_cpus; n++) {
212 /* Create the actual CPUs */
213 for (n = 0; n < smp_cpus; n++) {
220 Object *cpuobj = object_new(object_class_get_name(cpu_oc));
214 Object *cpuobj = object_new(cpu_type);
221
222 if (!secure) {
223 object_property_set_bool(cpuobj, false, "has_el3", NULL);
224 }
225
226 if (object_property_find(cpuobj, "reset-cbar", NULL)) {
227 object_property_set_int(cpuobj, periphbase,
228 "reset-cbar", &error_abort);

--- 28 unchanged lines hidden (view full) ---

257 sysbus_connect_irq(busdev, n, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
258 sysbus_connect_irq(busdev, n + smp_cpus,
259 qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
260 }
261}
262
263static void a9_daughterboard_init(const VexpressMachineState *vms,
264 ram_addr_t ram_size,
215
216 if (!secure) {
217 object_property_set_bool(cpuobj, false, "has_el3", NULL);
218 }
219
220 if (object_property_find(cpuobj, "reset-cbar", NULL)) {
221 object_property_set_int(cpuobj, periphbase,
222 "reset-cbar", &error_abort);

--- 28 unchanged lines hidden (view full) ---

251 sysbus_connect_irq(busdev, n, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
252 sysbus_connect_irq(busdev, n + smp_cpus,
253 qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
254 }
255}
256
257static void a9_daughterboard_init(const VexpressMachineState *vms,
258 ram_addr_t ram_size,
265 const char *cpu_model,
259 const char *cpu_type,
266 qemu_irq *pic)
267{
268 MemoryRegion *sysmem = get_system_memory();
269 MemoryRegion *ram = g_new(MemoryRegion, 1);
270 MemoryRegion *lowram = g_new(MemoryRegion, 1);
271 ram_addr_t low_ram_size;
272
260 qemu_irq *pic)
261{
262 MemoryRegion *sysmem = get_system_memory();
263 MemoryRegion *ram = g_new(MemoryRegion, 1);
264 MemoryRegion *lowram = g_new(MemoryRegion, 1);
265 ram_addr_t low_ram_size;
266
273 if (!cpu_model) {
274 cpu_model = "cortex-a9";
275 }
276
277 if (ram_size > 0x40000000) {
278 /* 1GB is the maximum the address space permits */
279 fprintf(stderr, "vexpress-a9: cannot model more than 1GB RAM\n");
280 exit(1);
281 }
282
283 memory_region_allocate_system_memory(ram, NULL, "vexpress.highmem",
284 ram_size);

--- 5 unchanged lines hidden (view full) ---

290 * address space should in theory be remappable to various
291 * things including ROM or RAM; we always map the RAM there.
292 */
293 memory_region_init_alias(lowram, NULL, "vexpress.lowmem", ram, 0, low_ram_size);
294 memory_region_add_subregion(sysmem, 0x0, lowram);
295 memory_region_add_subregion(sysmem, 0x60000000, ram);
296
297 /* 0x1e000000 A9MPCore (SCU) private memory region */
267 if (ram_size > 0x40000000) {
268 /* 1GB is the maximum the address space permits */
269 fprintf(stderr, "vexpress-a9: cannot model more than 1GB RAM\n");
270 exit(1);
271 }
272
273 memory_region_allocate_system_memory(ram, NULL, "vexpress.highmem",
274 ram_size);

--- 5 unchanged lines hidden (view full) ---

280 * address space should in theory be remappable to various
281 * things including ROM or RAM; we always map the RAM there.
282 */
283 memory_region_init_alias(lowram, NULL, "vexpress.lowmem", ram, 0, low_ram_size);
284 memory_region_add_subregion(sysmem, 0x0, lowram);
285 memory_region_add_subregion(sysmem, 0x60000000, ram);
286
287 /* 0x1e000000 A9MPCore (SCU) private memory region */
298 init_cpus(cpu_model, TYPE_A9MPCORE_PRIV, 0x1e000000, pic, vms->secure);
288 init_cpus(cpu_type, TYPE_A9MPCORE_PRIV, 0x1e000000, pic, vms->secure);
299
300 /* Daughterboard peripherals : 0x10020000 .. 0x20000000 */
301
302 /* 0x10020000 PL111 CLCD (daughterboard) */
303 sysbus_create_simple("pl111", 0x10020000, pic[44]);
304
305 /* 0x10060000 AXI RAM */
306 /* 0x100e0000 PL341 Dynamic Memory Controller */

--- 39 unchanged lines hidden (view full) ---

346 .voltages = a9_voltages,
347 .num_clocks = ARRAY_SIZE(a9_clocks),
348 .clocks = a9_clocks,
349 .init = a9_daughterboard_init,
350};
351
352static void a15_daughterboard_init(const VexpressMachineState *vms,
353 ram_addr_t ram_size,
289
290 /* Daughterboard peripherals : 0x10020000 .. 0x20000000 */
291
292 /* 0x10020000 PL111 CLCD (daughterboard) */
293 sysbus_create_simple("pl111", 0x10020000, pic[44]);
294
295 /* 0x10060000 AXI RAM */
296 /* 0x100e0000 PL341 Dynamic Memory Controller */

--- 39 unchanged lines hidden (view full) ---

336 .voltages = a9_voltages,
337 .num_clocks = ARRAY_SIZE(a9_clocks),
338 .clocks = a9_clocks,
339 .init = a9_daughterboard_init,
340};
341
342static void a15_daughterboard_init(const VexpressMachineState *vms,
343 ram_addr_t ram_size,
354 const char *cpu_model,
344 const char *cpu_type,
355 qemu_irq *pic)
356{
357 MemoryRegion *sysmem = get_system_memory();
358 MemoryRegion *ram = g_new(MemoryRegion, 1);
359 MemoryRegion *sram = g_new(MemoryRegion, 1);
360
345 qemu_irq *pic)
346{
347 MemoryRegion *sysmem = get_system_memory();
348 MemoryRegion *ram = g_new(MemoryRegion, 1);
349 MemoryRegion *sram = g_new(MemoryRegion, 1);
350
361 if (!cpu_model) {
362 cpu_model = "cortex-a15";
363 }
364
365 {
366 /* We have to use a separate 64 bit variable here to avoid the gcc
367 * "comparison is always false due to limited range of data type"
368 * warning if we are on a host where ram_addr_t is 32 bits.
369 */
370 uint64_t rsz = ram_size;
371 if (rsz > (30ULL * 1024 * 1024 * 1024)) {
372 fprintf(stderr, "vexpress-a15: cannot model more than 30GB RAM\n");
373 exit(1);
374 }
375 }
376
377 memory_region_allocate_system_memory(ram, NULL, "vexpress.highmem",
378 ram_size);
379 /* RAM is from 0x80000000 upwards; there is no low-memory alias for it. */
380 memory_region_add_subregion(sysmem, 0x80000000, ram);
381
382 /* 0x2c000000 A15MPCore private memory region (GIC) */
351 {
352 /* We have to use a separate 64 bit variable here to avoid the gcc
353 * "comparison is always false due to limited range of data type"
354 * warning if we are on a host where ram_addr_t is 32 bits.
355 */
356 uint64_t rsz = ram_size;
357 if (rsz > (30ULL * 1024 * 1024 * 1024)) {
358 fprintf(stderr, "vexpress-a15: cannot model more than 30GB RAM\n");
359 exit(1);
360 }
361 }
362
363 memory_region_allocate_system_memory(ram, NULL, "vexpress.highmem",
364 ram_size);
365 /* RAM is from 0x80000000 upwards; there is no low-memory alias for it. */
366 memory_region_add_subregion(sysmem, 0x80000000, ram);
367
368 /* 0x2c000000 A15MPCore private memory region (GIC) */
383 init_cpus(cpu_model, TYPE_A15MPCORE_PRIV, 0x2c000000, pic, vms->secure);
369 init_cpus(cpu_type, TYPE_A15MPCORE_PRIV, 0x2c000000, pic, vms->secure);
384
385 /* A15 daughterboard peripherals: */
386
387 /* 0x20000000: CoreSight interfaces: not modelled */
388 /* 0x2a000000: PL301 AXI interconnect: not modelled */
389 /* 0x2a420000: SCC: not modelled */
390 /* 0x2a430000: system counter: not modelled */
391 /* 0x2b000000: HDLCD controller: not modelled */

--- 163 unchanged lines hidden (view full) ---

555 MemoryRegion *sysmem = get_system_memory();
556 MemoryRegion *vram = g_new(MemoryRegion, 1);
557 MemoryRegion *sram = g_new(MemoryRegion, 1);
558 MemoryRegion *flashalias = g_new(MemoryRegion, 1);
559 MemoryRegion *flash0mem;
560 const hwaddr *map = daughterboard->motherboard_map;
561 int i;
562
370
371 /* A15 daughterboard peripherals: */
372
373 /* 0x20000000: CoreSight interfaces: not modelled */
374 /* 0x2a000000: PL301 AXI interconnect: not modelled */
375 /* 0x2a420000: SCC: not modelled */
376 /* 0x2a430000: system counter: not modelled */
377 /* 0x2b000000: HDLCD controller: not modelled */

--- 163 unchanged lines hidden (view full) ---

541 MemoryRegion *sysmem = get_system_memory();
542 MemoryRegion *vram = g_new(MemoryRegion, 1);
543 MemoryRegion *sram = g_new(MemoryRegion, 1);
544 MemoryRegion *flashalias = g_new(MemoryRegion, 1);
545 MemoryRegion *flash0mem;
546 const hwaddr *map = daughterboard->motherboard_map;
547 int i;
548
563 daughterboard->init(vms, machine->ram_size, machine->cpu_model, pic);
549 daughterboard->init(vms, machine->ram_size, machine->cpu_type, pic);
564
565 /*
566 * If a bios file was provided, attempt to map it into memory
567 */
568 if (bios_name) {
569 char *fn;
570 int image_size;
571

--- 184 unchanged lines hidden (view full) ---

756}
757
758static void vexpress_a9_class_init(ObjectClass *oc, void *data)
759{
760 MachineClass *mc = MACHINE_CLASS(oc);
761 VexpressMachineClass *vmc = VEXPRESS_MACHINE_CLASS(oc);
762
763 mc->desc = "ARM Versatile Express for Cortex-A9";
550
551 /*
552 * If a bios file was provided, attempt to map it into memory
553 */
554 if (bios_name) {
555 char *fn;
556 int image_size;
557

--- 184 unchanged lines hidden (view full) ---

742}
743
744static void vexpress_a9_class_init(ObjectClass *oc, void *data)
745{
746 MachineClass *mc = MACHINE_CLASS(oc);
747 VexpressMachineClass *vmc = VEXPRESS_MACHINE_CLASS(oc);
748
749 mc->desc = "ARM Versatile Express for Cortex-A9";
750 mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a9");
764
765 vmc->daughterboard = &a9_daughterboard;
766}
767
768static void vexpress_a15_class_init(ObjectClass *oc, void *data)
769{
770 MachineClass *mc = MACHINE_CLASS(oc);
771 VexpressMachineClass *vmc = VEXPRESS_MACHINE_CLASS(oc);
772
773 mc->desc = "ARM Versatile Express for Cortex-A15";
751
752 vmc->daughterboard = &a9_daughterboard;
753}
754
755static void vexpress_a15_class_init(ObjectClass *oc, void *data)
756{
757 MachineClass *mc = MACHINE_CLASS(oc);
758 VexpressMachineClass *vmc = VEXPRESS_MACHINE_CLASS(oc);
759
760 mc->desc = "ARM Versatile Express for Cortex-A15";
761 mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
774
775 vmc->daughterboard = &a15_daughterboard;
776}
777
778static const TypeInfo vexpress_info = {
779 .name = TYPE_VEXPRESS_MACHINE,
780 .parent = TYPE_MACHINE,
781 .abstract = true,

--- 26 unchanged lines hidden ---
762
763 vmc->daughterboard = &a15_daughterboard;
764}
765
766static const TypeInfo vexpress_info = {
767 .name = TYPE_VEXPRESS_MACHINE,
768 .parent = TYPE_MACHINE,
769 .abstract = true,

--- 26 unchanged lines hidden ---