Exemple #1
0
static void beagle_common_init(ram_addr_t ram_size,
                        const char *boot_device,
                        const char *kernel_filename,
                        const char *kernel_cmdline,
                        const char *initrd_filename,
                        int cpu_model)
{
    struct beagle_s *s = (struct beagle_s *) qemu_mallocz(sizeof(*s));
    DriveInfo *dmtd = drive_get(IF_MTD, 0, 0);
    DriveInfo *dsd  = drive_get(IF_SD, 0, 0);

    if (!dmtd && !dsd) {
        hw_error("%s: SD or NAND image required", __FUNCTION__);
    }
#if MAX_SERIAL_PORTS < 1
#error MAX_SERIAL_PORTS must be at least 1!
#endif
    s->cpu = omap3_mpu_init(cpu_model, 1, ram_size,
                            NULL, NULL, serial_hds[0], NULL);

    s->nand = nand_init(NAND_MFR_MICRON, 0xba, dmtd ? dmtd->bdrv : NULL);
    nand_setpins(s->nand, 0, 0, 0, 1, 0); /* no write-protect */
    omap_gpmc_attach(s->cpu->gpmc, BEAGLE_NAND_CS, s->nand, 0, 2);

    if (dsd) {
        omap3_mmc_attach(s->cpu->omap3_mmc[0], dsd->bdrv, 0, 0);
    }

    s->twl4030 = twl4030_init(omap_i2c_bus(s->cpu->i2c, 0),
                              s->cpu->irq[0][OMAP_INT_3XXX_SYS_NIRQ],
                              NULL, NULL);
    int i;
    for (i = 0; i < nb_nics; i++) {
        if (!nd_table[i].model || !strcmp(nd_table[i].model, "smc91c111")) {
            break;
        }
    }
    if (cpu_model == omap3430) {
        qemu_set_irq(qdev_get_gpio_in(s->cpu->gpio, BEAGLE_GPIO_ID1),1);
        qemu_set_irq(qdev_get_gpio_in(s->cpu->gpio, BEAGLE_GPIO_ID3),1);
    }
    if (i < nb_nics) {
        s->smc = qdev_create(NULL, "smc91c111");
        qdev_set_nic_properties(s->smc, &nd_table[i]);
        qdev_init_nofail(s->smc);
        sysbus_connect_irq(sysbus_from_qdev(s->smc), 0,
                           qdev_get_gpio_in(s->cpu->gpio, 54));
    } else {
        hw_error("%s: no NIC for smc91c111\n", __FUNCTION__);
    }
    omap_gpmc_attach(s->cpu->gpmc, BEAGLE_SMC_CS, s->smc, 0, 0);

    /* 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);
}
Exemple #2
0
static void lx60_net_init(MemoryRegion *address_space,
        target_phys_addr_t base,
        target_phys_addr_t descriptors,
        target_phys_addr_t buffers,
        qemu_irq irq, NICInfo *nd)
{
    DeviceState *dev;
    SysBusDevice *s;
    MemoryRegion *ram;

    dev = qdev_create(NULL, "open_eth");
    qdev_set_nic_properties(dev, nd);
    qdev_init_nofail(dev);

    s = sysbus_from_qdev(dev);
    sysbus_connect_irq(s, 0, irq);
    memory_region_add_subregion(address_space, base,
            sysbus_mmio_get_region(s, 0));
    memory_region_add_subregion(address_space, descriptors,
            sysbus_mmio_get_region(s, 1));

    ram = g_malloc(sizeof(*ram));
    memory_region_init_ram(ram, "open_eth.ram", 16384);
    vmstate_register_ram_global(ram);
    memory_region_add_subregion(address_space, buffers, ram);
}
Exemple #3
0
static void lx60_net_init(MemoryRegion *address_space,
        hwaddr base,
        hwaddr descriptors,
        hwaddr buffers,
        qemu_irq irq, NICInfo *nd)
{
    DeviceState *dev;
    SysBusDevice *s;
    MemoryRegion *ram;

    dev = qdev_create(NULL, "open_eth");
    qdev_set_nic_properties(dev, nd);
    qdev_init_nofail(dev);

    s = SYS_BUS_DEVICE(dev);
    sysbus_connect_irq(s, 0, irq);
    memory_region_add_subregion(address_space, base,
            sysbus_mmio_get_region(s, 0));
    memory_region_add_subregion(address_space, descriptors,
            sysbus_mmio_get_region(s, 1));

    ram = g_malloc(sizeof(*ram));
    memory_region_init_ram(ram, OBJECT(s), "open_eth.ram", 16384,
                           &error_fatal);
    vmstate_register_ram_global(ram);
    memory_region_add_subregion(address_space, buffers, ram);
}
Exemple #4
0
static void overo_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)
{
    struct overo_s *s = (struct overo_s *) g_malloc0(sizeof(*s));
    DriveInfo *dmtd = drive_get(IF_MTD, 0, 0);
    DriveInfo *dsd  = drive_get(IF_SD, 0, 0);

    if (ram_size > 1024 * 1024 * 1024) {
        fprintf(stderr, "overo: maximum permitted RAM size 1024MB\n");
        exit(1);
    }

    if (!dmtd && !dsd) {
        hw_error("%s: SD or NAND image required", __FUNCTION__);
    }
    s->cpu = omap3_mpu_init(omap3430, ram_size,
                            NULL, NULL, serial_hds[0], NULL);

    s->nand = nand_init(dmtd ? dmtd->bdrv : NULL, NAND_MFR_MICRON, 0xba);
    nand_setpins(s->nand, 0, 0, 0, 1, 0); /* no write-protect */
    omap_gpmc_attach_nand(s->cpu->gpmc, OVERO_NAND_CS, s->nand);

    if (dsd) {
        omap3_mmc_attach(s->cpu->omap3_mmc[0], dsd->bdrv, 0, 0);
    }

    /* 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 (nd_table[0].vlan) {
        /* 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, OVERO_NET_CS,
                         sysbus_mmio_get_region(sysbus_from_qdev(s->eth), 0));
        sysbus_connect_irq(sysbus_from_qdev(s->eth), 0,
                           qdev_get_gpio_in(s->cpu->gpio, 176));
    }
}
void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd)
{
    DeviceState *dev;

    dev = qdev_create(&bus->bus, "spapr-vlan");

    qdev_set_nic_properties(dev, nd);

    qdev_init_nofail(dev);
}
Exemple #6
0
static void gem_init(NICInfo *nd, uint32_t base, qemu_irq irq)
{
    DeviceState *dev;
    SysBusDevice *s;

    qemu_check_nic_model(nd, "cadence_gem");
    dev = qdev_create(NULL, "cadence_gem");
    qdev_set_nic_properties(dev, nd);
    qdev_init_nofail(dev);
    s = sysbus_from_qdev(dev);
    sysbus_mmio_map(s, 0, base);
    sysbus_connect_irq(s, 0, irq);
}
Exemple #7
0
/* Legacy helper function.  Should go away when machine config files are
   implemented.  */
void smc91c111_init(NICInfo *nd, uint32_t base, qemu_irq irq)
{
    DeviceState *dev;
    SysBusDevice *s;

    qemu_check_nic_model(nd, "smc91c111");
    dev = qdev_create(NULL, "smc91c111");
    qdev_set_nic_properties(dev, nd);
    qdev_init_nofail(dev);
    s = SYS_BUS_DEVICE(dev);
    sysbus_mmio_map(s, 0, base);
    sysbus_connect_irq(s, 0, irq);
}
Exemple #8
0
static void mipsnet_init(int base, qemu_irq irq, NICInfo *nd)
{
    DeviceState *dev;
    SysBusDevice *s;

    dev = qdev_create(NULL, "mipsnet");
    qdev_set_nic_properties(dev, nd);
    qdev_init_nofail(dev);

    s = SYS_BUS_DEVICE(dev);
    sysbus_connect_irq(s, 0, irq);
    memory_region_add_subregion(get_system_io(),
                                base,
                                sysbus_mmio_get_region(s, 0));
}
static void lan9215_init(uint32_t base, qemu_irq irq)
{
    DeviceState *dev;
    SysBusDevice *s;

    /* This should be a 9215 but the 9118 is close enough */
    if (nd_table[0].used) {
        qemu_check_nic_model(&nd_table[0], "lan9118");
        dev = qdev_create(NULL, "lan9118");
        qdev_set_nic_properties(dev, &nd_table[0]);
        qdev_prop_set_uint32(dev, "mode_16bit", 1);
        qdev_init_nofail(dev);
        s = SYS_BUS_DEVICE(dev);
        sysbus_mmio_map(s, 0, base);
        sysbus_connect_irq(s, 0, irq);
    }
}
Exemple #10
0
static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
                                  const char *name, hwaddr size)
{
    SysBusDevice *s;
    NICInfo *nd = &nd_table[0];

    /* In hardware this is a LAN9220; the LAN9118 is software compatible
     * except that it doesn't support the checksum-offload feature.
     */
    qemu_check_nic_model(nd, "lan9118");
    mms->lan9118 = qdev_create(NULL, "lan9118");
    qdev_set_nic_properties(mms->lan9118, nd);
    qdev_init_nofail(mms->lan9118);

    s = SYS_BUS_DEVICE(mms->lan9118);
    sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 16));
    return sysbus_mmio_get_region(s, 0);
}
Exemple #11
0
static void openrisc_sim_net_init(MemoryRegion *address_space,
                                  hwaddr base,
                                  hwaddr descriptors,
                                  qemu_irq irq, NICInfo *nd)
{
    DeviceState *dev;
    SysBusDevice *s;

    dev = qdev_create(NULL, "open_eth");
    qdev_set_nic_properties(dev, nd);
    qdev_init_nofail(dev);

    s = sysbus_from_qdev(dev);
    sysbus_connect_irq(s, 0, irq);
    memory_region_add_subregion(address_space, base,
                                sysbus_mmio_get_region(s, 0));
    memory_region_add_subregion(address_space, descriptors,
                                sysbus_mmio_get_region(s, 1));
}
Exemple #12
0
static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
                                  int num_cpus, qemu_irq **cpu_irqs,
                                  int irq_pin, NICInfo *nd)
{
    DeviceState *dev;
    SysBusDevice *s;
    int i;

    dev = qdev_create(NULL, "open_eth");
    qdev_set_nic_properties(dev, nd);
    qdev_init_nofail(dev);

    s = SYS_BUS_DEVICE(dev);
    for (i = 0; i < num_cpus; i++) {
        sysbus_connect_irq(s, 0, cpu_irqs[i][irq_pin]);
    }
    sysbus_mmio_map(s, 0, base);
    sysbus_mmio_map(s, 1, descriptors);
}
Exemple #13
0
static void lance_init(NICInfo *nd, hwaddr leaddr,
                       void *dma_opaque, qemu_irq irq)
{
    DeviceState *dev;
    SysBusDevice *s;
    qemu_irq reset;

    qemu_check_nic_model(&nd_table[0], "lance");

    dev = qdev_create(NULL, "lance");
    qdev_set_nic_properties(dev, nd);
    qdev_prop_set_ptr(dev, "dma", dma_opaque);
    qdev_init_nofail(dev);
    s = SYS_BUS_DEVICE(dev);
    sysbus_mmio_map(s, 0, leaddr);
    sysbus_connect_irq(s, 0, irq);
    reset = qdev_get_gpio_in(dev, 0);
    qdev_connect_gpio_out(dma_opaque, 0, reset);
}
Exemple #14
0
DeviceState *etsec_create(hwaddr         base,
                          MemoryRegion * mr,
                          NICInfo      * nd,
                          qemu_irq       tx_irq,
                          qemu_irq       rx_irq,
                          qemu_irq       err_irq)
{
    DeviceState *dev;

    dev = qdev_create(NULL, "eTSEC");
    qdev_set_nic_properties(dev, nd);
    qdev_init_nofail(dev);

    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, tx_irq);
    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, rx_irq);
    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, err_irq);

    memory_region_add_subregion(mr, base,
                                SYS_BUS_DEVICE(dev)->mmio[0].memory);

    return dev;
}
void s390_create_virtio_net(BusState *bus, const char *name)
{
    int i;

    for (i = 0; i < nb_nics; i++) {
        NICInfo *nd = &nd_table[i];
        DeviceState *dev;

        if (!nd->model) {
            nd->model = g_strdup("virtio");
        }

        if (strcmp(nd->model, "virtio")) {
            fprintf(stderr, "S390 only supports VirtIO nics\n");
            exit(1);
        }

        dev = qdev_create(bus, name);
        qdev_set_nic_properties(dev, nd);
        qdev_init_nofail(dev);
    }
}
Exemple #16
0
/* 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);
}
Exemple #17
0
static void
petalogix_ml605_init(MachineState *machine)
{
    ram_addr_t ram_size = machine->ram_size;
    MemoryRegion *address_space_mem = get_system_memory();
    DeviceState *dev, *dma, *eth0;
    Object *ds, *cs;
    MicroBlazeCPU *cpu;
    SysBusDevice *busdev;
    DriveInfo *dinfo;
    int i;
    MemoryRegion *phys_lmb_bram = g_new(MemoryRegion, 1);
    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
    qemu_irq irq[32];

    /* init CPUs */
    cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU));
    object_property_set_str(OBJECT(cpu), "8.10.a", "version", &error_abort);
    /* Use FPU but don't use floating point conversion and square
     * root instructions
     */
    object_property_set_int(OBJECT(cpu), 1, "use-fpu", &error_abort);
    object_property_set_bool(OBJECT(cpu), true, "dcache-writeback",
                             &error_abort);
    object_property_set_bool(OBJECT(cpu), true, "endianness", &error_abort);
    object_property_set_bool(OBJECT(cpu), true, "realized", &error_abort);

    /* Attach emulated BRAM through the LMB.  */
    memory_region_init_ram(phys_lmb_bram, NULL, "petalogix_ml605.lmb_bram",
                           LMB_BRAM_SIZE, &error_fatal);
    vmstate_register_ram_global(phys_lmb_bram);
    memory_region_add_subregion(address_space_mem, 0x00000000, phys_lmb_bram);

    memory_region_init_ram(phys_ram, NULL, "petalogix_ml605.ram", ram_size,
                           &error_fatal);
    vmstate_register_ram_global(phys_ram);
    memory_region_add_subregion(address_space_mem, MEMORY_BASEADDR, phys_ram);

    dinfo = drive_get(IF_PFLASH, 0, 0);
    /* 5th parameter 2 means bank-width
     * 10th paremeter 0 means little-endian */
    pflash_cfi01_register(FLASH_BASEADDR,
                          NULL, "petalogix_ml605.flash", FLASH_SIZE,
                          dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
                          (64 * 1024), FLASH_SIZE >> 16,
                          2, 0x89, 0x18, 0x0000, 0x0, 0);


    dev = qdev_create(NULL, "xlnx.xps-intc");
    qdev_prop_set_uint32(dev, "kind-of-intr", 1 << TIMER_IRQ);
    qdev_init_nofail(dev);
    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, INTC_BASEADDR);
    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
                       qdev_get_gpio_in(DEVICE(cpu), MB_CPU_IRQ));
    for (i = 0; i < 32; i++) {
        irq[i] = qdev_get_gpio_in(dev, i);
    }

    serial_mm_init(address_space_mem, UART16550_BASEADDR + 0x1000, 2,
                   irq[UART16550_IRQ], 115200, serial_hds[0],
                   DEVICE_LITTLE_ENDIAN);

    /* 2 timers at irq 2 @ 100 Mhz.  */
    dev = qdev_create(NULL, "xlnx.xps-timer");
    qdev_prop_set_uint32(dev, "one-timer-only", 0);
    qdev_prop_set_uint32(dev, "clock-frequency", 100 * 1000000);
    qdev_init_nofail(dev);
    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, TIMER_BASEADDR);
    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[TIMER_IRQ]);

    /* axi ethernet and dma initialization. */
    qemu_check_nic_model(&nd_table[0], "xlnx.axi-ethernet");
    eth0 = qdev_create(NULL, "xlnx.axi-ethernet");
    dma = qdev_create(NULL, "xlnx.axi-dma");

    /* FIXME: attach to the sysbus instead */
    object_property_add_child(qdev_get_machine(), "xilinx-eth", OBJECT(eth0),
                              NULL);
    object_property_add_child(qdev_get_machine(), "xilinx-dma", OBJECT(dma),
                              NULL);

    ds = object_property_get_link(OBJECT(dma),
                                  "axistream-connected-target", NULL);
    cs = object_property_get_link(OBJECT(dma),
                                  "axistream-control-connected-target", NULL);
    qdev_set_nic_properties(eth0, &nd_table[0]);
    qdev_prop_set_uint32(eth0, "rxmem", 0x1000);
    qdev_prop_set_uint32(eth0, "txmem", 0x1000);
    object_property_set_link(OBJECT(eth0), OBJECT(ds),
                             "axistream-connected", &error_abort);
    object_property_set_link(OBJECT(eth0), OBJECT(cs),
                             "axistream-control-connected", &error_abort);
    qdev_init_nofail(eth0);
    sysbus_mmio_map(SYS_BUS_DEVICE(eth0), 0, AXIENET_BASEADDR);
    sysbus_connect_irq(SYS_BUS_DEVICE(eth0), 0, irq[AXIENET_IRQ]);

    ds = object_property_get_link(OBJECT(eth0),
                                  "axistream-connected-target", NULL);
    cs = object_property_get_link(OBJECT(eth0),
                                  "axistream-control-connected-target", NULL);
    qdev_prop_set_uint32(dma, "freqhz", 100 * 1000000);
    object_property_set_link(OBJECT(dma), OBJECT(ds),
                             "axistream-connected", &error_abort);
    object_property_set_link(OBJECT(dma), OBJECT(cs),
                             "axistream-control-connected", &error_abort);
    qdev_init_nofail(dma);
    sysbus_mmio_map(SYS_BUS_DEVICE(dma), 0, AXIDMA_BASEADDR);
    sysbus_connect_irq(SYS_BUS_DEVICE(dma), 0, irq[AXIDMA_IRQ0]);
    sysbus_connect_irq(SYS_BUS_DEVICE(dma), 1, irq[AXIDMA_IRQ1]);

    {
        SSIBus *spi;

        dev = qdev_create(NULL, "xlnx.xps-spi");
        qdev_prop_set_uint8(dev, "num-ss-bits", NUM_SPI_FLASHES);
        qdev_init_nofail(dev);
        busdev = SYS_BUS_DEVICE(dev);
        sysbus_mmio_map(busdev, 0, SPI_BASEADDR);
        sysbus_connect_irq(busdev, 0, irq[SPI_IRQ]);

        spi = (SSIBus *)qdev_get_child_bus(dev, "spi");

        for (i = 0; i < NUM_SPI_FLASHES; i++) {
            qemu_irq cs_line;

            dev = ssi_create_slave(spi, "n25q128");
            cs_line = qdev_get_gpio_in_named(dev, SSI_GPIO_CS, 0);
            sysbus_connect_irq(busdev, i+1, cs_line);
        }
    }

    /* setup PVR to match kernel settings */
    cpu->env.pvr.regs[4] = 0xc56b8000;
    cpu->env.pvr.regs[5] = 0xc56be000;
    cpu->env.pvr.regs[10] = 0x0e000000; /* virtex 6 */

    microblaze_load_kernel(cpu, MEMORY_BASEADDR, ram_size,
                           machine->initrd_filename,
                           BINARY_DEVICE_TREE_FILE,
                           NULL);

}
Exemple #18
0
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));
}
Exemple #19
0
static void mips_jazz_init(MachineState *machine,
                           enum jazz_model_e jazz_model)
{
    MemoryRegion *address_space = get_system_memory();
    char *filename;
    int bios_size, n;
    MIPSCPU *cpu;
    CPUClass *cc;
    CPUMIPSState *env;
    qemu_irq *i8259;
    rc4030_dma *dmas;
    IOMMUMemoryRegion *rc4030_dma_mr;
    MemoryRegion *isa_mem = g_new(MemoryRegion, 1);
    MemoryRegion *isa_io = g_new(MemoryRegion, 1);
    MemoryRegion *rtc = g_new(MemoryRegion, 1);
    MemoryRegion *i8042 = g_new(MemoryRegion, 1);
    MemoryRegion *dma_dummy = g_new(MemoryRegion, 1);
    NICInfo *nd;
    DeviceState *dev, *rc4030;
    SysBusDevice *sysbus;
    ISABus *isa_bus;
    ISADevice *pit;
    DriveInfo *fds[MAX_FD];
    qemu_irq esp_reset, dma_enable;
    MemoryRegion *ram = g_new(MemoryRegion, 1);
    MemoryRegion *bios = g_new(MemoryRegion, 1);
    MemoryRegion *bios2 = g_new(MemoryRegion, 1);

    /* init CPUs */
    cpu = MIPS_CPU(cpu_create(machine->cpu_type));
    env = &cpu->env;
    qemu_register_reset(main_cpu_reset, cpu);

    /* Chipset returns 0 in invalid reads and do not raise data exceptions.
     * However, we can't simply add a global memory region to catch
     * everything, as memory core directly call unassigned_mem_read/write
     * on some invalid accesses, which call do_unassigned_access on the
     * CPU, which raise an exception.
     * Handle that case by hijacking the do_unassigned_access method on
     * the CPU, and do not raise exceptions for data access. */
    cc = CPU_GET_CLASS(cpu);
    real_do_unassigned_access = cc->do_unassigned_access;
    cc->do_unassigned_access = mips_jazz_do_unassigned_access;

    /* allocate RAM */
    memory_region_allocate_system_memory(ram, NULL, "mips_jazz.ram",
                                         machine->ram_size);
    memory_region_add_subregion(address_space, 0, ram);

    memory_region_init_ram(bios, NULL, "mips_jazz.bios", MAGNUM_BIOS_SIZE,
                           &error_fatal);
    memory_region_set_readonly(bios, true);
    memory_region_init_alias(bios2, NULL, "mips_jazz.bios", bios,
                             0, MAGNUM_BIOS_SIZE);
    memory_region_add_subregion(address_space, 0x1fc00000LL, bios);
    memory_region_add_subregion(address_space, 0xfff00000LL, bios2);

    /* load the BIOS image. */
    if (bios_name == NULL)
        bios_name = BIOS_FILENAME;
    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
    if (filename) {
        bios_size = load_image_targphys(filename, 0xfff00000LL,
                                        MAGNUM_BIOS_SIZE);
        g_free(filename);
    } else {
        bios_size = -1;
    }
    if ((bios_size < 0 || bios_size > MAGNUM_BIOS_SIZE) && !qtest_enabled()) {
        error_report("Could not load MIPS bios '%s'", bios_name);
        exit(1);
    }

    /* Init CPU internal devices */
    cpu_mips_irq_init_cpu(cpu);
    cpu_mips_clock_init(cpu);

    /* Chipset */
    rc4030 = rc4030_init(&dmas, &rc4030_dma_mr);
    sysbus = SYS_BUS_DEVICE(rc4030);
    sysbus_connect_irq(sysbus, 0, env->irq[6]);
    sysbus_connect_irq(sysbus, 1, env->irq[3]);
    memory_region_add_subregion(address_space, 0x80000000,
                                sysbus_mmio_get_region(sysbus, 0));
    memory_region_add_subregion(address_space, 0xf0000000,
                                sysbus_mmio_get_region(sysbus, 1));
    memory_region_init_io(dma_dummy, NULL, &dma_dummy_ops, NULL, "dummy_dma", 0x1000);
    memory_region_add_subregion(address_space, 0x8000d000, dma_dummy);

    /* ISA bus: IO space at 0x90000000, mem space at 0x91000000 */
    memory_region_init(isa_io, NULL, "isa-io", 0x00010000);
    memory_region_init(isa_mem, NULL, "isa-mem", 0x01000000);
    memory_region_add_subregion(address_space, 0x90000000, isa_io);
    memory_region_add_subregion(address_space, 0x91000000, isa_mem);
    isa_bus = isa_bus_new(NULL, isa_mem, isa_io, &error_abort);

    /* ISA devices */
    i8259 = i8259_init(isa_bus, env->irq[4]);
    isa_bus_irqs(isa_bus, i8259);
    DMA_init(isa_bus, 0);
    pit = pit_init(isa_bus, 0x40, 0, NULL);
    pcspk_init(isa_bus, pit);

    /* Video card */
    switch (jazz_model) {
    case JAZZ_MAGNUM:
        dev = qdev_create(NULL, "sysbus-g364");
        qdev_init_nofail(dev);
        sysbus = SYS_BUS_DEVICE(dev);
        sysbus_mmio_map(sysbus, 0, 0x60080000);
        sysbus_mmio_map(sysbus, 1, 0x40000000);
        sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(rc4030, 3));
        {
            /* Simple ROM, so user doesn't have to provide one */
            MemoryRegion *rom_mr = g_new(MemoryRegion, 1);
            memory_region_init_ram(rom_mr, NULL, "g364fb.rom", 0x80000,
                                   &error_fatal);
            memory_region_set_readonly(rom_mr, true);
            uint8_t *rom = memory_region_get_ram_ptr(rom_mr);
            memory_region_add_subregion(address_space, 0x60000000, rom_mr);
            rom[0] = 0x10; /* Mips G364 */
        }
        break;
    case JAZZ_PICA61:
        isa_vga_mm_init(0x40000000, 0x60000000, 0, get_system_memory());
        break;
    default:
        break;
    }

    /* Network controller */
    for (n = 0; n < nb_nics; n++) {
        nd = &nd_table[n];
        if (!nd->model)
            nd->model = g_strdup("dp83932");
        if (strcmp(nd->model, "dp83932") == 0) {
            qemu_check_nic_model(nd, "dp83932");

            dev = qdev_create(NULL, "dp8393x");
            qdev_set_nic_properties(dev, nd);
            qdev_prop_set_uint8(dev, "it_shift", 2);
            qdev_prop_set_ptr(dev, "dma_mr", rc4030_dma_mr);
            qdev_init_nofail(dev);
            sysbus = SYS_BUS_DEVICE(dev);
            sysbus_mmio_map(sysbus, 0, 0x80001000);
            sysbus_mmio_map(sysbus, 1, 0x8000b000);
            sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(rc4030, 4));
            break;
        } else if (is_help_option(nd->model)) {
            fprintf(stderr, "qemu: Supported NICs: dp83932\n");
            exit(1);
        } else {
            fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model);
            exit(1);
        }
    }

    /* SCSI adapter */
    esp_init(0x80002000, 0,
             rc4030_dma_read, rc4030_dma_write, dmas[0],
             qdev_get_gpio_in(rc4030, 5), &esp_reset, &dma_enable);

    /* Floppy */
    for (n = 0; n < MAX_FD; n++) {
        fds[n] = drive_get(IF_FLOPPY, 0, n);
    }
    /* FIXME: we should enable DMA with a custom IsaDma device */
    fdctrl_init_sysbus(qdev_get_gpio_in(rc4030, 1), -1, 0x80003000, fds);

    /* Real time clock */
    rtc_init(isa_bus, 1980, NULL);
    memory_region_init_io(rtc, NULL, &rtc_ops, NULL, "rtc", 0x1000);
    memory_region_add_subregion(address_space, 0x80004000, rtc);

    /* Keyboard (i8042) */
    i8042_mm_init(qdev_get_gpio_in(rc4030, 6), qdev_get_gpio_in(rc4030, 7),
                  i8042, 0x1000, 0x1);
    memory_region_add_subregion(address_space, 0x80005000, i8042);

    /* Serial ports */
    if (serial_hds[0]) {
        serial_mm_init(address_space, 0x80006000, 0,
                       qdev_get_gpio_in(rc4030, 8), 8000000/16,
                       serial_hds[0], DEVICE_NATIVE_ENDIAN);
    }
    if (serial_hds[1]) {
        serial_mm_init(address_space, 0x80007000, 0,
                       qdev_get_gpio_in(rc4030, 9), 8000000/16,
                       serial_hds[1], DEVICE_NATIVE_ENDIAN);
    }

    /* Parallel port */
    if (parallel_hds[0])
        parallel_mm_init(address_space, 0x80008000, 0,
                         qdev_get_gpio_in(rc4030, 0), parallel_hds[0]);

    /* FIXME: missing Jazz sound at 0x8000c000, rc4030[2] */

    /* NVRAM */
    dev = qdev_create(NULL, "ds1225y");
    qdev_init_nofail(dev);
    sysbus = SYS_BUS_DEVICE(dev);
    sysbus_mmio_map(sysbus, 0, 0x80009000);

    /* LED indicator */
    sysbus_create_simple("jazz-led", 0x8000f000, NULL);
}
static void
petalogix_s3adsp1800_init(MachineState *machine)
{
    ram_addr_t ram_size = machine->ram_size;
    DeviceState *dev;
    MicroBlazeCPU *cpu;
    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];
    MemoryRegion *sysmem = get_system_memory();

    cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU));
    object_property_set_str(OBJECT(cpu), "7.10.d", "version", &error_abort);
    object_property_set_bool(OBJECT(cpu), true, "realized", &error_abort);

    /* Attach emulated BRAM through the LMB.  */
    memory_region_init_ram(phys_lmb_bram, NULL,
                           "petalogix_s3adsp1800.lmb_bram", LMB_BRAM_SIZE,
                           &error_fatal);
    memory_region_add_subregion(sysmem, 0x00000000, phys_lmb_bram);

    memory_region_init_ram(phys_ram, NULL, "petalogix_s3adsp1800.ram",
                           ram_size, &error_fatal);
    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 ? blk_by_legacy_dinfo(dinfo) : NULL,
                          64 * KiB, FLASH_SIZE >> 16,
                          1, 0x89, 0x18, 0x0000, 0x0, 1);

    dev = qdev_create(NULL, "xlnx.xps-intc");
    qdev_prop_set_uint32(dev, "kind-of-intr",
                         1 << ETHLITE_IRQ | 1 << UARTLITE_IRQ);
    qdev_init_nofail(dev);
    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, INTC_BASEADDR);
    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
                       qdev_get_gpio_in(DEVICE(cpu), MB_CPU_IRQ));
    for (i = 0; i < 32; i++) {
        irq[i] = qdev_get_gpio_in(dev, i);
    }

    xilinx_uartlite_create(UARTLITE_BASEADDR, irq[UARTLITE_IRQ],
                           serial_hd(0));

    /* 2 timers at irq 2 @ 62 Mhz.  */
    dev = qdev_create(NULL, "xlnx.xps-timer");
    qdev_prop_set_uint32(dev, "one-timer-only", 0);
    qdev_prop_set_uint32(dev, "clock-frequency", 62 * 1000000);
    qdev_init_nofail(dev);
    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, TIMER_BASEADDR);
    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[TIMER_IRQ]);

    qemu_check_nic_model(&nd_table[0], "xlnx.xps-ethernetlite");
    dev = qdev_create(NULL, "xlnx.xps-ethernetlite");
    qdev_set_nic_properties(dev, &nd_table[0]);
    qdev_prop_set_uint32(dev, "tx-ping-pong", 0);
    qdev_prop_set_uint32(dev, "rx-ping-pong", 0);
    qdev_init_nofail(dev);
    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, ETHLITE_BASEADDR);
    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[ETHLITE_IRQ]);

    create_unimplemented_device("gpio", GPIO_BASEADDR, 0x10000);

    microblaze_load_kernel(cpu, ddr_base, ram_size,
                           machine->initrd_filename,
                           BINARY_DEVICE_TREE_FILE,
                           NULL);
}
Exemple #21
0
static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
{
    FslIMX6ULState *s = FSL_IMX6UL(dev);
    int i;
    qemu_irq irq;
    char name[NAME_SIZE];

    if (smp_cpus > FSL_IMX6UL_NUM_CPUS) {
        error_setg(errp, "%s: Only %d CPUs are supported (%d requested)",
                   TYPE_FSL_IMX6UL, FSL_IMX6UL_NUM_CPUS, smp_cpus);
        return;
    }

    for (i = 0; i < smp_cpus; i++) {
        Object *o = OBJECT(&s->cpu[i]);

        object_property_set_int(o, QEMU_PSCI_CONDUIT_SMC,
                                "psci-conduit", &error_abort);

        /* On uniprocessor, the CBAR is set to 0 */
        if (smp_cpus > 1) {
            object_property_set_int(o, FSL_IMX6UL_A7MPCORE_ADDR,
                                    "reset-cbar", &error_abort);
        }

        if (i) {
            /* Secondary CPUs start in PSCI powered-down state */
            object_property_set_bool(o, true,
                                     "start-powered-off", &error_abort);
        }

        object_property_set_bool(o, true, "realized", &error_abort);
    }

    /*
     * A7MPCORE
     */
    object_property_set_int(OBJECT(&s->a7mpcore), smp_cpus, "num-cpu",
                            &error_abort);
    object_property_set_int(OBJECT(&s->a7mpcore),
                            FSL_IMX6UL_MAX_IRQ + GIC_INTERNAL,
                            "num-irq", &error_abort);
    object_property_set_bool(OBJECT(&s->a7mpcore), true, "realized",
                             &error_abort);
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->a7mpcore), 0, FSL_IMX6UL_A7MPCORE_ADDR);

    for (i = 0; i < smp_cpus; i++) {
        SysBusDevice *sbd = SYS_BUS_DEVICE(&s->a7mpcore);
        DeviceState  *d   = DEVICE(qemu_get_cpu(i));

        irq = qdev_get_gpio_in(d, ARM_CPU_IRQ);
        sysbus_connect_irq(sbd, i, irq);
        sysbus_connect_irq(sbd, i + smp_cpus, qdev_get_gpio_in(d, ARM_CPU_FIQ));
        sysbus_connect_irq(sbd, i + 2 * smp_cpus,
                           qdev_get_gpio_in(d, ARM_CPU_VIRQ));
        sysbus_connect_irq(sbd, i + 3 * smp_cpus,
                           qdev_get_gpio_in(d, ARM_CPU_VFIQ));
    }

    /*
     * A7MPCORE DAP
     */
    create_unimplemented_device("a7mpcore-dap", FSL_IMX6UL_A7MPCORE_DAP_ADDR,
                                0x100000);

    /*
     * GPT 1, 2
     */
    for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
        static const hwaddr FSL_IMX6UL_GPTn_ADDR[FSL_IMX6UL_NUM_GPTS] = {
            FSL_IMX6UL_GPT1_ADDR,
            FSL_IMX6UL_GPT2_ADDR,
        };

        static const int FSL_IMX6UL_GPTn_IRQ[FSL_IMX6UL_NUM_GPTS] = {
            FSL_IMX6UL_GPT1_IRQ,
            FSL_IMX6UL_GPT2_IRQ,
        };

        s->gpt[i].ccm = IMX_CCM(&s->ccm);
        object_property_set_bool(OBJECT(&s->gpt[i]), true, "realized",
                                 &error_abort);

        sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0,
                        FSL_IMX6UL_GPTn_ADDR[i]);

        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->a7mpcore),
                                            FSL_IMX6UL_GPTn_IRQ[i]));
    }

    /*
     * EPIT 1, 2
     */
    for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
        static const hwaddr FSL_IMX6UL_EPITn_ADDR[FSL_IMX6UL_NUM_EPITS] = {
            FSL_IMX6UL_EPIT1_ADDR,
            FSL_IMX6UL_EPIT2_ADDR,
        };

        static const int FSL_IMX6UL_EPITn_IRQ[FSL_IMX6UL_NUM_EPITS] = {
            FSL_IMX6UL_EPIT1_IRQ,
            FSL_IMX6UL_EPIT2_IRQ,
        };

        s->epit[i].ccm = IMX_CCM(&s->ccm);
        object_property_set_bool(OBJECT(&s->epit[i]), true, "realized",
                                 &error_abort);

        sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0,
                        FSL_IMX6UL_EPITn_ADDR[i]);

        sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->a7mpcore),
                                            FSL_IMX6UL_EPITn_IRQ[i]));
    }

    /*
     * GPIO
     */
    for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
        static const hwaddr FSL_IMX6UL_GPIOn_ADDR[FSL_IMX6UL_NUM_GPIOS] = {
            FSL_IMX6UL_GPIO1_ADDR,
            FSL_IMX6UL_GPIO2_ADDR,
            FSL_IMX6UL_GPIO3_ADDR,
            FSL_IMX6UL_GPIO4_ADDR,
            FSL_IMX6UL_GPIO5_ADDR,
        };

        static const int FSL_IMX6UL_GPIOn_LOW_IRQ[FSL_IMX6UL_NUM_GPIOS] = {
            FSL_IMX6UL_GPIO1_LOW_IRQ,
            FSL_IMX6UL_GPIO2_LOW_IRQ,
            FSL_IMX6UL_GPIO3_LOW_IRQ,
            FSL_IMX6UL_GPIO4_LOW_IRQ,
            FSL_IMX6UL_GPIO5_LOW_IRQ,
        };

        static const int FSL_IMX6UL_GPIOn_HIGH_IRQ[FSL_IMX6UL_NUM_GPIOS] = {
            FSL_IMX6UL_GPIO1_HIGH_IRQ,
            FSL_IMX6UL_GPIO2_HIGH_IRQ,
            FSL_IMX6UL_GPIO3_HIGH_IRQ,
            FSL_IMX6UL_GPIO4_HIGH_IRQ,
            FSL_IMX6UL_GPIO5_HIGH_IRQ,
        };

        object_property_set_bool(OBJECT(&s->gpio[i]), true, "realized",
                                 &error_abort);

        sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0,
                        FSL_IMX6UL_GPIOn_ADDR[i]);

        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->a7mpcore),
                                            FSL_IMX6UL_GPIOn_LOW_IRQ[i]));

        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1,
                           qdev_get_gpio_in(DEVICE(&s->a7mpcore),
                                            FSL_IMX6UL_GPIOn_HIGH_IRQ[i]));
    }

    /*
     * IOMUXC and IOMUXC_GPR
     */
    for (i = 0; i < 1; i++) {
        static const hwaddr FSL_IMX6UL_IOMUXCn_ADDR[FSL_IMX6UL_NUM_IOMUXCS] = {
            FSL_IMX6UL_IOMUXC_ADDR,
            FSL_IMX6UL_IOMUXC_GPR_ADDR,
        };

        snprintf(name, NAME_SIZE, "iomuxc%d", i);
        create_unimplemented_device(name, FSL_IMX6UL_IOMUXCn_ADDR[i], 0x4000);
    }

    /*
     * CCM
     */
    object_property_set_bool(OBJECT(&s->ccm), true, "realized", &error_abort);
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX6UL_CCM_ADDR);

    /*
     * SRC
     */
    object_property_set_bool(OBJECT(&s->src), true, "realized", &error_abort);
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->src), 0, FSL_IMX6UL_SRC_ADDR);

    /*
     * GPCv2
     */
    object_property_set_bool(OBJECT(&s->gpcv2), true,
                             "realized", &error_abort);
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpcv2), 0, FSL_IMX6UL_GPC_ADDR);

    /* Initialize all ECSPI */
    for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
        static const hwaddr FSL_IMX6UL_SPIn_ADDR[FSL_IMX6UL_NUM_ECSPIS] = {
            FSL_IMX6UL_ECSPI1_ADDR,
            FSL_IMX6UL_ECSPI2_ADDR,
            FSL_IMX6UL_ECSPI3_ADDR,
            FSL_IMX6UL_ECSPI4_ADDR,
        };

        static const int FSL_IMX6UL_SPIn_IRQ[FSL_IMX6UL_NUM_ECSPIS] = {
            FSL_IMX6UL_ECSPI1_IRQ,
            FSL_IMX6UL_ECSPI2_IRQ,
            FSL_IMX6UL_ECSPI3_IRQ,
            FSL_IMX6UL_ECSPI4_IRQ,
        };

        /* Initialize the SPI */
        object_property_set_bool(OBJECT(&s->spi[i]), true, "realized",
                                 &error_abort);

        sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
                        FSL_IMX6UL_SPIn_ADDR[i]);

        sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->a7mpcore),
                                            FSL_IMX6UL_SPIn_IRQ[i]));
    }

    /*
     * I2C
     */
    for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
        static const hwaddr FSL_IMX6UL_I2Cn_ADDR[FSL_IMX6UL_NUM_I2CS] = {
            FSL_IMX6UL_I2C1_ADDR,
            FSL_IMX6UL_I2C2_ADDR,
            FSL_IMX6UL_I2C3_ADDR,
            FSL_IMX6UL_I2C4_ADDR,
        };

        static const int FSL_IMX6UL_I2Cn_IRQ[FSL_IMX6UL_NUM_I2CS] = {
            FSL_IMX6UL_I2C1_IRQ,
            FSL_IMX6UL_I2C2_IRQ,
            FSL_IMX6UL_I2C3_IRQ,
            FSL_IMX6UL_I2C4_IRQ,
        };

        object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized",
                                 &error_abort);
        sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, FSL_IMX6UL_I2Cn_ADDR[i]);

        sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->a7mpcore),
                                            FSL_IMX6UL_I2Cn_IRQ[i]));
    }

    /*
     * UART
     */
    for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
        static const hwaddr FSL_IMX6UL_UARTn_ADDR[FSL_IMX6UL_NUM_UARTS] = {
            FSL_IMX6UL_UART1_ADDR,
            FSL_IMX6UL_UART2_ADDR,
            FSL_IMX6UL_UART3_ADDR,
            FSL_IMX6UL_UART4_ADDR,
            FSL_IMX6UL_UART5_ADDR,
            FSL_IMX6UL_UART6_ADDR,
            FSL_IMX6UL_UART7_ADDR,
            FSL_IMX6UL_UART8_ADDR,
        };

        static const int FSL_IMX6UL_UARTn_IRQ[FSL_IMX6UL_NUM_UARTS] = {
            FSL_IMX6UL_UART1_IRQ,
            FSL_IMX6UL_UART2_IRQ,
            FSL_IMX6UL_UART3_IRQ,
            FSL_IMX6UL_UART4_IRQ,
            FSL_IMX6UL_UART5_IRQ,
            FSL_IMX6UL_UART6_IRQ,
            FSL_IMX6UL_UART7_IRQ,
            FSL_IMX6UL_UART8_IRQ,
        };

        qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", serial_hd(i));

        object_property_set_bool(OBJECT(&s->uart[i]), true, "realized",
                                 &error_abort);

        sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0,
                        FSL_IMX6UL_UARTn_ADDR[i]);

        sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->a7mpcore),
                                            FSL_IMX6UL_UARTn_IRQ[i]));
    }

    /*
     * Ethernet
     */
    for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
        static const hwaddr FSL_IMX6UL_ENETn_ADDR[FSL_IMX6UL_NUM_ETHS] = {
            FSL_IMX6UL_ENET1_ADDR,
            FSL_IMX6UL_ENET2_ADDR,
        };

        static const int FSL_IMX6UL_ENETn_IRQ[FSL_IMX6UL_NUM_ETHS] = {
            FSL_IMX6UL_ENET1_IRQ,
            FSL_IMX6UL_ENET2_IRQ,
        };

        static const int FSL_IMX6UL_ENETn_TIMER_IRQ[FSL_IMX6UL_NUM_ETHS] = {
            FSL_IMX6UL_ENET1_TIMER_IRQ,
            FSL_IMX6UL_ENET2_TIMER_IRQ,
        };

        object_property_set_uint(OBJECT(&s->eth[i]),
                                 FSL_IMX6UL_ETH_NUM_TX_RINGS,
                                 "tx-ring-num", &error_abort);
        qdev_set_nic_properties(DEVICE(&s->eth[i]), &nd_table[i]);
        object_property_set_bool(OBJECT(&s->eth[i]), true, "realized",
                                 &error_abort);

        sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth[i]), 0,
                        FSL_IMX6UL_ENETn_ADDR[i]);

        sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->a7mpcore),
                                            FSL_IMX6UL_ENETn_IRQ[i]));

        sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 1,
                           qdev_get_gpio_in(DEVICE(&s->a7mpcore),
                                            FSL_IMX6UL_ENETn_TIMER_IRQ[i]));
    }

    /*
     * USDHC
     */
    for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
        static const hwaddr FSL_IMX6UL_USDHCn_ADDR[FSL_IMX6UL_NUM_USDHCS] = {
            FSL_IMX6UL_USDHC1_ADDR,
            FSL_IMX6UL_USDHC2_ADDR,
        };

        static const int FSL_IMX6UL_USDHCn_IRQ[FSL_IMX6UL_NUM_USDHCS] = {
            FSL_IMX6UL_USDHC1_IRQ,
            FSL_IMX6UL_USDHC2_IRQ,
        };

        object_property_set_bool(OBJECT(&s->usdhc[i]), true, "realized",
                                 &error_abort);

        sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
                        FSL_IMX6UL_USDHCn_ADDR[i]);

        sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->a7mpcore),
                                            FSL_IMX6UL_USDHCn_IRQ[i]));
    }

    /*
     * SNVS
     */
    object_property_set_bool(OBJECT(&s->snvs), true, "realized", &error_abort);
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX6UL_SNVS_HP_ADDR);

    /*
     * Watchdog
     */
    for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
        static const hwaddr FSL_IMX6UL_WDOGn_ADDR[FSL_IMX6UL_NUM_WDTS] = {
            FSL_IMX6UL_WDOG1_ADDR,
            FSL_IMX6UL_WDOG2_ADDR,
            FSL_IMX6UL_WDOG3_ADDR,
        };

        object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized",
                                 &error_abort);

        sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0,
                        FSL_IMX6UL_WDOGn_ADDR[i]);
    }

    /*
     * GPR
     */
    object_property_set_bool(OBJECT(&s->gpr), true, "realized",
                             &error_abort);
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, FSL_IMX6UL_IOMUXC_GPR_ADDR);

    /*
     * SDMA
     */
    create_unimplemented_device("sdma", FSL_IMX6UL_SDMA_ADDR, 0x4000);

    /*
     * APHB_DMA
     */
    create_unimplemented_device("aphb_dma", FSL_IMX6UL_APBH_DMA_ADDR,
                                FSL_IMX6UL_APBH_DMA_SIZE);

    /*
     * ADCs
     */
    for (i = 0; i < FSL_IMX6UL_NUM_ADCS; i++) {
        static const hwaddr FSL_IMX6UL_ADCn_ADDR[FSL_IMX6UL_NUM_ADCS] = {
            FSL_IMX6UL_ADC1_ADDR,
            FSL_IMX6UL_ADC2_ADDR,
        };

        snprintf(name, NAME_SIZE, "adc%d", i);
        create_unimplemented_device(name, FSL_IMX6UL_ADCn_ADDR[i], 0x4000);
    }

    /*
     * LCD
     */
    create_unimplemented_device("lcdif", FSL_IMX6UL_LCDIF_ADDR, 0x4000);

    /*
     * ROM memory
     */
    memory_region_init_rom(&s->rom, NULL, "imx6ul.rom",
                           FSL_IMX6UL_ROM_SIZE, &error_abort);
    memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_ROM_ADDR,
                                &s->rom);

    /*
     * CAAM memory
     */
    memory_region_init_rom(&s->caam, NULL, "imx6ul.caam",
                           FSL_IMX6UL_CAAM_MEM_SIZE, &error_abort);
    memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_CAAM_MEM_ADDR,
                                &s->caam);

    /*
     * OCRAM memory
     */
    memory_region_init_ram(&s->ocram, NULL, "imx6ul.ocram",
                           FSL_IMX6UL_OCRAM_MEM_SIZE,
                           &error_abort);
    memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_OCRAM_MEM_ADDR,
                                &s->ocram);

    /*
     * internal OCRAM (128 KB) is aliased over 512 KB
     */
    memory_region_init_alias(&s->ocram_alias, NULL, "imx6ul.ocram_alias",
                             &s->ocram, 0, FSL_IMX6UL_OCRAM_ALIAS_SIZE);
    memory_region_add_subregion(get_system_memory(),
                                FSL_IMX6UL_OCRAM_ALIAS_ADDR, &s->ocram_alias);
}
Exemple #22
0
/* 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 highbank_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)
{
    CPUARMState *env = NULL;
    DeviceState *dev;
    SysBusDevice *busdev;
    qemu_irq *irqp;
    qemu_irq pic[128];
    int n;
    qemu_irq cpu_irq[4];
    MemoryRegion *sysram;
    MemoryRegion *dram;
    MemoryRegion *sysmem;
    char *sysboot_filename;

    if (!cpu_model) {
        cpu_model = "cortex-a9";
    }

    for (n = 0; n < smp_cpus; n++) {
        ARMCPU *cpu;
        cpu = cpu_arm_init(cpu_model);
        if (cpu == NULL) {
            fprintf(stderr, "Unable to find CPU definition\n");
            exit(1);
        }
        env = &cpu->env;
        /* This will become a QOM property eventually */
        cpu->reset_cbar = GIC_BASE_ADDR;
        irqp = arm_pic_init_cpu(env);
        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
    }

    sysmem = get_system_memory();
    dram = g_new(MemoryRegion, 1);
    memory_region_init_ram(dram, "highbank.dram", ram_size);
    /* SDRAM at address zero.  */
    memory_region_add_subregion(sysmem, 0, dram);

    sysram = g_new(MemoryRegion, 1);
    memory_region_init_ram(sysram, "highbank.sysram", 0x8000);
    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) {
            uint32_t filesize = get_image_size(sysboot_filename);
            if (load_image_targphys("sysram.bin", 0xfff88000, filesize) < 0) {
                hw_error("Unable to load %s\n", bios_name);
            }
        } else {
           hw_error("Unable to find %s\n", bios_name);
        }
    }

    dev = qdev_create(NULL, "a9mpcore_priv");
    qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
    qdev_prop_set_uint32(dev, "num-irq", NIRQ_GIC);
    qdev_init_nofail(dev);
    busdev = sysbus_from_qdev(dev);
    sysbus_mmio_map(busdev, 0, GIC_BASE_ADDR);
    for (n = 0; n < smp_cpus; n++) {
        sysbus_connect_irq(busdev, n, cpu_irq[n]);
    }

    for (n = 0; n < 128; n++) {
        pic[n] = qdev_get_gpio_in(dev, n);
    }

    dev = qdev_create(NULL, "l2x0");
    qdev_init_nofail(dev);
    busdev = sysbus_from_qdev(dev);
    sysbus_mmio_map(busdev, 0, 0xfff12000);

    dev = qdev_create(NULL, "sp804");
    qdev_prop_set_uint32(dev, "freq0", 150000000);
    qdev_prop_set_uint32(dev, "freq1", 150000000);
    qdev_init_nofail(dev);
    busdev = sysbus_from_qdev(dev);
    sysbus_mmio_map(busdev, 0, 0xfff34000);
    sysbus_connect_irq(busdev, 0, pic[18]);
    sysbus_create_simple("pl011", 0xfff36000, pic[20]);

    dev = qdev_create(NULL, "highbank-regs");
    qdev_init_nofail(dev);
    busdev = sysbus_from_qdev(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("sysbus-ahci", 0xffe08000, pic[83]);

    if (nd_table[0].vlan) {
        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(sysbus_from_qdev(dev), 0, 0xfff50000);
        sysbus_connect_irq(sysbus_from_qdev(dev), 0, pic[77]);
        sysbus_connect_irq(sysbus_from_qdev(dev), 1, pic[78]);
        sysbus_connect_irq(sysbus_from_qdev(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(sysbus_from_qdev(dev), 0, 0xfff51000);
        sysbus_connect_irq(sysbus_from_qdev(dev), 0, pic[80]);
        sysbus_connect_irq(sysbus_from_qdev(dev), 1, pic[81]);
        sysbus_connect_irq(sysbus_from_qdev(dev), 2, pic[82]);
    }

    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;
    arm_load_kernel(first_cpu, &highbank_binfo);
}
Exemple #23
0
static void aspeed_soc_realize(DeviceState *dev, Error **errp)
{
    int i;
    AspeedSoCState *s = ASPEED_SOC(dev);
    AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
    Error *err = NULL, *local_err = NULL;

    /* IO space */
    create_unimplemented_device("aspeed_soc.io",
                                ASPEED_SOC_IOMEM_BASE, ASPEED_SOC_IOMEM_SIZE);

    /* CPU */
    object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    /* SRAM */
    memory_region_init_ram(&s->sram, OBJECT(dev), "aspeed.sram",
                           sc->info->sram_size, &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    memory_region_add_subregion(get_system_memory(), ASPEED_SOC_SRAM_BASE,
                                &s->sram);

    /* SCU */
    object_property_set_bool(OBJECT(&s->scu), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, ASPEED_SOC_SCU_BASE);

    /* VIC */
    object_property_set_bool(OBJECT(&s->vic), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, ASPEED_SOC_VIC_BASE);
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0,
                       qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1,
                       qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ));

    /* Timer */
    object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, ASPEED_SOC_TIMER_BASE);
    for (i = 0; i < ARRAY_SIZE(timer_irqs); i++) {
        qemu_irq irq = qdev_get_gpio_in(DEVICE(&s->vic), timer_irqs[i]);
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
    }

    /* UART - attach an 8250 to the IO space as our UART5 */
    if (serial_hd(0)) {
        qemu_irq uart5 = qdev_get_gpio_in(DEVICE(&s->vic), uart_irqs[4]);
        serial_mm_init(get_system_memory(),
                       ASPEED_SOC_IOMEM_BASE + ASPEED_SOC_UART_5_BASE, 2,
                       uart5, 38400, serial_hd(0), DEVICE_LITTLE_ENDIAN);
    }

    /* I2C */
    object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, ASPEED_SOC_I2C_BASE);
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
                       qdev_get_gpio_in(DEVICE(&s->vic), 12));

    /* FMC, The number of CS is set at the board level */
    object_property_set_bool(OBJECT(&s->fmc), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, ASPEED_SOC_FMC_BASE);
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1,
                    s->fmc.ctrl->flash_window_base);
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0,
                       qdev_get_gpio_in(DEVICE(&s->vic), 19));

    /* SPI */
    for (i = 0; i < sc->info->spis_num; i++) {
        object_property_set_int(OBJECT(&s->spi[i]), 1, "num-cs", &err);
        object_property_set_bool(OBJECT(&s->spi[i]), true, "realized",
                                 &local_err);
        error_propagate(&err, local_err);
        if (err) {
            error_propagate(errp, err);
            return;
        }
        sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, sc->info->spi_bases[i]);
        sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1,
                        s->spi[i].ctrl->flash_window_base);
    }

    /* SDMC - SDRAM Memory Controller */
    object_property_set_bool(OBJECT(&s->sdmc), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, ASPEED_SOC_SDMC_BASE);

    /* Watch dog */
    for (i = 0; i < sc->info->wdts_num; i++) {
        object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }
        sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0,
                        ASPEED_SOC_WDT_BASE + i * 0x20);
    }

    /* Net */
    qdev_set_nic_properties(DEVICE(&s->ftgmac100), &nd_table[0]);
    object_property_set_bool(OBJECT(&s->ftgmac100), true, "aspeed", &err);
    object_property_set_bool(OBJECT(&s->ftgmac100), true, "realized",
                             &local_err);
    error_propagate(&err, local_err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->ftgmac100), 0, ASPEED_SOC_ETH1_BASE);
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100), 0,
                       qdev_get_gpio_in(DEVICE(&s->vic), 2));
}
Exemple #24
0
/* 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 *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;
    DeviceState *dev = NULL;
    SysBusDevice *busdev;
    qemu_irq pic[128];
    int n;
    qemu_irq cpu_irq[4];
    MemoryRegion *sysram;
    MemoryRegion *dram;
    MemoryRegion *sysmem;
    char *sysboot_filename;

    if (!cpu_model) {
        switch (machine_id) {
        case CALXEDA_HIGHBANK:
            cpu_model = "cortex-a9";
            break;
        case CALXEDA_MIDWAY:
            cpu_model = "cortex-a15";
            break;
        }
    }

    for (n = 0; n < smp_cpus; n++) {
        ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
        Object *cpuobj;
        ARMCPU *cpu;
        Error *err = NULL;

        if (!oc) {
            error_report("Unable to find CPU definition");
            exit(1);
        }

        cpuobj = object_new(object_class_get_name(oc));
        cpu = ARM_CPU(cpuobj);

        /* By default A9 and A15 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_err(err);
                exit(1);
            }
        }

        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", &err);
        if (err) {
            error_report_err(err);
            exit(1);
        }
        cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
    }

    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(sysram, NULL, "highbank.sysram", 0x8000,
                           &error_abort);
    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) {
                hw_error("Unable to load %s\n", bios_name);
            }
            g_free(sysboot_filename);
        } else {
           hw_error("Unable to find %s\n", bios_name);
        }
    }

    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, "a9mpcore_priv");
        break;
    case CALXEDA_MIDWAY:
        dev = qdev_create(NULL, "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]);
    }

    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]);
    sysbus_create_simple("pl011", 0xfff36000, pic[20]);

    dev = qdev_create(NULL, "highbank-regs");
    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("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]);
    }

    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;
    arm_load_kernel(ARM_CPU(first_cpu), &highbank_binfo);
}
Exemple #25
0
static void fsl_imx25_realize(DeviceState *dev, Error **errp)
{
    FslIMX25State *s = FSL_IMX25(dev);
    uint8_t i;
    Error *err = NULL;

    object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    object_property_set_bool(OBJECT(&s->avic), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->avic), 0, FSL_IMX25_AVIC_ADDR);
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 0,
                       qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 1,
                       qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ));

    object_property_set_bool(OBJECT(&s->ccm), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX25_CCM_ADDR);

    /* Initialize all UARTs */
    for (i = 0; i < FSL_IMX25_NUM_UARTS; i++) {
        static const struct {
            hwaddr addr;
            unsigned int irq;
        } serial_table[FSL_IMX25_NUM_UARTS] = {
            { FSL_IMX25_UART1_ADDR, FSL_IMX25_UART1_IRQ },
            { FSL_IMX25_UART2_ADDR, FSL_IMX25_UART2_IRQ },
            { FSL_IMX25_UART3_ADDR, FSL_IMX25_UART3_IRQ },
            { FSL_IMX25_UART4_ADDR, FSL_IMX25_UART4_IRQ },
            { FSL_IMX25_UART5_ADDR, FSL_IMX25_UART5_IRQ }
        };

        if (i < MAX_SERIAL_PORTS) {
            CharDriverState *chr;

            chr = serial_hds[i];

            if (!chr) {
                char label[20];
                snprintf(label, sizeof(label), "imx31.uart%d", i);
                chr = qemu_chr_new(label, "null", NULL);
            }

            qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", chr);
        }

        object_property_set_bool(OBJECT(&s->uart[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }
        sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, serial_table[i].addr);
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->avic),
                                            serial_table[i].irq));
    }

    /* Initialize all GPT timers */
    for (i = 0; i < FSL_IMX25_NUM_GPTS; i++) {
        static const struct {
            hwaddr addr;
            unsigned int irq;
        } gpt_table[FSL_IMX25_NUM_GPTS] = {
            { FSL_IMX25_GPT1_ADDR, FSL_IMX25_GPT1_IRQ },
            { FSL_IMX25_GPT2_ADDR, FSL_IMX25_GPT2_IRQ },
            { FSL_IMX25_GPT3_ADDR, FSL_IMX25_GPT3_IRQ },
            { FSL_IMX25_GPT4_ADDR, FSL_IMX25_GPT4_IRQ }
        };

        s->gpt[i].ccm = DEVICE(&s->ccm);

        object_property_set_bool(OBJECT(&s->gpt[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }
        sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0, gpt_table[i].addr);
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->avic),
                                            gpt_table[i].irq));
    }

    /* Initialize all EPIT timers */
    for (i = 0; i < FSL_IMX25_NUM_EPITS; i++) {
        static const struct {
            hwaddr addr;
            unsigned int irq;
        } epit_table[FSL_IMX25_NUM_EPITS] = {
            { FSL_IMX25_EPIT1_ADDR, FSL_IMX25_EPIT1_IRQ },
            { FSL_IMX25_EPIT2_ADDR, FSL_IMX25_EPIT2_IRQ }
        };

        s->epit[i].ccm = DEVICE(&s->ccm);

        object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }
        sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0, epit_table[i].addr);
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->avic),
                                            epit_table[i].irq));
    }

    qdev_set_nic_properties(DEVICE(&s->fec), &nd_table[0]);
    object_property_set_bool(OBJECT(&s->fec), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->fec), 0, FSL_IMX25_FEC_ADDR);
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->fec), 0,
                       qdev_get_gpio_in(DEVICE(&s->avic), FSL_IMX25_FEC_IRQ));


    /* Initialize all I2C */
    for (i = 0; i < FSL_IMX25_NUM_I2CS; i++) {
        static const struct {
            hwaddr addr;
            unsigned int irq;
        } i2c_table[FSL_IMX25_NUM_I2CS] = {
            { FSL_IMX25_I2C1_ADDR, FSL_IMX25_I2C1_IRQ },
            { FSL_IMX25_I2C2_ADDR, FSL_IMX25_I2C2_IRQ },
            { FSL_IMX25_I2C3_ADDR, FSL_IMX25_I2C3_IRQ }
        };

        object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }
        sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr);
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->avic),
                                            i2c_table[i].irq));
    }

    /* Initialize all GPIOs */
    for (i = 0; i < FSL_IMX25_NUM_GPIOS; i++) {
        static const struct {
            hwaddr addr;
            unsigned int irq;
        } gpio_table[FSL_IMX25_NUM_GPIOS] = {
            { FSL_IMX25_GPIO1_ADDR, FSL_IMX25_GPIO1_IRQ },
            { FSL_IMX25_GPIO2_ADDR, FSL_IMX25_GPIO2_IRQ },
            { FSL_IMX25_GPIO3_ADDR, FSL_IMX25_GPIO3_IRQ },
            { FSL_IMX25_GPIO4_ADDR, FSL_IMX25_GPIO4_IRQ }
        };

        object_property_set_bool(OBJECT(&s->gpio[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }
        sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, gpio_table[i].addr);
        /* Connect GPIO IRQ to PIC */
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->avic),
                                            gpio_table[i].irq));
    }

    /* initialize 2 x 16 KB ROM */
    memory_region_init_rom_device(&s->rom[0], NULL, NULL, NULL,
                                  "imx25.rom0", FSL_IMX25_ROM0_SIZE, &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    memory_region_add_subregion(get_system_memory(), FSL_IMX25_ROM0_ADDR,
                                &s->rom[0]);
    memory_region_init_rom_device(&s->rom[1], NULL, NULL, NULL,
                                  "imx25.rom1", FSL_IMX25_ROM1_SIZE, &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    memory_region_add_subregion(get_system_memory(), FSL_IMX25_ROM1_ADDR,
                                &s->rom[1]);

    /* initialize internal RAM (128 KB) */
    memory_region_init_ram(&s->iram, NULL, "imx25.iram", FSL_IMX25_IRAM_SIZE,
                           &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    memory_region_add_subregion(get_system_memory(), FSL_IMX25_IRAM_ADDR,
                                &s->iram);
    vmstate_register_ram_global(&s->iram);

    /* internal RAM (128 KB) is aliased over 128 MB - 128 KB */
    memory_region_init_alias(&s->iram_alias, NULL, "imx25.iram_alias",
                             &s->iram, 0, FSL_IMX25_IRAM_ALIAS_SIZE);
    memory_region_add_subregion(get_system_memory(), FSL_IMX25_IRAM_ALIAS_ADDR,
                                &s->iram_alias);
}
Exemple #26
0
static void aw_a10_realize(DeviceState *dev, Error **errp)
{
    AwA10State *s = AW_A10(dev);
    SysBusDevice *sysbusdev;
    uint8_t i;
    qemu_irq fiq, irq;
    Error *err = NULL;

    object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
    if (err != NULL) {
        error_propagate(errp, err);
        return;
    }
    irq = qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ);
    fiq = qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ);

    object_property_set_bool(OBJECT(&s->intc), true, "realized", &err);
    if (err != NULL) {
        error_propagate(errp, err);
        return;
    }
    sysbusdev = SYS_BUS_DEVICE(&s->intc);
    sysbus_mmio_map(sysbusdev, 0, AW_A10_PIC_REG_BASE);
    sysbus_connect_irq(sysbusdev, 0, irq);
    sysbus_connect_irq(sysbusdev, 1, fiq);
    for (i = 0; i < AW_A10_PIC_INT_NR; i++) {
        s->irq[i] = qdev_get_gpio_in(DEVICE(&s->intc), i);
    }

    object_property_set_bool(OBJECT(&s->timer), true, "realized", &err);
    if (err != NULL) {
        error_propagate(errp, err);
        return;
    }
    sysbusdev = SYS_BUS_DEVICE(&s->timer);
    sysbus_mmio_map(sysbusdev, 0, AW_A10_PIT_REG_BASE);
    sysbus_connect_irq(sysbusdev, 0, s->irq[22]);
    sysbus_connect_irq(sysbusdev, 1, s->irq[23]);
    sysbus_connect_irq(sysbusdev, 2, s->irq[24]);
    sysbus_connect_irq(sysbusdev, 3, s->irq[25]);
    sysbus_connect_irq(sysbusdev, 4, s->irq[67]);
    sysbus_connect_irq(sysbusdev, 5, s->irq[68]);

    memory_region_init_ram(&s->sram_a, OBJECT(dev), "sram A", 48 * KiB,
                           &error_fatal);
    memory_region_add_subregion(get_system_memory(), 0x00000000, &s->sram_a);
    create_unimplemented_device("a10-sram-ctrl", 0x01c00000, 4 * KiB);

    /* FIXME use qdev NIC properties instead of nd_table[] */
    if (nd_table[0].used) {
        qemu_check_nic_model(&nd_table[0], TYPE_AW_EMAC);
        qdev_set_nic_properties(DEVICE(&s->emac), &nd_table[0]);
    }
    object_property_set_bool(OBJECT(&s->emac), true, "realized", &err);
    if (err != NULL) {
        error_propagate(errp, err);
        return;
    }
    sysbusdev = SYS_BUS_DEVICE(&s->emac);
    sysbus_mmio_map(sysbusdev, 0, AW_A10_EMAC_BASE);
    sysbus_connect_irq(sysbusdev, 0, s->irq[55]);

    object_property_set_bool(OBJECT(&s->sata), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->sata), 0, AW_A10_SATA_BASE);
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->sata), 0, s->irq[56]);

    /* FIXME use a qdev chardev prop instead of serial_hd() */
    serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2, s->irq[1],
                   115200, serial_hd(0), DEVICE_NATIVE_ENDIAN);
}
Exemple #27
0
static int fdt_init_qdev(char *node_path, FDTMachineInfo *fdti, char *compat)
{
    int err;
    qemu_irq irq;
    hwaddr base;
    int offset;
    DeviceState *dev;
    char *dev_type = NULL;
    int is_intc;
    int i;

    dev = fdt_create_qdev_from_compat(compat, &dev_type);
    if (!dev) {
        DB_PRINT("no match found for %s\n", compat);
        return 1;
    }
    /* FIXME: attach to the sysbus instead */
    object_property_add_child(container_get(qdev_get_machine(), "/unattached"),
                              qemu_fdt_get_node_name(fdti->fdt, node_path),
                              OBJECT(dev), NULL);

    fdt_init_set_opaque(fdti, node_path, dev);

    /* connect nic if appropriate */
    static int nics;
    if (object_property_find(OBJECT(dev), "mac", NULL)) {
        qdev_set_nic_properties(dev, &nd_table[nics]);
        if (nd_table[nics].instantiated) {
            DB_PRINT("NIC instantiated: %s\n", dev_type);
            nics++;
        }
    }

    offset = fdt_path_offset(fdti->fdt, node_path);
    for (offset = fdt_first_property_offset(fdti->fdt, offset);
            offset != -FDT_ERR_NOTFOUND;
            offset = fdt_next_property_offset(fdti->fdt, offset)) {
        const char *propname;
        int len;
        const void *val = fdt_getprop_by_offset(fdti->fdt, offset,
                                                    &propname, &len);

        propname = trim_vendor(propname);
        ObjectProperty *p = object_property_find(OBJECT(dev), propname, NULL);
        if (p) {
            DB_PRINT("matched property: %s of type %s, len %d\n",
                                            propname, p->type, len);
        }
        if (!p) {
            continue;
        }

        /* FIXME: handle generically using accessors and stuff */
        if (!strcmp(p->type, "uint8") || !strcmp(p->type, "uint16") ||
                !strcmp(p->type, "uint32") || !strcmp(p->type, "uint64")) {
            uint64_t offset = (!strcmp(propname, "reg")) ?
                              fdt_get_parent_base(node_path, fdti) : 0;
            object_property_set_int(OBJECT(dev), get_int_be(val, len) + offset,
                                    propname, &error_abort);
            DB_PRINT("set property %s to %#llx\n", propname,
                                            (long long unsigned int)get_int_be(val, len));
        } else if (!strcmp(p->type, "bool")) {
            object_property_set_bool(OBJECT(dev), !!get_int_be(val, len),
                        propname, &error_abort);
            DB_PRINT("set property %s to %#llx\n", propname,
                                            (long long unsigned int)get_int_be(val, len));
        } else if (!strncmp(p->type, "link", 4)) {
            char target_node_path[DT_PATH_LENGTH];
            DeviceState *linked_dev;

            if (qemu_fdt_get_node_by_phandle(fdti->fdt, target_node_path,
                                                get_int_be(val, len))) {
                abort();
            }
            while (!fdt_init_has_opaque(fdti, target_node_path)) {
                fdt_init_yield(fdti);
            }
            linked_dev = fdt_init_get_opaque(fdti, target_node_path);
            object_property_set_link(OBJECT(dev), OBJECT(linked_dev), propname,
                                        &error_abort);
        } else if (!strcmp(p->type, "string")) {
            object_property_set_str(OBJECT(dev), strndup(val, len), propname, &error_abort);
	}
    }

    qdev_init_nofail(dev);
    /* map slave attachment */
    base = qemu_fdt_getprop_cell(fdti->fdt, node_path, "reg", 0, false, &error_abort);

    base += fdt_get_parent_base(node_path, fdti);
    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);

    {
        int len;
        fdt_get_property(fdti->fdt, fdt_path_offset(fdti->fdt, node_path),
                                "interrupt-controller", &len);
        is_intc = len >= 0;
        DB_PRINT("is interrupt controller: %c\n", is_intc ? 'y' : 'n');
    }
    /* connect irq */
    for (i = 0; ; ++i) {
        char irq_info[1024];
        irq = fdt_get_irq_info(fdti, node_path, i, &err, irq_info);
        /* INTCs inferr their top level, if no IRQ connection specified */
        if (err && is_intc) {
            irq = fdti->irq_base;
            sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq);
            fprintf(stderr, "FDT: (%s) connected top level irq %s\n", dev_type,
                        irq_info);
            break;
        }
        if (!err) {
            sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, irq);
            fprintf(stderr, "FDT: (%s) connected irq %s\n", dev_type, irq_info);
        } else {
            break;
        }
    }

    if (dev_type) {
        g_free(dev_type);
    }

    return 0;
}
/* PC hardware initialisation */
static void s390_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)
{
    CPUState *env = NULL;
    ram_addr_t ram_addr;
    ram_addr_t kernel_size = 0;
    ram_addr_t initrd_offset;
    ram_addr_t initrd_size = 0;
    int i;

    /* XXX we only work on KVM for now */

    if (!kvm_enabled()) {
        fprintf(stderr, "The S390 target only works with KVM enabled\n");
        exit(1);
    }

    /* get a BUS */
    s390_bus = s390_virtio_bus_init(&ram_size);

    /* allocate RAM */
    ram_addr = qemu_ram_alloc(NULL, "s390.ram", ram_size);
    cpu_register_physical_memory(0, ram_size, ram_addr);

    /* init CPUs */
    if (cpu_model == NULL) {
        cpu_model = "host";
    }

    ipi_states = qemu_malloc(sizeof(CPUState *) * smp_cpus);

    for (i = 0; i < smp_cpus; i++) {
        CPUState *tmp_env;

        tmp_env = cpu_init(cpu_model);
        if (!env) {
            env = tmp_env;
        }
        ipi_states[i] = tmp_env;
        tmp_env->halted = 1;
        tmp_env->exception_index = EXCP_HLT;
    }

    env->halted = 0;
    env->exception_index = 0;

    if (kernel_filename) {
        kernel_size = load_image(kernel_filename, qemu_get_ram_ptr(0));

        if (lduw_phys(KERN_IMAGE_START) != 0x0dd0) {
            fprintf(stderr, "Specified image is not an s390 boot image\n");
            exit(1);
        }

        env->psw.addr = KERN_IMAGE_START;
        env->psw.mask = 0x0000000180000000ULL;
    } else {
        ram_addr_t bios_size = 0;
        char *bios_filename;

        /* Load zipl bootloader */
        if (bios_name == NULL) {
            bios_name = ZIPL_FILENAME;
        }

        bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
        bios_size = load_image(bios_filename, qemu_get_ram_ptr(ZIPL_LOAD_ADDR));
        qemu_free(bios_filename);

        if ((long)bios_size < 0) {
            hw_error("could not load bootloader '%s'\n", bios_name);
        }

        if (bios_size > 4096) {
            hw_error("stage1 bootloader is > 4k\n");
        }

        env->psw.addr = ZIPL_START;
        env->psw.mask = 0x0000000180000000ULL;
    }

    if (initrd_filename) {
        initrd_offset = INITRD_START;
        while (kernel_size + 0x100000 > initrd_offset) {
            initrd_offset += 0x100000;
        }
        initrd_size = load_image(initrd_filename, qemu_get_ram_ptr(initrd_offset));

        stq_phys(INITRD_PARM_START, initrd_offset);
        stq_phys(INITRD_PARM_SIZE, initrd_size);
    }

    if (kernel_cmdline) {
        cpu_physical_memory_rw(KERN_PARM_AREA, (uint8_t *)kernel_cmdline,
                               strlen(kernel_cmdline), 1);
    }

    /* Create VirtIO network adapters */
    for(i = 0; i < nb_nics; i++) {
        NICInfo *nd = &nd_table[i];
        DeviceState *dev;

        if (!nd->model) {
            nd->model = qemu_strdup("virtio");
        }

        if (strcmp(nd->model, "virtio")) {
            fprintf(stderr, "S390 only supports VirtIO nics\n");
            exit(1);
        }

        dev = qdev_create((BusState *)s390_bus, "virtio-net-s390");
        qdev_set_nic_properties(dev, nd);
        qdev_init_nofail(dev);
    }

    /* Create VirtIO disk drives */
    for(i = 0; i < MAX_BLK_DEVS; i++) {
        DriveInfo *dinfo;
        DeviceState *dev;

        dinfo = drive_get(IF_IDE, 0, i);
        if (!dinfo) {
            continue;
        }

        dev = qdev_create((BusState *)s390_bus, "virtio-blk-s390");
        qdev_prop_set_drive_nofail(dev, "drive", dinfo->bdrv);
        qdev_init_nofail(dev);
    }
}
Exemple #29
0
/* PC hardware initialisation */
static void s390_init(ram_addr_t my_ram_size,
                      const char *boot_device,
                      const char *kernel_filename,
                      const char *kernel_cmdline,
                      const char *initrd_filename,
                      const char *cpu_model)
{
    CPUState *env = NULL;
    MemoryRegion *sysmem = get_system_memory();
    MemoryRegion *ram = g_new(MemoryRegion, 1);
    ram_addr_t kernel_size = 0;
    ram_addr_t initrd_offset;
    ram_addr_t initrd_size = 0;
    int shift = 0;
    uint8_t *storage_keys;
    void *virtio_region;
    target_phys_addr_t virtio_region_len;
    target_phys_addr_t virtio_region_start;
    int i;

    /* s390x ram size detection needs a 16bit multiplier + an increment. So
       guests > 64GB can be specified in 2MB steps etc. */
    while ((my_ram_size >> (20 + shift)) > 65535) {
        shift++;
    }
    my_ram_size = my_ram_size >> (20 + shift) << (20 + shift);

    /* lets propagate the changed ram size into the global variable. */
    ram_size = my_ram_size;

    /* get a BUS */
    s390_bus = s390_virtio_bus_init(&my_ram_size);

    /* allocate RAM */
    memory_region_init_ram(ram, "s390.ram", my_ram_size);
    vmstate_register_ram_global(ram);
    memory_region_add_subregion(sysmem, 0, ram);

    /* clear virtio region */
    virtio_region_len = my_ram_size - ram_size;
    virtio_region_start = ram_size;
    virtio_region = cpu_physical_memory_map(virtio_region_start,
                                            &virtio_region_len, true);
    memset(virtio_region, 0, virtio_region_len);
    cpu_physical_memory_unmap(virtio_region, virtio_region_len, 1,
                              virtio_region_len);

    /* allocate storage keys */
    storage_keys = g_malloc0(my_ram_size / TARGET_PAGE_SIZE);

    /* init CPUs */
    if (cpu_model == NULL) {
        cpu_model = "host";
    }

    ipi_states = g_malloc(sizeof(CPUState *) * smp_cpus);

    for (i = 0; i < smp_cpus; i++) {
        CPUState *tmp_env;

        tmp_env = cpu_init(cpu_model);
        if (!env) {
            env = tmp_env;
        }
        ipi_states[i] = tmp_env;
        tmp_env->halted = 1;
        tmp_env->exception_index = EXCP_HLT;
        tmp_env->storage_keys = storage_keys;
    }

    /* One CPU has to run */
    s390_add_running_cpu(env);

    if (kernel_filename) {

        kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, NULL,
                               NULL, 1, ELF_MACHINE, 0);
        if (kernel_size == -1UL) {
            kernel_size = load_image_targphys(kernel_filename, 0, ram_size);
        }
        /*
         * we can not rely on the ELF entry point, since up to 3.2 this
         * value was 0x800 (the SALIPL loader) and it wont work. For
         * all (Linux) cases 0x10000 (KERN_IMAGE_START) should be fine.
         */
        env->psw.addr = KERN_IMAGE_START;
        env->psw.mask = 0x0000000180000000ULL;
    } else {
        ram_addr_t bios_size = 0;
        char *bios_filename;

        /* Load zipl bootloader */
        if (bios_name == NULL) {
            bios_name = ZIPL_FILENAME;
        }

        bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
        bios_size = load_image_targphys(bios_filename, ZIPL_LOAD_ADDR, 4096);
        g_free(bios_filename);

        if ((long)bios_size < 0) {
            hw_error("could not load bootloader '%s'\n", bios_name);
        }

        if (bios_size > 4096) {
            hw_error("stage1 bootloader is > 4k\n");
        }

        env->psw.addr = ZIPL_START;
        env->psw.mask = 0x0000000180000000ULL;
    }

    if (initrd_filename) {
        initrd_offset = INITRD_START;
        while (kernel_size + 0x100000 > initrd_offset) {
            initrd_offset += 0x100000;
        }
        initrd_size = load_image_targphys(initrd_filename, initrd_offset,
                                          ram_size - initrd_offset);
        /* we have to overwrite values in the kernel image, which are "rom" */
        memcpy(rom_ptr(INITRD_PARM_START), &initrd_offset, 8);
        memcpy(rom_ptr(INITRD_PARM_SIZE), &initrd_size, 8);
    }

    if (kernel_cmdline) {
        /* we have to overwrite values in the kernel image, which are "rom" */
        memcpy(rom_ptr(KERN_PARM_AREA), kernel_cmdline,
               strlen(kernel_cmdline) + 1);
    }

    /* Create VirtIO network adapters */
    for(i = 0; i < nb_nics; i++) {
        NICInfo *nd = &nd_table[i];
        DeviceState *dev;

        if (!nd->model) {
            nd->model = g_strdup("virtio");
        }

        if (strcmp(nd->model, "virtio")) {
            fprintf(stderr, "S390 only supports VirtIO nics\n");
            exit(1);
        }

        dev = qdev_create((BusState *)s390_bus, "virtio-net-s390");
        qdev_set_nic_properties(dev, nd);
        qdev_init_nofail(dev);
    }

    /* Create VirtIO disk drives */
    for(i = 0; i < MAX_BLK_DEVS; i++) {
        DriveInfo *dinfo;
        DeviceState *dev;

        dinfo = drive_get(IF_IDE, 0, i);
        if (!dinfo) {
            continue;
        }

        dev = qdev_create((BusState *)s390_bus, "virtio-blk-s390");
        qdev_prop_set_drive_nofail(dev, "drive", dinfo->bdrv);
        qdev_init_nofail(dev);
    }
}
Exemple #30
0
static void sun4uv_init(MemoryRegion *address_space_mem,
                        MachineState *machine,
                        const struct hwdef *hwdef)
{
    SPARCCPU *cpu;
    Nvram *nvram;
    unsigned int i;
    uint64_t initrd_addr, initrd_size, kernel_addr, kernel_size, kernel_entry;
    SabreState *sabre;
    PCIBus *pci_bus, *pci_busA, *pci_busB;
    PCIDevice *ebus, *pci_dev;
    SysBusDevice *s;
    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
    DeviceState *iommu, *dev;
    FWCfgState *fw_cfg;
    NICInfo *nd;
    MACAddr macaddr;
    bool onboard_nic;

    /* init CPUs */
    cpu = sparc64_cpu_devinit(machine->cpu_type, hwdef->prom_addr);

    /* IOMMU */
    iommu = qdev_create(NULL, TYPE_SUN4U_IOMMU);
    qdev_init_nofail(iommu);

    /* set up devices */
    ram_init(0, machine->ram_size);

    prom_init(hwdef->prom_addr, bios_name);

    /* Init sabre (PCI host bridge) */
    sabre = SABRE_DEVICE(qdev_create(NULL, TYPE_SABRE));
    qdev_prop_set_uint64(DEVICE(sabre), "special-base", PBM_SPECIAL_BASE);
    qdev_prop_set_uint64(DEVICE(sabre), "mem-base", PBM_MEM_BASE);
    object_property_set_link(OBJECT(sabre), OBJECT(iommu), "iommu",
                             &error_abort);
    qdev_init_nofail(DEVICE(sabre));

    /* Wire up PCI interrupts to CPU */
    for (i = 0; i < IVEC_MAX; i++) {
        qdev_connect_gpio_out_named(DEVICE(sabre), "ivec-irq", i,
            qdev_get_gpio_in_named(DEVICE(cpu), "ivec-irq", i));
    }

    pci_bus = PCI_HOST_BRIDGE(sabre)->bus;
    pci_busA = pci_bridge_get_sec_bus(sabre->bridgeA);
    pci_busB = pci_bridge_get_sec_bus(sabre->bridgeB);

    /* Only in-built Simba APBs can exist on the root bus, slot 0 on busA is
       reserved (leaving no slots free after on-board devices) however slots
       0-3 are free on busB */
    pci_bus->slot_reserved_mask = 0xfffffffc;
    pci_busA->slot_reserved_mask = 0xfffffff1;
    pci_busB->slot_reserved_mask = 0xfffffff0;

    ebus = pci_create_multifunction(pci_busA, PCI_DEVFN(1, 0), true, TYPE_EBUS);
    qdev_prop_set_uint64(DEVICE(ebus), "console-serial-base",
                         hwdef->console_serial_base);
    qdev_init_nofail(DEVICE(ebus));

    /* Wire up "well-known" ISA IRQs to PBM legacy obio IRQs */
    qdev_connect_gpio_out_named(DEVICE(ebus), "isa-irq", 7,
        qdev_get_gpio_in_named(DEVICE(sabre), "pbm-irq", OBIO_LPT_IRQ));
    qdev_connect_gpio_out_named(DEVICE(ebus), "isa-irq", 6,
        qdev_get_gpio_in_named(DEVICE(sabre), "pbm-irq", OBIO_FDD_IRQ));
    qdev_connect_gpio_out_named(DEVICE(ebus), "isa-irq", 1,
        qdev_get_gpio_in_named(DEVICE(sabre), "pbm-irq", OBIO_KBD_IRQ));
    qdev_connect_gpio_out_named(DEVICE(ebus), "isa-irq", 12,
        qdev_get_gpio_in_named(DEVICE(sabre), "pbm-irq", OBIO_MSE_IRQ));
    qdev_connect_gpio_out_named(DEVICE(ebus), "isa-irq", 4,
        qdev_get_gpio_in_named(DEVICE(sabre), "pbm-irq", OBIO_SER_IRQ));

    pci_dev = pci_create_simple(pci_busA, PCI_DEVFN(2, 0), "VGA");

    memset(&macaddr, 0, sizeof(MACAddr));
    onboard_nic = false;
    for (i = 0; i < nb_nics; i++) {
        nd = &nd_table[i];

        if (!nd->model || strcmp(nd->model, "sunhme") == 0) {
            if (!onboard_nic) {
                pci_dev = pci_create_multifunction(pci_busA, PCI_DEVFN(1, 1),
                                                   true, "sunhme");
                memcpy(&macaddr, &nd->macaddr.a, sizeof(MACAddr));
                onboard_nic = true;
            } else {
                pci_dev = pci_create(pci_busB, -1, "sunhme");
            }
        } else {
            pci_dev = pci_create(pci_busB, -1, nd->model);
        }

        dev = &pci_dev->qdev;
        qdev_set_nic_properties(dev, nd);
        qdev_init_nofail(dev);
    }

    /* If we don't have an onboard NIC, grab a default MAC address so that
     * we have a valid machine id */
    if (!onboard_nic) {
        qemu_macaddr_default_if_unset(&macaddr);
    }

    ide_drive_get(hd, ARRAY_SIZE(hd));

    pci_dev = pci_create(pci_busA, PCI_DEVFN(3, 0), "cmd646-ide");
    qdev_prop_set_uint32(&pci_dev->qdev, "secondary", 1);
    qdev_init_nofail(&pci_dev->qdev);
    pci_ide_create_devs(pci_dev, hd);

    /* Map NVRAM into I/O (ebus) space */
    nvram = m48t59_init(NULL, 0, 0, NVRAM_SIZE, 1968, 59);
    s = SYS_BUS_DEVICE(nvram);
    memory_region_add_subregion(pci_address_space_io(ebus), 0x2000,
                                sysbus_mmio_get_region(s, 0));
 
    initrd_size = 0;
    initrd_addr = 0;
    kernel_size = sun4u_load_kernel(machine->kernel_filename,
                                    machine->initrd_filename,
                                    ram_size, &initrd_size, &initrd_addr,
                                    &kernel_addr, &kernel_entry);

    sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", machine->ram_size,
                           machine->boot_order,
                           kernel_addr, kernel_size,
                           machine->kernel_cmdline,
                           initrd_addr, initrd_size,
                           /* XXX: need an option to load a NVRAM image */
                           0,
                           graphic_width, graphic_height, graphic_depth,
                           (uint8_t *)&macaddr);

    dev = qdev_create(NULL, TYPE_FW_CFG_IO);
    qdev_prop_set_bit(dev, "dma_enabled", false);
    object_property_add_child(OBJECT(ebus), TYPE_FW_CFG, OBJECT(dev), NULL);
    qdev_init_nofail(dev);
    memory_region_add_subregion(pci_address_space_io(ebus), BIOS_CFG_IOPORT,
                                &FW_CFG_IO(dev)->comb_iomem);

    fw_cfg = FW_CFG(dev);
    fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
    fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
    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_i64(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_entry);
    fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
    if (machine->kernel_cmdline) {
        fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
                       strlen(machine->kernel_cmdline) + 1);
        fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, machine->kernel_cmdline);
    } else {
        fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, 0);
    }
    fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr);
    fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, machine->boot_order[0]);

    fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_WIDTH, graphic_width);
    fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_HEIGHT, graphic_height);
    fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_DEPTH, graphic_depth);

    qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
}