static void puv3_soc_init(CPUUniCore32State *env) { qemu_irq *cpu_intc, irqs[PUV3_IRQS_NR]; DeviceState *dev; MemoryRegion *i8042 = g_new(MemoryRegion, 1); int i; /* Initialize interrupt controller */ cpu_intc = qemu_allocate_irqs(puv3_intc_cpu_handler, env, 1); dev = sysbus_create_simple("puv3_intc", PUV3_INTC_BASE, *cpu_intc); for (i = 0; i < PUV3_IRQS_NR; i++) { irqs[i] = qdev_get_gpio_in(dev, i); } /* Initialize minimal necessary devices for kernel booting */ sysbus_create_simple("puv3_pm", PUV3_PM_BASE, NULL); sysbus_create_simple("puv3_dma", PUV3_DMA_BASE, NULL); sysbus_create_simple("puv3_ost", PUV3_OST_BASE, irqs[PUV3_IRQS_OST0]); sysbus_create_varargs("puv3_gpio", PUV3_GPIO_BASE, irqs[PUV3_IRQS_GPIOLOW0], irqs[PUV3_IRQS_GPIOLOW1], irqs[PUV3_IRQS_GPIOLOW2], irqs[PUV3_IRQS_GPIOLOW3], irqs[PUV3_IRQS_GPIOLOW4], irqs[PUV3_IRQS_GPIOLOW5], irqs[PUV3_IRQS_GPIOLOW6], irqs[PUV3_IRQS_GPIOLOW7], irqs[PUV3_IRQS_GPIOHIGH], NULL); /* Keyboard (i8042), mouse disabled for nographic */ i8042_mm_init(irqs[PUV3_IRQS_PS2_KBD], NULL, i8042, PUV3_REGS_OFFSET, 4); memory_region_add_subregion(get_system_memory(), PUV3_PS2_BASE, i8042); }
static void a9_daughterboard_init(const VEDBoardInfo *daughterboard, ram_addr_t ram_size, const char *cpu_model, qemu_irq *pic) { MemoryRegion *sysmem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *lowram = g_new(MemoryRegion, 1); ram_addr_t low_ram_size; if (!cpu_model) { cpu_model = "cortex-a9"; } if (ram_size > 0x40000000) { /* 1GB is the maximum the address space permits */ fprintf(stderr, "vexpress-a9: cannot model more than 1GB RAM\n"); exit(1); } memory_region_init_ram(ram, NULL, "vexpress.highmem", ram_size, &error_abort); vmstate_register_ram_global(ram); low_ram_size = ram_size; if (low_ram_size > 0x4000000) { low_ram_size = 0x4000000; } /* RAM is from 0x60000000 upwards. The bottom 64MB of the * address space should in theory be remappable to various * things including ROM or RAM; we always map the RAM there. */ memory_region_init_alias(lowram, NULL, "vexpress.lowmem", ram, 0, low_ram_size); memory_region_add_subregion(sysmem, 0x0, lowram); memory_region_add_subregion(sysmem, 0x60000000, ram); /* 0x1e000000 A9MPCore (SCU) private memory region */ init_cpus(cpu_model, "a9mpcore_priv", 0x1e000000, pic); /* Daughterboard peripherals : 0x10020000 .. 0x20000000 */ /* 0x10020000 PL111 CLCD (daughterboard) */ sysbus_create_simple("pl111", 0x10020000, pic[44]); /* 0x10060000 AXI RAM */ /* 0x100e0000 PL341 Dynamic Memory Controller */ /* 0x100e1000 PL354 Static Memory Controller */ /* 0x100e2000 System Configuration Controller */ sysbus_create_simple("sp804", 0x100e4000, pic[48]); /* 0x100e5000 SP805 Watchdog module */ /* 0x100e6000 BP147 TrustZone Protection Controller */ /* 0x100e9000 PL301 'Fast' AXI matrix */ /* 0x100ea000 PL301 'Slow' AXI matrix */ /* 0x100ec000 TrustZone Address Space Controller */ /* 0x10200000 CoreSight debug APB */ /* 0x1e00a000 PL310 L2 Cache Controller */ sysbus_create_varargs("l2x0", 0x1e00a000, NULL); }
static int realview_mpcore_init(SysBusDevice *dev) { mpcore_rirq_state *s = FROM_SYSBUS(mpcore_rirq_state, dev); DeviceState *gic; DeviceState *priv; int n; int i; priv = qdev_create(NULL, "arm11mpcore_priv"); qdev_prop_set_uint32(priv, "num-cpu", s->num_cpu); qdev_init_nofail(priv); s->priv = SYS_BUS_DEVICE(priv); sysbus_pass_irq(dev, s->priv); for (i = 0; i < 32; i++) { s->cpuic[i] = qdev_get_gpio_in(priv, i); } /* ??? IRQ routing is hardcoded to "normal" mode. */ for (n = 0; n < 4; n++) { gic = sysbus_create_simple("realview_gic", 0x10040000 + n * 0x10000, s->cpuic[10 + n]); for (i = 0; i < 64; i++) { s->rvic[n][i] = qdev_get_gpio_in(gic, i); } } qdev_init_gpio_in(&dev->qdev, mpcore_rirq_set_irq, 64); sysbus_init_mmio(dev, sysbus_mmio_get_region(s->priv, 0)); return 0; }
static void collie_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { StrongARMState *s; DriveInfo *dinfo; ram_addr_t phys_flash; if (!cpu_model) { cpu_model = "sa1110"; } s = sa1110_init(collie_binfo.ram_size, cpu_model); phys_flash = qemu_ram_alloc(NULL, "collie.fl1", 0x02000000); dinfo = drive_get(IF_PFLASH, 0, 0); pflash_cfi01_register(SA_CS0, phys_flash, dinfo ? dinfo->bdrv : NULL, (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0); phys_flash = qemu_ram_alloc(NULL, "collie.fl2", 0x02000000); dinfo = drive_get(IF_PFLASH, 0, 1); pflash_cfi01_register(SA_CS1, phys_flash, dinfo ? dinfo->bdrv : NULL, (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0); sysbus_create_simple("scoop", 0x40800000, NULL); collie_binfo.kernel_filename = kernel_filename; collie_binfo.kernel_cmdline = kernel_cmdline; collie_binfo.initrd_filename = initrd_filename; collie_binfo.board_id = 0x208; arm_load_kernel(s->env, &collie_binfo); }
static void apic_common_realize(DeviceState *dev, Error **errp) { APICCommonState *s = APIC_COMMON(dev); APICCommonClass *info; static DeviceState *vapic; int instance_id = s->id; info = APIC_COMMON_GET_CLASS(s); info->realize(dev, errp); /* Note: We need at least 1M to map the VAPIC option ROM */ if (!vapic && s->vapic_control & VAPIC_ENABLE_MASK && ram_size >= 1024 * 1024) { vapic = sysbus_create_simple("kvmvapic", -1, NULL); } s->vapic = vapic; if (apic_report_tpr_access && info->enable_tpr_reporting) { info->enable_tpr_reporting(s, true); } if (s->legacy_instance_id) { instance_id = -1; } vmstate_register_with_alias_id(NULL, instance_id, &vmstate_apic_common, s, -1, 0); }
static int apic_init_common(SysBusDevice *dev) { APICCommonState *s = APIC_COMMON(dev); APICCommonClass *info; static DeviceState *vapic; static int apic_no; if (apic_no >= MAX_APICS) { return -1; } s->idx = apic_no++; info = APIC_COMMON_GET_CLASS(s); info->init(s); sysbus_init_mmio(dev, &s->io_memory); /* Note: We need at least 1M to map the VAPIC option ROM */ if (!vapic && s->vapic_control & VAPIC_ENABLE_MASK && ram_size >= 1024 * 1024) { vapic = sysbus_create_simple("kvmvapic", -1, NULL); } s->vapic = vapic; if (apic_report_tpr_access && info->enable_tpr_reporting) { info->enable_tpr_reporting(s, true); } return 0; }
static void apic_common_realize(DeviceState *dev, Error **errp) { APICCommonState *s = APIC_COMMON(dev); APICCommonClass *info; static DeviceState *vapic; static int apic_no; static bool mmio_registered; if (apic_no >= MAX_APICS) { error_setg(errp, "%s initialization failed.", object_get_typename(OBJECT(dev))); return; } s->idx = apic_no++; info = APIC_COMMON_GET_CLASS(s); info->realize(dev, errp); if (!mmio_registered) { ICCBus *b = ICC_BUS(qdev_get_parent_bus(dev)); memory_region_add_subregion(b->apic_address_space, 0, &s->io_memory); mmio_registered = true; } /* Note: We need at least 1M to map the VAPIC option ROM */ if (!vapic && s->vapic_control & VAPIC_ENABLE_MASK && ram_size >= 1024 * 1024) { vapic = sysbus_create_simple("kvmvapic", -1, NULL); } s->vapic = vapic; if (apic_report_tpr_access && info->enable_tpr_reporting) { info->enable_tpr_reporting(s, true); } }
/* Note: Must be called after VCPU initialization. */ void kvmclock_create(void) { if (kvm_enabled() && first_cpu->cpuid_kvm_features & (1ULL << KVM_FEATURE_CLOCKSOURCE)) { sysbus_create_simple("kvmclock", -1, NULL); } }
static void apic_common_realize(DeviceState *dev, Error **errp) { APICCommonState *s = APIC_COMMON(dev); APICCommonClass *info; static DeviceState *vapic; static int apic_no; if (apic_no >= MAX_APICS) { error_setg(errp, "%s initialization failed.", object_get_typename(OBJECT(dev))); return; } s->idx = apic_no++; info = APIC_COMMON_GET_CLASS(s); info->realize(dev, errp); /* Note: We need at least 1M to map the VAPIC option ROM */ if (!vapic && s->vapic_control & VAPIC_ENABLE_MASK && ram_size >= 1024 * 1024) { vapic = sysbus_create_simple("kvmvapic", -1, NULL); } s->vapic = vapic; if (apic_report_tpr_access && info->enable_tpr_reporting) { info->enable_tpr_reporting(s, true); } }
static void collie_init(QEMUMachineInitArgs *args) { const char *cpu_model = args->cpu_model; const char *kernel_filename = args->kernel_filename; const char *kernel_cmdline = args->kernel_cmdline; const char *initrd_filename = args->initrd_filename; StrongARMState *s; DriveInfo *dinfo; MemoryRegion *sysmem = get_system_memory(); if (!cpu_model) { cpu_model = "sa1110"; } s = sa1110_init(sysmem, collie_binfo.ram_size, cpu_model); dinfo = drive_get(IF_PFLASH, 0, 0); pflash_cfi01_register(SA_CS0, NULL, "collie.fl1", 0x02000000, dinfo ? dinfo->bdrv : NULL, (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0); dinfo = drive_get(IF_PFLASH, 0, 1); pflash_cfi01_register(SA_CS1, NULL, "collie.fl2", 0x02000000, dinfo ? dinfo->bdrv : NULL, (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0); sysbus_create_simple("scoop", 0x40800000, NULL); collie_binfo.kernel_filename = kernel_filename; collie_binfo.kernel_cmdline = kernel_cmdline; collie_binfo.initrd_filename = initrd_filename; collie_binfo.board_id = 0x208; arm_load_kernel(s->cpu, &collie_binfo); }
static void stm32l152rbt6_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { //Préparation de la mémoire MemoryRegion *address_space_mem = get_system_memory(); uint16_t flash_size = stm32_board.f_size; //128KBits uint16_t sram_size = 0x0010; //16 KBits //Initialisation du processeur (+ mémoire) qemu_irq* pic = armv7m_init(address_space_mem, flash_size, sram_size, kernel_filename, cpu_model); stm32l_sys_init(0x1FF00000, pic[28], &stm32_board); //FIXME: Vérifier l'implémentation de la sys memory //Structures GPIO static const uint32_t gpio_addr[NB_GPIO] = { 0x40020000, //GPIO_A 0x40020400, //GPIO_B 0x40020800, //GPIO_C 0x40020C00, //GPIO_D 0x40021000, //GPIO_E 0x40021400 //GPIO_H }; // static const int gpio_idIrqNVIC[NB_NVIC_IRQ] = {6,7,8,9,10}; DeviceState* gpio_dev[NB_GPIO]; //Création du bouton DeviceState* button = sysbus_create_simple("stm32_button", -1, NULL); //Création des leds DeviceState* led_dev6 = sysbus_create_simple("stm32_led_blue", -1, NULL); DeviceState* led_dev7 = sysbus_create_simple("stm32_led_green", -1, NULL); //Initialisation du GPIO_A gpio_dev[GPIO_A] = sysbus_create_varargs("stm32_gpio_A", gpio_addr[GPIO_A], NULL); //, pic[gpio_idIrqNVIC[0]], pic[gpio_idIrqNVIC[1]], pic[gpio_idIrqNVIC[2]], pic[gpio_idIrqNVIC[3]], pic[gpio_idIrqNVIC[4]], NULL); qemu_irq entreeBouton = qdev_get_gpio_in(gpio_dev[GPIO_A], 0); qdev_connect_gpio_out(button, 0, entreeBouton); //Initialisation du GPIO_B gpio_dev[GPIO_B] = sysbus_create_varargs("stm32_gpio_B", gpio_addr[GPIO_B], NULL); //, pic[gpio_idIrqNVIC[0]], pic[gpio_idIrqNVIC[1]], pic[gpio_idIrqNVIC[2]], pic[gpio_idIrqNVIC[3]], pic[gpio_idIrqNVIC[4]], NULL); qemu_irq entreeLED6 = qdev_get_gpio_in(led_dev6, 0); qdev_connect_gpio_out(gpio_dev[GPIO_B], 6, entreeLED6); qemu_irq entreeLED7 = qdev_get_gpio_in(led_dev7, 0); qdev_connect_gpio_out(gpio_dev[GPIO_B], 7, entreeLED7); }
void pc_basic_device_init(qemu_irq *isa_irq, FDCtrl **floppy_controller, ISADevice **rtc_state) { int i; DriveInfo *fd[MAX_FD]; PITState *pit; qemu_irq rtc_irq = NULL; qemu_irq *a20_line; ISADevice *i8042; qemu_irq *cpu_exit_irq; register_ioport_write(0x80, 1, 1, ioport80_write, NULL); register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL); if (!no_hpet) { DeviceState *hpet = sysbus_create_simple("hpet", HPET_BASE, NULL); for (i = 0; i < 24; i++) { sysbus_connect_irq(sysbus_from_qdev(hpet), i, isa_irq[i]); } rtc_irq = qdev_get_gpio_in(hpet, 0); } *rtc_state = rtc_init(2000, rtc_irq); qemu_register_boot_set(pc_boot_set, *rtc_state); pit = pit_init(0x40, isa_reserve_irq(0)); pcspk_init(pit); for(i = 0; i < MAX_SERIAL_PORTS; i++) { if (serial_hds[i]) { serial_isa_init(i, serial_hds[i]); } } for(i = 0; i < MAX_PARALLEL_PORTS; i++) { if (parallel_hds[i]) { parallel_init(i, parallel_hds[i]); } } a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 1); i8042 = isa_create_simple("i8042"); i8042_setup_a20_line(i8042, a20_line); vmmouse_init(i8042); cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1); DMA_init(0, cpu_exit_irq); for(i = 0; i < MAX_FD; i++) { fd[i] = drive_get(IF_FLOPPY, 0, i); } *floppy_controller = fdctrl_init_isa(fd); }
/* Note: Must be called after VCPU initialization. */ void kvmclock_create(void) { X86CPU *cpu = X86_CPU(first_cpu); if (kvm_enabled() && cpu->env.features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) | (1ULL << KVM_FEATURE_CLOCKSOURCE2))) { sysbus_create_simple(TYPE_KVM_CLOCK, -1, NULL); } }
static void petalogix_s3adsp1800_init(QEMUMachineInitArgs *args) { ram_addr_t ram_size = args->ram_size; const char *cpu_model = args->cpu_model; DeviceState *dev; MicroBlazeCPU *cpu; CPUMBState *env; DriveInfo *dinfo; int i; hwaddr ddr_base = MEMORY_BASEADDR; MemoryRegion *phys_lmb_bram = g_new(MemoryRegion, 1); MemoryRegion *phys_ram = g_new(MemoryRegion, 1); qemu_irq irq[32], *cpu_irq; MemoryRegion *sysmem = get_system_memory(); /* init CPUs */ if (cpu_model == NULL) { cpu_model = "microblaze"; } cpu = cpu_mb_init(cpu_model); env = &cpu->env; /* Attach emulated BRAM through the LMB. */ memory_region_init_ram(phys_lmb_bram, "petalogix_s3adsp1800.lmb_bram", LMB_BRAM_SIZE); vmstate_register_ram_global(phys_lmb_bram); memory_region_add_subregion(sysmem, 0x00000000, phys_lmb_bram); memory_region_init_ram(phys_ram, "petalogix_s3adsp1800.ram", ram_size); vmstate_register_ram_global(phys_ram); memory_region_add_subregion(sysmem, ddr_base, phys_ram); dinfo = drive_get(IF_PFLASH, 0, 0); pflash_cfi01_register(FLASH_BASEADDR, NULL, "petalogix_s3adsp1800.flash", FLASH_SIZE, dinfo ? dinfo->bdrv : NULL, (64 * 1024), FLASH_SIZE >> 16, 1, 0x89, 0x18, 0x0000, 0x0, 1); cpu_irq = microblaze_pic_init_cpu(env); dev = xilinx_intc_create(INTC_BASEADDR, cpu_irq[0], 2); for (i = 0; i < 32; i++) { irq[i] = qdev_get_gpio_in(dev, i); } sysbus_create_simple("xlnx.xps-uartlite", UARTLITE_BASEADDR, irq[3]); /* 2 timers at irq 2 @ 62 Mhz. */ xilinx_timer_create(TIMER_BASEADDR, irq[0], 0, 62 * 1000000); xilinx_ethlite_create(&nd_table[0], ETHLITE_BASEADDR, irq[1], 0, 0); microblaze_load_kernel(cpu, ddr_base, ram_size, BINARY_DEVICE_TREE_FILE, machine_cpu_reset); }
static inline void zynq_init_zc70x_i2c(uint32_t base_addr, qemu_irq irq) { DeviceState *dev = sysbus_create_simple("cdns.i2c-r1p10", base_addr, irq); I2CBus *i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c"); int i, bus; dev = i2c_create_slave(i2c, "pca9548", 0); for (bus = 2; bus <= 3; bus++) { char bus_name[16]; snprintf(bus_name, sizeof(bus_name), "i2c@%d", bus); i2c = (I2CBus *)qdev_get_child_bus(dev, bus_name); assert(i2c); assert(NUM_I2C_EEPROMS <= 2); /* not enough address space for anymore */ for (i = 0; i < NUM_I2C_EEPROMS; ++i) { DeviceState *eeprom_dev = i2c_create_slave_no_init(i2c, "at.24c08", 0x50 + 0x4 * i); qdev_prop_set_uint16(eeprom_dev, "size", 1024); /* M24C08 */ qdev_init_nofail(eeprom_dev); } } }
static void a9_daughterboard_init(const VEDBoardInfo *daughterboard, ram_addr_t ram_size, const char *cpu_model, qemu_irq *pic) { MemoryRegion *sysmem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *lowram = g_new(MemoryRegion, 1); DeviceState *dev; SysBusDevice *busdev; int n; qemu_irq cpu_irq[4]; ram_addr_t low_ram_size; if (!cpu_model) { cpu_model = "cortex-a9"; } for (n = 0; n < smp_cpus; n++) { ARMCPU *cpu = cpu_arm_init(cpu_model); if (!cpu) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ); } if (ram_size > 0x40000000) { /* 1GB is the maximum the address space permits */ fprintf(stderr, "vexpress-a9: cannot model more than 1GB RAM\n"); exit(1); } memory_region_init_ram(ram, NULL, "vexpress.highmem", ram_size); vmstate_register_ram_global(ram); low_ram_size = ram_size; if (low_ram_size > 0x4000000) { low_ram_size = 0x4000000; } /* RAM is from 0x60000000 upwards. The bottom 64MB of the * address space should in theory be remappable to various * things including ROM or RAM; we always map the RAM there. */ memory_region_init_alias(lowram, NULL, "vexpress.lowmem", ram, 0, low_ram_size); memory_region_add_subregion(sysmem, 0x0, lowram); memory_region_add_subregion(sysmem, 0x60000000, ram); /* 0x1e000000 A9MPCore (SCU) private memory region */ dev = qdev_create(NULL, "a9mpcore_priv"); qdev_prop_set_uint32(dev, "num-cpu", smp_cpus); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_mmio_map(busdev, 0, 0x1e000000); for (n = 0; n < smp_cpus; n++) { sysbus_connect_irq(busdev, n, cpu_irq[n]); } /* Interrupts [42:0] are from the motherboard; * [47:43] are reserved; [63:48] are daughterboard * peripherals. Note that some documentation numbers * external interrupts starting from 32 (because the * A9MP has internal interrupts 0..31). */ for (n = 0; n < 64; n++) { pic[n] = qdev_get_gpio_in(dev, n); } /* Daughterboard peripherals : 0x10020000 .. 0x20000000 */ /* 0x10020000 PL111 CLCD (daughterboard) */ sysbus_create_simple("pl111", 0x10020000, pic[44]); /* 0x10060000 AXI RAM */ /* 0x100e0000 PL341 Dynamic Memory Controller */ /* 0x100e1000 PL354 Static Memory Controller */ /* 0x100e2000 System Configuration Controller */ sysbus_create_simple("sp804", 0x100e4000, pic[48]); /* 0x100e5000 SP805 Watchdog module */ /* 0x100e6000 BP147 TrustZone Protection Controller */ /* 0x100e9000 PL301 'Fast' AXI matrix */ /* 0x100ea000 PL301 'Slow' AXI matrix */ /* 0x100ec000 TrustZone Address Space Controller */ /* 0x10200000 CoreSight debug APB */ /* 0x1e00a000 PL310 L2 Cache Controller */ sysbus_create_varargs("l2x0", 0x1e00a000, NULL); }
/* ram_size must be set to match the upper bound of memory in the * device tree (linux/arch/arm/boot/dts/highbank.dts), which is * normally 0xff900000 or -m 4089. When running this board on a * 32-bit host, set the reg value of memory to 0xf7ff00000 in the * device tree and pass -m 2047 to QEMU. */ static void calxeda_init(MachineState *machine, enum cxmachines machine_id) { ram_addr_t ram_size = machine->ram_size; const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; DeviceState *dev = NULL; SysBusDevice *busdev; qemu_irq pic[128]; int n; qemu_irq cpu_irq[4]; qemu_irq cpu_fiq[4]; MemoryRegion *sysram; MemoryRegion *dram; MemoryRegion *sysmem; char *sysboot_filename; switch (machine_id) { case CALXEDA_HIGHBANK: machine->cpu_type = ARM_CPU_TYPE_NAME("cortex-a9"); break; case CALXEDA_MIDWAY: machine->cpu_type = ARM_CPU_TYPE_NAME("cortex-a15"); break; default: assert(0); } for (n = 0; n < smp_cpus; n++) { Object *cpuobj; ARMCPU *cpu; cpuobj = object_new(machine->cpu_type); cpu = ARM_CPU(cpuobj); object_property_set_int(cpuobj, QEMU_PSCI_CONDUIT_SMC, "psci-conduit", &error_abort); if (n) { /* Secondary CPUs start in PSCI powered-down state */ object_property_set_bool(cpuobj, true, "start-powered-off", &error_abort); } if (object_property_find(cpuobj, "reset-cbar", NULL)) { object_property_set_int(cpuobj, MPCORE_PERIPHBASE, "reset-cbar", &error_abort); } object_property_set_bool(cpuobj, true, "realized", &error_fatal); cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ); cpu_fiq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ); } sysmem = get_system_memory(); dram = g_new(MemoryRegion, 1); memory_region_allocate_system_memory(dram, NULL, "highbank.dram", ram_size); /* SDRAM at address zero. */ memory_region_add_subregion(sysmem, 0, dram); sysram = g_new(MemoryRegion, 1); memory_region_init_ram_nomigrate(sysram, NULL, "highbank.sysram", 0x8000, &error_fatal); memory_region_add_subregion(sysmem, 0xfff88000, sysram); if (bios_name != NULL) { sysboot_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (sysboot_filename != NULL) { if (load_image_targphys(sysboot_filename, 0xfff88000, 0x8000) < 0) { error_report("Unable to load %s", bios_name); exit(1); } g_free(sysboot_filename); } else { error_report("Unable to find %s", bios_name); exit(1); } } switch (machine_id) { case CALXEDA_HIGHBANK: dev = qdev_create(NULL, "l2x0"); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_mmio_map(busdev, 0, 0xfff12000); dev = qdev_create(NULL, TYPE_A9MPCORE_PRIV); break; case CALXEDA_MIDWAY: dev = qdev_create(NULL, TYPE_A15MPCORE_PRIV); break; } qdev_prop_set_uint32(dev, "num-cpu", smp_cpus); qdev_prop_set_uint32(dev, "num-irq", NIRQ_GIC); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_mmio_map(busdev, 0, MPCORE_PERIPHBASE); for (n = 0; n < smp_cpus; n++) { sysbus_connect_irq(busdev, n, cpu_irq[n]); sysbus_connect_irq(busdev, n + smp_cpus, cpu_fiq[n]); } for (n = 0; n < 128; n++) { pic[n] = qdev_get_gpio_in(dev, n); } dev = qdev_create(NULL, "sp804"); qdev_prop_set_uint32(dev, "freq0", 150000000); qdev_prop_set_uint32(dev, "freq1", 150000000); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_mmio_map(busdev, 0, 0xfff34000); sysbus_connect_irq(busdev, 0, pic[18]); pl011_create(0xfff36000, pic[20], serial_hds[0]); dev = qdev_create(NULL, TYPE_HIGHBANK_REGISTERS); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_mmio_map(busdev, 0, 0xfff3c000); sysbus_create_simple("pl061", 0xfff30000, pic[14]); sysbus_create_simple("pl061", 0xfff31000, pic[15]); sysbus_create_simple("pl061", 0xfff32000, pic[16]); sysbus_create_simple("pl061", 0xfff33000, pic[17]); sysbus_create_simple("pl031", 0xfff35000, pic[19]); sysbus_create_simple("pl022", 0xfff39000, pic[23]); sysbus_create_simple(TYPE_SYSBUS_AHCI, 0xffe08000, pic[83]); if (nd_table[0].used) { qemu_check_nic_model(&nd_table[0], "xgmac"); dev = qdev_create(NULL, "xgmac"); qdev_set_nic_properties(dev, &nd_table[0]); qdev_init_nofail(dev); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xfff50000); sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[77]); sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, pic[78]); sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, pic[79]); qemu_check_nic_model(&nd_table[1], "xgmac"); dev = qdev_create(NULL, "xgmac"); qdev_set_nic_properties(dev, &nd_table[1]); qdev_init_nofail(dev); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xfff51000); sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[80]); sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, pic[81]); sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, pic[82]); } /* TODO create and connect IDE devices for ide_drive_get() */ highbank_binfo.ram_size = ram_size; highbank_binfo.kernel_filename = kernel_filename; highbank_binfo.kernel_cmdline = kernel_cmdline; highbank_binfo.initrd_filename = initrd_filename; /* highbank requires a dtb in order to boot, and the dtb will override * the board ID. The following value is ignored, so set it to -1 to be * clear that the value is meaningless. */ highbank_binfo.board_id = -1; highbank_binfo.nb_cpus = smp_cpus; highbank_binfo.loader_start = 0; highbank_binfo.write_secondary_boot = hb_write_secondary; highbank_binfo.secondary_cpu_reset_hook = hb_reset_secondary; if (!kvm_enabled()) { highbank_binfo.board_setup_addr = BOARD_SETUP_ADDR; highbank_binfo.write_board_setup = hb_write_board_setup; highbank_binfo.secure_board_setup = true; } else { warn_report("cannot load built-in Monitor support " "if KVM is enabled. Some guests (such as Linux) " "may not boot."); } arm_load_kernel(ARM_CPU(first_cpu), &highbank_binfo); }
static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, MachineState *machine) { const char *cpu_model = machine->cpu_model; unsigned int i; void *iommu, *espdma, *ledma, *nvram; qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS], espdma_irq, ledma_irq; qemu_irq esp_reset, dma_enable; qemu_irq fdc_tc; qemu_irq *cpu_halt; unsigned long kernel_size; DriveInfo *fd[MAX_FD]; FWCfgState *fw_cfg; unsigned int num_vsimms; /* init CPUs */ if (!cpu_model) cpu_model = hwdef->default_cpu_model; for(i = 0; i < smp_cpus; i++) { cpu_devinit(cpu_model, i, hwdef->slavio_base, &cpu_irqs[i]); } for (i = smp_cpus; i < MAX_CPUS; i++) cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS); /* set up devices */ ram_init(0, machine->ram_size, hwdef->max_mem); /* models without ECC don't trap when missing ram is accessed */ if (!hwdef->ecc_base) { empty_slot_init(machine->ram_size, hwdef->max_mem - machine->ram_size); } prom_init(hwdef->slavio_base, bios_name); slavio_intctl = slavio_intctl_init(hwdef->intctl_base, hwdef->intctl_base + 0x10000ULL, cpu_irqs); for (i = 0; i < 32; i++) { slavio_irq[i] = qdev_get_gpio_in(slavio_intctl, i); } for (i = 0; i < MAX_CPUS; i++) { slavio_cpu_irq[i] = qdev_get_gpio_in(slavio_intctl, 32 + i); } if (hwdef->idreg_base) { idreg_init(hwdef->idreg_base); } if (hwdef->afx_base) { afx_init(hwdef->afx_base); } iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version, slavio_irq[30]); if (hwdef->iommu_pad_base) { /* On the real hardware (SS-5, LX) the MMU is not padded, but aliased. Software shouldn't use aliased addresses, neither should it crash when does. Using empty_slot instead of aliasing can help with debugging such accesses */ empty_slot_init(hwdef->iommu_pad_base,hwdef->iommu_pad_len); } espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[18], iommu, &espdma_irq, 0); ledma = sparc32_dma_init(hwdef->dma_base + 16ULL, slavio_irq[16], iommu, &ledma_irq, 1); if (graphic_depth != 8 && graphic_depth != 24) { error_report("Unsupported depth: %d", graphic_depth); exit (1); } num_vsimms = 0; if (num_vsimms == 0) { if (vga_interface_type == VGA_CG3) { if (graphic_depth != 8) { error_report("Unsupported depth: %d", graphic_depth); exit(1); } if (!(graphic_width == 1024 && graphic_height == 768) && !(graphic_width == 1152 && graphic_height == 900)) { error_report("Unsupported resolution: %d x %d", graphic_width, graphic_height); exit(1); } /* sbus irq 5 */ cg3_init(hwdef->tcx_base, slavio_irq[11], 0x00100000, graphic_width, graphic_height, graphic_depth); } else { /* If no display specified, default to TCX */ if (graphic_depth != 8 && graphic_depth != 24) { error_report("Unsupported depth: %d", graphic_depth); exit(1); } if (!(graphic_width == 1024 && graphic_height == 768)) { error_report("Unsupported resolution: %d x %d", graphic_width, graphic_height); exit(1); } tcx_init(hwdef->tcx_base, slavio_irq[11], 0x00100000, graphic_width, graphic_height, graphic_depth); } } for (i = num_vsimms; i < MAX_VSIMMS; i++) { /* vsimm registers probed by OBP */ if (hwdef->vsimm[i].reg_base) { empty_slot_init(hwdef->vsimm[i].reg_base, 0x2000); } } if (hwdef->sx_base) { empty_slot_init(hwdef->sx_base, 0x2000); } lance_init(&nd_table[0], hwdef->le_base, ledma, ledma_irq); nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, 0x2000, 8); slavio_timer_init_all(hwdef->counter_base, slavio_irq[19], slavio_cpu_irq, smp_cpus); slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[14], display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1); /* Slavio TTYA (base+4, Linux ttyS0) is the first QEMU serial device Slavio TTYB (base+0, Linux ttyS1) is the second QEMU serial device */ escc_init(hwdef->serial_base, slavio_irq[15], slavio_irq[15], serial_hds[0], serial_hds[1], ESCC_CLOCK, 1); cpu_halt = qemu_allocate_irqs(cpu_halt_signal, NULL, 1); if (hwdef->apc_base) { apc_init(hwdef->apc_base, cpu_halt[0]); } if (hwdef->fd_base) { /* there is zero or one floppy drive */ memset(fd, 0, sizeof(fd)); fd[0] = drive_get(IF_FLOPPY, 0, 0); sun4m_fdctrl_init(slavio_irq[22], hwdef->fd_base, fd, &fdc_tc); } else { fdc_tc = *qemu_allocate_irqs(dummy_fdc_tc, NULL, 1); } slavio_misc_init(hwdef->slavio_base, hwdef->aux1_base, hwdef->aux2_base, slavio_irq[30], fdc_tc); if (drive_get_max_bus(IF_SCSI) > 0) { fprintf(stderr, "qemu: too many SCSI bus\n"); exit(1); } esp_init(hwdef->esp_base, 2, espdma_memory_read, espdma_memory_write, espdma, espdma_irq, &esp_reset, &dma_enable); qdev_connect_gpio_out(espdma, 0, esp_reset); qdev_connect_gpio_out(espdma, 1, dma_enable); if (hwdef->cs_base) { sysbus_create_simple("SUNW,CS4231", hwdef->cs_base, slavio_irq[5]); } if (hwdef->dbri_base) { /* ISDN chip with attached CS4215 audio codec */ /* prom space */ empty_slot_init(hwdef->dbri_base+0x1000, 0x30); /* reg space */ empty_slot_init(hwdef->dbri_base+0x10000, 0x100); } if (hwdef->bpp_base) { /* parallel port */ empty_slot_init(hwdef->bpp_base, 0x20); } kernel_size = sun4m_load_kernel(machine->kernel_filename, machine->initrd_filename, machine->ram_size); nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, machine->kernel_cmdline, machine->boot_order, machine->ram_size, kernel_size, graphic_width, graphic_height, graphic_depth, hwdef->nvram_machine_id, "Sun4m"); if (hwdef->ecc_base) ecc_init(hwdef->ecc_base, slavio_irq[28], hwdef->ecc_version); fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2); fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id); fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_DEPTH, graphic_depth); fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_WIDTH, graphic_width); fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_HEIGHT, graphic_height); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, KERNEL_LOAD_ADDR); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); if (machine->kernel_cmdline) { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR); pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, machine->kernel_cmdline); fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, machine->kernel_cmdline); fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, strlen(machine->kernel_cmdline) + 1); } else { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0); fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, 0); } fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR); fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, 0); // not used fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, machine->boot_order[0]); qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); }
static void lm32_evr_init(ram_addr_t ram_size_not_used, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { LM32CPU *cpu; CPULM32State *env; DriveInfo *dinfo; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *phys_ram = g_new(MemoryRegion, 1); qemu_irq *cpu_irq, irq[32]; ResetInfo *reset_info; int i; /* memory map */ target_phys_addr_t flash_base = 0x04000000; size_t flash_sector_size = 256 * 1024; size_t flash_size = 32 * 1024 * 1024; target_phys_addr_t ram_base = 0x08000000; size_t ram_size = 64 * 1024 * 1024; target_phys_addr_t timer0_base = 0x80002000; target_phys_addr_t uart0_base = 0x80006000; target_phys_addr_t timer1_base = 0x8000a000; int uart0_irq = 0; int timer0_irq = 1; int timer1_irq = 3; reset_info = g_malloc0(sizeof(ResetInfo)); if (cpu_model == NULL) { cpu_model = "lm32-full"; } cpu = cpu_lm32_init(cpu_model); env = &cpu->env; reset_info->cpu = cpu; reset_info->flash_base = flash_base; memory_region_init_ram(phys_ram, "lm32_evr.sdram", ram_size); vmstate_register_ram_global(phys_ram); memory_region_add_subregion(address_space_mem, ram_base, phys_ram); dinfo = drive_get(IF_PFLASH, 0, 0); /* Spansion S29NS128P */ pflash_cfi02_register(flash_base, NULL, "lm32_evr.flash", flash_size, dinfo ? dinfo->bdrv : NULL, flash_sector_size, flash_size / flash_sector_size, 1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1); /* create irq lines */ cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1); env->pic_state = lm32_pic_init(*cpu_irq); for (i = 0; i < 32; i++) { irq[i] = qdev_get_gpio_in(env->pic_state, i); } sysbus_create_simple("lm32-uart", uart0_base, irq[uart0_irq]); sysbus_create_simple("lm32-timer", timer0_base, irq[timer0_irq]); sysbus_create_simple("lm32-timer", timer1_base, irq[timer1_irq]); /* make sure juart isn't the first chardev */ env->juart_state = lm32_juart_init(); reset_info->bootstrap_pc = flash_base; if (kernel_filename) { uint64_t entry; int kernel_size; kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL, 1, ELF_MACHINE, 0); reset_info->bootstrap_pc = entry; if (kernel_size < 0) { kernel_size = load_image_targphys(kernel_filename, ram_base, ram_size); reset_info->bootstrap_pc = ram_base; } if (kernel_size < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } } qemu_register_reset(main_cpu_reset, reset_info); }
static void lm32_uclinux_init(ram_addr_t ram_size_not_used, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { LM32CPU *cpu; CPULM32State *env; DriveInfo *dinfo; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *phys_ram = g_new(MemoryRegion, 1); qemu_irq *cpu_irq, irq[32]; HWSetup *hw; ResetInfo *reset_info; int i; /* memory map */ target_phys_addr_t flash_base = 0x04000000; size_t flash_sector_size = 256 * 1024; size_t flash_size = 32 * 1024 * 1024; target_phys_addr_t ram_base = 0x08000000; size_t ram_size = 64 * 1024 * 1024; target_phys_addr_t uart0_base = 0x80000000; target_phys_addr_t timer0_base = 0x80002000; target_phys_addr_t timer1_base = 0x80010000; target_phys_addr_t timer2_base = 0x80012000; int uart0_irq = 0; int timer0_irq = 1; int timer1_irq = 20; int timer2_irq = 21; target_phys_addr_t hwsetup_base = 0x0bffe000; target_phys_addr_t cmdline_base = 0x0bfff000; target_phys_addr_t initrd_base = 0x08400000; size_t initrd_max = 0x01000000; reset_info = g_malloc0(sizeof(ResetInfo)); if (cpu_model == NULL) { cpu_model = "lm32-full"; } cpu = cpu_lm32_init(cpu_model); env = &cpu->env; reset_info->cpu = cpu; reset_info->flash_base = flash_base; memory_region_init_ram(phys_ram, "lm32_uclinux.sdram", ram_size); vmstate_register_ram_global(phys_ram); memory_region_add_subregion(address_space_mem, ram_base, phys_ram); dinfo = drive_get(IF_PFLASH, 0, 0); /* Spansion S29NS128P */ pflash_cfi02_register(flash_base, NULL, "lm32_uclinux.flash", flash_size, dinfo ? dinfo->bdrv : NULL, flash_sector_size, flash_size / flash_sector_size, 1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1); /* create irq lines */ cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1); env->pic_state = lm32_pic_init(*cpu_irq); for (i = 0; i < 32; i++) { irq[i] = qdev_get_gpio_in(env->pic_state, i); } sysbus_create_simple("lm32-uart", uart0_base, irq[uart0_irq]); sysbus_create_simple("lm32-timer", timer0_base, irq[timer0_irq]); sysbus_create_simple("lm32-timer", timer1_base, irq[timer1_irq]); sysbus_create_simple("lm32-timer", timer2_base, irq[timer2_irq]); /* make sure juart isn't the first chardev */ env->juart_state = lm32_juart_init(); reset_info->bootstrap_pc = flash_base; if (kernel_filename) { uint64_t entry; int kernel_size; kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL, 1, ELF_MACHINE, 0); reset_info->bootstrap_pc = entry; if (kernel_size < 0) { kernel_size = load_image_targphys(kernel_filename, ram_base, ram_size); reset_info->bootstrap_pc = ram_base; } if (kernel_size < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } } /* generate a rom with the hardware description */ hw = hwsetup_init(); hwsetup_add_cpu(hw, "LM32", 75000000); hwsetup_add_flash(hw, "flash", flash_base, flash_size); hwsetup_add_ddr_sdram(hw, "ddr_sdram", ram_base, ram_size); hwsetup_add_timer(hw, "timer0", timer0_base, timer0_irq); hwsetup_add_timer(hw, "timer1_dev_only", timer1_base, timer1_irq); hwsetup_add_timer(hw, "timer2_dev_only", timer2_base, timer2_irq); hwsetup_add_uart(hw, "uart", uart0_base, uart0_irq); hwsetup_add_trailer(hw); hwsetup_create_rom(hw, hwsetup_base); hwsetup_free(hw); reset_info->hwsetup_base = hwsetup_base; if (kernel_cmdline && strlen(kernel_cmdline)) { pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline); reset_info->cmdline_base = cmdline_base; } if (initrd_filename) { size_t initrd_size; initrd_size = load_image_targphys(initrd_filename, initrd_base, initrd_max); reset_info->initrd_base = initrd_base; reset_info->initrd_size = initrd_size; } qemu_register_reset(main_cpu_reset, reset_info); }
static void reptar_init(MachineState *machine) { MemoryRegion *sysmem = get_system_memory(); struct reptar_s *s = (struct reptar_s *)g_malloc0(sizeof(*s)); DriveInfo *dmtd = NULL, *dsd = NULL, *pflash = NULL; const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; /* (DRE) */ uint32_t pflash_size = 16 << 10; /* 16 KB */ if (ram_size > 1024 * 1024 * 1024) { fprintf(stderr, "reptar: maximum permitted RAM size 1024MB\n"); exit(1); } /* Check if we are in -kernel u-boot.bin mode */ if (kernel_filename) { /* (DRE) We do the following in order to retrieve the kernel filename during the boot process. * For example, if qemu was launched with -kernel u-boot.bin */ reptar_binfo.ram_size = ram_size; reptar_binfo.kernel_filename = kernel_filename; reptar_binfo.kernel_cmdline = kernel_cmdline; reptar_binfo.initrd_filename = initrd_filename; reptar_binfo.loader_start = 0x40014100; /* Start of small bootloader*/ reptar_binfo.board_id = 0; } else reptar_binfo.kernel_filename = NULL; s->cpu = omap3_mpu_init(sysmem, omap3430, ram_size, NULL, NULL, serial_hds[0], NULL); pflash = drive_get(IF_PFLASH, 0, 0); if (pflash) { if (!pflash_cfi02_register(0x30000000, NULL, "reptar.nand_flash", pflash_size, blk_by_legacy_dinfo(pflash), sector_len, pflash_size / sector_len, 1, 2, 0, 0, 0, 0, 0x555, 0x2AA, 0)) { fprintf(stderr, "qemu: Error registering flash memory.\n"); exit(1); } } else { dmtd = drive_get(IF_MTD, 0, 0); s->nand = nand_init(dmtd ? blk_by_legacy_dinfo(dmtd) : NULL, NAND_MFR_MICRON, 0xba); nand_setpins(s->nand, 0, 0, 0, 1, 0); /* no write-protect */ omap_gpmc_attach_nand(s->cpu->gpmc, REPTAR_NAND_CS, s->nand); } /* * (DRE) Define MMC if any */ dsd = drive_get(IF_SD, 0, 0); if (dsd) omap3_mmc_attach(s->cpu->omap3_mmc[0], blk_by_legacy_dinfo(dsd), 0, 0); if (!pflash && !dmtd && !dsd) hw_error("%s: SD or NAND image required", __FUNCTION__); /* FAB revs >= 2516: 4030 interrupt is GPIO 0 (earlier ones were 112) */ s->twl4030 = twl4030_init(omap_i2c_bus(s->cpu->i2c[0]), qdev_get_gpio_in(s->cpu->gpio, 0), NULL, NULL); /* Wire up an I2C slave which returns EDID monitor information; * newer Linux kernels won't turn on the display unless they * detect a monitor over DDC. */ s->ddc = i2c_create_slave(omap_i2c_bus(s->cpu->i2c[2]), "i2c-ddc", 0x50); omap_lcd_panel_attach(s->cpu->dss); /* Strictly this should be a LAN9221 */ #if 0 if (nd_table[0].vlan) { #endif /* 0 */ /* The ethernet chip hangs off the GPMC */ NICInfo *nd = &nd_table[0]; qemu_check_nic_model(nd, "lan9118"); s->eth = qdev_create(NULL, "lan9118"); qdev_set_nic_properties(s->eth, nd); qdev_init_nofail(s->eth); omap_gpmc_attach(s->cpu->gpmc, REPTAR_NET_CS, sysbus_mmio_get_region(SYS_BUS_DEVICE(s->eth), 0)); sysbus_connect_irq(SYS_BUS_DEVICE(s->eth), 0, qdev_get_gpio_in(s->cpu->gpio, 29)); #if 0 } #endif /* 0 */ // Create reptar_sp6 with it's base address s->sp6 = sysbus_create_simple("reptar_sp6",0x18000000,NULL); // Connect reptar_sp6 to GPIO10 for the IRQ sysbus_connect_irq(SYS_BUS_DEVICE(s->sp6), 0, qdev_get_gpio_in(s->cpu->gpio, 10)); }
static void vexpress_common_init(MachineState *machine) { VexpressMachineState *vms = VEXPRESS_MACHINE(machine); VexpressMachineClass *vmc = VEXPRESS_MACHINE_GET_CLASS(machine); VEDBoardInfo *daughterboard = vmc->daughterboard; DeviceState *dev, *sysctl, *pl041; qemu_irq pic[64]; uint32_t sys_id; DriveInfo *dinfo; pflash_t *pflash0; ram_addr_t vram_size, sram_size; MemoryRegion *sysmem = get_system_memory(); MemoryRegion *vram = g_new(MemoryRegion, 1); MemoryRegion *sram = g_new(MemoryRegion, 1); MemoryRegion *flashalias = g_new(MemoryRegion, 1); MemoryRegion *flash0mem; const hwaddr *map = daughterboard->motherboard_map; int i; daughterboard->init(vms, machine->ram_size, machine->cpu_model, pic); /* * If a bios file was provided, attempt to map it into memory */ if (bios_name) { char *fn; int image_size; if (drive_get(IF_PFLASH, 0, 0)) { error_report("The contents of the first flash device may be " "specified with -bios or with -drive if=pflash... " "but you cannot use both options at once"); exit(1); } fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (!fn) { error_report("Could not find ROM image '%s'", bios_name); exit(1); } image_size = load_image_targphys(fn, map[VE_NORFLASH0], VEXPRESS_FLASH_SIZE); g_free(fn); if (image_size < 0) { error_report("Could not load ROM image '%s'", bios_name); exit(1); } } /* Motherboard peripherals: the wiring is the same but the * addresses vary between the legacy and A-Series memory maps. */ sys_id = 0x1190f500; sysctl = qdev_create(NULL, "realview_sysctl"); qdev_prop_set_uint32(sysctl, "sys_id", sys_id); qdev_prop_set_uint32(sysctl, "proc_id", daughterboard->proc_id); qdev_prop_set_uint32(sysctl, "len-db-voltage", daughterboard->num_voltage_sensors); for (i = 0; i < daughterboard->num_voltage_sensors; i++) { char *propname = g_strdup_printf("db-voltage[%d]", i); qdev_prop_set_uint32(sysctl, propname, daughterboard->voltages[i]); g_free(propname); } qdev_prop_set_uint32(sysctl, "len-db-clock", daughterboard->num_clocks); for (i = 0; i < daughterboard->num_clocks; i++) { char *propname = g_strdup_printf("db-clock[%d]", i); qdev_prop_set_uint32(sysctl, propname, daughterboard->clocks[i]); g_free(propname); } qdev_init_nofail(sysctl); sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, map[VE_SYSREGS]); /* VE_SP810: not modelled */ /* VE_SERIALPCI: not modelled */ pl041 = qdev_create(NULL, "pl041"); qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512); qdev_init_nofail(pl041); sysbus_mmio_map(SYS_BUS_DEVICE(pl041), 0, map[VE_PL041]); sysbus_connect_irq(SYS_BUS_DEVICE(pl041), 0, pic[11]); dev = sysbus_create_varargs("pl181", map[VE_MMCI], pic[9], pic[10], NULL); /* Wire up MMC card detect and read-only signals */ qdev_connect_gpio_out(dev, 0, qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT)); qdev_connect_gpio_out(dev, 1, qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN)); sysbus_create_simple("pl050_keyboard", map[VE_KMI0], pic[12]); sysbus_create_simple("pl050_mouse", map[VE_KMI1], pic[13]); sysbus_create_simple("pl011", map[VE_UART0], pic[5]); sysbus_create_simple("pl011", map[VE_UART1], pic[6]); sysbus_create_simple("pl011", map[VE_UART2], pic[7]); sysbus_create_simple("pl011", map[VE_UART3], pic[8]); sysbus_create_simple("sp804", map[VE_TIMER01], pic[2]); sysbus_create_simple("sp804", map[VE_TIMER23], pic[3]); /* VE_SERIALDVI: not modelled */ sysbus_create_simple("pl031", map[VE_RTC], pic[4]); /* RTC */ /* VE_COMPACTFLASH: not modelled */ sysbus_create_simple("pl111", map[VE_CLCD], pic[14]); dinfo = drive_get_next(IF_PFLASH); pflash0 = ve_pflash_cfi01_register(map[VE_NORFLASH0], "vexpress.flash0", dinfo); if (!pflash0) { fprintf(stderr, "vexpress: error registering flash 0.\n"); exit(1); } if (map[VE_NORFLASHALIAS] != -1) { /* Map flash 0 as an alias into low memory */ flash0mem = sysbus_mmio_get_region(SYS_BUS_DEVICE(pflash0), 0); memory_region_init_alias(flashalias, NULL, "vexpress.flashalias", flash0mem, 0, VEXPRESS_FLASH_SIZE); memory_region_add_subregion(sysmem, map[VE_NORFLASHALIAS], flashalias); } dinfo = drive_get_next(IF_PFLASH); if (!ve_pflash_cfi01_register(map[VE_NORFLASH1], "vexpress.flash1", dinfo)) { fprintf(stderr, "vexpress: error registering flash 1.\n"); exit(1); } sram_size = 0x2000000; memory_region_init_ram(sram, NULL, "vexpress.sram", sram_size, &error_abort); vmstate_register_ram_global(sram); memory_region_add_subregion(sysmem, map[VE_SRAM], sram); vram_size = 0x800000; memory_region_init_ram(vram, NULL, "vexpress.vram", vram_size, &error_abort); vmstate_register_ram_global(vram); memory_region_add_subregion(sysmem, map[VE_VIDEORAM], vram); /* 0x4e000000 LAN9118 Ethernet */ if (nd_table[0].used) { lan9118_init(&nd_table[0], map[VE_ETHERNET], pic[15]); } /* VE_USB: not modelled */ /* VE_DAPROM: not modelled */ /* Create mmio transports, so the user can create virtio backends * (which will be automatically plugged in to the transports). If * no backend is created the transport will just sit harmlessly idle. */ for (i = 0; i < NUM_VIRTIO_TRANSPORTS; i++) { sysbus_create_simple("virtio-mmio", map[VE_VIRTIO] + 0x200 * i, pic[40 + i]); } daughterboard->bootinfo.ram_size = machine->ram_size; daughterboard->bootinfo.kernel_filename = machine->kernel_filename; daughterboard->bootinfo.kernel_cmdline = machine->kernel_cmdline; daughterboard->bootinfo.initrd_filename = machine->initrd_filename; daughterboard->bootinfo.nb_cpus = smp_cpus; daughterboard->bootinfo.board_id = VEXPRESS_BOARD_ID; daughterboard->bootinfo.loader_start = daughterboard->loader_start; daughterboard->bootinfo.smp_loader_start = map[VE_SRAM]; daughterboard->bootinfo.smp_bootreg_addr = map[VE_SYSREGS] + 0x30; daughterboard->bootinfo.gic_cpu_if_addr = daughterboard->gic_cpu_if_addr; daughterboard->bootinfo.modify_dtb = vexpress_modify_dtb; /* Indicate that when booting Linux we should be in secure state */ daughterboard->bootinfo.secure_boot = true; arm_load_kernel(ARM_CPU(first_cpu), &daughterboard->bootinfo); }
static void petalogix_s3adsp1800_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { DeviceState *dev; CPUState *env; int kernel_size; DriveInfo *dinfo; int i; target_phys_addr_t ddr_base = 0x90000000; ram_addr_t phys_lmb_bram; ram_addr_t phys_ram; ram_addr_t phys_flash; qemu_irq irq[32], *cpu_irq; /* init CPUs */ if (cpu_model == NULL) { cpu_model = "microblaze"; } env = cpu_init(cpu_model); env->pvr.regs[10] = 0x0c000000; /* spartan 3a dsp family. */ qemu_register_reset(main_cpu_reset, env); /* Attach emulated BRAM through the LMB. */ phys_lmb_bram = qemu_ram_alloc(LMB_BRAM_SIZE); cpu_register_physical_memory(0x00000000, LMB_BRAM_SIZE, phys_lmb_bram | IO_MEM_RAM); phys_ram = qemu_ram_alloc(ram_size); cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM); phys_flash = qemu_ram_alloc(FLASH_SIZE); dinfo = drive_get(IF_PFLASH, 0, 0); pflash_cfi02_register(0xa0000000, phys_flash, dinfo ? dinfo->bdrv : NULL, (64 * 1024), FLASH_SIZE >> 16, 1, 1, 0x0000, 0x0000, 0x0000, 0x0000, 0x555, 0x2aa); cpu_irq = microblaze_pic_init_cpu(env); dev = xilinx_intc_create(0x81800000, cpu_irq[0], 2); for (i = 0; i < 32; i++) { irq[i] = qdev_get_gpio_in(dev, i); } sysbus_create_simple("xilinx,uartlite", 0x84000000, irq[3]); /* 2 timers at irq 2 @ 62 Mhz. */ xilinx_timer_create(0x83c00000, irq[0], 2, 62 * 1000000); xilinx_ethlite_create(&nd_table[0], 0x81000000, irq[1], 0, 0); if (kernel_filename) { uint64_t entry, low, high; int kcmdline_len; uint32_t base32; /* Boots a kernel elf binary. */ kernel_size = load_elf(kernel_filename, 0, &entry, &low, &high, 1, ELF_MACHINE, 0); base32 = entry; if (base32 == 0xc0000000) { kernel_size = load_elf(kernel_filename, -0x30000000LL, &entry, NULL, NULL, 1, ELF_MACHINE, 0); } /* Always boot into physical ram. */ bootstrap_pc = ddr_base + (entry & 0x0fffffff); if (kernel_size < 0) { /* If we failed loading ELF's try a raw image. */ kernel_size = load_image_targphys(kernel_filename, ddr_base, ram_size); bootstrap_pc = ddr_base; } env->regs[5] = ddr_base + kernel_size + 8192; if (kernel_cmdline && (kcmdline_len = strlen(kernel_cmdline))) { pstrcpy_targphys("cmdline", env->regs[5], 256, kernel_cmdline); } env->regs[6] = 0; /* Provide a device-tree. */ env->regs[7] = ddr_base + kernel_size + 256; petalogix_load_device_tree(env->regs[7], ram_size, env->regs[6], 0, kernel_cmdline); } env->sregs[SR_PC] = bootstrap_pc; }
static void realview_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, enum realview_board_type board_type) { ARMCPU *cpu = NULL; CPUARMState *env; MemoryRegion *sysmem = get_system_memory(); MemoryRegion *ram_lo = g_new(MemoryRegion, 1); MemoryRegion *ram_hi = g_new(MemoryRegion, 1); MemoryRegion *ram_alias = g_new(MemoryRegion, 1); MemoryRegion *ram_hack = g_new(MemoryRegion, 1); DeviceState *dev, *sysctl, *gpio2, *pl041; SysBusDevice *busdev; qemu_irq *irqp; qemu_irq pic[64]; qemu_irq mmc_irq[2]; PCIBus *pci_bus; NICInfo *nd; i2c_bus *i2c; int n; int done_nic = 0; qemu_irq cpu_irq[4]; int is_mpcore = 0; int is_pb = 0; uint32_t proc_id = 0; uint32_t sys_id; ram_addr_t low_ram_size; switch (board_type) { case BOARD_EB: break; case BOARD_EB_MPCORE: is_mpcore = 1; break; case BOARD_PB_A8: is_pb = 1; break; case BOARD_PBX_A9: is_mpcore = 1; is_pb = 1; break; } for (n = 0; n < smp_cpus; n++) { cpu = cpu_arm_init(cpu_model); if (!cpu) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } irqp = arm_pic_init_cpu(cpu); cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ]; } env = &cpu->env; if (arm_feature(env, ARM_FEATURE_V7)) { if (is_mpcore) { proc_id = 0x0c000000; } else { proc_id = 0x0e000000; } } else if (arm_feature(env, ARM_FEATURE_V6K)) { proc_id = 0x06000000; } else if (arm_feature(env, ARM_FEATURE_V6)) { proc_id = 0x04000000; } else { proc_id = 0x02000000; } if (is_pb && ram_size > 0x20000000) { /* Core tile RAM. */ low_ram_size = ram_size - 0x20000000; ram_size = 0x20000000; memory_region_init_ram(ram_lo, "realview.lowmem", low_ram_size); vmstate_register_ram_global(ram_lo); memory_region_add_subregion(sysmem, 0x20000000, ram_lo); } memory_region_init_ram(ram_hi, "realview.highmem", ram_size); vmstate_register_ram_global(ram_hi); low_ram_size = ram_size; if (low_ram_size > 0x10000000) low_ram_size = 0x10000000; /* SDRAM at address zero. */ memory_region_init_alias(ram_alias, "realview.alias", ram_hi, 0, low_ram_size); memory_region_add_subregion(sysmem, 0, ram_alias); if (is_pb) { /* And again at a high address. */ memory_region_add_subregion(sysmem, 0x70000000, ram_hi); } else { ram_size = low_ram_size; } sys_id = is_pb ? 0x01780500 : 0xc1400400; sysctl = qdev_create(NULL, "realview_sysctl"); qdev_prop_set_uint32(sysctl, "sys_id", sys_id); qdev_prop_set_uint32(sysctl, "proc_id", proc_id); qdev_init_nofail(sysctl); sysbus_mmio_map(sysbus_from_qdev(sysctl), 0, 0x10000000); if (is_mpcore) { target_phys_addr_t periphbase; dev = qdev_create(NULL, is_pb ? "a9mpcore_priv": "realview_mpcore"); qdev_prop_set_uint32(dev, "num-cpu", smp_cpus); qdev_init_nofail(dev); busdev = sysbus_from_qdev(dev); if (is_pb) { periphbase = 0x1f000000; } else { periphbase = 0x10100000; } sysbus_mmio_map(busdev, 0, periphbase); for (n = 0; n < smp_cpus; n++) { sysbus_connect_irq(busdev, n, cpu_irq[n]); } sysbus_create_varargs("l2x0", periphbase + 0x2000, NULL); /* Both A9 and 11MPCore put the GIC CPU i/f at base + 0x100 */ realview_binfo.gic_cpu_if_addr = periphbase + 0x100; } else { uint32_t gic_addr = is_pb ? 0x1e000000 : 0x10040000; /* For now just create the nIRQ GIC, and ignore the others. */ dev = sysbus_create_simple("realview_gic", gic_addr, cpu_irq[0]); } for (n = 0; n < 64; n++) { pic[n] = qdev_get_gpio_in(dev, n); } pl041 = qdev_create(NULL, "pl041"); qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512); qdev_init_nofail(pl041); sysbus_mmio_map(sysbus_from_qdev(pl041), 0, 0x10004000); sysbus_connect_irq(sysbus_from_qdev(pl041), 0, pic[19]); sysbus_create_simple("pl050_keyboard", 0x10006000, pic[20]); sysbus_create_simple("pl050_mouse", 0x10007000, pic[21]); sysbus_create_simple("pl011", 0x10009000, pic[12]); sysbus_create_simple("pl011", 0x1000a000, pic[13]); sysbus_create_simple("pl011", 0x1000b000, pic[14]); sysbus_create_simple("pl011", 0x1000c000, pic[15]); /* DMA controller is optional, apparently. */ sysbus_create_simple("pl081", 0x10030000, pic[24]); sysbus_create_simple("sp804", 0x10011000, pic[4]); sysbus_create_simple("sp804", 0x10012000, pic[5]); sysbus_create_simple("pl061", 0x10013000, pic[6]); sysbus_create_simple("pl061", 0x10014000, pic[7]); gpio2 = sysbus_create_simple("pl061", 0x10015000, pic[8]); sysbus_create_simple("pl111", 0x10020000, pic[23]); dev = sysbus_create_varargs("pl181", 0x10005000, pic[17], pic[18], NULL); /* Wire up MMC card detect and read-only signals. These have * to go to both the PL061 GPIO and the sysctl register. * Note that the PL181 orders these lines (readonly,inserted) * and the PL061 has them the other way about. Also the card * detect line is inverted. */ mmc_irq[0] = qemu_irq_split( qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT), qdev_get_gpio_in(gpio2, 1)); mmc_irq[1] = qemu_irq_split( qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN), qemu_irq_invert(qdev_get_gpio_in(gpio2, 0))); qdev_connect_gpio_out(dev, 0, mmc_irq[0]); qdev_connect_gpio_out(dev, 1, mmc_irq[1]); sysbus_create_simple("pl031", 0x10017000, pic[10]); if (!is_pb) { dev = qdev_create(NULL, "realview_pci"); busdev = sysbus_from_qdev(dev); qdev_init_nofail(dev); sysbus_mmio_map(busdev, 0, 0x61000000); /* PCI self-config */ sysbus_mmio_map(busdev, 1, 0x62000000); /* PCI config */ sysbus_mmio_map(busdev, 2, 0x63000000); /* PCI I/O */ sysbus_connect_irq(busdev, 0, pic[48]); sysbus_connect_irq(busdev, 1, pic[49]); sysbus_connect_irq(busdev, 2, pic[50]); sysbus_connect_irq(busdev, 3, pic[51]); pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci"); if (usb_enabled) { pci_create_simple(pci_bus, -1, "pci-ohci"); } n = drive_get_max_bus(IF_SCSI); while (n >= 0) { pci_create_simple(pci_bus, -1, "lsi53c895a"); n--; } } for(n = 0; n < nb_nics; n++) { nd = &nd_table[n]; if (!done_nic && (!nd->model || strcmp(nd->model, is_pb ? "lan9118" : "smc91c111") == 0)) { if (is_pb) { lan9118_init(nd, 0x4e000000, pic[28]); } else { smc91c111_init(nd, 0x4e000000, pic[28]); } done_nic = 1; } else { pci_nic_init_nofail(nd, "rtl8139", NULL); } } dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL); i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); i2c_create_slave(i2c, "ds1338", 0x68); /* Memory map for RealView Emulation Baseboard: */ /* 0x10000000 System registers. */ /* 0x10001000 System controller. */ /* 0x10002000 Two-Wire Serial Bus. */ /* 0x10003000 Reserved. */ /* 0x10004000 AACI. */ /* 0x10005000 MCI. */ /* 0x10006000 KMI0. */ /* 0x10007000 KMI1. */ /* 0x10008000 Character LCD. (EB) */ /* 0x10009000 UART0. */ /* 0x1000a000 UART1. */ /* 0x1000b000 UART2. */ /* 0x1000c000 UART3. */ /* 0x1000d000 SSPI. */ /* 0x1000e000 SCI. */ /* 0x1000f000 Reserved. */ /* 0x10010000 Watchdog. */ /* 0x10011000 Timer 0+1. */ /* 0x10012000 Timer 2+3. */ /* 0x10013000 GPIO 0. */ /* 0x10014000 GPIO 1. */ /* 0x10015000 GPIO 2. */ /* 0x10002000 Two-Wire Serial Bus - DVI. (PB) */ /* 0x10017000 RTC. */ /* 0x10018000 DMC. */ /* 0x10019000 PCI controller config. */ /* 0x10020000 CLCD. */ /* 0x10030000 DMA Controller. */ /* 0x10040000 GIC1. (EB) */ /* 0x10050000 GIC2. (EB) */ /* 0x10060000 GIC3. (EB) */ /* 0x10070000 GIC4. (EB) */ /* 0x10080000 SMC. */ /* 0x1e000000 GIC1. (PB) */ /* 0x1e001000 GIC2. (PB) */ /* 0x1e002000 GIC3. (PB) */ /* 0x1e003000 GIC4. (PB) */ /* 0x40000000 NOR flash. */ /* 0x44000000 DoC flash. */ /* 0x48000000 SRAM. */ /* 0x4c000000 Configuration flash. */ /* 0x4e000000 Ethernet. */ /* 0x4f000000 USB. */ /* 0x50000000 PISMO. */ /* 0x54000000 PISMO. */ /* 0x58000000 PISMO. */ /* 0x5c000000 PISMO. */ /* 0x60000000 PCI. */ /* 0x61000000 PCI Self Config. */ /* 0x62000000 PCI Config. */ /* 0x63000000 PCI IO. */ /* 0x64000000 PCI mem 0. */ /* 0x68000000 PCI mem 1. */ /* 0x6c000000 PCI mem 2. */ /* ??? Hack to map an additional page of ram for the secondary CPU startup code. I guess this works on real hardware because the BootROM happens to be in ROM/flash or in memory that isn't clobbered until after Linux boots the secondary CPUs. */ memory_region_init_ram(ram_hack, "realview.hack", 0x1000); vmstate_register_ram_global(ram_hack); memory_region_add_subregion(sysmem, SMP_BOOT_ADDR, ram_hack); realview_binfo.ram_size = ram_size; realview_binfo.kernel_filename = kernel_filename; realview_binfo.kernel_cmdline = kernel_cmdline; realview_binfo.initrd_filename = initrd_filename; realview_binfo.nb_cpus = smp_cpus; realview_binfo.board_id = realview_board_id[board_type]; realview_binfo.loader_start = (board_type == BOARD_PB_A8 ? 0x70000000 : 0); arm_load_kernel(arm_env_get_cpu(first_cpu), &realview_binfo); }
static void vexpress_common_init(VEDBoardInfo *daughterboard, QEMUMachineInitArgs *args) { DeviceState *dev, *sysctl, *pl041; qemu_irq pic[64]; uint32_t sys_id; DriveInfo *dinfo; pflash_t *pflash0; ram_addr_t vram_size, sram_size; MemoryRegion *sysmem = get_system_memory(); MemoryRegion *vram = g_new(MemoryRegion, 1); MemoryRegion *sram = g_new(MemoryRegion, 1); MemoryRegion *flashalias = g_new(MemoryRegion, 1); MemoryRegion *flash0mem; const hwaddr *map = daughterboard->motherboard_map; int i; daughterboard->init(daughterboard, args->ram_size, args->cpu_model, pic); /* Motherboard peripherals: the wiring is the same but the * addresses vary between the legacy and A-Series memory maps. */ sys_id = 0x1190f500; sysctl = qdev_create(NULL, "realview_sysctl"); qdev_prop_set_uint32(sysctl, "sys_id", sys_id); qdev_prop_set_uint32(sysctl, "proc_id", daughterboard->proc_id); qdev_prop_set_uint32(sysctl, "len-db-voltage", daughterboard->num_voltage_sensors); for (i = 0; i < daughterboard->num_voltage_sensors; i++) { char *propname = g_strdup_printf("db-voltage[%d]", i); qdev_prop_set_uint32(sysctl, propname, daughterboard->voltages[i]); g_free(propname); } qdev_prop_set_uint32(sysctl, "len-db-clock", daughterboard->num_clocks); for (i = 0; i < daughterboard->num_clocks; i++) { char *propname = g_strdup_printf("db-clock[%d]", i); qdev_prop_set_uint32(sysctl, propname, daughterboard->clocks[i]); g_free(propname); } qdev_init_nofail(sysctl); sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, map[VE_SYSREGS]); /* VE_SP810: not modelled */ /* VE_SERIALPCI: not modelled */ pl041 = qdev_create(NULL, "pl041"); qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512); qdev_init_nofail(pl041); sysbus_mmio_map(SYS_BUS_DEVICE(pl041), 0, map[VE_PL041]); sysbus_connect_irq(SYS_BUS_DEVICE(pl041), 0, pic[11]); dev = sysbus_create_varargs("pl181", map[VE_MMCI], pic[9], pic[10], NULL); /* Wire up MMC card detect and read-only signals */ qdev_connect_gpio_out(dev, 0, qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT)); qdev_connect_gpio_out(dev, 1, qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN)); sysbus_create_simple("pl050_keyboard", map[VE_KMI0], pic[12]); sysbus_create_simple("pl050_mouse", map[VE_KMI1], pic[13]); sysbus_create_simple("pl011", map[VE_UART0], pic[5]); sysbus_create_simple("pl011", map[VE_UART1], pic[6]); sysbus_create_simple("pl011", map[VE_UART2], pic[7]); sysbus_create_simple("pl011", map[VE_UART3], pic[8]); sysbus_create_simple("sp804", map[VE_TIMER01], pic[2]); sysbus_create_simple("sp804", map[VE_TIMER23], pic[3]); /* VE_SERIALDVI: not modelled */ sysbus_create_simple("pl031", map[VE_RTC], pic[4]); /* RTC */ /* VE_COMPACTFLASH: not modelled */ sysbus_create_simple("pl111", map[VE_CLCD], pic[14]); dinfo = drive_get_next(IF_PFLASH); pflash0 = pflash_cfi01_register(map[VE_NORFLASH0], NULL, "vexpress.flash0", VEXPRESS_FLASH_SIZE, dinfo ? dinfo->bdrv : NULL, VEXPRESS_FLASH_SECT_SIZE, VEXPRESS_FLASH_SIZE / VEXPRESS_FLASH_SECT_SIZE, 4, 0x00, 0x89, 0x00, 0x18, 0); if (!pflash0) { fprintf(stderr, "vexpress: error registering flash 0.\n"); exit(1); } if (map[VE_NORFLASHALIAS] != -1) { /* Map flash 0 as an alias into low memory */ flash0mem = sysbus_mmio_get_region(SYS_BUS_DEVICE(pflash0), 0); memory_region_init_alias(flashalias, NULL, "vexpress.flashalias", flash0mem, 0, VEXPRESS_FLASH_SIZE); memory_region_add_subregion(sysmem, map[VE_NORFLASHALIAS], flashalias); } dinfo = drive_get_next(IF_PFLASH); if (!pflash_cfi01_register(map[VE_NORFLASH1], NULL, "vexpress.flash1", VEXPRESS_FLASH_SIZE, dinfo ? dinfo->bdrv : NULL, VEXPRESS_FLASH_SECT_SIZE, VEXPRESS_FLASH_SIZE / VEXPRESS_FLASH_SECT_SIZE, 4, 0x00, 0x89, 0x00, 0x18, 0)) { fprintf(stderr, "vexpress: error registering flash 1.\n"); exit(1); } sram_size = 0x2000000; memory_region_init_ram(sram, NULL, "vexpress.sram", sram_size); vmstate_register_ram_global(sram); memory_region_add_subregion(sysmem, map[VE_SRAM], sram); vram_size = 0x800000; memory_region_init_ram(vram, NULL, "vexpress.vram", vram_size); vmstate_register_ram_global(vram); memory_region_add_subregion(sysmem, map[VE_VIDEORAM], vram); /* 0x4e000000 LAN9118 Ethernet */ if (nd_table[0].used) { lan9118_init(&nd_table[0], map[VE_ETHERNET], pic[15]); } /* VE_USB: not modelled */ /* VE_DAPROM: not modelled */ /* Create mmio transports, so the user can create virtio backends * (which will be automatically plugged in to the transports). If * no backend is created the transport will just sit harmlessly idle. */ for (i = 0; i < NUM_VIRTIO_TRANSPORTS; i++) { sysbus_create_simple("virtio-mmio", map[VE_VIRTIO] + 0x200 * i, pic[40 + i]); } daughterboard->bootinfo.ram_size = args->ram_size; daughterboard->bootinfo.kernel_filename = args->kernel_filename; daughterboard->bootinfo.kernel_cmdline = args->kernel_cmdline; daughterboard->bootinfo.initrd_filename = args->initrd_filename; daughterboard->bootinfo.nb_cpus = smp_cpus; daughterboard->bootinfo.board_id = VEXPRESS_BOARD_ID; daughterboard->bootinfo.loader_start = daughterboard->loader_start; daughterboard->bootinfo.smp_loader_start = map[VE_SRAM]; daughterboard->bootinfo.smp_bootreg_addr = map[VE_SYSREGS] + 0x30; daughterboard->bootinfo.gic_cpu_if_addr = daughterboard->gic_cpu_if_addr; daughterboard->bootinfo.modify_dtb = vexpress_modify_dtb; arm_load_kernel(ARM_CPU(first_cpu), &daughterboard->bootinfo); }
Exynos4210State *exynos4210_init(MemoryRegion *system_mem, unsigned long ram_size) { int i, n; Exynos4210State *s = g_new(Exynos4210State, 1); qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS]; unsigned long mem_size; DeviceState *dev; SysBusDevice *busdev; ObjectClass *cpu_oc; cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, "cortex-a9"); assert(cpu_oc); for (n = 0; n < EXYNOS4210_NCPUS; n++) { Object *cpuobj = object_new(object_class_get_name(cpu_oc)); Error *err = NULL; /* By default A9 CPUs have EL3 enabled. This board does not currently * support EL3 so the CPU EL3 property is disabled before realization. */ if (object_property_find(cpuobj, "has_el3", NULL)) { object_property_set_bool(cpuobj, false, "has_el3", &err); if (err) { error_report("%s", error_get_pretty(err)); exit(1); } } s->cpu[n] = ARM_CPU(cpuobj); object_property_set_int(cpuobj, EXYNOS4210_SMP_PRIVATE_BASE_ADDR, "reset-cbar", &error_abort); object_property_set_bool(cpuobj, true, "realized", &err); if (err) { error_report("%s", error_get_pretty(err)); exit(1); } } /*** IRQs ***/ s->irq_table = exynos4210_init_irq(&s->irqs); /* IRQ Gate */ for (i = 0; i < EXYNOS4210_NCPUS; i++) { dev = qdev_create(NULL, "exynos4210.irq_gate"); qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS); qdev_init_nofail(dev); /* Get IRQ Gate input in gate_irq */ for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) { gate_irq[i][n] = qdev_get_gpio_in(dev, n); } busdev = SYS_BUS_DEVICE(dev); /* Connect IRQ Gate output to CPU's IRQ line */ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ)); } /* Private memory region and Internal GIC */ dev = qdev_create(NULL, "a9mpcore_priv"); qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR); for (n = 0; n < EXYNOS4210_NCPUS; n++) { sysbus_connect_irq(busdev, n, gate_irq[n][0]); } for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) { s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n); } /* Cache controller */ sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL); /* External GIC */ dev = qdev_create(NULL, "exynos4210.gic"); qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); /* Map CPU interface */ sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_GIC_CPU_BASE_ADDR); /* Map Distributer interface */ sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR); for (n = 0; n < EXYNOS4210_NCPUS; n++) { sysbus_connect_irq(busdev, n, gate_irq[n][1]); } for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) { s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n); } /* Internal Interrupt Combiner */ dev = qdev_create(NULL, "exynos4210.combiner"); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) { sysbus_connect_irq(busdev, n, s->irqs.int_gic_irq[n]); } exynos4210_combiner_get_gpioin(&s->irqs, dev, 0); sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR); /* External Interrupt Combiner */ dev = qdev_create(NULL, "exynos4210.combiner"); qdev_prop_set_uint32(dev, "external", 1); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) { sysbus_connect_irq(busdev, n, s->irqs.ext_gic_irq[n]); } exynos4210_combiner_get_gpioin(&s->irqs, dev, 1); sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR); /* Initialize board IRQs. */ exynos4210_init_board_irqs(&s->irqs); /*** Memory ***/ /* Chip-ID and OMR */ memory_region_init_io(&s->chipid_mem, NULL, &exynos4210_chipid_and_omr_ops, NULL, "exynos4210.chipid", sizeof(chipid_and_omr)); memory_region_add_subregion(system_mem, EXYNOS4210_CHIPID_ADDR, &s->chipid_mem); /* Internal ROM */ memory_region_init_ram(&s->irom_mem, NULL, "exynos4210.irom", EXYNOS4210_IROM_SIZE, &error_abort); vmstate_register_ram_global(&s->irom_mem); memory_region_set_readonly(&s->irom_mem, true); memory_region_add_subregion(system_mem, EXYNOS4210_IROM_BASE_ADDR, &s->irom_mem); /* mirror of iROM */ memory_region_init_alias(&s->irom_alias_mem, NULL, "exynos4210.irom_alias", &s->irom_mem, 0, EXYNOS4210_IROM_SIZE); memory_region_set_readonly(&s->irom_alias_mem, true); memory_region_add_subregion(system_mem, EXYNOS4210_IROM_MIRROR_BASE_ADDR, &s->irom_alias_mem); /* Internal RAM */ memory_region_init_ram(&s->iram_mem, NULL, "exynos4210.iram", EXYNOS4210_IRAM_SIZE, &error_abort); vmstate_register_ram_global(&s->iram_mem); memory_region_add_subregion(system_mem, EXYNOS4210_IRAM_BASE_ADDR, &s->iram_mem); /* DRAM */ mem_size = ram_size; if (mem_size > EXYNOS4210_DRAM_MAX_SIZE) { memory_region_init_ram(&s->dram1_mem, NULL, "exynos4210.dram1", mem_size - EXYNOS4210_DRAM_MAX_SIZE, &error_abort); vmstate_register_ram_global(&s->dram1_mem); memory_region_add_subregion(system_mem, EXYNOS4210_DRAM1_BASE_ADDR, &s->dram1_mem); mem_size = EXYNOS4210_DRAM_MAX_SIZE; } memory_region_init_ram(&s->dram0_mem, NULL, "exynos4210.dram0", mem_size, &error_abort); vmstate_register_ram_global(&s->dram0_mem); memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR, &s->dram0_mem); /* PMU. * The only reason of existence at the moment is that secondary CPU boot * loader uses PMU INFORM5 register as a holding pen. */ sysbus_create_simple("exynos4210.pmu", EXYNOS4210_PMU_BASE_ADDR, NULL); /* PWM */ sysbus_create_varargs("exynos4210.pwm", EXYNOS4210_PWM_BASE_ADDR, s->irq_table[exynos4210_get_irq(22, 0)], s->irq_table[exynos4210_get_irq(22, 1)], s->irq_table[exynos4210_get_irq(22, 2)], s->irq_table[exynos4210_get_irq(22, 3)], s->irq_table[exynos4210_get_irq(22, 4)], NULL); /* RTC */ sysbus_create_varargs("exynos4210.rtc", EXYNOS4210_RTC_BASE_ADDR, s->irq_table[exynos4210_get_irq(23, 0)], s->irq_table[exynos4210_get_irq(23, 1)], NULL); /* Multi Core Timer */ dev = qdev_create(NULL, "exynos4210.mct"); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); for (n = 0; n < 4; n++) { /* Connect global timer interrupts to Combiner gpio_in */ sysbus_connect_irq(busdev, n, s->irq_table[exynos4210_get_irq(1, 4 + n)]); } /* Connect local timer interrupts to Combiner gpio_in */ sysbus_connect_irq(busdev, 4, s->irq_table[exynos4210_get_irq(51, 0)]); sysbus_connect_irq(busdev, 5, s->irq_table[exynos4210_get_irq(35, 3)]); sysbus_mmio_map(busdev, 0, EXYNOS4210_MCT_BASE_ADDR); /*** I2C ***/ for (n = 0; n < EXYNOS4210_I2C_NUMBER; n++) { uint32_t addr = EXYNOS4210_I2C_BASE_ADDR + EXYNOS4210_I2C_SHIFT * n; qemu_irq i2c_irq; if (n < 8) { i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_I2C_INTG, n)]; } else { i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_HDMI_INTG, 1)]; } dev = qdev_create(NULL, "exynos4210.i2c"); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_connect_irq(busdev, 0, i2c_irq); sysbus_mmio_map(busdev, 0, addr); s->i2c_if[n] = (I2CBus *)qdev_get_child_bus(dev, "i2c"); } /*** UARTs ***/ exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR, EXYNOS4210_UART0_FIFO_SIZE, 0, NULL, s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 0)]); exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR, EXYNOS4210_UART1_FIFO_SIZE, 1, NULL, s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 1)]); exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR, EXYNOS4210_UART2_FIFO_SIZE, 2, NULL, s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 2)]); exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR, EXYNOS4210_UART3_FIFO_SIZE, 3, NULL, s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 3)]); /*** Display controller (FIMD) ***/ sysbus_create_varargs("exynos4210.fimd", EXYNOS4210_FIMD0_BASE_ADDR, s->irq_table[exynos4210_get_irq(11, 0)], s->irq_table[exynos4210_get_irq(11, 1)], s->irq_table[exynos4210_get_irq(11, 2)], NULL); sysbus_create_simple(TYPE_EXYNOS4210_EHCI, EXYNOS4210_EHCI_BASE_ADDR, s->irq_table[exynos4210_get_irq(28, 3)]); return s; }
Exynos4210State *exynos4210_init(MemoryRegion *system_mem, unsigned long ram_size) { qemu_irq cpu_irq[EXYNOS4210_NCPUS]; int i, n; Exynos4210State *s = g_new(Exynos4210State, 1); qemu_irq *irqp; qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS]; unsigned long mem_size; DeviceState *dev; SysBusDevice *busdev; for (n = 0; n < EXYNOS4210_NCPUS; n++) { s->cpu[n] = cpu_arm_init("cortex-a9"); if (!s->cpu[n]) { fprintf(stderr, "Unable to find CPU %d definition\n", n); exit(1); } /* Create PIC controller for each processor instance */ irqp = arm_pic_init_cpu(s->cpu[n]); /* * Get GICs gpio_in cpu_irq to connect a combiner to them later. * Use only IRQ for a while. */ cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ]; } /*** IRQs ***/ s->irq_table = exynos4210_init_irq(&s->irqs); /* IRQ Gate */ for (i = 0; i < EXYNOS4210_NCPUS; i++) { dev = qdev_create(NULL, "exynos4210.irq_gate"); qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS); qdev_init_nofail(dev); /* Get IRQ Gate input in gate_irq */ for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) { gate_irq[i][n] = qdev_get_gpio_in(dev, n); } busdev = SYS_BUS_DEVICE(dev); /* Connect IRQ Gate output to cpu_irq */ sysbus_connect_irq(busdev, 0, cpu_irq[i]); } /* Private memory region and Internal GIC */ dev = qdev_create(NULL, "a9mpcore_priv"); qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR); for (n = 0; n < EXYNOS4210_NCPUS; n++) { sysbus_connect_irq(busdev, n, gate_irq[n][0]); } for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) { s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n); } /* Cache controller */ sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL); /* External GIC */ dev = qdev_create(NULL, "exynos4210.gic"); qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); /* Map CPU interface */ sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_GIC_CPU_BASE_ADDR); /* Map Distributer interface */ sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR); for (n = 0; n < EXYNOS4210_NCPUS; n++) { sysbus_connect_irq(busdev, n, gate_irq[n][1]); } for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) { s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n); } /* Internal Interrupt Combiner */ dev = qdev_create(NULL, "exynos4210.combiner"); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) { sysbus_connect_irq(busdev, n, s->irqs.int_gic_irq[n]); } exynos4210_combiner_get_gpioin(&s->irqs, dev, 0); sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR); /* External Interrupt Combiner */ dev = qdev_create(NULL, "exynos4210.combiner"); qdev_prop_set_uint32(dev, "external", 1); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) { sysbus_connect_irq(busdev, n, s->irqs.ext_gic_irq[n]); } exynos4210_combiner_get_gpioin(&s->irqs, dev, 1); sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR); /* Initialize board IRQs. */ exynos4210_init_board_irqs(&s->irqs); /*** Memory ***/ /* Chip-ID and OMR */ memory_region_init_ram_ptr(&s->chipid_mem, "exynos4210.chipid", sizeof(chipid_and_omr), chipid_and_omr); memory_region_set_readonly(&s->chipid_mem, true); memory_region_add_subregion(system_mem, EXYNOS4210_CHIPID_ADDR, &s->chipid_mem); /* Internal ROM */ memory_region_init_ram(&s->irom_mem, "exynos4210.irom", EXYNOS4210_IROM_SIZE); memory_region_set_readonly(&s->irom_mem, true); memory_region_add_subregion(system_mem, EXYNOS4210_IROM_BASE_ADDR, &s->irom_mem); /* mirror of iROM */ memory_region_init_alias(&s->irom_alias_mem, "exynos4210.irom_alias", &s->irom_mem, 0, EXYNOS4210_IROM_SIZE); memory_region_set_readonly(&s->irom_alias_mem, true); memory_region_add_subregion(system_mem, EXYNOS4210_IROM_MIRROR_BASE_ADDR, &s->irom_alias_mem); /* Internal RAM */ memory_region_init_ram(&s->iram_mem, "exynos4210.iram", EXYNOS4210_IRAM_SIZE); vmstate_register_ram_global(&s->iram_mem); memory_region_add_subregion(system_mem, EXYNOS4210_IRAM_BASE_ADDR, &s->iram_mem); /* DRAM */ mem_size = ram_size; if (mem_size > EXYNOS4210_DRAM_MAX_SIZE) { memory_region_init_ram(&s->dram1_mem, "exynos4210.dram1", mem_size - EXYNOS4210_DRAM_MAX_SIZE); vmstate_register_ram_global(&s->dram1_mem); memory_region_add_subregion(system_mem, EXYNOS4210_DRAM1_BASE_ADDR, &s->dram1_mem); mem_size = EXYNOS4210_DRAM_MAX_SIZE; } memory_region_init_ram(&s->dram0_mem, "exynos4210.dram0", mem_size); vmstate_register_ram_global(&s->dram0_mem); memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR, &s->dram0_mem); /* PMU. * The only reason of existence at the moment is that secondary CPU boot * loader uses PMU INFORM5 register as a holding pen. */ sysbus_create_simple("exynos4210.pmu", EXYNOS4210_PMU_BASE_ADDR, NULL); /* PWM */ sysbus_create_varargs("exynos4210.pwm", EXYNOS4210_PWM_BASE_ADDR, s->irq_table[exynos4210_get_irq(22, 0)], s->irq_table[exynos4210_get_irq(22, 1)], s->irq_table[exynos4210_get_irq(22, 2)], s->irq_table[exynos4210_get_irq(22, 3)], s->irq_table[exynos4210_get_irq(22, 4)], NULL); /* RTC */ sysbus_create_varargs("exynos4210.rtc", EXYNOS4210_RTC_BASE_ADDR, s->irq_table[exynos4210_get_irq(23, 0)], s->irq_table[exynos4210_get_irq(23, 1)], NULL); /* Multi Core Timer */ dev = qdev_create(NULL, "exynos4210.mct"); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); for (n = 0; n < 4; n++) { /* Connect global timer interrupts to Combiner gpio_in */ sysbus_connect_irq(busdev, n, s->irq_table[exynos4210_get_irq(1, 4 + n)]); } /* Connect local timer interrupts to Combiner gpio_in */ sysbus_connect_irq(busdev, 4, s->irq_table[exynos4210_get_irq(51, 0)]); sysbus_connect_irq(busdev, 5, s->irq_table[exynos4210_get_irq(35, 3)]); sysbus_mmio_map(busdev, 0, EXYNOS4210_MCT_BASE_ADDR); /*** I2C ***/ for (n = 0; n < EXYNOS4210_I2C_NUMBER; n++) { uint32_t addr = EXYNOS4210_I2C_BASE_ADDR + EXYNOS4210_I2C_SHIFT * n; qemu_irq i2c_irq; if (n < 8) { i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_I2C_INTG, n)]; } else { i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_HDMI_INTG, 1)]; } dev = qdev_create(NULL, "exynos4210.i2c"); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_connect_irq(busdev, 0, i2c_irq); sysbus_mmio_map(busdev, 0, addr); s->i2c_if[n] = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); } /*** UARTs ***/ exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR, EXYNOS4210_UART0_FIFO_SIZE, 0, NULL, s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 0)]); exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR, EXYNOS4210_UART1_FIFO_SIZE, 1, NULL, s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 1)]); exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR, EXYNOS4210_UART2_FIFO_SIZE, 2, NULL, s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 2)]); exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR, EXYNOS4210_UART3_FIFO_SIZE, 3, NULL, s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 3)]); /*** Display controller (FIMD) ***/ sysbus_create_varargs("exynos4210.fimd", EXYNOS4210_FIMD0_BASE_ADDR, s->irq_table[exynos4210_get_irq(11, 0)], s->irq_table[exynos4210_get_irq(11, 1)], s->irq_table[exynos4210_get_irq(11, 2)], NULL); sysbus_create_simple(TYPE_EXYNOS4210_EHCI, EXYNOS4210_EHCI_BASE_ADDR, s->irq_table[exynos4210_get_irq(28, 3)]); return s; }
static void zynq_init(MachineState *machine) { ram_addr_t ram_size = machine->ram_size; const char *cpu_model = machine->cpu_model; const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; ObjectClass *cpu_oc; ARMCPU *cpu; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *ext_ram = g_new(MemoryRegion, 1); MemoryRegion *ocm_ram = g_new(MemoryRegion, 1); DeviceState *dev; SysBusDevice *busdev; qemu_irq pic[64]; Error *err = NULL; int n; if (!cpu_model) { cpu_model = "cortex-a9"; } cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model); cpu = ARM_CPU(object_new(object_class_get_name(cpu_oc))); /* By default A9 CPUs have EL3 enabled. This board does not * currently support EL3 so the CPU EL3 property is disabled before * realization. */ if (object_property_find(OBJECT(cpu), "has_el3", NULL)) { object_property_set_bool(OBJECT(cpu), false, "has_el3", &err); if (err) { error_report_err(err); exit(1); } } object_property_set_int(OBJECT(cpu), ZYNQ_BOARD_MIDR, "midr", &err); if (err) { error_report_err(err); exit(1); } object_property_set_int(OBJECT(cpu), MPCORE_PERIPHBASE, "reset-cbar", &err); if (err) { error_report_err(err); exit(1); } object_property_set_bool(OBJECT(cpu), true, "realized", &err); if (err) { error_report_err(err); exit(1); } /* max 2GB ram */ if (ram_size > 0x80000000) { ram_size = 0x80000000; } /* DDR remapped to address zero. */ memory_region_allocate_system_memory(ext_ram, NULL, "zynq.ext_ram", ram_size); memory_region_add_subregion(address_space_mem, 0, ext_ram); /* 256K of on-chip memory */ memory_region_init_ram(ocm_ram, NULL, "zynq.ocm_ram", 256 << 10, &error_fatal); vmstate_register_ram_global(ocm_ram); memory_region_add_subregion(address_space_mem, 0xFFFC0000, ocm_ram); DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0); /* AMD */ pflash_cfi02_register(0xe2000000, NULL, "zynq.pflash", FLASH_SIZE, dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, FLASH_SECTOR_SIZE, FLASH_SIZE/FLASH_SECTOR_SIZE, 1, 1, 0x0066, 0x0022, 0x0000, 0x0000, 0x0555, 0x2aa, 0); dev = qdev_create(NULL, "xilinx,zynq_slcr"); qdev_init_nofail(dev); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xF8000000); dev = qdev_create(NULL, "a9mpcore_priv"); qdev_prop_set_uint32(dev, "num-cpu", 1); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_mmio_map(busdev, 0, MPCORE_PERIPHBASE); sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ)); for (n = 0; n < 64; n++) { pic[n] = qdev_get_gpio_in(dev, n); } zynq_init_spi_flashes(0xE0006000, pic[58-IRQ_OFFSET], false); zynq_init_spi_flashes(0xE0007000, pic[81-IRQ_OFFSET], false); zynq_init_spi_flashes(0xE000D000, pic[51-IRQ_OFFSET], true); sysbus_create_simple("xlnx,ps7-usb", 0xE0002000, pic[53-IRQ_OFFSET]); sysbus_create_simple("xlnx,ps7-usb", 0xE0003000, pic[76-IRQ_OFFSET]); sysbus_create_simple("cadence_uart", 0xE0000000, pic[59-IRQ_OFFSET]); sysbus_create_simple("cadence_uart", 0xE0001000, pic[82-IRQ_OFFSET]); sysbus_create_varargs("cadence_ttc", 0xF8001000, pic[42-IRQ_OFFSET], pic[43-IRQ_OFFSET], pic[44-IRQ_OFFSET], NULL); sysbus_create_varargs("cadence_ttc", 0xF8002000, pic[69-IRQ_OFFSET], pic[70-IRQ_OFFSET], pic[71-IRQ_OFFSET], NULL); gem_init(&nd_table[0], 0xE000B000, pic[54-IRQ_OFFSET]); gem_init(&nd_table[1], 0xE000C000, pic[77-IRQ_OFFSET]); dev = qdev_create(NULL, "generic-sdhci"); qdev_init_nofail(dev); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xE0100000); sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[56-IRQ_OFFSET]); dev = qdev_create(NULL, "generic-sdhci"); qdev_init_nofail(dev); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xE0101000); sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[79-IRQ_OFFSET]); dev = qdev_create(NULL, "pl330"); qdev_prop_set_uint8(dev, "num_chnls", 8); qdev_prop_set_uint8(dev, "num_periph_req", 4); qdev_prop_set_uint8(dev, "num_events", 16); qdev_prop_set_uint8(dev, "data_width", 64); qdev_prop_set_uint8(dev, "wr_cap", 8); qdev_prop_set_uint8(dev, "wr_q_dep", 16); qdev_prop_set_uint8(dev, "rd_cap", 8); qdev_prop_set_uint8(dev, "rd_q_dep", 16); qdev_prop_set_uint16(dev, "data_buffer_dep", 256); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_mmio_map(busdev, 0, 0xF8003000); sysbus_connect_irq(busdev, 0, pic[45-IRQ_OFFSET]); /* abort irq line */ for (n = 0; n < 8; ++n) { /* event irqs */ sysbus_connect_irq(busdev, n + 1, pic[dma_irqs[n] - IRQ_OFFSET]); } zynq_binfo.ram_size = ram_size; zynq_binfo.kernel_filename = kernel_filename; zynq_binfo.kernel_cmdline = kernel_cmdline; zynq_binfo.initrd_filename = initrd_filename; zynq_binfo.nb_cpus = 1; zynq_binfo.board_id = 0xd32; zynq_binfo.loader_start = 0; zynq_binfo.board_setup_addr = BOARD_SETUP_ADDR; zynq_binfo.write_board_setup = zynq_write_board_setup; arm_load_kernel(ARM_CPU(first_cpu), &zynq_binfo); }
static void mpc8544ds_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); PCIBus *pci_bus; CPUPPCState *env = NULL; uint64_t elf_entry; uint64_t elf_lowaddr; target_phys_addr_t entry=0; target_phys_addr_t loadaddr=UIMAGE_LOAD_BASE; target_long kernel_size=0; target_ulong dt_base = 0; target_ulong initrd_base = 0; target_long initrd_size=0; int i=0; unsigned int pci_irq_nrs[4] = {1, 2, 3, 4}; qemu_irq **irqs, *mpic; DeviceState *dev; CPUPPCState *firstenv = NULL; /* Setup CPUs */ if (cpu_model == NULL) { cpu_model = "e500v2_v30"; } irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *)); irqs[0] = g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB); for (i = 0; i < smp_cpus; i++) { PowerPCCPU *cpu; qemu_irq *input; cpu = cpu_ppc_init(cpu_model); if (cpu == NULL) { fprintf(stderr, "Unable to initialize CPU!\n"); exit(1); } env = &cpu->env; if (!firstenv) { firstenv = env; } irqs[i] = irqs[0] + (i * OPENPIC_OUTPUT_NB); input = (qemu_irq *)env->irq_inputs; irqs[i][OPENPIC_OUTPUT_INT] = input[PPCE500_INPUT_INT]; irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT]; env->spr[SPR_BOOKE_PIR] = env->cpu_index = i; ppc_booke_timers_init(env, 400000000, PPC_TIMER_E500); /* Register reset handler */ if (!i) { /* Primary CPU */ struct boot_info *boot_info; boot_info = g_malloc0(sizeof(struct boot_info)); qemu_register_reset(mpc8544ds_cpu_reset, cpu); env->load_info = boot_info; } else { /* Secondary CPUs */ qemu_register_reset(mpc8544ds_cpu_reset_sec, cpu); } } env = firstenv; /* Fixup Memory size on a alignment boundary */ ram_size &= ~(RAM_SIZES_ALIGN - 1); /* Register Memory */ memory_region_init_ram(ram, "mpc8544ds.ram", ram_size); vmstate_register_ram_global(ram); memory_region_add_subregion(address_space_mem, 0, ram); /* MPIC */ mpic = mpic_init(address_space_mem, MPC8544_MPIC_REGS_BASE, smp_cpus, irqs, NULL); if (!mpic) { cpu_abort(env, "MPIC failed to initialize\n"); } /* Serial */ if (serial_hds[0]) { serial_mm_init(address_space_mem, MPC8544_SERIAL0_REGS_BASE, 0, mpic[12+26], 399193, serial_hds[0], DEVICE_BIG_ENDIAN); } if (serial_hds[1]) { serial_mm_init(address_space_mem, MPC8544_SERIAL1_REGS_BASE, 0, mpic[12+26], 399193, serial_hds[0], DEVICE_BIG_ENDIAN); } /* General Utility device */ sysbus_create_simple("mpc8544-guts", MPC8544_UTIL_BASE, NULL); /* PCI */ dev = sysbus_create_varargs("e500-pcihost", MPC8544_PCI_REGS_BASE, mpic[pci_irq_nrs[0]], mpic[pci_irq_nrs[1]], mpic[pci_irq_nrs[2]], mpic[pci_irq_nrs[3]], NULL); pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0"); if (!pci_bus) printf("couldn't create PCI controller!\n"); isa_mmio_init(MPC8544_PCI_IO, MPC8544_PCI_IOLEN); if (pci_bus) { /* Register network interfaces. */ for (i = 0; i < nb_nics; i++) { pci_nic_init_nofail(&nd_table[i], "virtio", NULL); } } /* Register spinning region */ sysbus_create_simple("e500-spin", MPC8544_SPIN_BASE, NULL); /* Load kernel. */ if (kernel_filename) { kernel_size = load_uimage(kernel_filename, &entry, &loadaddr, NULL); if (kernel_size < 0) { kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry, &elf_lowaddr, NULL, 1, ELF_MACHINE, 0); entry = elf_entry; loadaddr = elf_lowaddr; } /* XXX try again as binary */ if (kernel_size < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } } /* Load initrd. */ if (initrd_filename) { initrd_base = (kernel_size + INITRD_LOAD_PAD) & ~INITRD_PAD_MASK; initrd_size = load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); if (initrd_size < 0) { fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", initrd_filename); exit(1); } } /* If we're loading a kernel directly, we must load the device tree too. */ if (kernel_filename) { struct boot_info *boot_info; #ifndef CONFIG_FDT cpu_abort(env, "Compiled without FDT support - can't load kernel\n"); #endif dt_base = (kernel_size + DTC_LOAD_PAD) & ~DTC_PAD_MASK; if (mpc8544_load_device_tree(env, dt_base, ram_size, initrd_base, initrd_size, kernel_cmdline) < 0) { fprintf(stderr, "couldn't load device tree\n"); exit(1); } boot_info = env->load_info; boot_info->entry = entry; boot_info->dt_base = dt_base; } if (kvm_enabled()) { kvmppc_init(); } }
static void zynq_init(QEMUMachineInitArgs *args) { ram_addr_t ram_size = args->ram_size; const char *cpu_model = args->cpu_model; const char *kernel_filename = args->kernel_filename; const char *kernel_cmdline = args->kernel_cmdline; const char *initrd_filename = args->initrd_filename; ARMCPU *cpu; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *ext_ram = g_new(MemoryRegion, 1); MemoryRegion *ocm_ram = g_new(MemoryRegion, 1); DeviceState *dev; SysBusDevice *busdev; qemu_irq *irqp; qemu_irq pic[64]; NICInfo *nd; int n; qemu_irq cpu_irq; if (!cpu_model) { cpu_model = "cortex-a9"; } cpu = cpu_arm_init(cpu_model); if (!cpu) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } irqp = arm_pic_init_cpu(cpu); cpu_irq = irqp[ARM_PIC_CPU_IRQ]; /* max 2GB ram */ if (ram_size > 0x80000000) { ram_size = 0x80000000; } /* DDR remapped to address zero. */ memory_region_init_ram(ext_ram, "zynq.ext_ram", ram_size); vmstate_register_ram_global(ext_ram); memory_region_add_subregion(address_space_mem, 0, ext_ram); /* 256K of on-chip memory */ memory_region_init_ram(ocm_ram, "zynq.ocm_ram", 256 << 10); vmstate_register_ram_global(ocm_ram); memory_region_add_subregion(address_space_mem, 0xFFFC0000, ocm_ram); DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0); /* AMD */ pflash_cfi02_register(0xe2000000, NULL, "zynq.pflash", FLASH_SIZE, dinfo ? dinfo->bdrv : NULL, FLASH_SECTOR_SIZE, FLASH_SIZE/FLASH_SECTOR_SIZE, 1, 1, 0x0066, 0x0022, 0x0000, 0x0000, 0x0555, 0x2aa, 0); dev = qdev_create(NULL, "xilinx,zynq_slcr"); qdev_init_nofail(dev); sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0xF8000000); dev = qdev_create(NULL, "a9mpcore_priv"); qdev_prop_set_uint32(dev, "num-cpu", 1); qdev_init_nofail(dev); busdev = sysbus_from_qdev(dev); sysbus_mmio_map(busdev, 0, 0xF8F00000); sysbus_connect_irq(busdev, 0, cpu_irq); for (n = 0; n < 64; n++) { pic[n] = qdev_get_gpio_in(dev, n); } zynq_init_spi_flashes(0xE0006000, pic[58-IRQ_OFFSET]); zynq_init_spi_flashes(0xE0007000, pic[81-IRQ_OFFSET]); sysbus_create_simple("cadence_uart", 0xE0000000, pic[59-IRQ_OFFSET]); sysbus_create_simple("cadence_uart", 0xE0001000, pic[82-IRQ_OFFSET]); sysbus_create_varargs("cadence_ttc", 0xF8001000, pic[42-IRQ_OFFSET], pic[43-IRQ_OFFSET], pic[44-IRQ_OFFSET], NULL); sysbus_create_varargs("cadence_ttc", 0xF8002000, pic[69-IRQ_OFFSET], pic[70-IRQ_OFFSET], pic[71-IRQ_OFFSET], NULL); for (n = 0; n < nb_nics; n++) { nd = &nd_table[n]; if (n == 0) { gem_init(nd, 0xE000B000, pic[54-IRQ_OFFSET]); } else if (n == 1) { gem_init(nd, 0xE000C000, pic[77-IRQ_OFFSET]); } } zynq_binfo.ram_size = ram_size; zynq_binfo.kernel_filename = kernel_filename; zynq_binfo.kernel_cmdline = kernel_cmdline; zynq_binfo.initrd_filename = initrd_filename; zynq_binfo.nb_cpus = 1; zynq_binfo.board_id = 0xd32; zynq_binfo.loader_start = 0; arm_load_kernel(arm_env_get_cpu(first_cpu), &zynq_binfo); }