summaryrefslogtreecommitdiff
path: root/hw/sparc64
diff options
context:
space:
mode:
Diffstat (limited to 'hw/sparc64')
-rw-r--r--hw/sparc64/sun4u.c60
1 files changed, 43 insertions, 17 deletions
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 8282651aeb..55d81ee73e 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -27,6 +27,7 @@
#include "cpu.h"
#include "hw/hw.h"
#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
#include "hw/pci-host/apb.h"
#include "hw/i386/pc.h"
#include "hw/char/serial.h"
@@ -42,6 +43,7 @@
#include "hw/nvram/fw_cfg.h"
#include "hw/sysbus.h"
#include "hw/ide.h"
+#include "hw/ide/pci.h"
#include "hw/loader.h"
#include "elf.h"
#include "qemu/cutils.h"
@@ -440,7 +442,8 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
DeviceState *dev;
FWCfgState *fw_cfg;
NICInfo *nd;
- int onboard_nic_idx;
+ MACAddr macaddr;
+ bool onboard_nic;
/* init CPUs */
cpu = sparc64_cpu_devinit(machine->cpu_model, hwdef->default_cpu_model,
@@ -454,10 +457,17 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
ivec_irqs = qemu_allocate_irqs(sparc64_cpu_set_ivec_irq, cpu, IVEC_MAX);
pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, ivec_irqs, &pci_busA,
&pci_busB, &pbm_irqs);
- pci_vga_init(pci_bus);
- /* XXX Should be pci_busA */
- ebus = pci_create_simple(pci_bus, -1, "ebus");
+ /* Only in-built Simba PBMs 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, "ebus");
+ qdev_init_nofail(DEVICE(ebus));
+
isa_bus = pci_ebus_init(ebus, pbm_irqs);
i = 0;
@@ -470,27 +480,43 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
serial_hds_isa_init(isa_bus, i, MAX_SERIAL_PORTS);
parallel_hds_isa_init(isa_bus, MAX_PARALLEL_PORTS);
- onboard_nic_idx = -1;
+ 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 (onboard_nic_idx == -1 &&
- (!nd->model || strcmp(nd->model, "sunhme") == 0)) {
- pci_dev = pci_create(pci_bus, -1, "sunhme");
- dev = &pci_dev->qdev;
- qdev_set_nic_properties(dev, nd);
- qdev_init_nofail(dev);
-
- onboard_nic_idx = 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_simple(pci_busB, -1, "sunhme");
+ }
} else {
- pci_nic_init_nofail(nd, pci_bus, "ne2k_pci", NULL);
+ pci_dev = pci_create_simple(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);
}
- onboard_nic_idx = MAX(onboard_nic_idx, 0);
ide_drive_get(hd, ARRAY_SIZE(hd));
- pci_cmd646_ide_init(pci_bus, hd, 1);
+ 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);
isa_create_simple(isa_bus, "i8042");
@@ -531,7 +557,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
/* XXX: need an option to load a NVRAM image */
0,
graphic_width, graphic_height, graphic_depth,
- (uint8_t *)&nd_table[onboard_nic_idx].macaddr);
+ (uint8_t *)&macaddr);
dev = qdev_create(NULL, TYPE_FW_CFG_IO);
qdev_prop_set_bit(dev, "dma_enabled", false);