示例#1
0
文件: etraxfs_eth.c 项目: 8tab/qemu
static int fs_eth_init(SysBusDevice *sbd)
{
    DeviceState *dev = DEVICE(sbd);
    ETRAXFSEthState *s = ETRAX_FS_ETH(dev);

    if (!s->dma_out || !s->dma_in) {
        error_report("Unconnected ETRAX-FS Ethernet MAC");
        return -1;
    }

    s->dma_out->client.push = eth_tx_push;
    s->dma_out->client.opaque = s;
    s->dma_in->client.opaque = s;
    s->dma_in->client.pull = NULL;

    memory_region_init_io(&s->mmio, OBJECT(dev), &eth_ops, s,
                          "etraxfs-eth", 0x5c);
    sysbus_init_mmio(sbd, &s->mmio);

    qemu_macaddr_default_if_unset(&s->conf.macaddr);
    s->nic = qemu_new_nic(&net_etraxfs_info, &s->conf,
                          object_get_typename(OBJECT(s)), dev->id, s);
    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);


    tdk_init(&s->phy);
    mdio_attach(&s->mdio_bus, &s->phy, s->phyaddr);
    return 0;
}
示例#2
0
static int fs_eth_init(SysBusDevice *dev)
{
	struct fs_eth *s = FROM_SYSBUS(typeof(*s), dev);

	if (!s->dma_out || !s->dma_in) {
		hw_error("Unconnected ETRAX-FS Ethernet MAC.\n");
	}

	s->dma_out->client.push = eth_tx_push;
	s->dma_out->client.opaque = s;
	s->dma_in->client.opaque = s;
	s->dma_in->client.pull = NULL;

	memory_region_init_io(&s->mmio, &eth_ops, s, "etraxfs-eth", 0x5c);
	sysbus_init_mmio(dev, &s->mmio);

	qemu_macaddr_default_if_unset(&s->conf.macaddr);
	s->nic = qemu_new_nic(&net_etraxfs_info, &s->conf,
			      object_get_typename(OBJECT(s)), dev->qdev.id, s);
	qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);

	tdk_init(&s->phy);
	mdio_attach(&s->mdio_bus, &s->phy, s->phyaddr);
	return 0;
}
示例#3
0
static void bcm2835_property_realize(DeviceState *dev, Error **errp)
{
    BCM2835PropertyState *s = BCM2835_PROPERTY(dev);
    Object *obj;
    Error *err = NULL;

    obj = object_property_get_link(OBJECT(dev), "fb", &err);
    if (obj == NULL) {
        error_setg(errp, "%s: required fb link not found: %s",
                   __func__, error_get_pretty(err));
        return;
    }

    s->fbdev = BCM2835_FB(obj);

    obj = object_property_get_link(OBJECT(dev), "dma-mr", &err);
    if (obj == NULL) {
        error_setg(errp, "%s: required dma-mr link not found: %s",
                   __func__, error_get_pretty(err));
        return;
    }

    s->dma_mr = MEMORY_REGION(obj);
    address_space_init(&s->dma_as, s->dma_mr, NULL);

    /* TODO: connect to MAC address of USB NIC device, once we emulate it */
    qemu_macaddr_default_if_unset(&s->macaddr);

    bcm2835_property_reset(dev);
}
示例#4
0
static int fs_eth_init(SysBusDevice *dev)
{
	struct fs_eth *s = FROM_SYSBUS(typeof(*s), dev);
	int eth_regs;

	if (!s->dma_out || !s->dma_in) {
		hw_error("Unconnected ETRAX-FS Ethernet MAC.\n");
	}

	s->dma_out->client.push = eth_tx_push;
	s->dma_out->client.opaque = s;
	s->dma_in->client.opaque = s;
	s->dma_in->client.pull = NULL;

	eth_regs = cpu_register_io_memory(eth_read, eth_write, s,
					  DEVICE_LITTLE_ENDIAN);
	sysbus_init_mmio(dev, 0x5c, eth_regs);

	qemu_macaddr_default_if_unset(&s->conf.macaddr);
	s->nic = qemu_new_nic(&net_etraxfs_info, &s->conf,
			      dev->qdev.info->name, dev->qdev.id, s);
	qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);

	tdk_init(&s->phy);
	mdio_attach(&s->mdio_bus, &s->phy, s->phyaddr);
	return 0;
}
示例#5
0
static void xilinx_ethlite_realize(DeviceState *dev, Error **errp)
{
    struct xlx_ethlite *s = XILINX_ETHLITE(dev);

    qemu_macaddr_default_if_unset(&s->conf.macaddr);
    s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf,
                          object_get_typename(OBJECT(dev)), dev->id, s);
    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
}
示例#6
0
static int spapr_vlan_init(VIOsPAPRDevice *sdev)
{
    VIOsPAPRVLANDevice *dev = (VIOsPAPRVLANDevice *)sdev;

    qemu_macaddr_default_if_unset(&dev->nicconf.macaddr);

    dev->nic = qemu_new_nic(&net_spapr_vlan_info, &dev->nicconf,
                            object_get_typename(OBJECT(sdev)), sdev->qdev.id, dev);
    qemu_format_nic_info_str(&dev->nic->nc, dev->nicconf.macaddr.a);

    return 0;
}
示例#7
0
文件: spapr_llan.c 项目: AlexHai/qemu
static int spapr_vlan_init(VIOsPAPRDevice *sdev)
{
    VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);

    qemu_macaddr_default_if_unset(&dev->nicconf.macaddr);

    dev->nic = qemu_new_nic(&net_spapr_vlan_info, &dev->nicconf,
                            object_get_typename(OBJECT(sdev)), sdev->qdev.id, dev);
    qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);

    add_boot_device_path(dev->nicconf.bootindex, DEVICE(dev), "");

    return 0;
}
示例#8
0
static int smc91c111_init1(SysBusDevice *dev)
{
    smc91c111_state *s = FROM_SYSBUS(smc91c111_state, dev);
    memory_region_init_io(&s->mmio, &smc91c111_mem_ops, s,
                          "smc91c111-mmio", 16);
    sysbus_init_mmio(dev, &s->mmio);
    sysbus_init_irq(dev, &s->irq);
    qemu_macaddr_default_if_unset(&s->conf.macaddr);
    s->nic = qemu_new_nic(&net_smc91c111_info, &s->conf,
                          object_get_typename(OBJECT(dev)), dev->qdev.id, s);
    qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
    /* ??? Save/restore.  */
    return 0;
}
示例#9
0
static void spapr_vlan_realize(VIOsPAPRDevice *sdev, Error **errp)
{
    VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);

    qemu_macaddr_default_if_unset(&dev->nicconf.macaddr);

    memcpy(&dev->perm_mac.a, &dev->nicconf.macaddr.a, sizeof(dev->perm_mac.a));

    dev->nic = qemu_new_nic(&net_spapr_vlan_info, &dev->nicconf,
                            object_get_typename(OBJECT(sdev)), sdev->qdev.id, dev);
    qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);

    dev->rxp_timer = timer_new_us(QEMU_CLOCK_VIRTUAL, spapr_vlan_flush_rx_queue,
                                  dev);
}
示例#10
0
static int xilinx_ethlite_init(SysBusDevice *dev)
{
    struct xlx_ethlite *s = FROM_SYSBUS(typeof (*s), dev);

    sysbus_init_irq(dev, &s->irq);
    s->rxbuf = 0;

    memory_region_init_io(&s->mmio, &eth_ops, s, "xilinx-ethlite", R_MAX * 4);
    sysbus_init_mmio(dev, &s->mmio);

    qemu_macaddr_default_if_unset(&s->conf.macaddr);
    s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf,
                          dev->qdev.info->name, dev->qdev.id, s);
    qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
    return 0;
}
示例#11
0
static int smc91c111_init1(SysBusDevice *sbd)
{
    DeviceState *dev = DEVICE(sbd);
    smc91c111_state *s = SMC91C111(dev);

    memory_region_init_io(&s->mmio, OBJECT(s), &smc91c111_mem_ops, s,
                          "smc91c111-mmio", 16);
    sysbus_init_mmio(sbd, &s->mmio);
    sysbus_init_irq(sbd, &s->irq);
    qemu_macaddr_default_if_unset(&s->conf.macaddr);
    s->nic = qemu_new_nic(&net_smc91c111_info, &s->conf,
                          object_get_typename(OBJECT(dev)), dev->id, s);
    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
    /* ??? Save/restore.  */
    return 0;
}
示例#12
0
static int xilinx_ethlite_init(SysBusDevice *dev)
{
    struct xlx_ethlite *s = FROM_SYSBUS(typeof (*s), dev);

    sysbus_init_irq(dev, &s->irq);
    s->rxbuf = 0;

    memory_region_init_io(&s->mmio, &eth_ops, s, "xlnx.xps-ethernetlite",
                                                                    R_MAX * 4);
    sysbus_init_mmio(dev, &s->mmio);

    qemu_macaddr_default_if_unset(&s->conf.macaddr);
    s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf,
                          object_get_typename(OBJECT(dev)), dev->qdev.id, s);
    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
    return 0;
}
示例#13
0
static int xilinx_ethlite_init(SysBusDevice *dev)
{
    struct xlx_ethlite *s = FROM_SYSBUS(typeof (*s), dev);
    int regs;

    sysbus_init_irq(dev, &s->irq);
    s->rxbuf = 0;

    regs = cpu_register_io_memory(eth_read, eth_write, s, DEVICE_NATIVE_ENDIAN);
    sysbus_init_mmio(dev, R_MAX * 4, regs);

    qemu_macaddr_default_if_unset(&s->conf.macaddr);
    s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf,
                          dev->qdev.info->name, dev->qdev.id, s);
    qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
    return 0;
}
示例#14
0
static int smc91c111_init1(SysBusDevice *dev)
{
    smc91c111_state *s = FROM_SYSBUS(smc91c111_state, dev);

    s->mmio_index = cpu_register_io_memory(smc91c111_readfn,
                                           smc91c111_writefn, s);
    sysbus_init_mmio(dev, 16, s->mmio_index);
    sysbus_init_irq(dev, &s->irq);
    qemu_macaddr_default_if_unset(&s->conf.macaddr);

    smc91c111_reset(s);

    s->nic = qemu_new_nic(&net_smc91c111_info, &s->conf,
                          dev->qdev.info->name, dev->qdev.id, s);
    qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
    /* ??? Save/restore.  */
    return 0;
}
示例#15
0
文件: ftgmac100.c 项目: openbmc/qemu
static void ftgmac100_realize(DeviceState *dev, Error **errp)
{
    Ftgmac100State *s = FTGMAC100(dev);
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);

    memory_region_init_io(&s->iomem, OBJECT(dev), &ftgmac100_ops, s,
                          TYPE_FTGMAC100, 0x2000);
    sysbus_init_mmio(sbd, &s->iomem);
    sysbus_init_irq(sbd, &s->irq);
    qemu_macaddr_default_if_unset(&s->conf.macaddr);

    s->conf.peers.ncs[0] = nd_table[0].netdev;

    s->nic = qemu_new_nic(&net_ftgmac100_info, &s->conf,
                          object_get_typename(OBJECT(dev)), DEVICE(dev)->id,
                          s);
    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
}
示例#16
0
static int isa_ne2000_initfn(ISADevice *dev)
{
    ISANE2000State *isa = DO_UPCAST(ISANE2000State, dev, dev);
    NE2000State *s = &isa->ne2000;

    ne2000_setup_io(s, 0x20);
    isa_register_ioport(dev, &s->io, isa->iobase);

    isa_init_irq(dev, &s->irq, isa->isairq);

    qemu_macaddr_default_if_unset(&s->c.macaddr);
    ne2000_reset(s);

    s->nic = qemu_new_nic(&net_ne2000_isa_info, &s->c,
                          object_get_typename(OBJECT(dev)), dev->qdev.id, s);
    qemu_format_nic_info_str(&s->nic->nc, s->c.macaddr.a);

    return 0;
}
示例#17
0
文件: tnetw1130.c 项目: stweil/qemu
static int tnetw1130_init(PCIDevice *pci_dev)
{
    TNETW1130State *d = DO_UPCAST(TNETW1130State, dev, pci_dev);
    tnetw1130_t *s = &d->tnetw1130;

    /* TI TNETW1130 */
    tnetw1130_pci_config(d->dev.config);

    /* Handler for memory-mapped I/O */
    memory_region_init_io(&d->mmio_bar0, &tnetw1130_ops0, s, "tnetw1130_mmio0",
                          TNETW1130_MEM0_SIZE);
    memory_region_init_io(&d->mmio_bar1, &tnetw1130_ops1, s, "tnetw1130_mmio1",
                          TNETW1130_MEM1_SIZE);

    pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio_bar0);
    pci_register_bar(&d->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio_bar1);

#if 0
    static const char macaddr[6] = {
        0x00, 0x60, 0x65, 0x02, 0x4a, 0x8e
    };
    memcpy(s->conf.macaddr.a, macaddr, 6);
#endif
    qemu_macaddr_default_if_unset(&s->conf.macaddr);
    tnetw1130_reset(s);

    s->nic = qemu_new_nic(&net_info, &s->conf,
                          object_get_typename(OBJECT(pci_dev)),
                          pci_dev->qdev.id, s);

    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);

    qemu_register_reset(nic_reset, d);

    return 0;
}
示例#18
0
static void e1000e_pci_realize(PCIDevice *pci_dev, Error **errp)
{
    static const uint16_t e1000e_pmrb_offset = 0x0C8;
    static const uint16_t e1000e_pcie_offset = 0x0E0;
    static const uint16_t e1000e_aer_offset =  0x100;
    static const uint16_t e1000e_dsn_offset =  0x140;
    E1000EState *s = E1000E(pci_dev);
    uint8_t *macaddr;
    int ret;

    trace_e1000e_cb_pci_realize();

    pci_dev->config_write = e1000e_write_config;

    pci_dev->config[PCI_CACHE_LINE_SIZE] = 0x10;
    pci_dev->config[PCI_INTERRUPT_PIN] = 1;

    pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID, s->subsys_ven);
    pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID, s->subsys);

    s->subsys_ven_used = s->subsys_ven;
    s->subsys_used = s->subsys;

    /* Define IO/MMIO regions */
    memory_region_init_io(&s->mmio, OBJECT(s), &mmio_ops, s,
                          "e1000e-mmio", E1000E_MMIO_SIZE);
    pci_register_bar(pci_dev, E1000E_MMIO_IDX,
                     PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);

    /*
     * We provide a dummy implementation for the flash BAR
     * for drivers that may theoretically probe for its presence.
     */
    memory_region_init(&s->flash, OBJECT(s),
                       "e1000e-flash", E1000E_FLASH_SIZE);
    pci_register_bar(pci_dev, E1000E_FLASH_IDX,
                     PCI_BASE_ADDRESS_SPACE_MEMORY, &s->flash);

    memory_region_init_io(&s->io, OBJECT(s), &io_ops, s,
                          "e1000e-io", E1000E_IO_SIZE);
    pci_register_bar(pci_dev, E1000E_IO_IDX,
                     PCI_BASE_ADDRESS_SPACE_IO, &s->io);

    memory_region_init(&s->msix, OBJECT(s), "e1000e-msix",
                       E1000E_MSIX_SIZE);
    pci_register_bar(pci_dev, E1000E_MSIX_IDX,
                     PCI_BASE_ADDRESS_SPACE_MEMORY, &s->msix);

    /* Create networking backend */
    qemu_macaddr_default_if_unset(&s->conf.macaddr);
    macaddr = s->conf.macaddr.a;

    e1000e_init_msix(s);

    if (pcie_endpoint_cap_v1_init(pci_dev, e1000e_pcie_offset) < 0) {
        hw_error("Failed to initialize PCIe capability");
    }

    ret = msi_init(PCI_DEVICE(s), 0xD0, 1, true, false, NULL);
    if (ret) {
        trace_e1000e_msi_init_fail(ret);
    }

    if (e1000e_add_pm_capability(pci_dev, e1000e_pmrb_offset,
                                  PCI_PM_CAP_DSI) < 0) {
        hw_error("Failed to initialize PM capability");
    }

    if (pcie_aer_init(pci_dev, PCI_ERR_VER, e1000e_aer_offset,
                      PCI_ERR_SIZEOF, NULL) < 0) {
        hw_error("Failed to initialize AER capability");
    }

    pcie_dev_ser_num_init(pci_dev, e1000e_dsn_offset,
                          e1000e_gen_dsn(macaddr));

    e1000e_init_net_peer(s, pci_dev, macaddr);

    /* Initialize core */
    e1000e_core_realize(s);

    e1000e_core_pci_realize(&s->core,
                            e1000e_eeprom_template,
                            sizeof(e1000e_eeprom_template),
                            macaddr);
}
示例#19
0
文件: sun4u.c 项目: Marshalzxy/qemu
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);
}