diff options
51 files changed, 572 insertions, 596 deletions
diff --git a/.gitignore b/.gitignore index 406f75f2b6..f5aab2cb07 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,10 @@ qemu-ga qemu-monitor.texi QMP/qmp-commands.txt test-coroutine +test-qmp-input-visitor +test-qmp-output-visitor +fsdev/virtfs-proxy-helper.1 +fsdev/virtfs-proxy-helper.pod .gdbinit *.a *.aux diff --git a/MAINTAINERS b/MAINTAINERS index 148f0d2bc5..73c0a10006 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -93,6 +93,7 @@ F: target-mips/ PowerPC M: Alexander Graf <agraf@suse.de> +L: qemu-ppc@nongnu.org S: Maintained F: target-ppc/ @@ -290,21 +291,28 @@ PowerPC Machines ---------------- 405 M: Alexander Graf <agraf@suse.de> +L: qemu-ppc@nongnu.org S: Maintained F: hw/ppc405_boards.c New World M: Alexander Graf <agraf@suse.de> +L: qemu-ppc@nongnu.org S: Maintained F: hw/ppc_newworld.c +F: hw/unin_pci.c +F: hw/dec_pci.[hc] Old World M: Alexander Graf <agraf@suse.de> +L: qemu-ppc@nongnu.org S: Maintained F: hw/ppc_oldworld.c +F: hw/grackle_pci.c PReP M: Andreas Färber <andreas.faerber@web.de> +L: qemu-ppc@nongnu.org S: Odd Fixes F: hw/ppc_prep.c F: hw/prep_pci.[hc] diff --git a/Makefile.target b/Makefile.target index 06d79b8028..bb18d72e42 100644 --- a/Makefile.target +++ b/Makefile.target @@ -196,6 +196,8 @@ obj-$(CONFIG_VHOST_NET) += vhost.o obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o obj-$(CONFIG_KVM) += kvm.o kvm-all.o obj-$(CONFIG_NO_KVM) += kvm-stub.o +obj-$(CONFIG_VGA) += vga.o +obj-$(CONFIG_VGA_CIRRUS) += cirrus_vga.o obj-y += memory.o savevm.o LIBS+=-lz @@ -224,9 +226,8 @@ obj-$(CONFIG_IVSHMEM) += ivshmem.o obj-y += device-hotplug.o # Hardware support -obj-i386-y += vga.o obj-i386-y += mc146818rtc.o pc.o -obj-i386-y += cirrus_vga.o sga.o apic.o ioapic.o piix_pci.o +obj-i386-y += sga.o apic.o ioapic.o piix_pci.o obj-i386-y += vmport.o obj-i386-y += pci-hotplug.o smbios.o wdt_ib700.o obj-i386-y += debugcon.o multiboot.o @@ -236,7 +237,6 @@ obj-i386-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o # shared objects obj-ppc-y = ppc.o ppc_booke.o -obj-ppc-y += vga.o # PREP target obj-ppc-y += mc146818rtc.o obj-ppc-y += ppc_prep.o @@ -250,7 +250,7 @@ obj-ppc-$(CONFIG_PSERIES) += xics.o spapr_vty.o spapr_llan.o spapr_vscsi.o obj-ppc-$(CONFIG_PSERIES) += spapr_pci.o device-hotplug.o pci-hotplug.o # PowerPC 4xx boards obj-ppc-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o -obj-ppc-y += ppc440.o ppc440_bamboo.o +obj-ppc-y += ppc440_bamboo.o # PowerPC E500 boards obj-ppc-y += ppce500_mpc8544ds.o mpc8544_guts.o ppce500_spin.o # PowerPC 440 Xilinx ML507 reference board. @@ -290,10 +290,8 @@ obj-lm32-y += framebuffer.o obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o obj-mips-y += mips_addr.o mips_timer.o mips_int.o -obj-mips-y += vga.o obj-mips-y += jazz_led.o obj-mips-y += gt64xxx.o mc146818rtc.o -obj-mips-y += cirrus_vga.o obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o mips_fulong2e.o obj-microblaze-y = petalogix_s3adsp1800_mmu.o @@ -323,9 +321,7 @@ obj-cris-y += etraxfs_ser.o ifeq ($(TARGET_ARCH), sparc64) obj-sparc-y = sun4u.o apb_pci.o -obj-sparc-y += vga.o obj-sparc-y += mc146818rtc.o -obj-sparc-y += cirrus_vga.o else obj-sparc-y = sun4m.o lance.o tcx.o sun4m_iommu.o slavio_intctl.o obj-sparc-y += slavio_timer.o slavio_misc.o sparc32_dma.o @@ -353,7 +349,7 @@ obj-arm-y += omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o \ obj-arm-y += omap2.o omap_dss.o soc_dma.o omap_gptimer.o omap_synctimer.o \ omap_gpmc.o omap_sdrc.o omap_spi.o omap_tap.o omap_l4.o obj-arm-y += omap_sx1.o palm.o tsc210x.o -obj-arm-y += nseries.o blizzard.o onenand.o vga.o cbus.o tusb6010.o usb-musb.o +obj-arm-y += nseries.o blizzard.o onenand.o cbus.o tusb6010.o usb-musb.o obj-arm-y += mst_fpga.o mainstone.o obj-arm-y += z2.o obj-arm-y += musicpal.o bitbang_i2c.o marvell_88w8618_audio.o @@ -373,7 +369,6 @@ obj-m68k-y += m68k-semi.o dummy_m68k.o obj-s390x-y = s390-virtio-bus.o s390-virtio.o obj-alpha-y = mc146818rtc.o -obj-alpha-y += vga.o cirrus_vga.o obj-alpha-y += alpha_pci.o alpha_dp264.o alpha_typhoon.o obj-xtensa-y += xtensa_pic.o diff --git a/default-configs/alpha-softmmu.mak b/default-configs/alpha-softmmu.mak index bd1dd95a2a..501dd413b7 100644 --- a/default-configs/alpha-softmmu.mak +++ b/default-configs/alpha-softmmu.mak @@ -4,7 +4,9 @@ include pci.mak CONFIG_SERIAL=y CONFIG_I8254=y CONFIG_PCKBD=y +CONFIG_VGA=y CONFIG_VGA_PCI=y +CONFIG_VGA_CIRRUS=y CONFIG_IDE_CORE=y CONFIG_IDE_QDEV=y CONFIG_VMWARE_VGA=y diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index 8d1174f177..e542b4f8ee 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -2,6 +2,7 @@ include pci.mak CONFIG_GDBSTUB_XML=y +CONFIG_VGA=y CONFIG_ISA_MMIO=y CONFIG_NAND=y CONFIG_ECC=y diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index e67ebb360e..662348ef11 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -1,8 +1,10 @@ # Default configuration for i386-softmmu include pci.mak +CONFIG_VGA=y CONFIG_VGA_PCI=y CONFIG_VGA_ISA=y +CONFIG_VGA_CIRRUS=y CONFIG_VMWARE_VGA=y CONFIG_VMMOUSE=y CONFIG_SERIAL=y diff --git a/default-configs/mips-softmmu.mak b/default-configs/mips-softmmu.mak index 94a34862dc..308d04aeab 100644 --- a/default-configs/mips-softmmu.mak +++ b/default-configs/mips-softmmu.mak @@ -3,9 +3,11 @@ include pci.mak CONFIG_ISA_MMIO=y CONFIG_ESP=y +CONFIG_VGA=y CONFIG_VGA_PCI=y CONFIG_VGA_ISA=y CONFIG_VGA_ISA_MM=y +CONFIG_VGA_CIRRUS=y CONFIG_VMWARE_VGA=y CONFIG_SERIAL=y CONFIG_PARALLEL=y diff --git a/default-configs/mips64-softmmu.mak b/default-configs/mips64-softmmu.mak index b5d310816f..f1b92da8a3 100644 --- a/default-configs/mips64-softmmu.mak +++ b/default-configs/mips64-softmmu.mak @@ -3,9 +3,11 @@ include pci.mak CONFIG_ISA_MMIO=y CONFIG_ESP=y +CONFIG_VGA=y CONFIG_VGA_PCI=y CONFIG_VGA_ISA=y CONFIG_VGA_ISA_MM=y +CONFIG_VGA_CIRRUS=y CONFIG_VMWARE_VGA=y CONFIG_SERIAL=y CONFIG_PARALLEL=y diff --git a/default-configs/mips64el-softmmu.mak b/default-configs/mips64el-softmmu.mak index 2831f44f2a..567396c84f 100644 --- a/default-configs/mips64el-softmmu.mak +++ b/default-configs/mips64el-softmmu.mak @@ -3,9 +3,11 @@ include pci.mak CONFIG_ISA_MMIO=y CONFIG_ESP=y +CONFIG_VGA=y CONFIG_VGA_PCI=y CONFIG_VGA_ISA=y CONFIG_VGA_ISA_MM=y +CONFIG_VGA_CIRRUS=y CONFIG_VMWARE_VGA=y CONFIG_SERIAL=y CONFIG_PARALLEL=y diff --git a/default-configs/mipsel-softmmu.mak b/default-configs/mipsel-softmmu.mak index 14c949df13..a8e421b151 100644 --- a/default-configs/mipsel-softmmu.mak +++ b/default-configs/mipsel-softmmu.mak @@ -3,9 +3,11 @@ include pci.mak CONFIG_ISA_MMIO=y CONFIG_ESP=y +CONFIG_VGA=y CONFIG_VGA_PCI=y CONFIG_VGA_ISA=y CONFIG_VGA_ISA_MM=y +CONFIG_VGA_CIRRUS=y CONFIG_VMWARE_VGA=y CONFIG_SERIAL=y CONFIG_PARALLEL=y diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak index 1fe9c6d5d9..1a768fc519 100644 --- a/default-configs/ppc-softmmu.mak +++ b/default-configs/ppc-softmmu.mak @@ -5,6 +5,7 @@ CONFIG_GDBSTUB_XML=y CONFIG_ISA_MMIO=y CONFIG_ESCC=y CONFIG_M48T59=y +CONFIG_VGA=y CONFIG_VGA_PCI=y CONFIG_SERIAL=y CONFIG_I8254=y diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak index 8874115d81..f490368c64 100644 --- a/default-configs/ppc64-softmmu.mak +++ b/default-configs/ppc64-softmmu.mak @@ -5,6 +5,7 @@ CONFIG_GDBSTUB_XML=y CONFIG_ISA_MMIO=y CONFIG_ESCC=y CONFIG_M48T59=y +CONFIG_VGA=y CONFIG_VGA_PCI=y CONFIG_SERIAL=y CONFIG_I8254=y diff --git a/default-configs/ppcemb-softmmu.mak b/default-configs/ppcemb-softmmu.mak index 5db7205267..829f462105 100644 --- a/default-configs/ppcemb-softmmu.mak +++ b/default-configs/ppcemb-softmmu.mak @@ -5,6 +5,7 @@ CONFIG_GDBSTUB_XML=y CONFIG_ISA_MMIO=y CONFIG_ESCC=y CONFIG_M48T59=y +CONFIG_VGA=y CONFIG_VGA_PCI=y CONFIG_SERIAL=y CONFIG_I8254=y diff --git a/default-configs/sparc64-softmmu.mak b/default-configs/sparc64-softmmu.mak index d8f17e7b46..c9a36c1e46 100644 --- a/default-configs/sparc64-softmmu.mak +++ b/default-configs/sparc64-softmmu.mak @@ -4,7 +4,9 @@ include pci.mak CONFIG_ISA_MMIO=y CONFIG_M48T59=y CONFIG_PTIMER=y +CONFIG_VGA=y CONFIG_VGA_PCI=y +CONFIG_VGA_CIRRUS=y CONFIG_SERIAL=y CONFIG_PARALLEL=y CONFIG_PCKBD=y diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak index b75757ee5f..b445be2059 100644 --- a/default-configs/x86_64-softmmu.mak +++ b/default-configs/x86_64-softmmu.mak @@ -1,8 +1,10 @@ # Default configuration for x86_64-softmmu include pci.mak +CONFIG_VGA=y CONFIG_VGA_PCI=y CONFIG_VGA_ISA=y +CONFIG_VGA_CIRRUS=y CONFIG_VMWARE_VGA=y CONFIG_VMMOUSE=y CONFIG_SERIAL=y diff --git a/exec.c b/exec.c index 7f9f730250..5b9eb9aa19 100644 --- a/exec.c +++ b/exec.c @@ -4390,6 +4390,20 @@ tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong addr) return qemu_ram_addr_from_host_nofail(p); } +/* + * A helper function for the _utterly broken_ virtio device model to find out if + * it's running on a big endian machine. Don't do this at home kids! + */ +bool virtio_is_big_endian(void); +bool virtio_is_big_endian(void) +{ +#if defined(TARGET_WORDS_BIGENDIAN) + return true; +#else + return false; +#endif +} + #define MMUSUFFIX _cmmu #undef GETPC #define GETPC() NULL diff --git a/hw/alpha_pci.c b/hw/alpha_pci.c index e9757028af..673557781e 100644 --- a/hw/alpha_pci.c +++ b/hw/alpha_pci.c @@ -121,10 +121,8 @@ void alpha_pci_vga_setup(PCIBus *pci_bus) pci_cirrus_vga_init(pci_bus); return; case VGA_VMWARE: - if (pci_vmsvga_init(pci_bus)) { - return; - } - break; + pci_vmsvga_init(pci_bus); + return; } /* If VGA is enabled at all, and one of the above didn't work, then fallback to Standard VGA. */ diff --git a/hw/boards.h b/hw/boards.h index 716fd7b1a6..f6d3784cf1 100644 --- a/hw/boards.h +++ b/hw/boards.h @@ -22,7 +22,6 @@ typedef struct QEMUMachine { unsigned int no_serial:1, no_parallel:1, use_virtcon:1, - no_vga:1, no_floppy:1, no_cdrom:1, no_sdcard:1; diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index f7b1d3d785..8506bb5777 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -250,6 +250,11 @@ typedef struct PCICirrusVGAState { CirrusVGAState cirrus_vga; } PCICirrusVGAState; +typedef struct ISACirrusVGAState { + ISADevice dev; + CirrusVGAState cirrus_vga; +} ISACirrusVGAState; + static uint8_t rop_to_index[256]; /*************************************** @@ -2883,23 +2888,35 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci, * ***************************************/ -DeviceState *isa_cirrus_vga_init(MemoryRegion *system_memory) +static int vga_initfn(ISADevice *dev) { - CirrusVGAState *s; - - s = g_malloc0(sizeof(CirrusVGAState)); - - vga_common_init(&s->vga, VGA_RAM_SIZE); - cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0, system_memory); - s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate, - s->vga.screen_dump, s->vga.text_update, - &s->vga); - vmstate_register(NULL, 0, &vmstate_cirrus_vga, s); + ISACirrusVGAState *d = DO_UPCAST(ISACirrusVGAState, dev, dev); + VGACommonState *s = &d->cirrus_vga.vga; + + vga_common_init(s, VGA_RAM_SIZE); + cirrus_init_common(&d->cirrus_vga, CIRRUS_ID_CLGD5430, 0, + isa_address_space(dev)); + s->ds = graphic_console_init(s->update, s->invalidate, + s->screen_dump, s->text_update, + s); rom_add_vga(VGABIOS_CIRRUS_FILENAME); /* XXX ISA-LFB support */ /* FIXME not qdev yet */ - return NULL; + return 0; +} + +static ISADeviceInfo isa_cirrus_vga_info = { + .qdev.name = "isa-cirrus-vga", + .qdev.size = sizeof(ISACirrusVGAState), + .qdev.vmsd = &vmstate_cirrus_vga, + .init = vga_initfn, +}; + +static void isa_cirrus_vga_register(void) +{ + isa_qdev_register(&isa_cirrus_vga_info); } +device_init(isa_cirrus_vga_register) /*************************************** * diff --git a/hw/e1000.c b/hw/e1000.c index a29c944df4..86c5416bd1 100644 --- a/hw/e1000.c +++ b/hw/e1000.c @@ -466,6 +466,8 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp) bytes = split_size; if (tp->size + bytes > msh) bytes = msh - tp->size; + + bytes = MIN(sizeof(tp->data) - tp->size, bytes); pci_dma_read(&s->dev, addr, tp->data + tp->size, bytes); if ((sz = tp->size + bytes) >= hdr && tp->size < hdr) memmove(tp->header, tp->data, hdr); @@ -481,6 +483,7 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp) // context descriptor TSE is not set, while data descriptor TSE is set DBGOUT(TXERR, "TCP segmentaion Error\n"); } else { + split_size = MIN(sizeof(tp->data) - tp->size, split_size); pci_dma_read(&s->dev, addr, tp->data + tp->size, split_size); tp->size += split_size; } diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c index 1e529fb5d0..be10a6d5a3 100644 --- a/hw/grackle_pci.c +++ b/hw/grackle_pci.c @@ -71,7 +71,7 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic, SysBusDevice *s; GrackleState *d; - dev = qdev_create(NULL, "grackle"); + dev = qdev_create(NULL, "grackle-pcihost"); qdev_init_nofail(dev); s = sysbus_from_qdev(dev); d = FROM_SYSBUS(GrackleState, s); @@ -121,9 +121,10 @@ static int grackle_pci_host_init(PCIDevice *d) return 0; } -static PCIDeviceInfo grackle_pci_host_info = { +static PCIDeviceInfo grackle_pci_info = { .qdev.name = "grackle", .qdev.size = sizeof(PCIDevice), + .qdev.no_user = 1, .init = grackle_pci_host_init, .vendor_id = PCI_VENDOR_ID_MOTOROLA, .device_id = PCI_DEVICE_ID_MOTOROLA_MPC106, @@ -131,11 +132,17 @@ static PCIDeviceInfo grackle_pci_host_info = { .class_id = PCI_CLASS_BRIDGE_HOST, }; +static SysBusDeviceInfo grackle_pci_host_info = { + .qdev.name = "grackle-pcihost", + .qdev.size = sizeof(GrackleState), + .qdev.no_user = 1, + .init = pci_grackle_init_device, +}; + static void grackle_register_devices(void) { - sysbus_register_dev("grackle", sizeof(GrackleState), - pci_grackle_init_device); - pci_qdev_register(&grackle_pci_host_info); + sysbus_register_withprop(&grackle_pci_host_info); + pci_qdev_register(&grackle_pci_info); } device_init(grackle_register_devices) diff --git a/hw/ide/pci.c b/hw/ide/pci.c index cb3de6537b..246dd5704b 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -327,7 +327,7 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val) bm->cmd = val & 0x09; } -static uint64_t bmdma_addr_read(void *opaque, dma_addr_t addr, +static uint64_t bmdma_addr_read(void *opaque, target_phys_addr_t addr, unsigned width) { BMDMAState *bm = opaque; @@ -341,7 +341,7 @@ static uint64_t bmdma_addr_read(void *opaque, dma_addr_t addr, return data; } -static void bmdma_addr_write(void *opaque, dma_addr_t addr, +static void bmdma_addr_write(void *opaque, target_phys_addr_t addr, uint64_t data, unsigned width) { BMDMAState *bm = opaque; diff --git a/hw/loader.c b/hw/loader.c index 446b62874e..415cdce534 100644 --- a/hw/loader.c +++ b/hw/loader.c @@ -108,8 +108,12 @@ int load_image_targphys(const char *filename, int size; size = get_image_size(filename); - if (size > 0) + if (size > max_sz) { + return -1; + } + if (size > 0) { rom_add_file_fixed(filename, addr, -1); + } return size; } diff --git a/hw/mips_malta.c b/hw/mips_malta.c index e625ec398f..4a4f76d9f2 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -996,11 +996,7 @@ void mips_malta_init (ram_addr_t ram_size, if (cirrus_vga_enabled) { pci_cirrus_vga_init(pci_bus); } else if (vmsvga_enabled) { - if (!pci_vmsvga_init(pci_bus)) { - fprintf(stderr, "Warning: vmware_vga not available," - " using standard VGA instead\n"); - pci_vga_init(pci_bus); - } + pci_vmsvga_init(pci_bus); } else if (std_vga_enabled) { pci_vga_init(pci_bus); } diff --git a/hw/pc.c b/hw/pc.c index 85304cf115..b1fd4b004c 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -1080,16 +1080,11 @@ DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus) if (pci_bus) { dev = pci_cirrus_vga_init(pci_bus); } else { - dev = isa_cirrus_vga_init(get_system_memory()); + dev = &isa_create_simple(isa_bus, "isa-cirrus-vga")->qdev; } } else if (vmsvga_enabled) { if (pci_bus) { dev = pci_vmsvga_init(pci_bus); - if (!dev) { - fprintf(stderr, "Warning: vmware_vga not available," - " using standard VGA instead\n"); - dev = pci_vga_init(pci_bus); - } } else { fprintf(stderr, "%s: vmware_vga: no PCI bus\n", __FUNCTION__); } diff --git a/hw/pc.h b/hw/pc.h index 13e41f101e..58a7ea910f 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -226,7 +226,6 @@ int isa_vga_mm_init(target_phys_addr_t vram_base, /* cirrus_vga.c */ DeviceState *pci_cirrus_vga_init(PCIBus *bus); -DeviceState *isa_cirrus_vga_init(MemoryRegion *address_space); /* ne2000.c */ static inline bool isa_ne2000_init(ISABus *bus, int base, int irq, NICInfo *nd) diff --git a/hw/pci.c b/hw/pci.c index c3082bc7c6..54400ac134 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -1572,21 +1572,6 @@ PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction, return DO_UPCAST(PCIDevice, qdev, dev); } -PCIDevice *pci_try_create_multifunction(PCIBus *bus, int devfn, - bool multifunction, - const char *name) -{ - DeviceState *dev; - - dev = qdev_try_create(&bus->qbus, name); - if (!dev) { - return NULL; - } - qdev_prop_set_uint32(dev, "addr", devfn); - qdev_prop_set_bit(dev, "multifunction", multifunction); - return DO_UPCAST(PCIDevice, qdev, dev); -} - PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn, bool multifunction, const char *name) @@ -1606,11 +1591,6 @@ PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name) return pci_create_simple_multifunction(bus, devfn, false, name); } -PCIDevice *pci_try_create(PCIBus *bus, int devfn, const char *name) -{ - return pci_try_create_multifunction(bus, devfn, false, name); -} - static int pci_find_space(PCIDevice *pdev, uint8_t size) { int config_size = pci_config_size(pdev); diff --git a/hw/pci.h b/hw/pci.h index 0d2cff6fec..5501d9525d 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -469,12 +469,8 @@ PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction, PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn, bool multifunction, const char *name); -PCIDevice *pci_try_create_multifunction(PCIBus *bus, int devfn, - bool multifunction, - const char *name); PCIDevice *pci_create(PCIBus *bus, int devfn, const char *name); PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name); -PCIDevice *pci_try_create(PCIBus *bus, int devfn, const char *name); static inline int pci_is_express(const PCIDevice *d) { diff --git a/hw/ppc440.c b/hw/ppc440.c deleted file mode 100644 index cd8a95d52b..0000000000 --- a/hw/ppc440.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Qemu PowerPC 440 chip emulation - * - * Copyright 2007 IBM Corporation. - * Authors: - * Jerone Young <jyoung5@us.ibm.com> - * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com> - * Hollis Blanchard <hollisb@us.ibm.com> - * - * This work is licensed under the GNU GPL license version 2 or later. - * - */ - -#include "hw.h" -#include "pc.h" -#include "isa.h" -#include "ppc.h" -#include "ppc4xx.h" -#include "ppc440.h" -#include "ppc405.h" -#include "sysemu.h" -#include "kvm.h" - -#define PPC440EP_PCI_CONFIG 0xeec00000 -#define PPC440EP_PCI_INTACK 0xeed00000 -#define PPC440EP_PCI_SPECIAL 0xeed00000 -#define PPC440EP_PCI_REGS 0xef400000 -#define PPC440EP_PCI_IO 0xe8000000 -#define PPC440EP_PCI_IOLEN 0x00010000 - -#define PPC440EP_SDRAM_NR_BANKS 4 - -static const unsigned int ppc440ep_sdram_bank_sizes[] = { - 256<<20, 128<<20, 64<<20, 32<<20, 16<<20, 8<<20, 0 -}; - -CPUState *ppc440ep_init(MemoryRegion *address_space_mem, ram_addr_t *ram_size, - PCIBus **pcip, const unsigned int pci_irq_nrs[4], - int do_init, const char *cpu_model) -{ - MemoryRegion *ram_memories - = g_malloc(PPC440EP_SDRAM_NR_BANKS * sizeof(*ram_memories)); - target_phys_addr_t ram_bases[PPC440EP_SDRAM_NR_BANKS]; - target_phys_addr_t ram_sizes[PPC440EP_SDRAM_NR_BANKS]; - CPUState *env; - qemu_irq *pic; - qemu_irq *irqs; - qemu_irq *pci_irqs; - - if (cpu_model == NULL) { - cpu_model = "440-Xilinx"; // XXX: should be 440EP - } - env = cpu_init(cpu_model); - if (!env) { - fprintf(stderr, "Unable to initialize CPU!\n"); - exit(1); - } - - ppc_dcr_init(env, NULL, NULL); - - /* interrupt controller */ - irqs = g_malloc0(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB); - irqs[PPCUIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT]; - irqs[PPCUIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT]; - pic = ppcuic_init(env, irqs, 0x0C0, 0, 1); - - /* SDRAM controller */ - memset(ram_bases, 0, sizeof(ram_bases)); - memset(ram_sizes, 0, sizeof(ram_sizes)); - *ram_size = ppc4xx_sdram_adjust(*ram_size, PPC440EP_SDRAM_NR_BANKS, - ram_memories, - ram_bases, ram_sizes, - ppc440ep_sdram_bank_sizes); - /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */ - ppc4xx_sdram_init(env, pic[14], PPC440EP_SDRAM_NR_BANKS, ram_memories, - ram_bases, ram_sizes, do_init); - - /* PCI */ - pci_irqs = g_malloc(sizeof(qemu_irq) * 4); - pci_irqs[0] = pic[pci_irq_nrs[0]]; - pci_irqs[1] = pic[pci_irq_nrs[1]]; - pci_irqs[2] = pic[pci_irq_nrs[2]]; - pci_irqs[3] = pic[pci_irq_nrs[3]]; - *pcip = ppc4xx_pci_init(env, pci_irqs, - PPC440EP_PCI_CONFIG, - PPC440EP_PCI_INTACK, - PPC440EP_PCI_SPECIAL, - PPC440EP_PCI_REGS); - if (!*pcip) - printf("couldn't create PCI controller!\n"); - - isa_mmio_init(PPC440EP_PCI_IO, PPC440EP_PCI_IOLEN); - - if (serial_hds[0] != NULL) { - serial_mm_init(address_space_mem, 0xef600300, 0, pic[0], - PPC_SERIAL_MM_BAUDBASE, serial_hds[0], - DEVICE_BIG_ENDIAN); - } - if (serial_hds[1] != NULL) { - serial_mm_init(address_space_mem, 0xef600400, 0, pic[1], - PPC_SERIAL_MM_BAUDBASE, serial_hds[1], - DEVICE_BIG_ENDIAN); - } - - return env; -} diff --git a/hw/ppc440.h b/hw/ppc440.h deleted file mode 100644 index 9c27c36fd0..0000000000 --- a/hw/ppc440.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Qemu PowerPC 440 board emualtion - * - * Copyright 2007 IBM Corporation. - * Authors: Jerone Young <jyoung5@us.ibm.com> - * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com> - * - * This work is licensed under the GNU GPL licence version 2 or later - * - */ - -#ifndef QEMU_PPC440_H -#define QEMU_PPC440_H - -#include "hw.h" - -CPUState *ppc440ep_init(MemoryRegion *address_space, ram_addr_t *ram_size, - PCIBus **pcip, const unsigned int pci_irq_nrs[4], - int do_init, const char *cpu_model); - -#endif diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c index b734e3a56c..f86b16838a 100644 --- a/hw/ppc440_bamboo.c +++ b/hw/ppc440_bamboo.c @@ -3,9 +3,9 @@ * * Copyright 2007 IBM Corporation. * Authors: - * Jerone Young <jyoung5@us.ibm.com> - * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com> - * Hollis Blanchard <hollisb@us.ibm.com> + * Jerone Young <jyoung5@us.ibm.com> + * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com> + * Hollis Blanchard <hollisb@us.ibm.com> * * This work is licensed under the GNU GPL license version 2 or later. * @@ -17,13 +17,17 @@ #include "hw.h" #include "pci.h" #include "boards.h" -#include "ppc440.h" #include "kvm.h" #include "kvm_ppc.h" #include "device_tree.h" #include "loader.h" #include "elf.h" #include "exec-memory.h" +#include "pc.h" +#include "ppc.h" +#include "ppc405.h" +#include "sysemu.h" +#include "sysbus.h" #define BINARY_DEVICE_TREE_FILE "bamboo.dtb" @@ -32,6 +36,21 @@ #define FDT_ADDR 0x1800000 #define RAMDISK_ADDR 0x1900000 +#define PPC440EP_PCI_CONFIG 0xeec00000 +#define PPC440EP_PCI_INTACK 0xeed00000 +#define PPC440EP_PCI_SPECIAL 0xeed00000 +#define PPC440EP_PCI_REGS 0xef400000 +#define PPC440EP_PCI_IO 0xe8000000 +#define PPC440EP_PCI_IOLEN 0x00010000 + +#define PPC440EP_SDRAM_NR_BANKS 4 + +static const unsigned int ppc440ep_sdram_bank_sizes[] = { + 256<<20, 128<<20, 64<<20, 32<<20, 16<<20, 8<<20, 0 +}; + +static target_phys_addr_t entry; + static int bamboo_load_device_tree(target_phys_addr_t addr, uint32_t ramsize, target_phys_addr_t initrd_base, @@ -101,6 +120,42 @@ out: return ret; } +/* Create reset TLB entries for BookE, spanning the 32bit addr space. */ +static void mmubooke_create_initial_mapping(CPUState *env, + target_ulong va, + target_phys_addr_t pa) +{ + ppcemb_tlb_t *tlb = &env->tlb.tlbe[0]; + + tlb->attr = 0; + tlb->prot = PAGE_VALID | ((PAGE_READ | PAGE_WRITE | PAGE_EXEC) << 4); + tlb->size = 1 << 31; /* up to 0x80000000 */ + tlb->EPN = va & TARGET_PAGE_MASK; + tlb->RPN = pa & TARGET_PAGE_MASK; + tlb->PID = 0; + + tlb = &env->tlb.tlbe[1]; + tlb->attr = 0; + tlb->prot = PAGE_VALID | ((PAGE_READ | PAGE_WRITE | PAGE_EXEC) << 4); + tlb->size = 1 << 31; /* up to 0xffffffff */ + tlb->EPN = 0x80000000 & TARGET_PAGE_MASK; + tlb->RPN = 0x80000000 & TARGET_PAGE_MASK; + tlb->PID = 0; +} + +static void main_cpu_reset(void *opaque) +{ + CPUState *env = opaque; + + cpu_reset(env); + env->gpr[1] = (16<<20) - 8; + env->gpr[3] = FDT_ADDR; + env->nip = entry; + + /* Create a mapping for the kernel. */ + mmubooke_create_initial_mapping(env, 0, 0); +} + static void bamboo_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, @@ -110,19 +165,76 @@ static void bamboo_init(ram_addr_t ram_size, { unsigned int pci_irq_nrs[4] = { 28, 27, 26, 25 }; MemoryRegion *address_space_mem = get_system_memory(); + MemoryRegion *ram_memories + = g_malloc(PPC440EP_SDRAM_NR_BANKS * sizeof(*ram_memories)); + target_phys_addr_t ram_bases[PPC440EP_SDRAM_NR_BANKS]; + target_phys_addr_t ram_sizes[PPC440EP_SDRAM_NR_BANKS]; + qemu_irq *pic; + qemu_irq *irqs; PCIBus *pcibus; CPUState *env; uint64_t elf_entry; uint64_t elf_lowaddr; - target_phys_addr_t entry = 0; target_phys_addr_t loadaddr = 0; target_long initrd_size = 0; + DeviceState *dev; int success; int i; /* Setup CPU. */ - env = ppc440ep_init(address_space_mem, &ram_size, &pcibus, - pci_irq_nrs, 1, cpu_model); + if (cpu_model == NULL) { + cpu_model = "440EP"; + } + env = cpu_init(cpu_model); + if (!env) { + fprintf(stderr, "Unable to initialize CPU!\n"); + exit(1); + } + + qemu_register_reset(main_cpu_reset, env); + ppc_booke_timers_init(env, 400000000, 0); + ppc_dcr_init(env, NULL, NULL); + + /* interrupt controller */ + irqs = g_malloc0(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB); + irqs[PPCUIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT]; + irqs[PPCUIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT]; + pic = ppcuic_init(env, irqs, 0x0C0, 0, 1); + + /* SDRAM controller */ + memset(ram_bases, 0, sizeof(ram_bases)); + memset(ram_sizes, 0, sizeof(ram_sizes)); + ram_size = ppc4xx_sdram_adjust(ram_size, PPC440EP_SDRAM_NR_BANKS, + ram_memories, + ram_bases, ram_sizes, + ppc440ep_sdram_bank_sizes); + /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */ + ppc4xx_sdram_init(env, pic[14], PPC440EP_SDRAM_NR_BANKS, ram_memories, + ram_bases, ram_sizes, 1); + + /* PCI */ + dev = sysbus_create_varargs("ppc4xx-pcihost", PPC440EP_PCI_CONFIG, + pic[pci_irq_nrs[0]], pic[pci_irq_nrs[1]], + pic[pci_irq_nrs[2]], pic[pci_irq_nrs[3]], + NULL); + pcibus = (PCIBus *)qdev_get_child_bus(dev, "pci.0"); + if (!pcibus) { + fprintf(stderr, "couldn't create PCI controller!\n"); + exit(1); + } + + isa_mmio_init(PPC440EP_PCI_IO, PPC440EP_PCI_IOLEN); + + if (serial_hds[0] != NULL) { + serial_mm_init(address_space_mem, 0xef600300, 0, pic[0], + PPC_SERIAL_MM_BAUDBASE, serial_hds[0], + DEVICE_BIG_ENDIAN); + } + if (serial_hds[1] != NULL) { + serial_mm_init(address_space_mem, 0xef600400, 0, pic[1], + PPC_SERIAL_MM_BAUDBASE, serial_hds[1], + DEVICE_BIG_ENDIAN); + } if (pcibus) { /* Register network interfaces. */ @@ -169,12 +281,6 @@ static void bamboo_init(ram_addr_t ram_size, fprintf(stderr, "couldn't load device tree\n"); exit(1); } - - /* Set initial guest state. */ - env->gpr[1] = (16<<20) - 8; - env->gpr[3] = FDT_ADDR; - env->nip = entry; - /* XXX we currently depend on KVM to create some initial TLB entries. */ } if (kvm_enabled()) @@ -182,34 +288,14 @@ static void bamboo_init(ram_addr_t ram_size, } static QEMUMachine bamboo_machine = { - .name = "bamboo-0.13", - .alias = "bamboo", - .desc = "bamboo", - .init = bamboo_init, -}; - -static QEMUMachine bamboo_machine_v0_12 = { - .name = "bamboo-0.12", + .name = "bamboo", .desc = "bamboo", .init = bamboo_init, - .compat_props = (GlobalProperty[]) { - { - .driver = "virtio-serial-pci", - .property = "max_ports", - .value = stringify(1), - },{ - .driver = "virtio-serial-pci", - .property = "vectors", - .value = stringify(0), - }, - { /* end of list */ } - }, }; static void bamboo_machine_init(void) { qemu_register_machine(&bamboo_machine); - qemu_register_machine(&bamboo_machine_v0_12); } machine_init(bamboo_machine_init); diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c index 2c69210225..26de007c0f 100644 --- a/hw/ppc4xx_pci.c +++ b/hw/ppc4xx_pci.c @@ -49,13 +49,14 @@ struct PCITargetMap { #define PPC4xx_PCI_NR_PTMS 2 struct PPC4xxPCIState { + PCIHostState pci_state; + struct PCIMasterMap pmm[PPC4xx_PCI_NR_PMMS]; struct PCITargetMap ptm[PPC4xx_PCI_NR_PTMS]; + qemu_irq irq[4]; - PCIHostState pci_state; - PCIDevice *pci_dev; - MemoryRegion iomem_addr; - MemoryRegion iomem_regs; + MemoryRegion container; + MemoryRegion iomem; }; typedef struct PPC4xxPCIState PPC4xxPCIState; @@ -83,8 +84,10 @@ typedef struct PPC4xxPCIState PPC4xxPCIState; #define PCIL0_PTM1LA 0x34 #define PCIL0_PTM2MS 0x38 #define PCIL0_PTM2LA 0x3c +#define PCI_REG_BASE 0x800000 #define PCI_REG_SIZE 0x40 +#define PCI_ALL_SIZE (PCI_REG_BASE + PCI_REG_SIZE) static uint64_t pci4xx_cfgaddr_read(void *opaque, target_phys_addr_t addr, unsigned size) @@ -275,6 +278,10 @@ static void ppc4xx_pci_set_irq(void *opaque, int irq_num, int level) qemu_irq *pci_irqs = opaque; DPRINTF("%s: PCI irq %d\n", __func__, irq_num); + if (irq_num < 0) { + fprintf(stderr, "%s: PCI irq %d\n", __func__, irq_num); + return; + } qemu_set_irq(pci_irqs[irq_num], level); } @@ -310,7 +317,6 @@ static const VMStateDescription vmstate_ppc4xx_pci = { .minimum_version_id = 1, .minimum_version_id_old = 1, .fields = (VMStateField[]) { - VMSTATE_PCI_DEVICE_POINTER(pci_dev, PPC4xxPCIState), VMSTATE_STRUCT_ARRAY(pmm, PPC4xxPCIState, PPC4xx_PCI_NR_PMMS, 1, vmstate_pci_master_map, struct PCIMasterMap), @@ -322,60 +328,63 @@ static const VMStateDescription vmstate_ppc4xx_pci = { }; /* XXX Interrupt acknowledge cycles not supported. */ -PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4], - target_phys_addr_t config_space, - target_phys_addr_t int_ack, - target_phys_addr_t special_cycle, - target_phys_addr_t registers) +static int ppc4xx_pcihost_initfn(SysBusDevice *dev) +{ + PPC4xxPCIState *s; + PCIHostState *h; + PCIBus *b; + int i; + + h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev)); + s = DO_UPCAST(PPC4xxPCIState, pci_state, h); + + for (i = 0; i < ARRAY_SIZE(s->irq); i++) { + sysbus_init_irq(dev, &s->irq[i]); + } + + b = pci_register_bus(&s->pci_state.busdev.qdev, NULL, ppc4xx_pci_set_irq, + ppc4xx_pci_map_irq, s->irq, get_system_memory(), + get_system_io(), 0, 4); + s->pci_state.bus = b; + + pci_create_simple(b, 0, "ppc4xx-host-bridge"); + + /* XXX split into 2 memory regions, one for config space, one for regs */ + memory_region_init(&s->container, "pci-container", PCI_ALL_SIZE); + memory_region_init_io(&h->conf_mem, &pci_host_conf_le_ops, h, + "pci-conf-idx", 4); + memory_region_init_io(&h->data_mem, &pci_host_data_le_ops, h, + "pci-conf-data", 4); + memory_region_init_io(&s->iomem, &pci_reg_ops, s, + "pci.reg", PCI_REG_SIZE); + memory_region_add_subregion(&s->container, PCIC0_CFGADDR, &h->conf_mem); + memory_region_add_subregion(&s->container, PCIC0_CFGDATA, &h->data_mem); + memory_region_add_subregion(&s->container, PCI_REG_BASE, &s->iomem); + sysbus_init_mmio(dev, &s->container); + qemu_register_reset(ppc4xx_pci_reset, s); + + return 0; +} + +static PCIDeviceInfo ppc4xx_host_bridge_info = { + .qdev.name = "ppc4xx-host-bridge", + .qdev.desc = "Host bridge", + .qdev.size = sizeof(PCIDevice), + .vendor_id = PCI_VENDOR_ID_IBM, + .device_id = PCI_DEVICE_ID_IBM_440GX, + .class_id = PCI_CLASS_BRIDGE_OTHER, +}; + +static SysBusDeviceInfo ppc4xx_pcihost_info = { + .init = ppc4xx_pcihost_initfn, + .qdev.name = "ppc4xx-pcihost", + .qdev.size = sizeof(PPC4xxPCIState), + .qdev.vmsd = &vmstate_ppc4xx_pci, +}; + +static void ppc4xx_pci_register(void) { - PPC4xxPCIState *controller; - static int ppc4xx_pci_id; - uint8_t *pci_conf; - - controller = g_malloc0(sizeof(PPC4xxPCIState)); - - controller->pci_state.bus = pci_register_bus(NULL, "pci", - ppc4xx_pci_set_irq, - ppc4xx_pci_map_irq, - pci_irqs, - get_system_memory(), - get_system_io(), - 0, 4); - - controller->pci_dev = pci_register_device(controller->pci_state.bus, - "host bridge", sizeof(PCIDevice), - 0, NULL, NULL); - pci_conf = controller->pci_dev->config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_IBM); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_IBM_440GX); - pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_OTHER); - - /* CFGADDR */ - memory_region_init_io(&controller->iomem_addr, &pci4xx_cfgaddr_ops, - controller, "pci.cfgaddr", 4); - memory_region_add_subregion(get_system_memory(), - config_space + PCIC0_CFGADDR, - &controller->iomem_addr); - - /* CFGDATA */ - memory_region_init_io(&controller->pci_state.data_mem, - &pci_host_data_be_ops, - &controller->pci_state, "pci-conf-data", 4); - memory_region_add_subregion(get_system_memory(), - config_space + PCIC0_CFGDATA, - &controller->pci_state.data_mem); - - /* Internal registers */ - memory_region_init_io(&controller->iomem_regs, &pci_reg_ops, controller, - "pci.regs", PCI_REG_SIZE); - memory_region_add_subregion(get_system_memory(), registers, - &controller->iomem_regs); - - qemu_register_reset(ppc4xx_pci_reset, controller); - - /* XXX load/save code not tested. */ - vmstate_register(&controller->pci_dev->qdev, ppc4xx_pci_id++, - &vmstate_ppc4xx_pci, controller); - - return controller->pci_state.bus; + sysbus_register_withprop(&ppc4xx_pcihost_info); + pci_qdev_register(&ppc4xx_host_bridge_info); } +device_init(ppc4xx_pci_register); diff --git a/hw/qdev.c b/hw/qdev.c index e59f3455d7..5a7566850a 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -80,6 +80,10 @@ static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name) return NULL; } +bool qdev_exists(const char *name) +{ + return !!qdev_find_info(NULL, name); +} static void qdev_property_add_legacy(DeviceState *dev, Property *prop, Error **errp); diff --git a/hw/qdev.h b/hw/qdev.h index 2abb767389..6b58dd8aeb 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -179,6 +179,7 @@ typedef struct GlobalProperty { DeviceState *qdev_create(BusState *bus, const char *name); DeviceState *qdev_try_create(BusState *bus, const char *name); +bool qdev_exists(const char *name); int qdev_device_help(QemuOpts *opts); DeviceState *qdev_device_add(QemuOpts *opts); int qdev_init(DeviceState *dev) QEMU_WARN_UNUSED_RESULT; diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c index 2210b8ac7e..51123a7535 100644 --- a/hw/s390-virtio.c +++ b/hw/s390-virtio.c @@ -317,7 +317,6 @@ static QEMUMachine s390_machine = { .no_serial = 1, .no_parallel = 1, .use_virtcon = 1, - .no_vga = 1, .max_cpus = 255, .is_default = 1, }; diff --git a/hw/sga.c b/hw/sga.c index 7ef750adf6..ea1193749a 100644 --- a/hw/sga.c +++ b/hw/sga.c @@ -35,7 +35,7 @@ typedef struct ISAGAState { ISADevice dev; } ISASGAState; -static int isa_cirrus_vga_initfn(ISADevice *dev) +static int sga_initfn(ISADevice *dev) { rom_add_vga(SGABIOS_FILENAME); return 0; @@ -45,7 +45,7 @@ static ISADeviceInfo sga_info = { .qdev.name = "sga", .qdev.desc = "Serial Graphics Adapter", .qdev.size = sizeof(ISASGAState), - .init = isa_cirrus_vga_initfn, + .init = sga_initfn, }; static void sga_register(void) diff --git a/hw/spapr.c b/hw/spapr.c index 0e1f80dfdc..dffb6a2a50 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -50,19 +50,29 @@ #include <libfdt.h> -#define KERNEL_LOAD_ADDR 0x00000000 -#define INITRD_LOAD_ADDR 0x02800000 +/* SLOF memory layout: + * + * SLOF raw image loaded at 0, copies its romfs right below the flat + * device-tree, then position SLOF itself 31M below that + * + * So we set FW_OVERHEAD to 40MB which should account for all of that + * and more + * + * We load our kernel at 4M, leaving space for SLOF initial image + */ #define FDT_MAX_SIZE 0x10000 #define RTAS_MAX_SIZE 0x10000 #define FW_MAX_SIZE 0x400000 #define FW_FILE_NAME "slof.bin" +#define FW_OVERHEAD 0x2800000 +#define KERNEL_LOAD_ADDR FW_MAX_SIZE -#define MIN_RMA_SLOF 128UL +#define MIN_RMA_SLOF 128UL #define TIMEBASE_FREQ 512000000ULL #define MAX_CPUS 256 -#define XICS_IRQS 1024 +#define XICS_IRQS 1024 #define SPAPR_PCI_BUID 0x800000020000001ULL #define SPAPR_PCI_MEM_WIN_ADDR (0x10000000000ULL + 0xA0000000) @@ -139,6 +149,7 @@ static void *spapr_create_fdt_skel(const char *cpu_model, target_phys_addr_t rma_size, target_phys_addr_t initrd_base, target_phys_addr_t initrd_size, + target_phys_addr_t kernel_size, const char *boot_device, const char *kernel_cmdline, long hash_shift) @@ -176,6 +187,12 @@ static void *spapr_create_fdt_skel(const char *cpu_model, fdt = g_malloc0(FDT_MAX_SIZE); _FDT((fdt_create(fdt, FDT_MAX_SIZE))); + if (kernel_size) { + _FDT((fdt_add_reservemap_entry(fdt, KERNEL_LOAD_ADDR, kernel_size))); + } + if (initrd_size) { + _FDT((fdt_add_reservemap_entry(fdt, initrd_base, initrd_size))); + } _FDT((fdt_finish_reservemap(fdt))); /* Root node */ @@ -197,15 +214,13 @@ static void *spapr_create_fdt_skel(const char *cpu_model, &start_prop, sizeof(start_prop)))); _FDT((fdt_property(fdt, "linux,initrd-end", &end_prop, sizeof(end_prop)))); - _FDT((fdt_property_string(fdt, "qemu,boot-device", boot_device))); + if (kernel_size) { + uint64_t kprop[2] = { cpu_to_be64(KERNEL_LOAD_ADDR), + cpu_to_be64(kernel_size) }; - /* - * Because we don't always invoke any firmware, we can't rely on - * that to do BAR allocation. Long term, we should probably do - * that ourselves, but for now, this setting (plus advertising the - * current BARs as 0) causes sufficiently recent kernels to to the - * BAR assignment themselves */ - _FDT((fdt_property_cell(fdt, "linux,pci-probe-only", 0))); + _FDT((fdt_property(fdt, "qemu,boot-kernel", &kprop, sizeof(kprop)))); + } + _FDT((fdt_property_string(fdt, "qemu,boot-device", boot_device))); _FDT((fdt_end_node(fdt))); @@ -445,6 +460,12 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr, _FDT((fdt_pack(fdt))); + if (fdt_totalsize(fdt) > FDT_MAX_SIZE) { + hw_error("FDT too big ! 0x%x bytes (max is 0x%x)\n", + fdt_totalsize(fdt), FDT_MAX_SIZE); + exit(1); + } + cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt)); g_free(fdt); @@ -494,8 +515,9 @@ static void ppc_spapr_init(ram_addr_t ram_size, MemoryRegion *sysmem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); target_phys_addr_t rma_alloc_size, rma_size; - uint32_t initrd_base; - long kernel_size, initrd_size, fw_size; + uint32_t initrd_base = 0; + long kernel_size = 0, initrd_size = 0; + long load_limit, rtas_limit, fw_size; long pteg_shift = 17; char *filename; @@ -517,11 +539,13 @@ static void ppc_spapr_init(ram_addr_t ram_size, rma_size = ram_size; } - /* We place the device tree just below either the top of the RMA, + /* We place the device tree and RTAS just below either the top of the RMA, * or just below 2GB, whichever is lowere, so that it can be * processed with 32-bit real mode code if necessary */ - spapr->fdt_addr = MIN(rma_size, 0x80000000) - FDT_MAX_SIZE; - spapr->rtas_addr = spapr->fdt_addr - RTAS_MAX_SIZE; + rtas_limit = MIN(rma_size, 0x80000000); + spapr->rtas_addr = rtas_limit - RTAS_MAX_SIZE; + spapr->fdt_addr = spapr->rtas_addr - FDT_MAX_SIZE; + load_limit = spapr->fdt_addr - FW_OVERHEAD; /* init CPUs */ if (cpu_model == NULL) { @@ -577,13 +601,19 @@ static void ppc_spapr_init(ram_addr_t ram_size, filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin"); spapr->rtas_size = load_image_targphys(filename, spapr->rtas_addr, - ram_size - spapr->rtas_addr); + rtas_limit - spapr->rtas_addr); if (spapr->rtas_size < 0) { hw_error("qemu: could not load LPAR rtas '%s'\n", filename); exit(1); } + if (spapr->rtas_size > RTAS_MAX_SIZE) { + hw_error("RTAS too big ! 0x%lx bytes (max is 0x%x)\n", + spapr->rtas_size, RTAS_MAX_SIZE); + exit(1); + } g_free(filename); + /* Set up Interrupt Controller */ spapr->icp = xics_system_init(XICS_IRQS); spapr->next_irq = 16; @@ -622,6 +652,20 @@ static void ppc_spapr_init(ram_addr_t ram_size, spapr_vscsi_create(spapr->vio_bus, 0x2000 + i); } + if (rma_size < (MIN_RMA_SLOF << 20)) { + fprintf(stderr, "qemu: pSeries SLOF firmware requires >= " + "%ldM guest RMA (Real Mode Area memory)\n", MIN_RMA_SLOF); + exit(1); + } + + fprintf(stderr, "sPAPR memory map:\n"); + fprintf(stderr, "RTAS : 0x%08lx..%08lx\n", + (unsigned long)spapr->rtas_addr, + (unsigned long)(spapr->rtas_addr + spapr->rtas_size - 1)); + fprintf(stderr, "FDT : 0x%08lx..%08lx\n", + (unsigned long)spapr->fdt_addr, + (unsigned long)(spapr->fdt_addr + FDT_MAX_SIZE - 1)); + if (kernel_filename) { uint64_t lowaddr = 0; @@ -630,57 +674,60 @@ static void ppc_spapr_init(ram_addr_t ram_size, if (kernel_size < 0) { kernel_size = load_image_targphys(kernel_filename, KERNEL_LOAD_ADDR, - ram_size - KERNEL_LOAD_ADDR); + load_limit - KERNEL_LOAD_ADDR); } if (kernel_size < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } + fprintf(stderr, "Kernel : 0x%08x..%08lx\n", + KERNEL_LOAD_ADDR, KERNEL_LOAD_ADDR + kernel_size - 1); /* load initrd */ if (initrd_filename) { - initrd_base = INITRD_LOAD_ADDR; + /* Try to locate the initrd in the gap between the kernel + * and the firmware. Add a bit of space just in case + */ + initrd_base = (KERNEL_LOAD_ADDR + kernel_size + 0x1ffff) & ~0xffff; initrd_size = load_image_targphys(initrd_filename, initrd_base, - ram_size - initrd_base); + load_limit - initrd_base); if (initrd_size < 0) { fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", initrd_filename); exit(1); } + fprintf(stderr, "Ramdisk : 0x%08lx..%08lx\n", + (long)initrd_base, (long)(initrd_base + initrd_size - 1)); } else { initrd_base = 0; initrd_size = 0; } + } - spapr->entry_point = KERNEL_LOAD_ADDR; - } else { - if (rma_size < (MIN_RMA_SLOF << 20)) { - fprintf(stderr, "qemu: pSeries SLOF firmware requires >= " - "%ldM guest RMA (Real Mode Area memory)\n", MIN_RMA_SLOF); - exit(1); - } - filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, FW_FILE_NAME); - fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE); - if (fw_size < 0) { - hw_error("qemu: could not load LPAR rtas '%s'\n", filename); - exit(1); - } - g_free(filename); - spapr->entry_point = 0x100; - initrd_base = 0; - initrd_size = 0; - - /* SLOF will startup the secondary CPUs using RTAS, - rather than expecting a kexec() style entry */ - for (env = first_cpu; env != NULL; env = env->next_cpu) { - env->halted = 1; - } + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, FW_FILE_NAME); + fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE); + if (fw_size < 0) { + hw_error("qemu: could not load LPAR rtas '%s'\n", filename); + exit(1); + } + g_free(filename); + fprintf(stderr, "Firmware load : 0x%08x..%08lx\n", + 0, fw_size); + fprintf(stderr, "Firmware runtime : 0x%08lx..%08lx\n", + load_limit, (unsigned long)spapr->fdt_addr); + + spapr->entry_point = 0x100; + + /* SLOF will startup the secondary CPUs using RTAS */ + for (env = first_cpu; env != NULL; env = env->next_cpu) { + env->halted = 1; } /* Prepare the device tree */ spapr->fdt_skel = spapr_create_fdt_skel(cpu_model, rma_size, initrd_base, initrd_size, + kernel_size, boot_device, kernel_cmdline, pteg_shift + 7); assert(spapr->fdt_skel != NULL); @@ -693,7 +740,6 @@ static QEMUMachine spapr_machine = { .desc = "pSeries Logical Partition (PAPR compliant)", .init = ppc_spapr_init, .max_cpus = MAX_CPUS, - .no_vga = 1, .no_parallel = 1, .use_scsi = 1, }; diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index 9b6a032cce..2c95faa8c1 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -62,6 +62,30 @@ static PCIDevice *find_dev(sPAPREnvironment *spapr, return NULL; } +static uint32_t rtas_pci_cfgaddr(uint32_t arg) +{ + return ((arg >> 20) & 0xf00) | (arg & 0xff); +} + +static uint32_t rtas_read_pci_config_do(PCIDevice *pci_dev, uint32_t addr, + uint32_t limit, uint32_t len) +{ + if ((addr + len) <= limit) { + return pci_host_config_read_common(pci_dev, addr, limit, len); + } else { + return ~0x0; + } +} + +static void rtas_write_pci_config_do(PCIDevice *pci_dev, uint32_t addr, + uint32_t limit, uint32_t val, + uint32_t len) +{ + if ((addr + len) <= limit) { + pci_host_config_write_common(pci_dev, addr, limit, val, len); + } +} + static void rtas_ibm_read_pci_config(sPAPREnvironment *spapr, uint32_t token, uint32_t nargs, target_ulong args, @@ -76,8 +100,8 @@ static void rtas_ibm_read_pci_config(sPAPREnvironment *spapr, return; } size = rtas_ld(args, 3); - addr = rtas_ld(args, 0) & 0xFF; - val = pci_default_read_config(dev, addr, size); + addr = rtas_pci_cfgaddr(rtas_ld(args, 0)); + val = rtas_read_pci_config_do(dev, addr, pci_config_size(dev), size); rtas_st(rets, 0, 0); rtas_st(rets, 1, val); } @@ -95,8 +119,8 @@ static void rtas_read_pci_config(sPAPREnvironment *spapr, return; } size = rtas_ld(args, 1); - addr = rtas_ld(args, 0) & 0xFF; - val = pci_default_read_config(dev, addr, size); + addr = rtas_pci_cfgaddr(rtas_ld(args, 0)); + val = rtas_read_pci_config_do(dev, addr, pci_config_size(dev), size); rtas_st(rets, 0, 0); rtas_st(rets, 1, val); } @@ -116,8 +140,8 @@ static void rtas_ibm_write_pci_config(sPAPREnvironment *spapr, } val = rtas_ld(args, 4); size = rtas_ld(args, 3); - addr = rtas_ld(args, 0) & 0xFF; - pci_default_write_config(dev, addr, val, size); + addr = rtas_pci_cfgaddr(rtas_ld(args, 0)); + rtas_write_pci_config_do(dev, addr, pci_config_size(dev), val, size); rtas_st(rets, 0, 0); } @@ -135,8 +159,8 @@ static void rtas_write_pci_config(sPAPREnvironment *spapr, } val = rtas_ld(args, 2); size = rtas_ld(args, 1); - addr = rtas_ld(args, 0) & 0xFF; - pci_default_write_config(dev, addr, val, size); + addr = rtas_pci_cfgaddr(rtas_ld(args, 0)); + rtas_write_pci_config_do(dev, addr, pci_config_size(dev), val, size); rtas_st(rets, 0, 0); } @@ -319,31 +343,13 @@ void spapr_create_phb(sPAPREnvironment *spapr, #define b_fff(x) b_x((x), 8, 3) /* function number */ #define b_rrrrrrrr(x) b_x((x), 0, 8) /* register number */ -static uint32_t regtype_to_ss(uint8_t type) -{ - if (type & PCI_BASE_ADDRESS_MEM_TYPE_64) { - return 3; - } - if (type == PCI_BASE_ADDRESS_SPACE_IO) { - return 1; - } - return 2; -} - int spapr_populate_pci_devices(sPAPRPHBState *phb, uint32_t xics_phandle, void *fdt) { PCIBus *bus = phb->host_state.bus; - int bus_off, node_off = 0, devid, fn, i, n, devices; - DeviceState *qdev; + int bus_off, i; char nodename[256]; - struct { - uint32_t hi; - uint64_t addr; - uint64_t size; - } __attribute__((packed)) reg[PCI_NUM_REGIONS + 1], - assigned_addresses[PCI_NUM_REGIONS]; uint32_t bus_range[] = { cpu_to_be32(0), cpu_to_be32(0xff) }; struct { uint32_t hi; @@ -364,7 +370,7 @@ int spapr_populate_pci_devices(sPAPRPHBState *phb, }; uint64_t bus_reg[] = { cpu_to_be64(phb->buid), 0 }; uint32_t interrupt_map_mask[] = { - cpu_to_be32(b_ddddd(-1)|b_fff(-1)), 0x0, 0x0, 0x0}; + cpu_to_be32(b_ddddd(-1)|b_fff(0)), 0x0, 0x0, 0x0}; uint32_t interrupt_map[bus->nirq][7]; /* Start populating the FDT */ @@ -392,117 +398,26 @@ int spapr_populate_pci_devices(sPAPRPHBState *phb, _FDT(fdt_setprop(fdt, bus_off, "bus-range", &bus_range, sizeof(bus_range))); _FDT(fdt_setprop(fdt, bus_off, "ranges", &ranges, sizeof(ranges))); _FDT(fdt_setprop(fdt, bus_off, "reg", &bus_reg, sizeof(bus_reg))); + _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pci-config-space-type", 0x1)); + + /* Build the interrupt-map, this must matches what is done + * in pci_spapr_map_irq + */ _FDT(fdt_setprop(fdt, bus_off, "interrupt-map-mask", &interrupt_map_mask, sizeof(interrupt_map_mask))); - - /* Populate PCI devices and allocate IRQs */ - devices = 0; - QTAILQ_FOREACH(qdev, &bus->qbus.children, sibling) { - PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, qdev); - int irq_index = pci_spapr_map_irq(dev, 0); - uint32_t *irqmap = interrupt_map[devices]; - uint8_t *config = dev->config; - - devid = dev->devfn >> 3; - fn = dev->devfn & 7; - - sprintf(nodename, "pci@%u,%u", devid, fn); - - /* Allocate interrupt from the map */ - if (devid > bus->nirq) { - printf("Unexpected behaviour in spapr_populate_pci_devices," - "wrong devid %u\n", devid); - exit(-1); - } - irqmap[0] = cpu_to_be32(b_ddddd(devid)|b_fff(fn)); + for (i = 0; i < 7; i++) { + uint32_t *irqmap = interrupt_map[i]; + irqmap[0] = cpu_to_be32(b_ddddd(i)|b_fff(0)); irqmap[1] = 0; irqmap[2] = 0; irqmap[3] = 0; irqmap[4] = cpu_to_be32(xics_phandle); - irqmap[5] = cpu_to_be32(phb->lsi_table[irq_index].dt_irq); + irqmap[5] = cpu_to_be32(phb->lsi_table[i % SPAPR_PCI_NUM_LSI].dt_irq); irqmap[6] = cpu_to_be32(0x8); - - /* Add node to FDT */ - node_off = fdt_add_subnode(fdt, bus_off, nodename); - if (node_off < 0) { - return node_off; - } - - _FDT(fdt_setprop_cell(fdt, node_off, "vendor-id", - pci_get_word(&config[PCI_VENDOR_ID]))); - _FDT(fdt_setprop_cell(fdt, node_off, "device-id", - pci_get_word(&config[PCI_DEVICE_ID]))); - _FDT(fdt_setprop_cell(fdt, node_off, "revision-id", - pci_get_byte(&config[PCI_REVISION_ID]))); - _FDT(fdt_setprop_cell(fdt, node_off, "class-code", - pci_get_long(&config[PCI_CLASS_REVISION]) >> 8)); - _FDT(fdt_setprop_cell(fdt, node_off, "subsystem-id", - pci_get_word(&config[PCI_SUBSYSTEM_ID]))); - _FDT(fdt_setprop_cell(fdt, node_off, "subsystem-vendor-id", - pci_get_word(&config[PCI_SUBSYSTEM_VENDOR_ID]))); - - /* Config space region comes first */ - reg[0].hi = cpu_to_be32( - b_n(0) | - b_p(0) | - b_t(0) | - b_ss(0/*config*/) | - b_bbbbbbbb(0) | - b_ddddd(devid) | - b_fff(fn)); - reg[0].addr = 0; - reg[0].size = 0; - - n = 0; - for (i = 0; i < ARRAY_SIZE(bars); ++i) { - if (0 == dev->io_regions[i].size) { - continue; - } - - reg[n+1].hi = cpu_to_be32( - b_n(0) | - b_p(0) | - b_t(0) | - b_ss(regtype_to_ss(dev->io_regions[i].type)) | - b_bbbbbbbb(0) | - b_ddddd(devid) | - b_fff(fn) | - b_rrrrrrrr(bars[i])); - reg[n+1].addr = 0; - reg[n+1].size = cpu_to_be64(dev->io_regions[i].size); - - assigned_addresses[n].hi = cpu_to_be32( - b_n(1) | - b_p(0) | - b_t(0) | - b_ss(regtype_to_ss(dev->io_regions[i].type)) | - b_bbbbbbbb(0) | - b_ddddd(devid) | - b_fff(fn) | - b_rrrrrrrr(bars[i])); - - /* - * Writing zeroes to assigned_addresses causes the guest kernel to - * reassign BARs - */ - assigned_addresses[n].addr = cpu_to_be64(dev->io_regions[i].addr); - assigned_addresses[n].size = reg[n+1].size; - - ++n; - } - _FDT(fdt_setprop(fdt, node_off, "reg", reg, sizeof(reg[0])*(n+1))); - _FDT(fdt_setprop(fdt, node_off, "assigned-addresses", - assigned_addresses, - sizeof(assigned_addresses[0])*(n))); - _FDT(fdt_setprop_cell(fdt, node_off, "interrupts", - pci_get_byte(&config[PCI_INTERRUPT_PIN]))); - - ++devices; } - /* Write interrupt map */ _FDT(fdt_setprop(fdt, bus_off, "interrupt-map", &interrupt_map, - devices * sizeof(interrupt_map[0]))); + 7 * sizeof(interrupt_map[0]))); return 0; } diff --git a/hw/virtex_ml507.c b/hw/virtex_ml507.c index bd16b97934..f8d2b1be04 100644 --- a/hw/virtex_ml507.c +++ b/hw/virtex_ml507.c @@ -38,7 +38,6 @@ #include "ppc.h" #include "ppc4xx.h" -#include "ppc440.h" #include "ppc405.h" #include "blockdev.h" diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index caff0aa2eb..c93889a2ab 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -91,6 +91,9 @@ */ #define wmb() do { } while (0) +/* HACK for virtio to determine if it's running a big endian guest */ +bool virtio_is_big_endian(void); + /* virtio device */ static void virtio_pci_notify(void *opaque, uint16_t vector) @@ -414,20 +417,35 @@ static uint32_t virtio_pci_config_readw(void *opaque, uint32_t addr) { VirtIOPCIProxy *proxy = opaque; uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); + uint16_t val; if (addr < config) return virtio_ioport_read(proxy, addr); addr -= config; - return virtio_config_readw(proxy->vdev, addr); + val = virtio_config_readw(proxy->vdev, addr); + if (virtio_is_big_endian()) { + /* + * virtio is odd, ioports are LE but config space is target native + * endian. However, in qemu, all PIO is LE, so we need to re-swap + * on BE targets + */ + val = bswap16(val); + } + return val; } static uint32_t virtio_pci_config_readl(void *opaque, uint32_t addr) { VirtIOPCIProxy *proxy = opaque; uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); + uint32_t val; if (addr < config) return virtio_ioport_read(proxy, addr); addr -= config; - return virtio_config_readl(proxy->vdev, addr); + val = virtio_config_readl(proxy->vdev, addr); + if (virtio_is_big_endian()) { + val = bswap32(val); + } + return val; } static void virtio_pci_config_writeb(void *opaque, uint32_t addr, uint32_t val) @@ -451,6 +469,9 @@ static void virtio_pci_config_writew(void *opaque, uint32_t addr, uint32_t val) return; } addr -= config; + if (virtio_is_big_endian()) { + val = bswap16(val); + } virtio_config_writew(proxy->vdev, addr, val); } @@ -463,6 +484,9 @@ static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val) return; } addr -= config; + if (virtio_is_big_endian()) { + val = bswap32(val); + } virtio_config_writel(proxy->vdev, addr, val); } diff --git a/hw/virtio.c b/hw/virtio.c index 81ecc40b31..74cc038af9 100644 --- a/hw/virtio.c +++ b/hw/virtio.c @@ -539,7 +539,7 @@ uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr) if (addr > (vdev->config_len - sizeof(val))) return (uint32_t)-1; - memcpy(&val, vdev->config + addr, sizeof(val)); + val = ldub_p(vdev->config + addr); return val; } @@ -552,7 +552,7 @@ uint32_t virtio_config_readw(VirtIODevice *vdev, uint32_t addr) if (addr > (vdev->config_len - sizeof(val))) return (uint32_t)-1; - memcpy(&val, vdev->config + addr, sizeof(val)); + val = lduw_p(vdev->config + addr); return val; } @@ -565,7 +565,7 @@ uint32_t virtio_config_readl(VirtIODevice *vdev, uint32_t addr) if (addr > (vdev->config_len - sizeof(val))) return (uint32_t)-1; - memcpy(&val, vdev->config + addr, sizeof(val)); + val = ldl_p(vdev->config + addr); return val; } @@ -576,7 +576,7 @@ void virtio_config_writeb(VirtIODevice *vdev, uint32_t addr, uint32_t data) if (addr > (vdev->config_len - sizeof(val))) return; - memcpy(vdev->config + addr, &val, sizeof(val)); + stb_p(vdev->config + addr, val); if (vdev->set_config) vdev->set_config(vdev, vdev->config); @@ -589,7 +589,7 @@ void virtio_config_writew(VirtIODevice *vdev, uint32_t addr, uint32_t data) if (addr > (vdev->config_len - sizeof(val))) return; - memcpy(vdev->config + addr, &val, sizeof(val)); + stw_p(vdev->config + addr, val); if (vdev->set_config) vdev->set_config(vdev, vdev->config); @@ -602,7 +602,7 @@ void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data) if (addr > (vdev->config_len - sizeof(val))) return; - memcpy(vdev->config + addr, &val, sizeof(val)); + stl_p(vdev->config + addr, val); if (vdev->set_config) vdev->set_config(vdev, vdev->config); diff --git a/hw/vmware_vga.h b/hw/vmware_vga.h index db11cbfac8..000fbddc0f 100644 --- a/hw/vmware_vga.h +++ b/hw/vmware_vga.h @@ -8,12 +8,8 @@ static inline DeviceState *pci_vmsvga_init(PCIBus *bus) { PCIDevice *dev; - dev = pci_try_create(bus, -1, "vmware-svga"); - if (!dev || qdev_init(&dev->qdev) < 0) { - return NULL; - } else { - return &dev->qdev; - } + dev = pci_create_simple(bus, -1, "vmware-svga"); + return &dev->qdev; } #endif diff --git a/kvm-all.c b/kvm-all.c index 2cc4562921..9e84d35e94 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -344,7 +344,8 @@ static int kvm_get_dirty_pages_log_range(MemoryRegionSection *section, unsigned long *bitmap) { unsigned int i, j; - unsigned long page_number, addr, addr1, c; + unsigned long page_number, c; + target_phys_addr_t addr, addr1; unsigned int len = ((section->size / TARGET_PAGE_SIZE) + HOST_LONG_BITS - 1) / HOST_LONG_BITS; /* diff --git a/pc-bios/README b/pc-bios/README index 1cebbbc89a..5dce355f56 100644 --- a/pc-bios/README +++ b/pc-bios/README @@ -17,7 +17,7 @@ - SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware implementation for certain IBM POWER hardware. The sources are at https://github.com/dgibson/SLOF, and the image currently in qemu is - built from git tag qemu-slof-20111013. + built from git tag qemu-slof-20120111.1. - sgabios (the Serial Graphics Adapter option ROM) provides a means for legacy x86 software to communicate with an attached serial console as diff --git a/pc-bios/bamboo.dtb b/pc-bios/bamboo.dtb index c78e2544c0..d12e201aa0 100644 --- a/pc-bios/bamboo.dtb +++ b/pc-bios/bamboo.dtb Binary files differdiff --git a/pc-bios/bamboo.dts b/pc-bios/bamboo.dts index 655442ca69..62fabcca68 100644 --- a/pc-bios/bamboo.dts +++ b/pc-bios/bamboo.dts @@ -9,12 +9,14 @@ * any warranty of any kind, whether express or implied. */ +/dts-v1/; + / { #address-cells = <2>; #size-cells = <1>; model = "amcc,bamboo"; compatible = "amcc,bamboo"; - dcr-parent = <&/cpus/cpu@0>; + dcr-parent = <&{/cpus/cpu@0}>; aliases { serial0 = &UART0; @@ -29,12 +31,12 @@ device_type = "cpu"; model = "PowerPC,440EP"; reg = <0>; - clock-frequency = <1fca0550>; - timebase-frequency = <017d7840>; - i-cache-line-size = <20>; - d-cache-line-size = <20>; - i-cache-size = <8000>; - d-cache-size = <8000>; + clock-frequency = <0x1fca0550>; + timebase-frequency = <0x017d7840>; + i-cache-line-size = <0x20>; + d-cache-line-size = <0x20>; + i-cache-size = <0x8000>; + d-cache-size = <0x8000>; dcr-controller; dcr-access-method = "native"; }; @@ -42,40 +44,27 @@ memory { device_type = "memory"; - reg = <0 0 9000000>; + reg = <0x0 0x0 0x9000000>; }; UIC0: interrupt-controller0 { compatible = "ibm,uic-440ep","ibm,uic"; interrupt-controller; - cell-index = <0>; - dcr-reg = <0c0 009>; - #address-cells = <0>; - #size-cells = <0>; - #interrupt-cells = <2>; - }; -/* - UIC1: interrupt-controller1 { - compatible = "ibm,uic-440ep","ibm,uic"; - interrupt-controller; - cell-index = <1>; - dcr-reg = <0d0 009>; - #address-cells = <0>; - #size-cells = <0>; - #interrupt-cells = <2>; - interrupts = <1e 4 1f 4>; - interrupt-parent = <&UIC0>; + cell-index = <0x0>; + dcr-reg = <0x0c0 0x009>; + #address-cells = <0x0>; + #size-cells = <0x0>; + #interrupt-cells = <0x2>; }; -*/ SDR0: sdr { compatible = "ibm,sdr-440ep"; - dcr-reg = <00e 002>; + dcr-reg = <0x00e 0x002>; }; CPR0: cpr { compatible = "ibm,cpr-440ep"; - dcr-reg = <00c 002>; + dcr-reg = <0x00c 0x002>; }; plb { @@ -83,16 +72,16 @@ #address-cells = <2>; #size-cells = <1>; ranges; - clock-frequency = <07f28154>; + clock-frequency = <0x07f28154>; SDRAM0: sdram { compatible = "ibm,sdram-440ep", "ibm,sdram-405gp"; - dcr-reg = <010 2>; + dcr-reg = <0x010 0x2>; }; DMA0: dma { compatible = "ibm,dma-440ep", "ibm,dma-440gp"; - dcr-reg = <100 027>; + dcr-reg = <0x100 0x027>; }; POB0: opb { @@ -102,18 +91,18 @@ /* Bamboo is oddball in the 44x world and doesn't use the ERPN * bits. */ - ranges = <00000000 0 00000000 80000000 - 80000000 0 80000000 80000000>; + ranges = <0x00000000 0x0 0x00000000 0x80000000 + 0x80000000 0x0 0x80000000 0x80000000>; /* interrupt-parent = <&UIC1>; */ interrupts = <7 4>; - clock-frequency = <03f940aa>; + clock-frequency = <0x03f940aa>; EBC0: ebc { compatible = "ibm,ebc-440ep", "ibm,ebc-440gp", "ibm,ebc"; - dcr-reg = <012 2>; + dcr-reg = <0x012 2>; #address-cells = <2>; #size-cells = <1>; - clock-frequency = <03f940aa>; + clock-frequency = <0x03f940aa>; interrupts = <5 1>; /* interrupt-parent = <&UIC1>; */ }; @@ -121,10 +110,10 @@ UART0: serial@ef600300 { device_type = "serial"; compatible = "ns16550"; - reg = <ef600300 8>; - virtual-reg = <ef600300>; - clock-frequency = <00a8c000>; - current-speed = <1c200>; + reg = <0xef600300 8>; + virtual-reg = <0xef600300>; + clock-frequency = <0x00a8c000>; + current-speed = <0x1c200>; interrupt-parent = <&UIC0>; interrupts = <0 4>; }; @@ -132,41 +121,18 @@ UART1: serial@ef600400 { device_type = "serial"; compatible = "ns16550"; - reg = <ef600400 8>; - virtual-reg = <ef600400>; - clock-frequency = <00a8c000>; + reg = <0xef600400 8>; + virtual-reg = <0xef600400>; + clock-frequency = <0x00a8c000>; current-speed = <0>; interrupt-parent = <&UIC0>; interrupts = <1 4>; }; -/* - UART2: serial@ef600500 { - device_type = "serial"; - compatible = "ns16550"; - reg = <ef600500 8>; - virtual-reg = <ef600500>; - clock-frequency = <0>; - current-speed = <0>; - interrupt-parent = <&UIC0>; - interrupts = <3 4>; - }; - - UART3: serial@ef600600 { - device_type = "serial"; - compatible = "ns16550"; - reg = <ef600600 8>; - virtual-reg = <ef600600>; - clock-frequency = <0>; - current-speed = <0>; - interrupt-parent = <&UIC0>; - interrupts = <4 4>; - }; -*/ IIC0: i2c@ef600700 { device_type = "i2c"; compatible = "ibm,iic-440ep", "ibm,iic-440gp", "ibm,iic"; - reg = <ef600700 14>; + reg = <0xef600700 0x14>; interrupt-parent = <&UIC0>; interrupts = <2 4>; }; @@ -174,7 +140,7 @@ IIC1: i2c@ef600800 { device_type = "i2c"; compatible = "ibm,iic-440ep", "ibm,iic-440gp", "ibm,iic"; - reg = <ef600800 14>; + reg = <0xef600800 14>; interrupt-parent = <&UIC0>; interrupts = <7 4>; }; @@ -182,7 +148,7 @@ ZMII0: emac-zmii@ef600d00 { device_type = "zmii-interface"; compatible = "ibm,zmii-440ep", "ibm,zmii-440gp", "ibm,zmii"; - reg = <ef600d00 c>; + reg = <0xef600d00 0xc>; }; }; @@ -194,35 +160,35 @@ #address-cells = <3>; compatible = "ibm,plb440ep-pci", "ibm,plb-pci"; primary; - reg = <0 eec00000 8 /* Config space access */ - 0 eed00000 4 /* IACK */ - 0 eed00000 4 /* Special cycle */ - 0 ef400000 40>; /* Internal registers */ + reg = <0 0xeec00000 8 /* Config space access */ + 0 0xeed00000 4 /* IACK */ + 0 0xeed00000 4 /* Special cycle */ + 0 0xef400000 0x40>; /* Internal registers */ /* Outbound ranges, one memory and one IO, * later cannot be changed. Chip supports a second * IO range but we don't use it for now */ - ranges = <02000000 0 a0000000 0 a0000000 0 20000000 - 01000000 0 00000000 0 e8000000 0 00010000>; + ranges = <0x02000000 0 0xa0000000 0 0xa0000000 0 0x20000000 + 0x01000000 0 0x00000000 0 0xe8000000 0 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0 0 0 0 0 0x80000000>; /* Bamboo has all 4 IRQ pins tied together per slot */ - interrupt-map-mask = <f800 0 0 0>; + interrupt-map-mask = <0xf800 0 0 0>; interrupt-map = < /* IDSEL 1 */ - 0800 0 0 0 &UIC0 1c 8 + 0x0800 0 0 0 &UIC0 0x1c 8 /* IDSEL 2 */ - 1000 0 0 0 &UIC0 1b 8 + 0x1000 0 0 0 &UIC0 0x1b 8 /* IDSEL 3 */ - 1800 0 0 0 &UIC0 1a 8 + 0x1800 0 0 0 &UIC0 0x1a 8 /* IDSEL 4 */ - 2000 0 0 0 &UIC0 19 8 + 0x2000 0 0 0 &UIC0 0x19 8 >; }; diff --git a/pc-bios/slof.bin b/pc-bios/slof.bin index 1e84582cc6..8554f54b57 100644 --- a/pc-bios/slof.bin +++ b/pc-bios/slof.bin Binary files differdiff --git a/roms/SLOF b/roms/SLOF -Subproject 32e3430c018ceb8413cb808477449d1968c4249 +Subproject ab062ff3b37c39649f2b0d94ed607adc6f6b3c7 diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 47d73a6bf9..4d692d0dd3 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -3516,6 +3516,9 @@ static void init_proc_405 (CPUPPCState *env) /* PowerPC 440 EP */ #define POWERPC_INSNS_440EP (PPC_INSNS_BASE | PPC_STRING | \ + PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL | \ + PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | \ + PPC_FLOAT_STFIWX | \ PPC_DCR | PPC_WRTEE | PPC_RFMCI | \ PPC_CACHE | PPC_CACHE_ICBI | \ PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \ @@ -3523,7 +3526,7 @@ static void init_proc_405 (CPUPPCState *env) PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | \ PPC_440_SPEC) #define POWERPC_INSNS2_440EP (PPC_NONE) -#define POWERPC_MSRM_440EP (0x000000000006D630ULL) +#define POWERPC_MSRM_440EP (0x000000000006FF30ULL) #define POWERPC_MMU_440EP (POWERPC_MMU_BOOKE) #define POWERPC_EXCP_440EP (POWERPC_EXCP_BOOKE) #define POWERPC_INPUT_440EP (PPC_FLAGS_INPUT_BookE) @@ -3532,7 +3535,6 @@ static void init_proc_405 (CPUPPCState *env) POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK) #define check_pow_440EP check_pow_nocheck -__attribute__ (( unused )) static void init_proc_440EP (CPUPPCState *env) { /* Time base */ @@ -3593,7 +3595,7 @@ static void init_proc_440EP (CPUPPCState *env) init_excp_BookE(env); env->dcache_line_size = 32; env->icache_line_size = 32; - /* XXX: TODO: allocate internal IRQ controller */ + ppc40x_irq_init(env); SET_FIT_PERIOD(12, 16, 20, 24); SET_WDT_PERIOD(20, 24, 28, 32); @@ -7869,22 +7871,14 @@ static const ppc_def_t ppc_defs[] = { POWERPC_DEF("440H6", CPU_POWERPC_440H6, 440Gx5), #endif /* PowerPC 440 microcontrolers */ -#if defined(TODO_USER_ONLY) /* PowerPC 440 EP */ POWERPC_DEF("440EP", CPU_POWERPC_440EP, 440EP), -#endif -#if defined(TODO_USER_ONLY) /* PowerPC 440 EPa */ POWERPC_DEF("440EPa", CPU_POWERPC_440EPa, 440EP), -#endif -#if defined(TODO_USER_ONLY) /* PowerPC 440 EPb */ POWERPC_DEF("440EPb", CPU_POWERPC_440EPb, 440EP), -#endif -#if defined(TODO_USER_ONLY) /* PowerPC 440 EPX */ POWERPC_DEF("440EPX", CPU_POWERPC_440EPX, 440EP), -#endif #if defined(TODO_USER_ONLY) /* PowerPC 440 GP */ POWERPC_DEF("440GP", CPU_POWERPC_440GP, 440GP), diff --git a/target-sparc/vis_helper.c b/target-sparc/vis_helper.c index a992c293af..9d2edb09bd 100644 --- a/target-sparc/vis_helper.c +++ b/target-sparc/vis_helper.c @@ -459,7 +459,7 @@ uint32_t helper_fpackfix(uint64_t gsr, uint64_t rs2) return ret; } -uint64 helper_bshuffle(uint64_t gsr, uint64_t src1, uint64_t src2) +uint64_t helper_bshuffle(uint64_t gsr, uint64_t src1, uint64_t src2) { union { uint64_t ll[2]; diff --git a/vl.c b/vl.c index ba55b356cf..d5868b197e 100644 --- a/vl.c +++ b/vl.c @@ -271,7 +271,6 @@ static int default_serial = 1; static int default_parallel = 1; static int default_virtcon = 1; static int default_monitor = 1; -static int default_vga = 1; static int default_floppy = 1; static int default_cdrom = 1; static int default_sdcard = 1; @@ -290,11 +289,6 @@ static struct { { .driver = "virtio-serial-pci", .flag = &default_virtcon }, { .driver = "virtio-serial-s390", .flag = &default_virtcon }, { .driver = "virtio-serial", .flag = &default_virtcon }, - { .driver = "VGA", .flag = &default_vga }, - { .driver = "cirrus-vga", .flag = &default_vga }, - { .driver = "vmware-svga", .flag = &default_vga }, - { .driver = "isa-vga", .flag = &default_vga }, - { .driver = "qxl-vga", .flag = &default_vga }, }; static void res_free(void) @@ -1525,18 +1519,48 @@ static const QEMUOption qemu_options[] = { #include "qemu-options-wrapper.h" { NULL }, }; + +static bool vga_available(void) +{ + return qdev_exists("VGA") || qdev_exists("isa-vga"); +} + +static bool cirrus_vga_available(void) +{ + return qdev_exists("cirrus-vga") || qdev_exists("isa-cirrus-vga"); +} + +static bool vmware_vga_available(void) +{ + return qdev_exists("vmware-svga"); +} + static void select_vgahw (const char *p) { const char *opts; - default_vga = 0; vga_interface_type = VGA_NONE; if (strstart(p, "std", &opts)) { - vga_interface_type = VGA_STD; + if (vga_available()) { + vga_interface_type = VGA_STD; + } else { + fprintf(stderr, "Error: standard VGA not available\n"); + exit(0); + } } else if (strstart(p, "cirrus", &opts)) { - vga_interface_type = VGA_CIRRUS; + if (cirrus_vga_available()) { + vga_interface_type = VGA_CIRRUS; + } else { + fprintf(stderr, "Error: Cirrus VGA not available\n"); + exit(0); + } } else if (strstart(p, "vmware", &opts)) { - vga_interface_type = VGA_VMWARE; + if (vmware_vga_available()) { + vga_interface_type = VGA_VMWARE; + } else { + fprintf(stderr, "Error: VMWare SVGA not available\n"); + exit(0); + } } else if (strstart(p, "xenfb", &opts)) { vga_interface_type = VGA_XENFB; } else if (strstart(p, "qxl", &opts)) { @@ -2155,6 +2179,7 @@ int main(int argc, char **argv, char **envp) const char *loadvm = NULL; QEMUMachine *machine; const char *cpu_model; + const char *vga_model = NULL; const char *pid_file = NULL; const char *incoming = NULL; #ifdef CONFIG_VNC @@ -2581,7 +2606,7 @@ int main(int argc, char **argv, char **envp) rtc_utc = 0; break; case QEMU_OPTION_vga: - select_vgahw (optarg); + vga_model = optarg; break; case QEMU_OPTION_g: { @@ -2978,7 +3003,6 @@ int main(int argc, char **argv, char **envp) default_parallel = 0; default_virtcon = 0; default_monitor = 0; - default_vga = 0; default_net = 0; default_floppy = 0; default_cdrom = 0; @@ -3140,9 +3164,6 @@ int main(int argc, char **argv, char **envp) if (!machine->use_virtcon) { default_virtcon = 0; } - if (machine->no_vga) { - default_vga = 0; - } if (machine->no_floppy) { default_floppy = 0; } @@ -3178,8 +3199,6 @@ int main(int argc, char **argv, char **envp) if (default_virtcon) add_device_config(DEV_VIRTCON, "vc:80Cx24C"); } - if (default_vga) - vga_interface_type = VGA_CIRRUS; socket_init(); @@ -3330,6 +3349,15 @@ int main(int argc, char **argv, char **envp) module_call_init(MODULE_INIT_DEVICE); + /* must be after qdev registration but before machine init */ + if (vga_model) { + select_vgahw(vga_model); + } else if (cirrus_vga_available()) { + select_vgahw("cirrus"); + } else { + select_vgahw("none"); + } + if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0) != 0) exit(0); |