diff options
Diffstat (limited to 'hw/ppc')
| -rw-r--r-- | hw/ppc/e500.c | 3 | ||||
| -rw-r--r-- | hw/ppc/ppc405_uc.c | 2 | ||||
| -rw-r--r-- | hw/ppc/ppce500_spin.c | 2 | ||||
| -rw-r--r-- | hw/ppc/prep.c | 149 | ||||
| -rw-r--r-- | hw/ppc/spapr.c | 111 | ||||
| -rw-r--r-- | hw/ppc/spapr_hcall.c | 60 | ||||
| -rw-r--r-- | hw/ppc/spapr_pci.c | 75 | ||||
| -rw-r--r-- | hw/ppc/spapr_vio.c | 3 |
8 files changed, 200 insertions, 205 deletions
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index 8a08752613..d7ba25f379 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -472,14 +472,13 @@ static void ppce500_cpu_reset_sec(void *opaque) { PowerPCCPU *cpu = opaque; CPUState *cs = CPU(cpu); - CPUPPCState *env = &cpu->env; cpu_reset(cs); /* Secondary CPU starts in halted state for now. Needs to change when implementing non-kernel boot. */ cs->halted = 1; - env->exception_index = EXCP_HLT; + cs->exception_index = EXCP_HLT; } static void ppce500_cpu_reset(void *opaque) diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c index ca520e8859..54ba59e73a 100644 --- a/hw/ppc/ppc405_uc.c +++ b/hw/ppc/ppc405_uc.c @@ -44,7 +44,7 @@ ram_addr_t ppc405_set_bootinfo (CPUPPCState *env, ppc4xx_bd_info_t *bd, uint32_t flags) { - CPUState *cs = ENV_GET_CPU(env); + CPUState *cs = CPU(ppc_env_get_cpu(env)); ram_addr_t bdloc; int i, n; diff --git a/hw/ppc/ppce500_spin.c b/hw/ppc/ppce500_spin.c index 78b23fa597..f9fdc8c548 100644 --- a/hw/ppc/ppce500_spin.c +++ b/hw/ppc/ppce500_spin.c @@ -117,7 +117,7 @@ static void spin_kick(void *data) mmubooke_create_initial_mapping(env, 0, map_start, map_size); cpu->halted = 0; - env->exception_index = -1; + cpu->exception_index = -1; cpu->stopped = false; qemu_cpu_kick(cpu); } diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c index 9f8538cd20..e2436512f7 100644 --- a/hw/ppc/prep.c +++ b/hw/ppc/prep.c @@ -185,6 +185,7 @@ typedef struct sysctrl_t { uint8_t state; uint8_t syscontrol; int contiguous_map; + qemu_irq contiguous_map_irq; int endian; } sysctrl_t; @@ -253,6 +254,7 @@ static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val) case 0x0850: /* I/O map type register */ sysctrl->contiguous_map = val & 0x01; + qemu_set_irq(sysctrl->contiguous_map_irq, sysctrl->contiguous_map); break; default: printf("ERROR: unaffected IO port write: %04" PRIx32 @@ -327,91 +329,6 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr) return retval; } -static inline hwaddr prep_IO_address(sysctrl_t *sysctrl, - hwaddr addr) -{ - if (sysctrl->contiguous_map == 0) { - /* 64 KB contiguous space for IOs */ - addr &= 0xFFFF; - } else { - /* 8 MB non-contiguous space for IOs */ - addr = (addr & 0x1F) | ((addr & 0x007FFF000) >> 7); - } - - return addr; -} - -static void PPC_prep_io_writeb (void *opaque, hwaddr addr, - uint32_t value) -{ - sysctrl_t *sysctrl = opaque; - - addr = prep_IO_address(sysctrl, addr); - cpu_outb(addr, value); -} - -static uint32_t PPC_prep_io_readb (void *opaque, hwaddr addr) -{ - sysctrl_t *sysctrl = opaque; - uint32_t ret; - - addr = prep_IO_address(sysctrl, addr); - ret = cpu_inb(addr); - - return ret; -} - -static void PPC_prep_io_writew (void *opaque, hwaddr addr, - uint32_t value) -{ - sysctrl_t *sysctrl = opaque; - - addr = prep_IO_address(sysctrl, addr); - PPC_IO_DPRINTF("0x" TARGET_FMT_plx " => 0x%08" PRIx32 "\n", addr, value); - cpu_outw(addr, value); -} - -static uint32_t PPC_prep_io_readw (void *opaque, hwaddr addr) -{ - sysctrl_t *sysctrl = opaque; - uint32_t ret; - - addr = prep_IO_address(sysctrl, addr); - ret = cpu_inw(addr); - PPC_IO_DPRINTF("0x" TARGET_FMT_plx " <= 0x%08" PRIx32 "\n", addr, ret); - - return ret; -} - -static void PPC_prep_io_writel (void *opaque, hwaddr addr, - uint32_t value) -{ - sysctrl_t *sysctrl = opaque; - - addr = prep_IO_address(sysctrl, addr); - PPC_IO_DPRINTF("0x" TARGET_FMT_plx " => 0x%08" PRIx32 "\n", addr, value); - cpu_outl(addr, value); -} - -static uint32_t PPC_prep_io_readl (void *opaque, hwaddr addr) -{ - sysctrl_t *sysctrl = opaque; - uint32_t ret; - - addr = prep_IO_address(sysctrl, addr); - ret = cpu_inl(addr); - PPC_IO_DPRINTF("0x" TARGET_FMT_plx " <= 0x%08" PRIx32 "\n", addr, ret); - - return ret; -} - -static const MemoryRegionOps PPC_prep_io_ops = { - .old_mmio = { - .read = { PPC_prep_io_readb, PPC_prep_io_readw, PPC_prep_io_readl }, - .write = { PPC_prep_io_writeb, PPC_prep_io_writew, PPC_prep_io_writel }, - }, - .endianness = DEVICE_NATIVE_ENDIAN, -}; #define NVRAM_SIZE 0x2000 @@ -456,17 +373,15 @@ static void ppc_prep_init(QEMUMachineInitArgs *args) MemoryRegion *sysmem = get_system_memory(); PowerPCCPU *cpu = NULL; CPUPPCState *env = NULL; - char *filename; nvram_t nvram; M48t59State *m48t59; - MemoryRegion *PPC_io_memory = g_new(MemoryRegion, 1); PortioList *port_list = g_new(PortioList, 1); #if 0 MemoryRegion *xcsr = g_new(MemoryRegion, 1); #endif - int linux_boot, i, nb_nics1, bios_size; + int linux_boot, i, nb_nics1; MemoryRegion *ram = g_new(MemoryRegion, 1); - MemoryRegion *bios = g_new(MemoryRegion, 1); + MemoryRegion *vga = g_new(MemoryRegion, 1); uint32_t kernel_base, initrd_base; long kernel_size, initrd_size; DeviceState *dev; @@ -509,43 +424,6 @@ static void ppc_prep_init(QEMUMachineInitArgs *args) vmstate_register_ram_global(ram); memory_region_add_subregion(sysmem, 0, ram); - /* allocate and load BIOS */ - memory_region_init_ram(bios, NULL, "ppc_prep.bios", BIOS_SIZE); - memory_region_set_readonly(bios, true); - memory_region_add_subregion(sysmem, (uint32_t)(-BIOS_SIZE), bios); - vmstate_register_ram_global(bios); - if (bios_name == NULL) - bios_name = BIOS_FILENAME; - filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); - if (filename) { - bios_size = load_elf(filename, NULL, NULL, NULL, - NULL, NULL, 1, ELF_MACHINE, 0); - if (bios_size < 0) { - bios_size = get_image_size(filename); - if (bios_size > 0 && bios_size <= BIOS_SIZE) { - hwaddr bios_addr; - bios_size = (bios_size + 0xfff) & ~0xfff; - bios_addr = (uint32_t)(-bios_size); - bios_size = load_image_targphys(filename, bios_addr, bios_size); - } - if (bios_size > BIOS_SIZE) { - fprintf(stderr, "qemu: PReP bios '%s' is too large (0x%x)\n", - bios_name, bios_size); - exit(1); - } - } - } else { - bios_size = -1; - } - if (bios_size < 0 && !qtest_enabled()) { - fprintf(stderr, "qemu: could not load PPC PReP bios '%s'\n", - bios_name); - exit(1); - } - if (filename) { - g_free(filename); - } - if (linux_boot) { kernel_base = KERNEL_LOAD_ADDR; /* now we can load the kernel */ @@ -593,6 +471,11 @@ static void ppc_prep_init(QEMUMachineInitArgs *args) } dev = qdev_create(NULL, "raven-pcihost"); + if (bios_name == NULL) { + bios_name = BIOS_FILENAME; + } + qdev_prop_set_string(dev, "bios-name", bios_name); + qdev_prop_set_uint32(dev, "elf-machine", ELF_MACHINE); pcihost = PCI_HOST_BRIDGE(dev); object_property_add_child(qdev_get_machine(), "raven", OBJECT(dev), NULL); qdev_init_nofail(dev); @@ -601,6 +484,7 @@ static void ppc_prep_init(QEMUMachineInitArgs *args) fprintf(stderr, "Couldn't create PCI host controller.\n"); exit(1); } + sysctrl->contiguous_map_irq = qdev_get_gpio_in(dev, 0); /* PCI -> ISA bridge */ pci = pci_create_simple(pci_bus, PCI_DEVFN(1, 0), "i82378"); @@ -621,13 +505,16 @@ static void ppc_prep_init(QEMUMachineInitArgs *args) qdev_prop_set_uint8(dev, "config", 13); /* fdc, ser0, ser1, par0 */ qdev_init_nofail(dev); - /* Register 8 MB of ISA IO space (needed for non-contiguous map) */ - memory_region_init_io(PPC_io_memory, NULL, &PPC_prep_io_ops, sysctrl, - "ppc-io", 0x00800000); - memory_region_add_subregion(sysmem, 0x80000000, PPC_io_memory); - /* init basic PC hardware */ pci_vga_init(pci_bus); + /* Open Hack'Ware hack: PCI BAR#0 is programmed to 0xf0000000. + * While bios will access framebuffer at 0xf0000000, real physical + * address is 0xf0000000 + 0xc0000000 (PCI memory base). + * Alias the wrong memory accesses to the right place. + */ + memory_region_init_alias(vga, NULL, "vga-alias", pci_address_space(pci), + 0xf0000000, 0x1000000); + memory_region_add_subregion_overlap(sysmem, 0xf0000000, vga, 10); nb_nics1 = nb_nics; if (nb_nics1 > NE2000_NB_MAX) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index bf46c380ec..a11e1217b9 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -26,6 +26,7 @@ */ #include "sysemu/sysemu.h" #include "hw/hw.h" +#include "hw/fw-path-provider.h" #include "elf.h" #include "net/net.h" #include "sysemu/blockdev.h" @@ -45,6 +46,8 @@ #include "hw/pci/msi.h" #include "hw/pci/pci.h" +#include "hw/scsi/scsi.h" +#include "hw/virtio/virtio-scsi.h" #include "exec/address-spaces.h" #include "hw/usb.h" @@ -81,6 +84,8 @@ #define HTAB_SIZE(spapr) (1ULL << ((spapr)->htab_shift)) +#define TYPE_SPAPR_MACHINE "spapr-machine" + sPAPREnvironment *spapr; int spapr_allocate_irq(int hint, bool lsi) @@ -598,7 +603,9 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr, hwaddr rtas_addr, hwaddr rtas_size) { - int ret; + int ret, i; + size_t cb = 0; + char *bootlist; void *fdt; sPAPRPHBState *phb; @@ -640,6 +647,21 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr, fprintf(stderr, "Couldn't finalize CPU device tree properties\n"); } + bootlist = get_boot_devices_list(&cb, true); + if (cb && bootlist) { + int offset = fdt_path_offset(fdt, "/chosen"); + if (offset < 0) { + exit(1); + } + for (i = 0; i < cb; i++) { + if (bootlist[i] == '\n') { + bootlist[i] = ' '; + } + + } + ret = fdt_setprop_string(fdt, offset, "qemu,boot-list", bootlist); + } + if (!spapr->has_graphics) { spapr_populate_chosen_stdout(fdt, spapr->vio_bus); } @@ -781,13 +803,15 @@ static int spapr_vga_init(PCIBus *pci_bus) { switch (vga_interface_type) { case VGA_NONE: + return false; + case VGA_DEVICE: + return true; case VGA_STD: return pci_vga_init(pci_bus) != NULL; default: fprintf(stderr, "This vga model is not supported," "currently it only supports -vga std\n"); exit(0); - break; } } @@ -1408,9 +1432,86 @@ static QEMUMachine spapr_machine = { .kvm_type = spapr_kvm_type, }; -static void spapr_machine_init(void) +/* + * Implementation of an interface to adjust firmware patch + * for the bootindex property handling. + */ +static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus, + DeviceState *dev) +{ +#define CAST(type, obj, name) \ + ((type *)object_dynamic_cast(OBJECT(obj), (name))) + SCSIDevice *d = CAST(SCSIDevice, dev, TYPE_SCSI_DEVICE); + sPAPRPHBState *phb = CAST(sPAPRPHBState, dev, TYPE_SPAPR_PCI_HOST_BRIDGE); + + if (d) { + void *spapr = CAST(void, bus->parent, "spapr-vscsi"); + VirtIOSCSI *virtio = CAST(VirtIOSCSI, bus->parent, TYPE_VIRTIO_SCSI); + USBDevice *usb = CAST(USBDevice, bus->parent, TYPE_USB_DEVICE); + + if (spapr) { + /* + * Replace "channel@0/disk@0,0" with "disk@8000000000000000": + * We use SRP luns of the form 8000 | (bus << 8) | (id << 5) | lun + * in the top 16 bits of the 64-bit LUN + */ + unsigned id = 0x8000 | (d->id << 8) | d->lun; + return g_strdup_printf("%s@%"PRIX64, qdev_fw_name(dev), + (uint64_t)id << 48); + } else if (virtio) { + /* + * We use SRP luns of the form 01000000 | (target << 8) | lun + * in the top 32 bits of the 64-bit LUN + * Note: the quote above is from SLOF and it is wrong, + * the actual binding is: + * swap 0100 or 10 << or 20 << ( target lun-id -- srplun ) + */ + unsigned id = 0x1000000 | (d->id << 16) | d->lun; + return g_strdup_printf("%s@%"PRIX64, qdev_fw_name(dev), + (uint64_t)id << 32); + } else if (usb) { + /* + * We use SRP luns of the form 01000000 | (usb-port << 16) | lun + * in the top 32 bits of the 64-bit LUN + */ + unsigned usb_port = atoi(usb->port->path); + unsigned id = 0x1000000 | (usb_port << 16) | d->lun; + return g_strdup_printf("%s@%"PRIX64, qdev_fw_name(dev), + (uint64_t)id << 32); + } + } + + if (phb) { + /* Replace "pci" with "pci@800000020000000" */ + return g_strdup_printf("pci@%"PRIX64, phb->buid); + } + + return NULL; +} + +static void spapr_machine_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc); + + mc->qemu_machine = data; + fwc->get_dev_path = spapr_get_fw_dev_path; +} + +static const TypeInfo spapr_machine_info = { + .name = TYPE_SPAPR_MACHINE, + .parent = TYPE_MACHINE, + .class_init = spapr_machine_class_init, + .class_data = &spapr_machine, + .interfaces = (InterfaceInfo[]) { + { TYPE_FW_PATH_PROVIDER }, + { } + }, +}; + +static void spapr_machine_register_types(void) { - qemu_register_machine(&spapr_machine); + type_register_static(&spapr_machine_info); } -machine_init(spapr_machine_init); +type_init(spapr_machine_register_types) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index d918780746..0bae0535e8 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -4,6 +4,36 @@ #include "hw/ppc/spapr.h" #include "mmu-hash64.h" +struct SPRSyncState { + CPUState *cs; + int spr; + target_ulong value; + target_ulong mask; +}; + +static void do_spr_sync(void *arg) +{ + struct SPRSyncState *s = arg; + PowerPCCPU *cpu = POWERPC_CPU(s->cs); + CPUPPCState *env = &cpu->env; + + cpu_synchronize_state(s->cs); + env->spr[s->spr] &= ~s->mask; + env->spr[s->spr] |= s->value; +} + +static void set_spr(CPUState *cs, int spr, target_ulong value, + target_ulong mask) +{ + struct SPRSyncState s = { + .cs = cs, + .spr = spr, + .value = value, + .mask = mask + }; + run_on_cpu(cs, do_spr_sync, &s); +} + static target_ulong compute_tlbie_rb(target_ulong v, target_ulong r, target_ulong pte_index) { @@ -110,16 +140,15 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr, if (likely((flags & H_EXACT) == 0)) { pte_index &= ~7ULL; token = ppc_hash64_start_access(cpu, pte_index); - do { - if (index == 8) { - ppc_hash64_stop_access(token); - return H_PTEG_FULL; - } + for (; index < 8; index++) { if ((ppc_hash64_load_hpte0(env, token, index) & HPTE64_V_VALID) == 0) { break; } - } while (index++); + } ppc_hash64_stop_access(token); + if (index == 8) { + return H_PTEG_FULL; + } } else { token = ppc_hash64_start_access(cpu, pte_index); if (ppc_hash64_load_hpte0(env, token, 0) & HPTE64_V_VALID) { @@ -356,7 +385,7 @@ static target_ulong h_set_dabr(PowerPCCPU *cpu, sPAPREnvironment *spapr, static target_ulong register_vpa(CPUPPCState *env, target_ulong vpa) { - CPUState *cs = ENV_GET_CPU(env); + CPUState *cs = CPU(ppc_env_get_cpu(env)); uint16_t size; uint8_t tmp; @@ -406,7 +435,7 @@ static target_ulong deregister_vpa(CPUPPCState *env, target_ulong vpa) static target_ulong register_slb_shadow(CPUPPCState *env, target_ulong addr) { - CPUState *cs = ENV_GET_CPU(env); + CPUState *cs = CPU(ppc_env_get_cpu(env)); uint32_t size; if (addr == 0) { @@ -442,7 +471,7 @@ static target_ulong deregister_slb_shadow(CPUPPCState *env, target_ulong addr) static target_ulong register_dtl(CPUPPCState *env, target_ulong addr) { - CPUState *cs = ENV_GET_CPU(env); + CPUState *cs = CPU(ppc_env_get_cpu(env)); uint32_t size; if (addr == 0) { @@ -529,7 +558,7 @@ static target_ulong h_cede(PowerPCCPU *cpu, sPAPREnvironment *spapr, hreg_compute_hflags(env); if (!cpu_has_work(cs)) { cs->halted = 1; - env->exception_index = EXCP_HLT; + cs->exception_index = EXCP_HLT; cs->exit_request = 1; } return H_SUCCESS; @@ -690,7 +719,7 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPREnvironment *spapr, target_ulong value2 = args[3]; target_ulong ret = H_P2; - if (resource == H_SET_MODE_ENDIAN) { + if (resource == H_SET_MODE_RESOURCE_LE) { if (value1) { ret = H_P3; goto out; @@ -699,22 +728,17 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPREnvironment *spapr, ret = H_P4; goto out; } - switch (mflags) { case H_SET_MODE_ENDIAN_BIG: CPU_FOREACH(cs) { - PowerPCCPU *cp = POWERPC_CPU(cs); - CPUPPCState *env = &cp->env; - env->spr[SPR_LPCR] &= ~LPCR_ILE; + set_spr(cs, SPR_LPCR, 0, LPCR_ILE); } ret = H_SUCCESS; break; case H_SET_MODE_ENDIAN_LITTLE: CPU_FOREACH(cs) { - PowerPCCPU *cp = POWERPC_CPU(cs); - CPUPPCState *env = &cp->env; - env->spr[SPR_LPCR] |= LPCR_ILE; + set_spr(cs, SPR_LPCR, LPCR_ILE, LPCR_ILE); } ret = H_SUCCESS; break; diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index cea9469872..cbef095935 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -32,6 +32,7 @@ #include "exec/address-spaces.h" #include <libfdt.h> #include "trace.h" +#include "qemu/error-report.h" #include "hw/pci/pci_bus.h" @@ -292,7 +293,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr, ret_intr_type = RTAS_TYPE_MSIX; break; default: - fprintf(stderr, "rtas_ibm_change_msi(%u) is not implemented\n", func); + error_report("rtas_ibm_change_msi(%u) is not implemented", func); rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); return; } @@ -326,7 +327,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr, /* Find a device number in the map to add or reuse the existing one */ ndev = spapr_msicfg_find(phb, config_addr, true); if (ndev >= SPAPR_MSIX_MAX_DEVS || ndev < 0) { - fprintf(stderr, "No free entry for a new MSI device\n"); + error_report("No free entry for a new MSI device"); rtas_st(rets, 0, RTAS_OUT_HW_ERROR); return; } @@ -335,7 +336,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr, /* Check if there is an old config and MSI number has not changed */ if (phb->msi_table[ndev].nvec && (req_num != phb->msi_table[ndev].nvec)) { /* Unexpected behaviour */ - fprintf(stderr, "Cannot reuse MSI config for device#%d", ndev); + error_report("Cannot reuse MSI config for device#%d", ndev); rtas_st(rets, 0, RTAS_OUT_HW_ERROR); return; } @@ -345,7 +346,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr, irq = spapr_allocate_irq_block(req_num, false, ret_intr_type == RTAS_TYPE_MSI); if (irq < 0) { - fprintf(stderr, "Cannot allocate MSIs for device#%d", ndev); + error_report("Cannot allocate MSIs for device#%d", ndev); rtas_st(rets, 0, RTAS_OUT_HW_ERROR); return; } @@ -505,12 +506,11 @@ static AddressSpace *spapr_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn) return &phb->iommu_as; } -static int spapr_phb_init(SysBusDevice *s) +static void spapr_phb_realize(DeviceState *dev, Error **errp) { - DeviceState *dev = DEVICE(s); + SysBusDevice *s = SYS_BUS_DEVICE(dev); sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s); PCIHostState *phb = PCI_HOST_BRIDGE(s); - const char *busname; char *namebuf; int i; PCIBus *bus; @@ -521,9 +521,9 @@ static int spapr_phb_init(SysBusDevice *s) if ((sphb->buid != -1) || (sphb->dma_liobn != -1) || (sphb->mem_win_addr != -1) || (sphb->io_win_addr != -1)) { - fprintf(stderr, "Either \"index\" or other parameters must" - " be specified for PAPR PHB, not both\n"); - return -1; + error_setg(errp, "Either \"index\" or other parameters must" + " be specified for PAPR PHB, not both"); + return; } sphb->buid = SPAPR_PCI_BASE_BUID + sphb->index; @@ -536,28 +536,28 @@ static int spapr_phb_init(SysBusDevice *s) } if (sphb->buid == -1) { - fprintf(stderr, "BUID not specified for PHB\n"); - return -1; + error_setg(errp, "BUID not specified for PHB"); + return; } if (sphb->dma_liobn == -1) { - fprintf(stderr, "LIOBN not specified for PHB\n"); - return -1; + error_setg(errp, "LIOBN not specified for PHB"); + return; } if (sphb->mem_win_addr == -1) { - fprintf(stderr, "Memory window address not specified for PHB\n"); - return -1; + error_setg(errp, "Memory window address not specified for PHB"); + return; } if (sphb->io_win_addr == -1) { - fprintf(stderr, "IO window address not specified for PHB\n"); - return -1; + error_setg(errp, "IO window address not specified for PHB"); + return; } if (find_phb(spapr, sphb->buid)) { - fprintf(stderr, "PCI host bridges must have unique BUIDs\n"); - return -1; + error_setg(errp, "PCI host bridges must have unique BUIDs"); + return; } sphb->dtbusname = g_strdup_printf("pci@%" PRIx64, sphb->buid); @@ -594,26 +594,8 @@ static int spapr_phb_init(SysBusDevice *s) get_system_io(), 0, SPAPR_PCI_IO_WIN_SIZE); memory_region_add_subregion(get_system_memory(), sphb->io_win_addr, &sphb->iowindow); - /* - * Selecting a busname is more complex than you'd think, due to - * interacting constraints. If the user has specified an id - * explicitly for the phb , then we want to use the qdev default - * of naming the bus based on the bridge device (so the user can - * then assign devices to it in the way they expect). For the - * first / default PCI bus (index=0) we want to use just "pci" - * because libvirt expects there to be a bus called, simply, - * "pci". Otherwise, we use the same name as in the device tree, - * since it's unique by construction, and makes the guest visible - * BUID clear. - */ - if (dev->id) { - busname = NULL; - } else if (sphb->index == 0) { - busname = "pci"; - } else { - busname = sphb->dtbusname; - } - bus = pci_register_bus(dev, busname, + + bus = pci_register_bus(dev, NULL, pci_spapr_set_irq, pci_spapr_map_irq, sphb, &sphb->memspace, &sphb->iospace, PCI_DEVFN(0, 0), PCI_NUM_PINS, TYPE_PCI_BUS); @@ -624,8 +606,9 @@ static int spapr_phb_init(SysBusDevice *s) sphb->tcet = spapr_tce_new_table(dev, sphb->dma_liobn, sphb->dma_window_size); if (!sphb->tcet) { - fprintf(stderr, "Unable to create TCE table for %s\n", sphb->dtbusname); - return -1; + error_setg(errp, "Unable to create TCE table for %s", + sphb->dtbusname); + return; } address_space_init(&sphb->iommu_as, spapr_tce_get_iommu(sphb->tcet), sphb->dtbusname); @@ -642,13 +625,12 @@ static int spapr_phb_init(SysBusDevice *s) irq = spapr_allocate_lsi(0); if (!irq) { - return -1; + error_setg(errp, "spapr_allocate_lsi failed"); + return; } sphb->lsi_table[i].irq = irq; } - - return 0; } static void spapr_phb_reset(DeviceState *qdev) @@ -731,11 +713,10 @@ static const char *spapr_phb_root_bus_path(PCIHostState *host_bridge, static void spapr_phb_class_init(ObjectClass *klass, void *data) { PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass); - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); hc->root_bus_path = spapr_phb_root_bus_path; - sdc->init = spapr_phb_init; + dc->realize = spapr_phb_realize; dc->props = spapr_phb_properties; dc->reset = spapr_phb_reset; dc->vmsd = &vmstate_spapr_pci; diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c index 4e33f462d9..2ae06a3356 100644 --- a/hw/ppc/spapr_vio.c +++ b/hw/ppc/spapr_vio.c @@ -68,6 +68,7 @@ static void spapr_vio_bus_class_init(ObjectClass *klass, void *data) BusClass *k = BUS_CLASS(klass); k->get_dev_path = spapr_vio_get_dev_name; + k->get_fw_dev_path = spapr_vio_get_dev_name; } static const TypeInfo spapr_vio_bus_info = { @@ -529,7 +530,9 @@ static int spapr_vio_bridge_init(SysBusDevice *dev) static void spapr_vio_bridge_class_init(ObjectClass *klass, void *data) { SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); + dc->fw_name = "vdevice"; k->init = spapr_vio_bridge_init; } |